From 85e3bde318af38a1726c0db76f9f00b9ce87b83d Mon Sep 17 00:00:00 2001 From: Ian He Date: Thu, 15 May 2025 12:14:05 +1200 Subject: [PATCH 1/2] introduce chat api to the project supported by langchain's sqlagent * remove project service to drop support for legacy version of subql node --- packages/query/README.md | 27 + packages/query/package.json | 6 + packages/query/src/app.module.ts | 5 +- .../query/src/configure/configure.module.ts | 18 +- packages/query/src/graphql/graphql.module.ts | 8 +- packages/query/src/graphql/project.service.ts | 39 -- packages/query/src/llm/chat.module.ts | 186 ++++++ packages/query/src/llm/createLLM.ts | 35 + packages/query/src/yargs.ts | 12 + yarn.lock | 598 +++++++++++++++++- 10 files changed, 877 insertions(+), 57 deletions(-) delete mode 100644 packages/query/src/graphql/project.service.ts create mode 100644 packages/query/src/llm/chat.module.ts create mode 100644 packages/query/src/llm/createLLM.ts diff --git a/packages/query/README.md b/packages/query/README.md index c330ca2af4..bea858b148 100644 --- a/packages/query/README.md +++ b/packages/query/README.md @@ -17,3 +17,30 @@ then run the following command ```sh NODE_OPTIONS="-r dotenv/config" yarn start:dev -- --name --playground ``` + +## LLM Configuration + +Suggest to use reasoning models to archive better quality of results. + +### Choose one of the following providers: + +### Option 1: OpenAI + +LLM_PROVIDER=openai +LLM_MODEL=o1 # Optional: defaults to '4o-mini' +OPENAI_API_KEY=your_openai_api_key + +### Option 2: Anthropic Claude + +LLM_PROVIDER=anthropic +LLM_MODEL=claude-3-7-sonnet-latest # Optional: defaults to 'claude-3-7-sonnet-latest' +ANTHROPIC_API_KEY=your_anthropic_api_key + +### Option 3: Custom OpenAI-compatible endpoint + +LLM_PROVIDER=openai +LLM_BASE_URL=http://your-llm-endpoint/v1 # Required for custom provider +LLM_MODEL=your-model-name # Required: model name for custom endpoint +OPENAI_API_KEY=your_api_key # Optional: API key for custom endpoint + +### Common LLM Settings diff --git a/packages/query/package.json b/packages/query/package.json index 235814bd66..4a8a072564 100644 --- a/packages/query/package.json +++ b/packages/query/package.json @@ -35,6 +35,10 @@ "@graphile-contrib/pg-simplify-inflector": "^6.1.0", "@graphile/pg-aggregates": "^0.1.1", "@graphile/pg-pubsub": "^4.13.0", + "@langchain/anthropic": "^0.3.20", + "@langchain/core": "^0.3.55", + "@langchain/langgraph": "^0.2.71", + "@langchain/openai": "^0.5.10", "@nestjs/common": "^9.4.0", "@nestjs/core": "^9.4.0", "@nestjs/platform-express": "^9.4.0", @@ -50,12 +54,14 @@ "graphql": "^15.8.0", "graphql-query-complexity": "^0.11.0", "graphql-ws": "^5.16.0", + "langchain": "^0.3.24", "lodash": "^4.17.21", "pg": "^8.12.0", "pg-tsquery": "^8.4.2", "postgraphile": "^4.13.0", "postgraphile-plugin-connection-filter": "^2.2.2", "rxjs": "^7.1.0", + "typeorm": "^0.3.23", "ws": "^8.18.0", "yargs": "^16.2.0" }, diff --git a/packages/query/src/app.module.ts b/packages/query/src/app.module.ts index 91306f6ead..49548e1173 100644 --- a/packages/query/src/app.module.ts +++ b/packages/query/src/app.module.ts @@ -4,9 +4,12 @@ import {Module} from '@nestjs/common'; import {ConfigureModule} from './configure/configure.module'; import {GraphqlModule} from './graphql/graphql.module'; +import {ChatModule} from './llm/chat.module'; @Module({ - imports: [ConfigureModule.register(), GraphqlModule], + // the order is essential, the ChatModule must be before the GraphqlModule so /v1/chat/completions + // can be handled without interference from the GraphqlModule + imports: [ConfigureModule.register(), ChatModule, GraphqlModule], controllers: [], }) export class AppModule {} diff --git a/packages/query/src/configure/configure.module.ts b/packages/query/src/configure/configure.module.ts index 9ab093a424..578898cfe3 100644 --- a/packages/query/src/configure/configure.module.ts +++ b/packages/query/src/configure/configure.module.ts @@ -5,6 +5,7 @@ import {ConnectionOptions} from 'tls'; import {DynamicModule, Global, Module} from '@nestjs/common'; import {getFileContent, CONNECTION_SSL_ERROR_REGEX} from '@subql/common'; import {Pool, PoolConfig} from 'pg'; +import {DataSource} from 'typeorm'; import {getLogger} from '../utils/logger'; import {getYargsOption} from '../yargs'; import {Config} from './config'; @@ -85,6 +86,17 @@ export class ConfigureModule { pgClient._explainResults = []; }); } + // todo: support ssl + const dataSource = new DataSource({ + type: 'postgres', + host: config.get('DB_HOST_READ'), + port: config.get('DB_PORT'), + username: config.get('DB_USER'), + password: config.get('DB_PASS'), + database: config.get('DB_DATABASE'), + schema: config.get('name'), + }); + await dataSource.initialize(); return { module: ConfigureModule, providers: [ @@ -96,8 +108,12 @@ export class ConfigureModule { provide: Pool, useValue: pgPool, }, + { + provide: DataSource, + useValue: dataSource, + }, ], - exports: [Config, Pool], + exports: [Config, Pool, DataSource], }; } } diff --git a/packages/query/src/graphql/graphql.module.ts b/packages/query/src/graphql/graphql.module.ts index 4a21da0d5b..816c1cd12b 100644 --- a/packages/query/src/graphql/graphql.module.ts +++ b/packages/query/src/graphql/graphql.module.ts @@ -30,7 +30,6 @@ import {playgroundPlugin} from './plugins/PlaygroundPlugin'; import {queryAliasLimit} from './plugins/QueryAliasLimitPlugin'; import {queryComplexityPlugin} from './plugins/QueryComplexityPlugin'; import {queryDepthLimitPlugin} from './plugins/QueryDepthLimitPlugin'; -import {ProjectService} from './project.service'; const {argv} = getYargsOption(); const logger = getLogger('graphql-module'); @@ -45,7 +44,7 @@ class NoInitError extends Error { } } @Module({ - providers: [ProjectService], + providers: [], }) export class GraphqlModule implements OnModuleInit, OnModuleDestroy { private _apolloServer?: ApolloServer; @@ -53,8 +52,7 @@ export class GraphqlModule implements OnModuleInit, OnModuleDestroy { constructor( private readonly httpAdapterHost: HttpAdapterHost, private readonly config: Config, - private readonly pgPool: Pool, - private readonly projectService: ProjectService + private readonly pgPool: Pool ) {} private get apolloServer(): ApolloServer { @@ -138,7 +136,7 @@ export class GraphqlModule implements OnModuleInit, OnModuleDestroy { const schemaName = this.config.get('name'); if (!schemaName) throw new Error('Unable to get schema name from config'); - const dbSchema = await this.projectService.getProjectSchema(schemaName); + const dbSchema = schemaName; let options: PostGraphileCoreOptions = { replaceAllPlugins: plugins, subscriptions: true, diff --git a/packages/query/src/graphql/project.service.ts b/packages/query/src/graphql/project.service.ts deleted file mode 100644 index 6656153aea..0000000000 --- a/packages/query/src/graphql/project.service.ts +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors -// SPDX-License-Identifier: GPL-3.0 - -import {Injectable} from '@nestjs/common'; -import {Pool} from 'pg'; -import {Config} from '../configure'; - -@Injectable() -export class ProjectService { - constructor( - private readonly pool: Pool, - private readonly config: Config - ) {} - - async getProjectSchema(name: string): Promise { - // After subqueries table has been deprecated, project may not be present in subqueries table - const result = await this.pool - .query<{schema_name: string}, any[]>(`SELECT schema_name FROM information_schema.schemata`) - .then((obj) => obj.rows.map((x) => x.schema_name)) - .catch((e) => { - throw new Error(`Unable to fetch all database schemas: ${e}`); - }); - if (result.includes(name)) { - return name; - } else { - // fallback to subqueries table - const {rows} = await this.pool.query( - `SELECT * - FROM public.subqueries - WHERE name = $1`, - [name] - ); - if (rows.length === 0) { - throw new Error(`unknown project name ${this.config.get('name')}`); - } - return rows[0].db_schema; - } - } -} diff --git a/packages/query/src/llm/chat.module.ts b/packages/query/src/llm/chat.module.ts new file mode 100644 index 0000000000..7c287a3dbb --- /dev/null +++ b/packages/query/src/llm/chat.module.ts @@ -0,0 +1,186 @@ +// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors +// SPDX-License-Identifier: GPL-3.0 + +import {BaseMessage, SystemMessage} from '@langchain/core/messages'; +import {createReactAgent} from '@langchain/langgraph/prebuilt'; +import {Module, OnModuleInit} from '@nestjs/common'; +import {HttpAdapterHost} from '@nestjs/core'; +import {SqlToolkit} from 'langchain/agents/toolkits/sql'; +import {SqlDatabase} from 'langchain/sql_db'; +import {DataSource} from 'typeorm'; +import {Config} from '../configure'; +import {getLogger} from '../utils/logger'; +import {getYargsOption} from '../yargs'; +import {createLLM} from './createLLM'; + +const {argv} = getYargsOption(); +const logger = getLogger('chat-module'); + +@Module({ + providers: [], +}) +export class ChatModule implements OnModuleInit { + agent?: ReturnType; + + constructor( + private readonly httpAdapterHost: HttpAdapterHost, + private readonly dataSource: DataSource, + private readonly config: Config + ) {} + + onModuleInit(): void { + if (!this.httpAdapterHost) { + return; + } + try { + this.createServer(); + } catch (e: any) { + throw new Error(`create apollo server failed, ${e.message}`); + } + } + + private async initializeAgent() { + const db = await SqlDatabase.fromDataSourceParams({ + appDataSource: this.dataSource, + }); + + const llm = createLLM(); + + const toolkit = new SqlToolkit(db, llm); + + this.agent = createReactAgent({ + llm, + tools: toolkit.getTools(), + prompt: new SystemMessage( + `You are an AI assistant that helps users query their PostgreSQL database using natural language. + +When generating SQL queries: +* Always use the correct schema (${this.config.get('name') || 'public'}) +* Only query tables that are available to you +* Never mutate database, including add/update/remove record from any table, run any DLL statements, only read. +* Always limit the query with maximum 100 rows +* Format your responses in a clear, readable way +* If you're unsure about the schema or table structure, ask for clarification +* If a table has column _block_range, it is a versioned table, You MUST always add \`_block_range @> 9223372036854775807\` to the where clause for all queries +* If it is a join query, \`_block_range @> 9223372036854775807\` is needed for all tables in the join` + ), + }); + } + + private createServer() { + const app = this.httpAdapterHost.httpAdapter.getInstance(); + + if (argv.chat) { + app.post('/v1/chat/completions', async (req, res) => { + try { + if (!this.agent) { + await this.initializeAgent(); + } + + const {messages, stream = false} = req.body; + + if (!messages || !Array.isArray(messages) || messages.length === 0) { + return res.status(400).json({ + error: { + message: 'messages is required and must be a non-empty array', + type: 'invalid_request_error', + code: 'invalid_messages', + }, + }); + } + + // Convert OpenAI format messages to LangChain format + const lastMessage = messages[messages.length - 1]; + const question = lastMessage.content; + + res.setHeader('Content-Type', 'text/event-stream'); + res.setHeader('Cache-Control', 'no-cache'); + res.setHeader('Connection', 'keep-alive'); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const result = await this.agent!.stream({messages: [['user', question]]}, {streamMode: 'values'}); + + let fullResponse = ''; + for await (const event of result) { + const lastMsg: BaseMessage = event.messages[event.messages.length - 1]; + if (lastMsg.content) { + fullResponse = lastMsg.content as string; + logger.info(`Streaming response: ${JSON.stringify(lastMsg)}`); + if (argv['llm-debug'] && stream) { + // todo: send them as thinking details + res.write( + `data: ${JSON.stringify({ + id: `chatcmpl-${Date.now()}`, + object: 'chat.completion.chunk', + created: Math.floor(Date.now() / 1000), + model: process.env.OPENAI_MODEL, + choices: [ + { + index: 0, + delta: {content: lastMsg.content}, + finish_reason: null, + }, + ], + })}\n\n` + ); + } + } + } + + // Send final message + if (stream) { + res.write( + `data: ${JSON.stringify({ + id: `chatcmpl-${Date.now()}`, + object: 'chat.completion.chunk', + created: Math.floor(Date.now() / 1000), + model: process.env.OPENAI_MODEL, + choices: [ + { + index: 0, + message: {role: 'assistant', content: fullResponse}, + finish_reason: 'stop', + }, + ], + })}\n\n` + ); + } else { + res.write( + `data: ${JSON.stringify({ + id: `chatcmpl-${Date.now()}`, + object: 'chat.completion', + created: Math.floor(Date.now() / 1000), + model: process.env.OPENAI_MODEL, + choices: [ + { + index: 0, + message: {role: 'assistant', content: fullResponse}, + finish_reason: 'stop', + }, + ], + })}\n\n` + ); + } + res.end(); + } catch (error) { + logger.error('Error processing request:', error); + res.status(500).json({ + error: { + message: (error as any).message, + type: 'internal_server_error', + }, + }); + } + }); + } else { + app.post('/v1/chat/completions', (req, res) => { + res.status(404).json({ + error: { + message: 'Chat completions API is not enabled', + type: 'invalid_request_error', + code: 'chat_api_not_enabled', + }, + }); + }); + } + } +} diff --git a/packages/query/src/llm/createLLM.ts b/packages/query/src/llm/createLLM.ts new file mode 100644 index 0000000000..22be4a8082 --- /dev/null +++ b/packages/query/src/llm/createLLM.ts @@ -0,0 +1,35 @@ +// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors +// SPDX-License-Identifier: GPL-3.0 + +import {ChatAnthropic} from '@langchain/anthropic'; +import {ChatOpenAI} from '@langchain/openai'; + +export function createLLM() { + const baseConfig = { + model: process.env.LLM_MODEL || 'gpt-4o', + }; + + // Determine which provider to use + const provider = process.env.LLM_PROVIDER?.toLowerCase() || 'openai'; + + switch (provider) { + case 'anthropic': + return new ChatAnthropic({ + ...baseConfig, + anthropicApiKey: process.env.ANTHROPIC_API_KEY, + // Claude models have different names + model: process.env.LLM_MODEL || 'claude-3-7-sonnet-latest', + }); + case 'openai': + default: + return new ChatOpenAI({ + ...baseConfig, + openAIApiKey: process.env.OPENAI_API_KEY || 'not-needed', + configuration: process.env.LLM_BASE_URL + ? { + baseURL: process.env.LLM_BASE_URL, + } + : undefined, + }); + } +} diff --git a/packages/query/src/yargs.ts b/packages/query/src/yargs.ts index 7267433ff5..84947d8dbd 100644 --- a/packages/query/src/yargs.ts +++ b/packages/query/src/yargs.ts @@ -16,6 +16,18 @@ export function getYargsOption() { describe: 'Enable aggregate feature', type: 'boolean', }, + chat: { + demandOption: false, + describe: 'enable openai compatible chat api, /v1/chat/completions', + type: 'boolean', + default: true, + }, + 'chat-debug': { + demandOption: false, + default: false, + describe: 'Enable debug for llm chat feature', + type: 'boolean', + }, 'disable-hot-schema': { demandOption: false, describe: 'Hot reload schema on schema-changes', diff --git a/yarn.lock b/yarn.lock index dfaded90c6..688a6f92b6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -129,6 +129,21 @@ __metadata: languageName: node linkType: hard +"@anthropic-ai/sdk@npm:^0.39.0": + version: 0.39.0 + resolution: "@anthropic-ai/sdk@npm:0.39.0" + dependencies: + "@types/node": ^18.11.18 + "@types/node-fetch": ^2.6.4 + abort-controller: ^3.0.0 + agentkeepalive: ^4.2.1 + form-data-encoder: 1.7.2 + formdata-node: ^4.3.2 + node-fetch: ^2.6.7 + checksum: 47f00c9d3ca2d497b25c688cdfd923474e2f16e774f67a3e2ef3f0c24cd80412687e3a2caee3024dd9a5d7a95e0717d85e3ffc9c4ba75ff6f1641d5820394a76 + languageName: node + linkType: hard + "@apollo/client@npm:^3.11.2": version: 3.11.2 resolution: "@apollo/client@npm:3.11.2" @@ -3234,6 +3249,13 @@ __metadata: languageName: node linkType: hard +"@cfworker/json-schema@npm:^4.0.2": + version: 4.1.1 + resolution: "@cfworker/json-schema@npm:4.1.1" + checksum: 35b5b246eff7bc75a17befb6e6d56475ab9261279c5d727610dc6827cce557d11db353cca3c06b8272f3974eb2ac508a7bbae3accd3d6c8402dfe0aafbfea0aa + languageName: node + linkType: hard + "@concordium/common-sdk@npm:9.4.0": version: 9.4.0 resolution: "@concordium/common-sdk@npm:9.4.0" @@ -5145,6 +5167,114 @@ __metadata: languageName: node linkType: hard +"@langchain/anthropic@npm:^0.3.20": + version: 0.3.20 + resolution: "@langchain/anthropic@npm:0.3.20" + dependencies: + "@anthropic-ai/sdk": ^0.39.0 + fast-xml-parser: ^4.4.1 + zod: ^3.22.4 + zod-to-json-schema: ^3.22.4 + peerDependencies: + "@langchain/core": ">=0.3.48 <0.4.0" + checksum: a7dcf60cc089696a7c9ff72ba89a2ceb79f902831d1e5d1e747473bfa20c870c16d30e25370252bf78d3dc812e49b3133463432d0792777a81bc6616d95aff0d + languageName: node + linkType: hard + +"@langchain/core@npm:^0.3.55": + version: 0.3.55 + resolution: "@langchain/core@npm:0.3.55" + dependencies: + "@cfworker/json-schema": ^4.0.2 + ansi-styles: ^5.0.0 + camelcase: 6 + decamelize: 1.2.0 + js-tiktoken: ^1.0.12 + langsmith: ^0.3.16 + mustache: ^4.2.0 + p-queue: ^6.6.2 + p-retry: 4 + uuid: ^10.0.0 + zod: ^3.22.4 + zod-to-json-schema: ^3.22.3 + checksum: 8a433f6f3118c0abfb9209cb31843e35a73f1f38aa8565383ec8ea5bd12e217be9369c88f4fb60215730f3248a069bcfbb9c036ea30fdbf2827c50c844ed8620 + languageName: node + linkType: hard + +"@langchain/langgraph-checkpoint@npm:~0.0.17": + version: 0.0.17 + resolution: "@langchain/langgraph-checkpoint@npm:0.0.17" + dependencies: + uuid: ^10.0.0 + peerDependencies: + "@langchain/core": ">=0.2.31 <0.4.0" + checksum: c8dc429e66ff5b0f31037c493c4f8687196f1800d52b48e8ff04829742cd7200af66ce46dee93ff3c0f6b6e6c2af36336f09626a5ce296ec610383a3bd7131ef + languageName: node + linkType: hard + +"@langchain/langgraph-sdk@npm:~0.0.32": + version: 0.0.74 + resolution: "@langchain/langgraph-sdk@npm:0.0.74" + dependencies: + "@types/json-schema": ^7.0.15 + p-queue: ^6.6.2 + p-retry: 4 + uuid: ^9.0.0 + peerDependencies: + "@langchain/core": ">=0.2.31 <0.4.0" + react: ^18 || ^19 + peerDependenciesMeta: + "@langchain/core": + optional: true + react: + optional: true + checksum: 816a680333c96ddeda1aca722f11fc4e9e21687b9faa908b4a340cb0107310ea71996681fc8379842e1a990dbc7d9cda1d8dc35ed2ff9ba2f6ba8323c1c57058 + languageName: node + linkType: hard + +"@langchain/langgraph@npm:^0.2.71": + version: 0.2.71 + resolution: "@langchain/langgraph@npm:0.2.71" + dependencies: + "@langchain/langgraph-checkpoint": ~0.0.17 + "@langchain/langgraph-sdk": ~0.0.32 + uuid: ^10.0.0 + zod: ^3.23.8 + peerDependencies: + "@langchain/core": ">=0.2.36 <0.3.0 || >=0.3.40 < 0.4.0" + zod-to-json-schema: ^3.x + peerDependenciesMeta: + zod-to-json-schema: + optional: true + checksum: c8d3d9b381509a4b82731990dbc4134cf4725e64ead82c2bd2e1aac17e742aeda0e45cc0ae5748a21baa63d0c80095a6ea5cbd2361145dccba9f4f62932f89bf + languageName: node + linkType: hard + +"@langchain/openai@npm:>=0.1.0 <0.6.0, @langchain/openai@npm:^0.5.10": + version: 0.5.10 + resolution: "@langchain/openai@npm:0.5.10" + dependencies: + js-tiktoken: ^1.0.12 + openai: ^4.96.0 + zod: ^3.22.4 + zod-to-json-schema: ^3.22.3 + peerDependencies: + "@langchain/core": ">=0.3.48 <0.4.0" + checksum: 0fbd0f6781b2069b8276df5837ea4c98f2344485622cc0f44633c8401cc7b9f1fdd0c53cef4ba860fc95bf1d37e905dc3a8d138c938735a0df24d4ecdf3137f1 + languageName: node + linkType: hard + +"@langchain/textsplitters@npm:>=0.0.0 <0.2.0": + version: 0.1.0 + resolution: "@langchain/textsplitters@npm:0.1.0" + dependencies: + js-tiktoken: ^1.0.12 + peerDependencies: + "@langchain/core": ">=0.2.21 <0.4.0" + checksum: f179113423b003968127abc0b41c23e9ba21bed9336745841bf54b95e283fc3cbfcd67e40d1b58922b89b35953caeb38d8d5d7a3a49c1c5b202f1542bf76dc3a + languageName: node + linkType: hard + "@lukeed/csprng@npm:^1.0.0": version: 1.1.0 resolution: "@lukeed/csprng@npm:1.1.0" @@ -6856,6 +6986,13 @@ __metadata: languageName: node linkType: hard +"@sqltools/formatter@npm:^1.2.5": + version: 1.2.5 + resolution: "@sqltools/formatter@npm:1.2.5" + checksum: 9b8354e715467d660daa5afe044860b5686bbb1a5cb67a60866b932effafbf5e8b429f19a8ae67cd412065a4f067161f227e182f3664a0245339d5eb1e26e355 + languageName: node + linkType: hard + "@stellar/js-xdr@npm:^3.1.2": version: 3.1.2 resolution: "@stellar/js-xdr@npm:3.1.2" @@ -7216,6 +7353,10 @@ __metadata: "@graphile-contrib/pg-simplify-inflector": ^6.1.0 "@graphile/pg-aggregates": ^0.1.1 "@graphile/pg-pubsub": ^4.13.0 + "@langchain/anthropic": ^0.3.20 + "@langchain/core": ^0.3.55 + "@langchain/langgraph": ^0.2.71 + "@langchain/openai": ^0.5.10 "@nestjs/common": ^9.4.0 "@nestjs/core": ^9.4.0 "@nestjs/platform-express": ^9.4.0 @@ -7240,6 +7381,7 @@ __metadata: graphql: ^15.8.0 graphql-query-complexity: ^0.11.0 graphql-ws: ^5.16.0 + langchain: ^0.3.24 lodash: ^4.17.21 nodemon: ^3.1.4 pg: ^8.12.0 @@ -7247,6 +7389,7 @@ __metadata: postgraphile: ^4.13.0 postgraphile-plugin-connection-filter: ^2.2.2 rxjs: ^7.1.0 + typeorm: ^0.3.23 ws: ^8.18.0 yargs: ^16.2.0 bin: @@ -8023,6 +8166,13 @@ __metadata: languageName: node linkType: hard +"@types/json-schema@npm:^7.0.15": + version: 7.0.15 + resolution: "@types/json-schema@npm:7.0.15" + checksum: 97ed0cb44d4070aecea772b7b2e2ed971e10c81ec87dd4ecc160322ffa55ff330dace1793489540e3e318d90942064bb697cc0f8989391797792d919737b3b98 + languageName: node + linkType: hard + "@types/json-schema@npm:^7.0.7, @types/json-schema@npm:^7.0.8, @types/json-schema@npm:^7.0.9": version: 7.0.11 resolution: "@types/json-schema@npm:7.0.11" @@ -8148,6 +8298,16 @@ __metadata: languageName: node linkType: hard +"@types/node-fetch@npm:^2.6.4": + version: 2.6.12 + resolution: "@types/node-fetch@npm:2.6.12" + dependencies: + "@types/node": "*" + form-data: ^4.0.0 + checksum: 9647e68f9a125a090220c38d77b3c8e669c488658ae7506f1b4f9568214beba087624b1705bba1dc76649a65281ce3fd5b400e15266cbef8088027fb88777557 + languageName: node + linkType: hard + "@types/node@npm:*, @types/node@npm:>=13.7.0": version: 17.0.31 resolution: "@types/node@npm:17.0.31" @@ -8169,6 +8329,15 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:^18.11.18": + version: 18.19.100 + resolution: "@types/node@npm:18.19.100" + dependencies: + undici-types: ~5.26.4 + checksum: b84c705cd723526aa10f08dce2f7df69d824f6702e728efd73a2819c0c618a4e0be4eedbca40454827625b00c0f5e1fd5ac4aedc81cb8b9222643f7d78dae473 + languageName: node + linkType: hard + "@types/node@npm:^18.19.42": version: 18.19.42 resolution: "@types/node@npm:18.19.42" @@ -8298,6 +8467,13 @@ __metadata: languageName: node linkType: hard +"@types/retry@npm:0.12.0": + version: 0.12.0 + resolution: "@types/retry@npm:0.12.0" + checksum: 61a072c7639f6e8126588bf1eb1ce8835f2cb9c2aba795c4491cf6310e013267b0c8488039857c261c387e9728c1b43205099223f160bb6a76b4374f741b5603 + languageName: node + linkType: hard + "@types/rimraf@npm:3.0.2": version: 3.0.2 resolution: "@types/rimraf@npm:3.0.2" @@ -8383,6 +8559,13 @@ __metadata: languageName: node linkType: hard +"@types/uuid@npm:^10.0.0": + version: 10.0.0 + resolution: "@types/uuid@npm:10.0.0" + checksum: e3958f8b0fe551c86c14431f5940c3470127293280830684154b91dc7eb3514aeb79fe3216968833cf79d4d1c67f580f054b5be2cd562bebf4f728913e73e944 + languageName: node + linkType: hard + "@types/validator@npm:^13.11.8": version: 13.11.9 resolution: "@types/validator@npm:13.11.9" @@ -9299,6 +9482,13 @@ __metadata: languageName: node linkType: hard +"ansis@npm:^3.17.0": + version: 3.17.0 + resolution: "ansis@npm:3.17.0" + checksum: 6fd6bc4d1187b894d9706f4c141c81b788e90766426617385486dae38f8b2f5a1726d8cc754939e44265f92a9db4647d5136cb1425435c39ac42b35e3acf4f3d + languageName: node + linkType: hard + "any-promise@npm:^1.0.0": version: 1.3.0 resolution: "any-promise@npm:1.3.0" @@ -9433,6 +9623,13 @@ __metadata: languageName: node linkType: hard +"app-root-path@npm:^3.1.0": + version: 3.1.0 + resolution: "app-root-path@npm:3.1.0" + checksum: e3db3957aee197143a0f6c75e39fe89b19e7244f28b4f2944f7276a9c526d2a7ab2d115b4b2d70a51a65a9a3ca17506690e5b36f75a068a7e5a13f8c092389ba + languageName: node + linkType: hard + "append-field@npm:^1.0.0": version: 1.0.0 resolution: "append-field@npm:1.0.0" @@ -9937,7 +10134,7 @@ __metadata: languageName: node linkType: hard -"base64-js@npm:^1.0.2, base64-js@npm:^1.3.0, base64-js@npm:^1.3.1": +"base64-js@npm:^1.0.2, base64-js@npm:^1.3.0, base64-js@npm:^1.3.1, base64-js@npm:^1.5.1": version: 1.5.1 resolution: "base64-js@npm:1.5.1" checksum: 669632eb3745404c2f822a18fc3a0122d2f9a7a13f7fb8b5823ee19d1d2ff9ee5b52c53367176ea4ad093c332fd5ab4bd0ebae5a8e27917a4105a4cfc86b1005 @@ -10607,6 +10804,13 @@ __metadata: languageName: node linkType: hard +"camelcase@npm:6, camelcase@npm:^6.2.0": + version: 6.3.0 + resolution: "camelcase@npm:6.3.0" + checksum: 8c96818a9076434998511251dcb2761a94817ea17dbdc37f47ac080bd088fc62c7369429a19e2178b993497132c8cbcf5cc1f44ba963e76782ba469c0474938d + languageName: node + linkType: hard + "camelcase@npm:^5.0.0, camelcase@npm:^5.3.1": version: 5.3.1 resolution: "camelcase@npm:5.3.1" @@ -10614,13 +10818,6 @@ __metadata: languageName: node linkType: hard -"camelcase@npm:^6.2.0": - version: 6.3.0 - resolution: "camelcase@npm:6.3.0" - checksum: 8c96818a9076434998511251dcb2761a94817ea17dbdc37f47ac080bd088fc62c7369429a19e2178b993497132c8cbcf5cc1f44ba963e76782ba469c0474938d - languageName: node - linkType: hard - "camelcase@npm:^7.0.1": version: 7.0.1 resolution: "camelcase@npm:7.0.1" @@ -11362,6 +11559,15 @@ __metadata: languageName: node linkType: hard +"console-table-printer@npm:^2.12.1": + version: 2.12.1 + resolution: "console-table-printer@npm:2.12.1" + dependencies: + simple-wcswidth: ^1.0.1 + checksum: 4d58fd4f18d3a69f421c9b0ffd44e5b0542677423491199e92c3e5ca0c023a06304a94bcc60f0d2b480a06cdf0720d2f228807f2af127abc8c905e73fcf64363 + languageName: node + linkType: hard + "content-disposition@npm:0.5.4": version: 0.5.4 resolution: "content-disposition@npm:0.5.4" @@ -11649,6 +11855,13 @@ __metadata: languageName: node linkType: hard +"dayjs@npm:^1.11.13": + version: 1.11.13 + resolution: "dayjs@npm:1.11.13" + checksum: f388db88a6aa93956c1f6121644e783391c7b738b73dbc54485578736565c8931bdfba4bb94e9b1535c6e509c97d5deb918bbe1ae6b34358d994de735055cca9 + languageName: node + linkType: hard + "debug@npm:2.6.9, debug@npm:^2.2.0, debug@npm:^2.6.9": version: 2.6.9 resolution: "debug@npm:2.6.9" @@ -11700,6 +11913,18 @@ __metadata: languageName: node linkType: hard +"debug@npm:^4.4.0": + version: 4.4.0 + resolution: "debug@npm:4.4.0" + dependencies: + ms: ^2.1.3 + peerDependenciesMeta: + supports-color: + optional: true + checksum: fb42df878dd0e22816fc56e1fdca9da73caa85212fbe40c868b1295a6878f9101ae684f4eeef516c13acfc700f5ea07f1136954f43d4cd2d477a811144136479 + languageName: node + linkType: hard + "debuglog@npm:^1.0.1": version: 1.0.1 resolution: "debuglog@npm:1.0.1" @@ -11707,6 +11932,13 @@ __metadata: languageName: node linkType: hard +"decamelize@npm:1.2.0": + version: 1.2.0 + resolution: "decamelize@npm:1.2.0" + checksum: ad8c51a7e7e0720c70ec2eeb1163b66da03e7616d7b98c9ef43cce2416395e84c1e9548dd94f5f6ffecfee9f8b94251fc57121a8b021f2ff2469b2bae247b8aa + languageName: node + linkType: hard + "decode-uri-component@npm:^0.2.0": version: 0.2.2 resolution: "decode-uri-component@npm:0.2.2" @@ -11950,6 +12182,13 @@ __metadata: languageName: node linkType: hard +"dotenv@npm:^16.4.7": + version: 16.5.0 + resolution: "dotenv@npm:16.5.0" + checksum: 6543fe87b5ddf2d60dd42df6616eec99148a5fc150cb4530fef5bda655db5204a3afa0e6f25f7cd64b20657ace4d79c0ef974bec32fdb462cad18754191e7a90 + languageName: node + linkType: hard + "dottie@npm:^2.0.2": version: 2.0.6 resolution: "dottie@npm:2.0.6" @@ -13223,6 +13462,17 @@ __metadata: languageName: node linkType: hard +"fast-xml-parser@npm:^4.4.1": + version: 4.5.3 + resolution: "fast-xml-parser@npm:4.5.3" + dependencies: + strnum: ^1.1.1 + bin: + fxparser: src/cli/cli.js + checksum: cd6a184941ec6c23f9e6b514421a3f396cfdff5f4a8c7c27bd0eff896edb4a2b55c27da16f09b789663613dfc4933602b9b71ac3e9d1d2ddcc0492fc46c8fa52 + languageName: node + linkType: hard + "fastest-levenshtein@npm:^1.0.7": version: 1.0.16 resolution: "fastest-levenshtein@npm:1.0.16" @@ -13489,6 +13739,13 @@ __metadata: languageName: node linkType: hard +"form-data-encoder@npm:1.7.2": + version: 1.7.2 + resolution: "form-data-encoder@npm:1.7.2" + checksum: aeebd87a1cb009e13cbb5e4e4008e6202ed5f6551eb6d9582ba8a062005178907b90f4887899d3c993de879159b6c0c940af8196725b428b4248cec5af3acf5f + languageName: node + linkType: hard + "form-data@npm:^4.0.0": version: 4.0.0 resolution: "form-data@npm:4.0.0" @@ -13511,6 +13768,16 @@ __metadata: languageName: node linkType: hard +"formdata-node@npm:^4.3.2": + version: 4.4.1 + resolution: "formdata-node@npm:4.4.1" + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 4.0.0-beta.3 + checksum: d91d4f667cfed74827fc281594102c0dabddd03c9f8b426fc97123eedbf73f5060ee43205d89284d6854e2fc5827e030cd352ef68b93beda8decc2d72128c576 + languageName: node + linkType: hard + "forwarded@npm:0.2.0": version: 0.2.0 resolution: "forwarded@npm:0.2.0" @@ -13976,7 +14243,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^10.3.7, glob@npm:^10.4": +"glob@npm:^10.3.7, glob@npm:^10.4, glob@npm:^10.4.5": version: 10.4.5 resolution: "glob@npm:10.4.5" dependencies: @@ -16198,6 +16465,15 @@ __metadata: languageName: node linkType: hard +"js-tiktoken@npm:^1.0.12": + version: 1.0.20 + resolution: "js-tiktoken@npm:1.0.20" + dependencies: + base64-js: ^1.5.1 + checksum: 29106a6faa65c85d13ead291ce17b007ef7c16918fdd570d4636b74da33e54b72af66f9d5dd963f2979733f70d4221e4a9655d236395719c5cc04620d9f1e2cd + languageName: node + linkType: hard + "js-tokens@npm:^3.0.0 || ^4.0.0, js-tokens@npm:^4.0.0": version: 4.0.0 resolution: "js-tokens@npm:4.0.0" @@ -16400,6 +16676,13 @@ __metadata: languageName: node linkType: hard +"jsonpointer@npm:^5.0.1": + version: 5.0.1 + resolution: "jsonpointer@npm:5.0.1" + checksum: 0b40f712900ad0c846681ea2db23b6684b9d5eedf55807b4708c656f5894b63507d0e28ae10aa1bddbea551241035afe62b6df0800fc94c2e2806a7f3adecd7c + languageName: node + linkType: hard + "jsonwebtoken@npm:^9.0.0": version: 9.0.0 resolution: "jsonwebtoken@npm:9.0.0" @@ -16479,6 +16762,100 @@ __metadata: languageName: node linkType: hard +"langchain@npm:^0.3.24": + version: 0.3.24 + resolution: "langchain@npm:0.3.24" + dependencies: + "@langchain/openai": ">=0.1.0 <0.6.0" + "@langchain/textsplitters": ">=0.0.0 <0.2.0" + js-tiktoken: ^1.0.12 + js-yaml: ^4.1.0 + jsonpointer: ^5.0.1 + langsmith: ^0.3.16 + openapi-types: ^12.1.3 + p-retry: 4 + uuid: ^10.0.0 + yaml: ^2.2.1 + zod: ^3.22.4 + zod-to-json-schema: ^3.22.3 + peerDependencies: + "@langchain/anthropic": "*" + "@langchain/aws": "*" + "@langchain/cerebras": "*" + "@langchain/cohere": "*" + "@langchain/core": ">=0.2.21 <0.4.0" + "@langchain/deepseek": "*" + "@langchain/google-genai": "*" + "@langchain/google-vertexai": "*" + "@langchain/google-vertexai-web": "*" + "@langchain/groq": "*" + "@langchain/mistralai": "*" + "@langchain/ollama": "*" + "@langchain/xai": "*" + axios: "*" + cheerio: "*" + handlebars: ^4.7.8 + peggy: ^3.0.2 + typeorm: "*" + peerDependenciesMeta: + "@langchain/anthropic": + optional: true + "@langchain/aws": + optional: true + "@langchain/cerebras": + optional: true + "@langchain/cohere": + optional: true + "@langchain/deepseek": + optional: true + "@langchain/google-genai": + optional: true + "@langchain/google-vertexai": + optional: true + "@langchain/google-vertexai-web": + optional: true + "@langchain/groq": + optional: true + "@langchain/mistralai": + optional: true + "@langchain/ollama": + optional: true + "@langchain/xai": + optional: true + axios: + optional: true + cheerio: + optional: true + handlebars: + optional: true + peggy: + optional: true + typeorm: + optional: true + checksum: 6d8426a89caab334ac90f3aaef83df870f5c2a875d7fb3b9d3741fcbe16bfba6856f82db157db158a541858bbab464554ad95d08c70aa4ff1dbc591225493462 + languageName: node + linkType: hard + +"langsmith@npm:^0.3.16": + version: 0.3.28 + resolution: "langsmith@npm:0.3.28" + dependencies: + "@types/uuid": ^10.0.0 + chalk: ^4.1.2 + console-table-printer: ^2.12.1 + p-queue: ^6.6.2 + p-retry: 4 + semver: ^7.6.3 + uuid: ^10.0.0 + peerDependencies: + openai: "*" + peerDependenciesMeta: + openai: + optional: true + checksum: 0057aa8bc40d6b22e7be6f294276b04e0d2842348d0b7e6f0b1e4ec3987572f68fd5e577559fde3341bb206c7504ce462c846b67e9f114488fbe30295ef0d4c9 + languageName: node + linkType: hard + "latest-version@npm:^5.1.0": version: 5.1.0 resolution: "latest-version@npm:5.1.0" @@ -17674,7 +18051,7 @@ __metadata: languageName: node linkType: hard -"mustache@npm:^4.0.0": +"mustache@npm:^4.0.0, mustache@npm:^4.2.0": version: 4.2.0 resolution: "mustache@npm:4.2.0" bin: @@ -17831,6 +18208,13 @@ __metadata: languageName: node linkType: hard +"node-domexception@npm:1.0.0": + version: 1.0.0 + resolution: "node-domexception@npm:1.0.0" + checksum: ee1d37dd2a4eb26a8a92cd6b64dfc29caec72bff5e1ed9aba80c294f57a31ba4895a60fd48347cf17dd6e766da0ae87d75657dfd1f384ebfa60462c2283f5c7f + languageName: node + linkType: hard + "node-fetch@npm:2.6.7": version: 2.6.7 resolution: "node-fetch@npm:2.6.7" @@ -18447,6 +18831,38 @@ __metadata: languageName: node linkType: hard +"openai@npm:^4.96.0": + version: 4.98.0 + resolution: "openai@npm:4.98.0" + dependencies: + "@types/node": ^18.11.18 + "@types/node-fetch": ^2.6.4 + abort-controller: ^3.0.0 + agentkeepalive: ^4.2.1 + form-data-encoder: 1.7.2 + formdata-node: ^4.3.2 + node-fetch: ^2.6.7 + peerDependencies: + ws: ^8.18.0 + zod: ^3.23.8 + peerDependenciesMeta: + ws: + optional: true + zod: + optional: true + bin: + openai: bin/cli + checksum: c16a64589ae6b917c6d1c5703047e6baa1f3186d37eb82299ceb6d3ba96222708758cedf9483b87b7cba3253fdfdd23e32899478c8a3f0154b4ef5e8b0cf437c + languageName: node + linkType: hard + +"openapi-types@npm:^12.1.3": + version: 12.1.3 + resolution: "openapi-types@npm:12.1.3" + checksum: 7fa5547f87a58d2aa0eba6e91d396f42d7d31bc3ae140e61b5d60b47d2fd068b48776f42407d5a8da7280cf31195aa128c2fc285e8bb871d1105edee5647a0bb + languageName: node + linkType: hard + "optimism@npm:^0.18.0": version: 0.18.0 resolution: "optimism@npm:0.18.0" @@ -18591,6 +19007,16 @@ __metadata: languageName: node linkType: hard +"p-retry@npm:4": + version: 4.6.2 + resolution: "p-retry@npm:4.6.2" + dependencies: + "@types/retry": 0.12.0 + retry: ^0.13.1 + checksum: 45c270bfddaffb4a895cea16cb760dcc72bdecb6cb45fef1971fa6ea2e91ddeafddefe01e444ac73e33b1b3d5d29fb0dd18a7effb294262437221ddc03ce0f2e + languageName: node + linkType: hard + "p-timeout@npm:^3.2.0": version: 3.2.0 resolution: "p-timeout@npm:3.2.0" @@ -20405,7 +20831,7 @@ __metadata: languageName: node linkType: hard -"retry@npm:0.13.1": +"retry@npm:0.13.1, retry@npm:^0.13.1": version: 0.13.1 resolution: "retry@npm:0.13.1" checksum: 47c4d5be674f7c13eee4cfe927345023972197dbbdfba5d3af7e461d13b44de1bfd663bfc80d2f601f8ef3fc8164c16dd99655a221921954a65d044a2fc1233b @@ -21012,6 +21438,13 @@ __metadata: languageName: node linkType: hard +"simple-wcswidth@npm:^1.0.1": + version: 1.0.1 + resolution: "simple-wcswidth@npm:1.0.1" + checksum: dc5bf4cb131d9c386825d1355add2b1ecc408b37dc2c2334edd7a1a4c9f527e6b594dedcdbf6d949bce2740c3a332e39af1183072a2d068e40d9e9146067a37f + languageName: node + linkType: hard + "sisteransi@npm:^1.0.5": version: 1.0.5 resolution: "sisteransi@npm:1.0.5" @@ -21249,6 +21682,13 @@ __metadata: languageName: node linkType: hard +"sql-highlight@npm:^6.0.0": + version: 6.0.0 + resolution: "sql-highlight@npm:6.0.0" + checksum: 34bfba3ada8e8f1ff9843f1dfa1386db4cf62be212676c300c9f455a6be202fced784098b16488c780198e109024ecb3efafef6ad5527fca46ebbf363080f31d + languageName: node + linkType: hard + "ssri@npm:^10.0.0": version: 10.0.5 resolution: "ssri@npm:10.0.5" @@ -21544,6 +21984,13 @@ __metadata: languageName: node linkType: hard +"strnum@npm:^1.1.1": + version: 1.1.2 + resolution: "strnum@npm:1.1.2" + checksum: a85219eda13e97151c95e343a9e5960eacfb0a0ff98104b4c9cb7a212e3008bddf0c9714c9c37c2e508be78e741a04afc80027c2dc18509d1b5ffd4c37191fc2 + languageName: node + linkType: hard + "subql-mono@workspace:.": version: 0.0.0-use.local resolution: "subql-mono@workspace:." @@ -22447,6 +22894,85 @@ __metadata: languageName: node linkType: hard +"typeorm@npm:^0.3.23": + version: 0.3.23 + resolution: "typeorm@npm:0.3.23" + dependencies: + "@sqltools/formatter": ^1.2.5 + ansis: ^3.17.0 + app-root-path: ^3.1.0 + buffer: ^6.0.3 + dayjs: ^1.11.13 + debug: ^4.4.0 + dotenv: ^16.4.7 + glob: ^10.4.5 + sha.js: ^2.4.11 + sql-highlight: ^6.0.0 + tslib: ^2.8.1 + uuid: ^11.1.0 + yargs: ^17.7.2 + peerDependencies: + "@google-cloud/spanner": ^5.18.0 || ^6.0.0 || ^7.0.0 + "@sap/hana-client": ^2.12.25 + better-sqlite3: ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 + hdb-pool: ^0.1.6 + ioredis: ^5.0.4 + mongodb: ^5.8.0 || ^6.0.0 + mssql: ^9.1.1 || ^10.0.1 || ^11.0.1 + mysql2: ^2.2.5 || ^3.0.1 + oracledb: ^6.3.0 + pg: ^8.5.1 + pg-native: ^3.0.0 + pg-query-stream: ^4.0.0 + redis: ^3.1.1 || ^4.0.0 + reflect-metadata: ^0.1.14 || ^0.2.0 + sql.js: ^1.4.0 + sqlite3: ^5.0.3 + ts-node: ^10.7.0 + typeorm-aurora-data-api-driver: ^2.0.0 || ^3.0.0 + peerDependenciesMeta: + "@google-cloud/spanner": + optional: true + "@sap/hana-client": + optional: true + better-sqlite3: + optional: true + hdb-pool: + optional: true + ioredis: + optional: true + mongodb: + optional: true + mssql: + optional: true + mysql2: + optional: true + oracledb: + optional: true + pg: + optional: true + pg-native: + optional: true + pg-query-stream: + optional: true + redis: + optional: true + sql.js: + optional: true + sqlite3: + optional: true + ts-node: + optional: true + typeorm-aurora-data-api-driver: + optional: true + bin: + typeorm: cli.js + typeorm-ts-node-commonjs: cli-ts-node-commonjs.js + typeorm-ts-node-esm: cli-ts-node-esm.js + checksum: f42770241d784354b0b868de8f2bf2761eff21e76650f6634f1a9fa5e6788dcef26c7d2b95b1a150f205c4f934431291cdac0cb5a4320c1a3fa52450f51813e6 + languageName: node + linkType: hard + "typescript@npm:^5.7.3": version: 5.7.3 resolution: "typescript@npm:5.7.3" @@ -22966,6 +23492,24 @@ __metadata: languageName: node linkType: hard +"uuid@npm:^10.0.0": + version: 10.0.0 + resolution: "uuid@npm:10.0.0" + bin: + uuid: dist/bin/uuid + checksum: 4b81611ade2885d2313ddd8dc865d93d8dccc13ddf901745edca8f86d99bc46d7a330d678e7532e7ebf93ce616679fb19b2e3568873ac0c14c999032acb25869 + languageName: node + linkType: hard + +"uuid@npm:^11.1.0": + version: 11.1.0 + resolution: "uuid@npm:11.1.0" + bin: + uuid: dist/esm/bin/uuid + checksum: 840f19758543c4631e58a29439e51b5b669d5f34b4dd2700b6a1d15c5708c7a6e0c3e2c8c4a2eae761a3a7caa7e9884d00c86c02622ba91137bd3deade6b4b4a + languageName: node + linkType: hard + "uuid@npm:^9.0.0": version: 9.0.0 resolution: "uuid@npm:9.0.0" @@ -23166,6 +23710,13 @@ __metadata: languageName: node linkType: hard +"web-streams-polyfill@npm:4.0.0-beta.3": + version: 4.0.0-beta.3 + resolution: "web-streams-polyfill@npm:4.0.0-beta.3" + checksum: dfec1fbf52b9140e4183a941e380487b6c3d5d3838dd1259be81506c1c9f2abfcf5aeb670aeeecfd9dff4271a6d8fef931b193c7bedfb42542a3b05ff36c0d16 + languageName: node + linkType: hard + "webidl-conversions@npm:^3.0.0": version: 3.0.1 resolution: "webidl-conversions@npm:3.0.1" @@ -23666,6 +24217,15 @@ __metadata: languageName: node linkType: hard +"yaml@npm:^2.2.1": + version: 2.7.1 + resolution: "yaml@npm:2.7.1" + bin: + yaml: bin.mjs + checksum: 385f8115ddfafdf8e599813cca8b2bf4e3f6a01b919fff5ae7da277e164df684d7dfe558b4085172094792b5a04786d3c55fa8b74abb0ee029873f031150bb80 + languageName: node + linkType: hard + "yaml@npm:~2.4.2": version: 2.4.5 resolution: "yaml@npm:2.4.5" @@ -23831,6 +24391,22 @@ __metadata: languageName: node linkType: hard +"zod-to-json-schema@npm:^3.22.3, zod-to-json-schema@npm:^3.22.4": + version: 3.24.5 + resolution: "zod-to-json-schema@npm:3.24.5" + peerDependencies: + zod: ^3.24.1 + checksum: dc4e5e4c06e9a5494e4b1d8c8363ac907f9d488f36c8e4923e1e5ac4f91f737722f99200cd92a409551e7456d960734d4cabd37935234ca95e290572468ffc08 + languageName: node + linkType: hard + +"zod@npm:^3.22.4, zod@npm:^3.23.8": + version: 3.24.4 + resolution: "zod@npm:3.24.4" + checksum: 62829789765a9187bd72bed3972a7c1a39fdfe6c59bc752eedabec5f99af701658471b8577d22e0fee2081e6e35d4efc93c02c90e13350755a36feadbf72bbbc + languageName: node + linkType: hard + "zwitch@npm:^1.0.0": version: 1.0.5 resolution: "zwitch@npm:1.0.5" From eb08c927d9ee83d532960ea17f516b3c048f10cb Mon Sep 17 00:00:00 2001 From: Ian He Date: Fri, 16 May 2025 12:12:23 +1200 Subject: [PATCH 2/2] return tool calling as reasoning content --- packages/query/src/llm/chat.module.ts | 57 ++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/packages/query/src/llm/chat.module.ts b/packages/query/src/llm/chat.module.ts index 7c287a3dbb..becd2f0d31 100644 --- a/packages/query/src/llm/chat.module.ts +++ b/packages/query/src/llm/chat.module.ts @@ -90,23 +90,44 @@ When generating SQL queries: } // Convert OpenAI format messages to LangChain format - const lastMessage = messages[messages.length - 1]; - const question = lastMessage.content; + // const lastMessage = messages[messages.length - 1]; + // const question = lastMessage.content; res.setHeader('Content-Type', 'text/event-stream'); res.setHeader('Cache-Control', 'no-cache'); res.setHeader('Connection', 'keep-alive'); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const result = await this.agent!.stream({messages: [['user', question]]}, {streamMode: 'values'}); + const result = await this.agent!.stream({messages}, {streamMode: 'values'}); let fullResponse = ''; + let first = true; + let thinking = false; for await (const event of result) { const lastMsg: BaseMessage = event.messages[event.messages.length - 1]; - if (lastMsg.content) { - fullResponse = lastMsg.content as string; - logger.info(`Streaming response: ${JSON.stringify(lastMsg)}`); - if (argv['llm-debug'] && stream) { + fullResponse = lastMsg.content as string; + if (lastMsg.content && lastMsg.getType() === 'tool') { + if (argv['chat-debug'] && stream && lastMsg.response_metadata?.finish_reason !== 'stop') { + if (first) { + res.write( + `data: ${JSON.stringify({ + id: `chatcmpl-${Date.now()}`, + object: 'chat.completion.chunk', + created: Math.floor(Date.now() / 1000), + model: process.env.OPENAI_MODEL, + choices: [ + { + index: 0, + delta: {role: 'assistant', content: '\n\n'}, + finish_reason: null, + }, + ], + })}\n\n` + ); + first = false; + thinking = true; + } // todo: send them as thinking details + logger.info(`Streaming response: ${JSON.stringify(lastMsg)}`); res.write( `data: ${JSON.stringify({ id: `chatcmpl-${Date.now()}`, @@ -116,7 +137,7 @@ When generating SQL queries: choices: [ { index: 0, - delta: {content: lastMsg.content}, + delta: {content: `${lastMsg.name}: ${lastMsg.content} \n\n`}, finish_reason: null, }, ], @@ -124,10 +145,28 @@ When generating SQL queries: ); } } + if (lastMsg.response_metadata?.finish_reason === 'stop' && thinking) { + res.write( + `data: ${JSON.stringify({ + id: `chatcmpl-${Date.now()}`, + object: 'chat.completion.chunk', + created: Math.floor(Date.now() / 1000), + model: process.env.OPENAI_MODEL, + choices: [ + { + index: 0, + delta: {content: '\n\n'}, + finish_reason: null, + }, + ], + })}\n\n` + ); + } } // Send final message if (stream) { + logger.info(`Final response: ${JSON.stringify(fullResponse)}`); res.write( `data: ${JSON.stringify({ id: `chatcmpl-${Date.now()}`, @@ -137,7 +176,7 @@ When generating SQL queries: choices: [ { index: 0, - message: {role: 'assistant', content: fullResponse}, + delta: {role: 'assistant', content: fullResponse}, finish_reason: 'stop', }, ],