@ainetwork/adk 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -24
- package/dist/cjs/{chunk-EOPW5OPE.cjs → chunk-77SJGFVU.cjs} +7 -7
- package/dist/cjs/{chunk-4DXS33VP.cjs.map → chunk-77SJGFVU.cjs.map} +1 -1
- package/dist/cjs/{chunk-GB3ON7UV.cjs → chunk-7PZP7YSA.cjs} +5 -5
- package/dist/cjs/{chunk-GB3ON7UV.cjs.map → chunk-7PZP7YSA.cjs.map} +1 -1
- package/dist/cjs/{chunk-ZZK4ACTV.cjs → chunk-A2ANDQNY.cjs} +75 -27
- package/dist/cjs/chunk-A2ANDQNY.cjs.map +1 -0
- package/dist/cjs/{chunk-MIWLK57K.cjs → chunk-A2I7D6JW.cjs} +1 -1
- package/dist/cjs/chunk-A2I7D6JW.cjs.map +1 -0
- package/dist/cjs/{chunk-6YVTJEMQ.cjs → chunk-BBFYVWE2.cjs} +17 -42
- package/dist/cjs/chunk-BBFYVWE2.cjs.map +1 -0
- package/dist/cjs/{chunk-4DXS33VP.cjs → chunk-CHC3HECE.cjs} +7 -7
- package/dist/cjs/{chunk-EOPW5OPE.cjs.map → chunk-CHC3HECE.cjs.map} +1 -1
- package/dist/cjs/{chunk-LRBRG2DS.cjs → chunk-E35E4LQY.cjs} +4 -4
- package/dist/cjs/chunk-E35E4LQY.cjs.map +1 -0
- package/dist/cjs/{chunk-45G7LDK7.cjs → chunk-FRWC3FQ4.cjs} +3 -3
- package/dist/cjs/{chunk-45G7LDK7.cjs.map → chunk-FRWC3FQ4.cjs.map} +1 -1
- package/dist/cjs/{chunk-2C33PZTV.cjs → chunk-HCN6JEJA.cjs} +6 -6
- package/dist/cjs/chunk-HCN6JEJA.cjs.map +1 -0
- package/dist/cjs/chunk-J7GCQY3S.cjs +18 -0
- package/dist/cjs/chunk-J7GCQY3S.cjs.map +1 -0
- package/dist/cjs/{chunk-AIE3SVG7.cjs → chunk-KHD7UAFW.cjs} +22 -24
- package/dist/cjs/chunk-KHD7UAFW.cjs.map +1 -0
- package/dist/cjs/{chunk-BOKIE5SM.cjs → chunk-LMR6B76V.cjs} +5 -5
- package/dist/cjs/chunk-LMR6B76V.cjs.map +1 -0
- package/dist/cjs/{chunk-ZZPJ5CPR.cjs → chunk-MCDRCKR6.cjs} +29 -24
- package/dist/cjs/chunk-MCDRCKR6.cjs.map +1 -0
- package/dist/cjs/{chunk-344VLDMS.cjs → chunk-O4QQH7VT.cjs} +7 -7
- package/dist/cjs/{chunk-RX72NXXR.cjs.map → chunk-O4QQH7VT.cjs.map} +1 -1
- package/dist/cjs/{chunk-55IME4BG.cjs → chunk-OKRBMMK2.cjs} +46 -24
- package/dist/cjs/chunk-OKRBMMK2.cjs.map +1 -0
- package/dist/cjs/{chunk-7GWYMGWW.cjs → chunk-PAWGHHSY.cjs} +15 -14
- package/dist/cjs/chunk-PAWGHHSY.cjs.map +1 -0
- package/dist/cjs/{chunk-DX2JH3FJ.cjs → chunk-QHQLU7BI.cjs} +1 -1
- package/dist/cjs/{chunk-DX2JH3FJ.cjs.map → chunk-QHQLU7BI.cjs.map} +1 -1
- package/dist/cjs/{chunk-QWASSVCU.cjs → chunk-RIJV7J5Z.cjs} +1 -1
- package/dist/cjs/chunk-RIJV7J5Z.cjs.map +1 -0
- package/dist/cjs/{chunk-HT3PACCL.cjs → chunk-UPQVXJK6.cjs} +6 -6
- package/dist/cjs/chunk-UPQVXJK6.cjs.map +1 -0
- package/dist/cjs/{chunk-3J3ORQOG.cjs → chunk-VLMHDHXT.cjs} +3 -3
- package/dist/cjs/{chunk-3J3ORQOG.cjs.map → chunk-VLMHDHXT.cjs.map} +1 -1
- package/dist/cjs/{chunk-RX72NXXR.cjs → chunk-W5VM75PL.cjs} +7 -7
- package/dist/cjs/{chunk-344VLDMS.cjs.map → chunk-W5VM75PL.cjs.map} +1 -1
- package/dist/cjs/{chunk-JXKLEQD6.cjs → chunk-WUOME625.cjs} +6 -6
- package/dist/cjs/chunk-WUOME625.cjs.map +1 -0
- package/dist/cjs/{chunk-CU5MOHJU.cjs → chunk-ZPYMLCQZ.cjs} +13 -14
- package/dist/cjs/chunk-ZPYMLCQZ.cjs.map +1 -0
- package/dist/cjs/controllers/api/threads.api.controller.cjs +2 -2
- package/dist/cjs/controllers/index.cjs +7 -7
- package/dist/cjs/controllers/index.cjs.map +1 -1
- package/dist/cjs/controllers/query.controller.cjs +3 -3
- package/dist/cjs/index.cjs +46 -32
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/middlewares/auth.middleware.cjs +3 -3
- package/dist/cjs/modules/a2a/a2a.module.cjs +3 -3
- package/dist/cjs/modules/index.cjs +9 -9
- package/dist/cjs/modules/index.cjs.map +1 -1
- package/dist/cjs/modules/models/model.module.cjs +2 -2
- package/dist/cjs/routes/a2a.routes.cjs +7 -6
- package/dist/cjs/routes/a2a.routes.cjs.map +1 -1
- package/dist/cjs/routes/api/threads.routes.cjs +4 -4
- package/dist/cjs/routes/api.routes.cjs +5 -5
- package/dist/cjs/routes/index.cjs +17 -17
- package/dist/cjs/routes/index.cjs.map +1 -1
- package/dist/cjs/routes/query.routes.cjs +7 -7
- package/dist/cjs/services/a2a.service.cjs +2 -2
- package/dist/cjs/services/index.cjs +6 -5
- package/dist/cjs/services/index.cjs.map +1 -1
- package/dist/cjs/services/query-stream.service.cjs +4 -3
- package/dist/cjs/services/query-stream.service.cjs.map +1 -1
- package/dist/cjs/services/query.service.cjs +3 -3
- package/dist/cjs/types/agent.cjs +2 -2
- package/dist/cjs/types/memory.cjs +2 -2
- package/dist/esm/{chunk-7D4SKPIS.js → chunk-4C2TLCWI.js} +2 -2
- package/dist/esm/{chunk-EIHZ4S5V.js → chunk-4R4TB2ZJ.js} +6 -6
- package/dist/esm/{chunk-PN6NMQBM.js → chunk-5JIXQ6PU.js} +2 -2
- package/dist/esm/chunk-5JIXQ6PU.js.map +1 -0
- package/dist/esm/{chunk-CWFIK2EK.js → chunk-KDVMHOLB.js} +11 -10
- package/dist/esm/chunk-KDVMHOLB.js.map +1 -0
- package/dist/esm/{chunk-LJVVSUF7.js → chunk-MJEPJ62P.js} +15 -40
- package/dist/esm/chunk-MJEPJ62P.js.map +1 -0
- package/dist/esm/{chunk-2L2KJNAM.js → chunk-NIT7ITZV.js} +6 -6
- package/dist/esm/chunk-NIT7ITZV.js.map +1 -0
- package/dist/esm/{chunk-MNAWSBYP.js → chunk-POQFOL6Y.js} +1 -1
- package/dist/esm/chunk-POQFOL6Y.js.map +1 -0
- package/dist/esm/{chunk-2RW77MJB.js → chunk-PUUZRUE6.js} +47 -25
- package/dist/esm/chunk-PUUZRUE6.js.map +1 -0
- package/dist/esm/{chunk-SYCFBEUA.js → chunk-QHWDMU43.js} +3 -3
- package/dist/esm/{chunk-WLT2B2SZ.js → chunk-RL6SRSSK.js} +1 -1
- package/dist/esm/chunk-RL6SRSSK.js.map +1 -0
- package/dist/esm/{chunk-VDXWZ4NK.js → chunk-TV2GJAEH.js} +2 -2
- package/dist/esm/{chunk-ILKEX4ZV.js → chunk-UK6K6ZPH.js} +26 -17
- package/dist/esm/chunk-UK6K6ZPH.js.map +1 -0
- package/dist/esm/{chunk-PHKK5NHK.js → chunk-VNQCUGC3.js} +1 -1
- package/dist/esm/chunk-VNQCUGC3.js.map +1 -0
- package/dist/esm/{chunk-FL3JRQM4.js → chunk-ZBUAT73P.js} +1 -1
- package/dist/esm/{chunk-FL3JRQM4.js.map → chunk-ZBUAT73P.js.map} +1 -1
- package/dist/esm/controllers/a2a.controller.d.ts +2 -2
- package/dist/esm/controllers/api/threads.api.controller.js +1 -1
- package/dist/esm/controllers/index.d.ts +3 -3
- package/dist/esm/controllers/index.js +3 -3
- package/dist/esm/controllers/query.controller.d.ts +2 -2
- package/dist/esm/controllers/query.controller.js +2 -2
- package/dist/esm/index.d.ts +1 -2
- package/dist/esm/index.js +37 -23
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/middlewares/auth.middleware.js +2 -2
- package/dist/esm/modules/a2a/a2a.module.d.ts +2 -9
- package/dist/esm/modules/a2a/a2a.module.js +2 -2
- package/dist/esm/modules/index.js +10 -10
- package/dist/esm/modules/models/model.module.d.ts +17 -0
- package/dist/esm/modules/models/model.module.js +1 -1
- package/dist/esm/routes/a2a.routes.js +5 -4
- package/dist/esm/routes/api/threads.routes.js +3 -3
- package/dist/esm/routes/api.routes.js +4 -4
- package/dist/esm/routes/index.js +11 -11
- package/dist/esm/routes/query.routes.js +6 -6
- package/dist/esm/services/a2a.service.d.ts +4 -4
- package/dist/esm/services/a2a.service.js +1 -1
- package/dist/esm/services/index.js +7 -6
- package/dist/esm/services/query-stream.service.d.ts +13 -10
- package/dist/esm/services/query-stream.service.js +3 -2
- package/dist/esm/services/query.service.d.ts +7 -4
- package/dist/esm/services/query.service.js +2 -2
- package/dist/esm/types/agent.d.ts +0 -2
- package/dist/esm/types/agent.js +1 -1
- package/dist/esm/types/memory.d.ts +6 -7
- package/dist/esm/types/memory.js +1 -1
- package/package.json +9 -4
- package/dist/cjs/chunk-2C33PZTV.cjs.map +0 -1
- package/dist/cjs/chunk-55IME4BG.cjs.map +0 -1
- package/dist/cjs/chunk-6YVTJEMQ.cjs.map +0 -1
- package/dist/cjs/chunk-7GWYMGWW.cjs.map +0 -1
- package/dist/cjs/chunk-7HUWKIXU.cjs +0 -128
- package/dist/cjs/chunk-7HUWKIXU.cjs.map +0 -1
- package/dist/cjs/chunk-AIE3SVG7.cjs.map +0 -1
- package/dist/cjs/chunk-BBCZU5VZ.cjs +0 -17
- package/dist/cjs/chunk-BBCZU5VZ.cjs.map +0 -1
- package/dist/cjs/chunk-BOKIE5SM.cjs.map +0 -1
- package/dist/cjs/chunk-CU5MOHJU.cjs.map +0 -1
- package/dist/cjs/chunk-CYW6ICAW.cjs +0 -106
- package/dist/cjs/chunk-CYW6ICAW.cjs.map +0 -1
- package/dist/cjs/chunk-EAK7MP6X.cjs +0 -22
- package/dist/cjs/chunk-EAK7MP6X.cjs.map +0 -1
- package/dist/cjs/chunk-F4CJCUAK.cjs +0 -22
- package/dist/cjs/chunk-F4CJCUAK.cjs.map +0 -1
- package/dist/cjs/chunk-FCZQBJTF.cjs +0 -36
- package/dist/cjs/chunk-FCZQBJTF.cjs.map +0 -1
- package/dist/cjs/chunk-G5KEV27W.cjs +0 -45
- package/dist/cjs/chunk-G5KEV27W.cjs.map +0 -1
- package/dist/cjs/chunk-H35XHCTA.cjs +0 -22
- package/dist/cjs/chunk-H35XHCTA.cjs.map +0 -1
- package/dist/cjs/chunk-HT3PACCL.cjs.map +0 -1
- package/dist/cjs/chunk-JXKLEQD6.cjs.map +0 -1
- package/dist/cjs/chunk-KE7SL3H6.cjs +0 -251
- package/dist/cjs/chunk-KE7SL3H6.cjs.map +0 -1
- package/dist/cjs/chunk-KRLUWTLN.cjs +0 -35
- package/dist/cjs/chunk-KRLUWTLN.cjs.map +0 -1
- package/dist/cjs/chunk-LRBRG2DS.cjs.map +0 -1
- package/dist/cjs/chunk-MIWLK57K.cjs.map +0 -1
- package/dist/cjs/chunk-MLUUV7UY.cjs +0 -36
- package/dist/cjs/chunk-MLUUV7UY.cjs.map +0 -1
- package/dist/cjs/chunk-QWASSVCU.cjs.map +0 -1
- package/dist/cjs/chunk-T2AKW5PA.cjs +0 -45
- package/dist/cjs/chunk-T2AKW5PA.cjs.map +0 -1
- package/dist/cjs/chunk-UTFWH24D.cjs +0 -22
- package/dist/cjs/chunk-UTFWH24D.cjs.map +0 -1
- package/dist/cjs/chunk-W52YCYRF.cjs +0 -43
- package/dist/cjs/chunk-W52YCYRF.cjs.map +0 -1
- package/dist/cjs/chunk-YNBMJ5QX.cjs +0 -129
- package/dist/cjs/chunk-YNBMJ5QX.cjs.map +0 -1
- package/dist/cjs/chunk-ZZK4ACTV.cjs.map +0 -1
- package/dist/cjs/chunk-ZZPJ5CPR.cjs.map +0 -1
- package/dist/cjs/controllers/api/thread.api.controller.cjs +0 -8
- package/dist/cjs/controllers/api/thread.api.controller.cjs.map +0 -1
- package/dist/cjs/routes/api/thread.routes.cjs +0 -9
- package/dist/cjs/routes/api/thread.routes.cjs.map +0 -1
- package/dist/esm/chunk-2L2KJNAM.js.map +0 -1
- package/dist/esm/chunk-2RW77MJB.js.map +0 -1
- package/dist/esm/chunk-CWFIK2EK.js.map +0 -1
- package/dist/esm/chunk-ILKEX4ZV.js.map +0 -1
- package/dist/esm/chunk-LJVVSUF7.js.map +0 -1
- package/dist/esm/chunk-MNAWSBYP.js.map +0 -1
- package/dist/esm/chunk-PHKK5NHK.js.map +0 -1
- package/dist/esm/chunk-PN6NMQBM.js.map +0 -1
- package/dist/esm/chunk-WLT2B2SZ.js.map +0 -1
- /package/dist/esm/{chunk-7D4SKPIS.js.map → chunk-4C2TLCWI.js.map} +0 -0
- /package/dist/esm/{chunk-EIHZ4S5V.js.map → chunk-4R4TB2ZJ.js.map} +0 -0
- /package/dist/esm/{chunk-SYCFBEUA.js.map → chunk-QHWDMU43.js.map} +0 -0
- /package/dist/esm/{chunk-VDXWZ4NK.js.map → chunk-TV2GJAEH.js.map} +0 -0
package/README.md
CHANGED
|
@@ -41,11 +41,11 @@ To see how to use this package in your project, check out our comprehensive exam
|
|
|
41
41
|
|
|
42
42
|
### Core Components
|
|
43
43
|
|
|
44
|
-
- **AINAgent** (`src/
|
|
45
|
-
- **ModelModule** (`src/modules/models/`): Manages AI model integrations
|
|
44
|
+
- **AINAgent** (`src/index.ts`): Main Express.js server class that orchestrates all modules
|
|
45
|
+
- **ModelModule** (`src/modules/models/`): Manages AI model integrations with streaming support
|
|
46
46
|
- **MCPModule** (`src/modules/mcp/`): Handles Model Context Protocol connections
|
|
47
47
|
- **A2AModule** (`src/modules/a2a/`): Manages agent-to-agent communication
|
|
48
|
-
- **MemoryModule** (`src/modules/memory/`): Provides threads and conversation history
|
|
48
|
+
- **MemoryModule** (`src/modules/memory/`): Provides threads, intents, and conversation history
|
|
49
49
|
|
|
50
50
|
### Module System
|
|
51
51
|
|
|
@@ -68,20 +68,25 @@ Each module can be independently configured and passed to the agent constructor.
|
|
|
68
68
|
- Connects to external MCP servers via stdio
|
|
69
69
|
- Automatic tool discovery and execution
|
|
70
70
|
- Supports multiple concurrent MCP servers
|
|
71
|
+
- Protocol-specific tool wrapping as `IMCPTool`
|
|
71
72
|
|
|
72
73
|
#### A2A (Agent-to-Agent)
|
|
73
74
|
- RESTful API for inter-agent communication
|
|
74
|
-
- Streaming response support
|
|
75
|
-
- Agent discovery via well-known endpoints
|
|
76
|
-
- Task delegation
|
|
75
|
+
- Streaming response support via SSE
|
|
76
|
+
- Agent discovery via well-known endpoints (`.well-known/agent-card.json`)
|
|
77
|
+
- Task delegation with thread context passing
|
|
78
|
+
- Protocol version 0.3.0 support
|
|
77
79
|
|
|
78
80
|
### Key Features
|
|
79
81
|
|
|
80
82
|
- **Unified Tool Interface**: Protocol-agnostic `IAgentTool` interface
|
|
83
|
+
- **Streaming Support**: Dual implementation for streaming and non-streaming queries
|
|
84
|
+
- **Intent System**: Intent detection and fulfillment with custom prompts
|
|
81
85
|
- **Service Layer**: Clean separation with controllers and services
|
|
82
|
-
- **Type Safety**: Comprehensive TypeScript types
|
|
86
|
+
- **Type Safety**: Comprehensive TypeScript types with strict mode
|
|
83
87
|
- **Error Handling**: Global error middleware with structured logging
|
|
84
|
-
- **Authentication**: Optional auth middleware
|
|
88
|
+
- **Authentication**: Optional auth middleware via `BaseAuth` interface
|
|
89
|
+
- **Graceful Shutdown**: Proper cleanup of modules and connections
|
|
85
90
|
|
|
86
91
|
## Development
|
|
87
92
|
|
|
@@ -96,10 +101,13 @@ yarn dev # Run TypeScript directly with tsx
|
|
|
96
101
|
|
|
97
102
|
# Code quality
|
|
98
103
|
yarn biome # Check code with Biome
|
|
99
|
-
yarn
|
|
104
|
+
yarn biome:write # Check and auto-fix with Biome
|
|
100
105
|
|
|
101
106
|
# Testing
|
|
102
107
|
yarn test # Run Jest tests
|
|
108
|
+
|
|
109
|
+
# Clean
|
|
110
|
+
yarn clean # Remove build artifacts
|
|
103
111
|
```
|
|
104
112
|
|
|
105
113
|
## Logging System
|
|
@@ -124,12 +132,13 @@ modelLogger.error('Model API error');
|
|
|
124
132
|
|
|
125
133
|
### Available Loggers
|
|
126
134
|
- `agent`: Main agent operations
|
|
127
|
-
- `intent`:
|
|
135
|
+
- `intent`: Non-streaming query processing and intent analysis
|
|
136
|
+
- `intentStream`: Streaming query processing
|
|
128
137
|
- `mcp`: MCP server connections and tool execution
|
|
129
138
|
- `a2a`: Agent-to-agent communication
|
|
130
139
|
- `model`: AI model interactions
|
|
131
140
|
- `server`: HTTP server operations
|
|
132
|
-
- `memory`: Threads,
|
|
141
|
+
- `memory`: Threads, intents, and agent data management
|
|
133
142
|
|
|
134
143
|
### Log Levels
|
|
135
144
|
- `error`: Error conditions
|
|
@@ -140,22 +149,35 @@ modelLogger.error('Model API error');
|
|
|
140
149
|
## API Endpoints
|
|
141
150
|
|
|
142
151
|
### Standard Endpoints
|
|
143
|
-
- `GET /` - Welcome message
|
|
144
|
-
- `POST /query` - Process queries
|
|
145
|
-
- Request: `{ message: string, threadId
|
|
146
|
-
- Response: `{ content: string }`
|
|
147
|
-
- `POST /query/stream` - Process queries with streaming
|
|
148
|
-
- Request: `{ message: string, threadId: string }`
|
|
152
|
+
- `GET /` - Welcome message and health check
|
|
153
|
+
- `POST /query` - Process queries (non-streaming)
|
|
154
|
+
- Request: `{ message: string, threadId?: string, type?: string }`
|
|
149
155
|
- Response: `{ content: string }`
|
|
156
|
+
- `POST /query/stream` - Process queries with streaming (SSE)
|
|
157
|
+
- Request: `{ message: string, threadId?: string, type?: string }`
|
|
158
|
+
- Response: Server-Sent Events stream with event types:
|
|
159
|
+
- `text_chunk`: Incremental text response
|
|
160
|
+
- `tool_start`: Tool execution started
|
|
161
|
+
- `tool_output`: Tool execution result
|
|
162
|
+
- `thread_id`: Thread metadata
|
|
163
|
+
- `error`: Error message
|
|
150
164
|
|
|
151
165
|
### Agent Management
|
|
166
|
+
- `GET /api/threads/:userId` - List user threads
|
|
167
|
+
- `POST /api/threads/:userId` - Create new thread
|
|
168
|
+
- `GET /api/threads/:userId/:threadId` - Get thread details
|
|
169
|
+
- `DELETE /api/threads/:userId/:threadId` - Delete thread
|
|
170
|
+
- `GET /api/model` - Get model configuration
|
|
171
|
+
- `POST /api/model` - Set default model
|
|
152
172
|
|
|
153
173
|
### A2A Server Endpoints (when `manifest.url` is configured)
|
|
154
|
-
- `GET /agent
|
|
155
|
-
- `GET /.well-known/agent.json` - Agent discovery endpoint
|
|
174
|
+
- `GET /.well-known/agent.json` - Agent discovery endpoint (A2A ~v0.2.0)
|
|
175
|
+
- `GET /.well-known/agent-card.json` - Agent discovery endpoint (A2A v0.3.0~)
|
|
176
|
+
- Returns `AgentCard` with capabilities and supported modes
|
|
156
177
|
- `POST /a2a` - A2A communication endpoint
|
|
157
|
-
- Supports streaming responses
|
|
158
|
-
- Request: `{ message: string, stream?: boolean }`
|
|
178
|
+
- Supports streaming responses via SSE
|
|
179
|
+
- Request: `{ message: string, threadId?: string, stream?: boolean }`
|
|
180
|
+
- Response: JSON or SSE stream based on `stream` parameter
|
|
159
181
|
|
|
160
182
|
## Build System
|
|
161
183
|
|
|
@@ -168,13 +190,15 @@ The project supports dual build output:
|
|
|
168
190
|
|
|
169
191
|
The library includes comprehensive error handling:
|
|
170
192
|
- Global error middleware for uncaught errors
|
|
171
|
-
-
|
|
193
|
+
- Custom `AinHttpError` class for HTTP-specific errors
|
|
194
|
+
- Service-specific error logging with structured context
|
|
172
195
|
- Graceful handling of:
|
|
173
196
|
- MCP server connection failures
|
|
174
197
|
- A2A agent communication errors
|
|
175
|
-
- Model API failures
|
|
198
|
+
- Model API failures (rate limits, timeouts)
|
|
176
199
|
- Tool execution errors
|
|
177
200
|
- Invalid requests
|
|
201
|
+
- Streaming errors with proper cleanup
|
|
178
202
|
|
|
179
203
|
All errors are logged with appropriate context for debugging.
|
|
180
204
|
|
|
@@ -197,11 +221,13 @@ const agent = new AINAgent(manifest, modules, new MyAuth());
|
|
|
197
221
|
|
|
198
222
|
## Contributing
|
|
199
223
|
|
|
200
|
-
1. Follow the established code conventions
|
|
224
|
+
1. Follow the established code conventions (tabs, double quotes)
|
|
201
225
|
2. Use TypeScript strict mode
|
|
202
226
|
3. Add appropriate service-specific logging
|
|
203
227
|
4. Run `yarn biome:write` and `yarn test` before submitting
|
|
204
228
|
5. Maintain the modular architecture
|
|
229
|
+
6. Update JSDoc comments when changing function signatures
|
|
230
|
+
7. Add streaming support when implementing new query handlers
|
|
205
231
|
|
|
206
232
|
## License
|
|
207
233
|
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunkZPYMLCQZcjs = require('./chunk-ZPYMLCQZ.cjs');
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
var
|
|
6
|
+
var _chunkA2ANDQNYcjs = require('./chunk-A2ANDQNY.cjs');
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
var
|
|
9
|
+
var _chunkVLMHDHXTcjs = require('./chunk-VLMHDHXT.cjs');
|
|
10
10
|
|
|
11
11
|
// src/routes/query.routes.ts
|
|
12
12
|
var _express = require('express');
|
|
13
13
|
var createQueryRouter = (agent, allowStream = false) => {
|
|
14
14
|
const router = _express.Router.call(void 0, );
|
|
15
|
-
const queryService = new (0,
|
|
15
|
+
const queryService = new (0, _chunkZPYMLCQZcjs.QueryService)(
|
|
16
16
|
agent.modelModule,
|
|
17
17
|
agent.a2aModule,
|
|
18
18
|
agent.mcpModule,
|
|
@@ -21,7 +21,7 @@ var createQueryRouter = (agent, allowStream = false) => {
|
|
|
21
21
|
);
|
|
22
22
|
let queryStreamService;
|
|
23
23
|
if (allowStream) {
|
|
24
|
-
queryStreamService = new (0,
|
|
24
|
+
queryStreamService = new (0, _chunkA2ANDQNYcjs.QueryStreamService)(
|
|
25
25
|
agent.modelModule,
|
|
26
26
|
agent.a2aModule,
|
|
27
27
|
agent.mcpModule,
|
|
@@ -29,7 +29,7 @@ var createQueryRouter = (agent, allowStream = false) => {
|
|
|
29
29
|
agent.manifest.prompts
|
|
30
30
|
);
|
|
31
31
|
}
|
|
32
|
-
const queryController = new (0,
|
|
32
|
+
const queryController = new (0, _chunkVLMHDHXTcjs.QueryController)(queryService, queryStreamService);
|
|
33
33
|
router.post("/", queryController.handleQueryRequest);
|
|
34
34
|
if (allowStream) {
|
|
35
35
|
router.post("/stream", queryController.handleQueryStreamRequest);
|
|
@@ -40,4 +40,4 @@ var createQueryRouter = (agent, allowStream = false) => {
|
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
exports.createQueryRouter = createQueryRouter;
|
|
43
|
-
//# sourceMappingURL=chunk-
|
|
43
|
+
//# sourceMappingURL=chunk-77SJGFVU.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/shyun/comcom/ain-agent/ain-adk/dist/cjs/chunk-
|
|
1
|
+
{"version":3,"sources":["/Users/shyun/comcom/ain-agent/ain-adk/dist/cjs/chunk-77SJGFVU.cjs","../../src/routes/query.routes.ts"],"names":[],"mappings":"AAAA;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACA;ACVA,kCAAuB;AAMhB,IAAM,kBAAA,EAAoB,CAChC,KAAA,EACA,YAAA,EAAc,KAAA,EAAA,GACF;AACZ,EAAA,MAAM,OAAA,EAAS,6BAAA,CAAO;AAEtB,EAAA,MAAM,aAAA,EAAe,IAAI,mCAAA;AAAA,IACxB,KAAA,CAAM,WAAA;AAAA,IACN,KAAA,CAAM,SAAA;AAAA,IACN,KAAA,CAAM,SAAA;AAAA,IACN,KAAA,CAAM,YAAA;AAAA,IACN,KAAA,CAAM,QAAA,CAAS;AAAA,EAChB,CAAA;AAEA,EAAA,IAAI,kBAAA;AAEJ,EAAA,GAAA,CAAI,WAAA,EAAa;AAChB,IAAA,mBAAA,EAAqB,IAAI,yCAAA;AAAA,MACxB,KAAA,CAAM,WAAA;AAAA,MACN,KAAA,CAAM,SAAA;AAAA,MACN,KAAA,CAAM,SAAA;AAAA,MACN,KAAA,CAAM,YAAA;AAAA,MACN,KAAA,CAAM,QAAA,CAAS;AAAA,IAChB,CAAA;AAAA,EACD;AAEA,EAAA,MAAM,gBAAA,EAAkB,IAAI,sCAAA,CAAgB,YAAA,EAAc,kBAAkB,CAAA;AAC5E,EAAA,MAAA,CAAO,IAAA,CAAK,GAAA,EAAK,eAAA,CAAgB,kBAAkB,CAAA;AAEnD,EAAA,GAAA,CAAI,WAAA,EAAa;AAChB,IAAA,MAAA,CAAO,IAAA,CAAK,SAAA,EAAW,eAAA,CAAgB,wBAAwB,CAAA;AAAA,EAChE;AAEA,EAAA,OAAO,MAAA;AACR,CAAA;ADFA;AACA;AACE;AACF,8CAAC","file":"/Users/shyun/comcom/ain-agent/ain-adk/dist/cjs/chunk-77SJGFVU.cjs","sourcesContent":[null,"import { Router } from \"express\";\nimport { QueryController } from \"@/controllers/query.controller.js\";\nimport type { AINAgent } from \"@/index.js\";\nimport { QueryService } from \"@/services/query.service.js\";\nimport { QueryStreamService } from \"@/services/query-stream.service.js\";\n\nexport const createQueryRouter = (\n\tagent: AINAgent,\n\tallowStream = false,\n): Router => {\n\tconst router = Router();\n\n\tconst queryService = new QueryService(\n\t\tagent.modelModule,\n\t\tagent.a2aModule,\n\t\tagent.mcpModule,\n\t\tagent.memoryModule,\n\t\tagent.manifest.prompts,\n\t);\n\n\tlet queryStreamService: QueryStreamService | undefined;\n\n\tif (allowStream) {\n\t\tqueryStreamService = new QueryStreamService(\n\t\t\tagent.modelModule,\n\t\t\tagent.a2aModule,\n\t\t\tagent.mcpModule,\n\t\t\tagent.memoryModule,\n\t\t\tagent.manifest.prompts,\n\t\t);\n\t}\n\n\tconst queryController = new QueryController(queryService, queryStreamService);\n\trouter.post(\"/\", queryController.handleQueryRequest);\n\n\tif (allowStream) {\n\t\trouter.post(\"/stream\", queryController.handleQueryStreamRequest);\n\t}\n\n\treturn router;\n};\n"]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunkA2I7D6JWcjs = require('./chunk-A2I7D6JW.cjs');
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
var
|
|
6
|
+
var _chunkQHQLU7BIcjs = require('./chunk-QHQLU7BI.cjs');
|
|
7
7
|
|
|
8
8
|
// src/routes/api/threads.routes.ts
|
|
9
9
|
|
|
@@ -12,11 +12,11 @@ var _express = require('express');
|
|
|
12
12
|
var _httpstatuscodes = require('http-status-codes');
|
|
13
13
|
var createThreadApiRouter = (memoryModule) => {
|
|
14
14
|
const router = _express.Router.call(void 0, );
|
|
15
|
-
const threadApiController = new (0,
|
|
15
|
+
const threadApiController = new (0, _chunkA2I7D6JWcjs.ThreadApiController)(memoryModule);
|
|
16
16
|
const checkThreadMemory = (req, res, next) => {
|
|
17
17
|
const threadMemory = memoryModule.getThreadMemory();
|
|
18
18
|
if (!threadMemory) {
|
|
19
|
-
const error = new (0,
|
|
19
|
+
const error = new (0, _chunkQHQLU7BIcjs.AinHttpError)(
|
|
20
20
|
_httpstatuscodes.StatusCodes.SERVICE_UNAVAILABLE,
|
|
21
21
|
"Memory module is not initialized"
|
|
22
22
|
);
|
|
@@ -37,4 +37,4 @@ var createThreadApiRouter = (memoryModule) => {
|
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
exports.createThreadApiRouter = createThreadApiRouter;
|
|
40
|
-
//# sourceMappingURL=chunk-
|
|
40
|
+
//# sourceMappingURL=chunk-7PZP7YSA.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/shyun/comcom/ain-agent/ain-adk/dist/cjs/chunk-
|
|
1
|
+
{"version":3,"sources":["/Users/shyun/comcom/ain-agent/ain-adk/dist/cjs/chunk-7PZP7YSA.cjs","../../src/routes/api/threads.routes.ts"],"names":[],"mappings":"AAAA;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACA;ACPA;AAIC;AAAA,kCACM;AACP,oDAA4B;AAKrB,IAAM,sBAAA,EAAwB,CAAC,YAAA,EAAA,GAAuC;AAC5E,EAAA,MAAM,OAAA,EAAS,6BAAA,CAAO;AACtB,EAAA,MAAM,oBAAA,EAAsB,IAAI,0CAAA,CAAoB,YAAY,CAAA;AAEhE,EAAA,MAAM,kBAAA,EAAoB,CACzB,GAAA,EACA,GAAA,EACA,IAAA,EAAA,GACI;AACJ,IAAA,MAAM,aAAA,EAAe,YAAA,CAAa,eAAA,CAAgB,CAAA;AAClD,IAAA,GAAA,CAAI,CAAC,YAAA,EAAc;AAClB,MAAA,MAAM,MAAA,EAAQ,IAAI,mCAAA;AAAA,QACjB,4BAAA,CAAY,mBAAA;AAAA,QACZ;AAAA,MACD,CAAA;AACA,MAAA,MAAM,KAAA;AAAA,IACP;AACA,IAAA,IAAA,CAAK,CAAA;AAAA,EACN,CAAA;AAGA,EAAA,MAAA,CAAO,GAAA,CAAI,GAAA,EAAK,iBAAA,EAAmB,mBAAA,CAAoB,oBAAoB,CAAA;AAC3E,EAAA,MAAA,CAAO,GAAA,CAAI,MAAA,EAAQ,iBAAA,EAAmB,mBAAA,CAAoB,eAAe,CAAA;AACzE,EAAA,MAAA,CAAO,MAAA;AAAA,IACN,MAAA;AAAA,IACA,iBAAA;AAAA,IACA,mBAAA,CAAoB;AAAA,EACrB,CAAA;AAEA,EAAA,OAAO,MAAA;AACR,CAAA;ADNA;AACA;AACE;AACF,sDAAC","file":"/Users/shyun/comcom/ain-agent/ain-adk/dist/cjs/chunk-7PZP7YSA.cjs","sourcesContent":[null,"import {\n\ttype NextFunction,\n\ttype Request,\n\ttype Response,\n\tRouter,\n} from \"express\";\nimport { StatusCodes } from \"http-status-codes\";\nimport { ThreadApiController } from \"@/controllers/api/threads.api.controller.js\";\nimport type { MemoryModule } from \"@/modules/index.js\";\nimport { AinHttpError } from \"@/types/agent\";\n\nexport const createThreadApiRouter = (memoryModule: MemoryModule): Router => {\n\tconst router = Router();\n\tconst threadApiController = new ThreadApiController(memoryModule);\n\n\tconst checkThreadMemory = (\n\t\treq: Request,\n\t\tres: Response,\n\t\tnext: NextFunction,\n\t) => {\n\t\tconst threadMemory = memoryModule.getThreadMemory();\n\t\tif (!threadMemory) {\n\t\t\tconst error = new AinHttpError(\n\t\t\t\tStatusCodes.SERVICE_UNAVAILABLE,\n\t\t\t\t\"Memory module is not initialized\",\n\t\t\t);\n\t\t\tthrow error;\n\t\t}\n\t\tnext();\n\t};\n\n\t// APIs (prefix: /api/threads)\n\trouter.get(\"/\", checkThreadMemory, threadApiController.handleGetUserThreads);\n\trouter.get(\"/:id\", checkThreadMemory, threadApiController.handleGetThread);\n\trouter.delete(\n\t\t\"/:id\",\n\t\tcheckThreadMemory,\n\t\tthreadApiController.handleDeleteThread,\n\t);\n\n\treturn router;\n};\n"]}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
2
|
|
|
3
|
+
var _chunkQHQLU7BIcjs = require('./chunk-QHQLU7BI.cjs');
|
|
4
|
+
|
|
5
|
+
|
|
3
6
|
var _chunk466ED5WNcjs = require('./chunk-466ED5WN.cjs');
|
|
4
7
|
|
|
5
8
|
// src/services/query-stream.service.ts
|
|
6
9
|
var _crypto = require('crypto');
|
|
10
|
+
var _httpstatuscodes = require('http-status-codes');
|
|
7
11
|
var QueryStreamService = class {
|
|
8
12
|
|
|
9
13
|
|
|
@@ -72,18 +76,20 @@ Please select and answer the most appropriate intent name from the available int
|
|
|
72
76
|
return intent;
|
|
73
77
|
}
|
|
74
78
|
/**
|
|
75
|
-
* Fulfills the detected intent by generating a response.
|
|
79
|
+
* Fulfills the detected intent by generating a streaming response.
|
|
76
80
|
*
|
|
77
81
|
* Manages the complete inference loop including:
|
|
78
82
|
* - Loading prompts and conversation history
|
|
79
83
|
* - Collecting available tools from modules
|
|
80
84
|
* - Executing model inference with tool support
|
|
81
85
|
* - Processing tool calls iteratively until completion
|
|
86
|
+
* - Streaming results as Server-Sent Events
|
|
82
87
|
*
|
|
83
88
|
* @param query - The user's input query
|
|
84
89
|
* @param threadId - Thread identifier for context
|
|
85
90
|
* @param thread - Previous conversation history
|
|
86
|
-
* @
|
|
91
|
+
* @param intent - Optional detected intent with custom prompt
|
|
92
|
+
* @returns AsyncGenerator yielding StreamEvent objects
|
|
87
93
|
*/
|
|
88
94
|
async *intentFulfilling(query, threadId, thread, intent) {
|
|
89
95
|
const systemPrompt = `
|
|
@@ -138,11 +144,8 @@ ${_optionalChain([intent, 'optionalAccess', _8 => _8.prompt]) || ""}
|
|
|
138
144
|
assembledToolCalls
|
|
139
145
|
});
|
|
140
146
|
if (assembledToolCalls.length > 0) {
|
|
141
|
-
const messagePayload = _optionalChain([this, 'access', _14 => _14.a2aModule, 'optionalAccess', _15 => _15.getMessagePayload, 'call', _16 => _16(
|
|
142
|
-
query,
|
|
143
|
-
threadId
|
|
144
|
-
)]);
|
|
145
147
|
for (const toolCall of assembledToolCalls) {
|
|
148
|
+
const toolCallId = _crypto.randomUUID.call(void 0, );
|
|
146
149
|
const toolName = toolCall.function.name;
|
|
147
150
|
const selectedTool = tools.filter((tool) => tool.id === toolName)[0];
|
|
148
151
|
let toolResult = "";
|
|
@@ -150,7 +153,12 @@ ${_optionalChain([intent, 'optionalAccess', _8 => _8.prompt]) || ""}
|
|
|
150
153
|
const toolArgs = JSON.parse(toolCall.function.arguments);
|
|
151
154
|
yield {
|
|
152
155
|
event: "tool_start",
|
|
153
|
-
data: {
|
|
156
|
+
data: {
|
|
157
|
+
toolCallId,
|
|
158
|
+
protocol: "MCP" /* MCP */,
|
|
159
|
+
toolName,
|
|
160
|
+
toolArgs
|
|
161
|
+
}
|
|
154
162
|
};
|
|
155
163
|
_chunk466ED5WNcjs.loggers.intent.debug("MCP tool call", { toolName, toolArgs });
|
|
156
164
|
toolResult = await this.mcpModule.useTool(
|
|
@@ -161,6 +169,7 @@ ${_optionalChain([intent, 'optionalAccess', _8 => _8.prompt]) || ""}
|
|
|
161
169
|
yield {
|
|
162
170
|
event: "tool_start",
|
|
163
171
|
data: {
|
|
172
|
+
toolCallId,
|
|
164
173
|
protocol: "A2A" /* A2A */,
|
|
165
174
|
toolName,
|
|
166
175
|
toolArgs: null
|
|
@@ -169,8 +178,7 @@ ${_optionalChain([intent, 'optionalAccess', _8 => _8.prompt]) || ""}
|
|
|
169
178
|
_chunk466ED5WNcjs.loggers.intent.debug("A2A tool call", { toolName });
|
|
170
179
|
toolResult = await this.a2aModule.useTool(
|
|
171
180
|
selectedTool,
|
|
172
|
-
|
|
173
|
-
messagePayload,
|
|
181
|
+
query,
|
|
174
182
|
threadId
|
|
175
183
|
);
|
|
176
184
|
} else {
|
|
@@ -182,6 +190,7 @@ ${_optionalChain([intent, 'optionalAccess', _8 => _8.prompt]) || ""}
|
|
|
182
190
|
yield {
|
|
183
191
|
event: "tool_output",
|
|
184
192
|
data: {
|
|
193
|
+
toolCallId,
|
|
185
194
|
protocol: selectedTool.protocol,
|
|
186
195
|
toolName,
|
|
187
196
|
result: toolResult
|
|
@@ -224,32 +233,36 @@ ${_optionalChain([intent, 'optionalAccess', _8 => _8.prompt]) || ""}
|
|
|
224
233
|
}
|
|
225
234
|
}
|
|
226
235
|
/**
|
|
227
|
-
* Main entry point for processing user queries.
|
|
236
|
+
* Main entry point for processing streaming user queries.
|
|
228
237
|
*
|
|
229
238
|
* Handles the complete query lifecycle:
|
|
230
|
-
* 1. Loads thread from memory
|
|
239
|
+
* 1. Loads or creates thread from memory
|
|
231
240
|
* 2. Detects intent from the query
|
|
232
|
-
* 3. Fulfills the intent with AI response
|
|
233
|
-
* 4. Updates conversation history
|
|
241
|
+
* 3. Fulfills the intent with streaming AI response
|
|
242
|
+
* 4. Updates conversation history in real-time
|
|
234
243
|
*
|
|
235
|
-
* @param
|
|
236
|
-
* @param
|
|
237
|
-
* @param
|
|
244
|
+
* @param threadMetadata - Metadata containing type, userId, and optional threadId
|
|
245
|
+
* @param threadMetadata.type - The type of thread (e.g., chat, workflow)
|
|
246
|
+
* @param threadMetadata.userId - The user's unique identifier
|
|
247
|
+
* @param threadMetadata.threadId - Optional thread identifier
|
|
238
248
|
* @param query - The user's input query
|
|
239
|
-
* @returns
|
|
249
|
+
* @returns AsyncGenerator yielding StreamEvent objects for SSE
|
|
240
250
|
*/
|
|
241
251
|
async *handleQueryStream(threadMetadata, query) {
|
|
242
252
|
const { type, userId } = threadMetadata;
|
|
243
253
|
const queryStartAt = Date.now();
|
|
244
|
-
const threadMemory = _optionalChain([this, 'access',
|
|
254
|
+
const threadMemory = _optionalChain([this, 'access', _14 => _14.memoryModule, 'optionalAccess', _15 => _15.getThreadMemory, 'call', _16 => _16()]);
|
|
245
255
|
let threadId = threadMetadata.threadId;
|
|
246
256
|
let thread;
|
|
247
257
|
if (threadId) {
|
|
248
|
-
thread = await _optionalChain([threadMemory, 'optionalAccess',
|
|
258
|
+
thread = await _optionalChain([threadMemory, 'optionalAccess', _17 => _17.getThread, 'call', _18 => _18(userId, threadId)]);
|
|
259
|
+
if (!thread) {
|
|
260
|
+
throw new (0, _chunkQHQLU7BIcjs.AinHttpError)(_httpstatuscodes.StatusCodes.NOT_FOUND, "Thread not found");
|
|
261
|
+
}
|
|
249
262
|
} else {
|
|
250
263
|
threadId = _crypto.randomUUID.call(void 0, );
|
|
251
264
|
const title = await this.generateTitle(query);
|
|
252
|
-
const metadata = await _optionalChain([threadMemory, 'optionalAccess',
|
|
265
|
+
const metadata = await _optionalChain([threadMemory, 'optionalAccess', _19 => _19.createThread, 'call', _20 => _20(type, userId, threadId, title)]) || {
|
|
253
266
|
type,
|
|
254
267
|
threadId,
|
|
255
268
|
title,
|
|
@@ -258,6 +271,14 @@ ${_optionalChain([intent, 'optionalAccess', _8 => _8.prompt]) || ""}
|
|
|
258
271
|
_chunk466ED5WNcjs.loggers.intentStream.info("Create new thread", { metadata });
|
|
259
272
|
yield { event: "thread_id", data: metadata };
|
|
260
273
|
}
|
|
274
|
+
await _optionalChain([threadMemory, 'optionalAccess', _21 => _21.addMessagesToThread, 'call', _22 => _22(userId, threadId, [
|
|
275
|
+
{
|
|
276
|
+
messageId: _crypto.randomUUID.call(void 0, ),
|
|
277
|
+
role: "USER" /* USER */,
|
|
278
|
+
timestamp: queryStartAt,
|
|
279
|
+
content: { type: "text", parts: [query] }
|
|
280
|
+
}
|
|
281
|
+
])]);
|
|
261
282
|
const intent = await this.intentTriggering(query, thread);
|
|
262
283
|
const stream = this.intentFulfilling(query, threadId, thread, intent);
|
|
263
284
|
let finalResponseText = "";
|
|
@@ -265,16 +286,43 @@ ${_optionalChain([intent, 'optionalAccess', _8 => _8.prompt]) || ""}
|
|
|
265
286
|
if (event.event === "text_chunk" && event.data.delta) {
|
|
266
287
|
_chunk466ED5WNcjs.loggers.intentStream.debug("text_chunk", { event });
|
|
267
288
|
finalResponseText += event.data.delta;
|
|
289
|
+
} else if (event.event === "tool_start") {
|
|
290
|
+
await _optionalChain([threadMemory, 'optionalAccess', _23 => _23.addMessagesToThread, 'call', _24 => _24(userId, threadId, [
|
|
291
|
+
{
|
|
292
|
+
messageId: _crypto.randomUUID.call(void 0, ),
|
|
293
|
+
role: "MODEL" /* MODEL */,
|
|
294
|
+
timestamp: Date.now(),
|
|
295
|
+
content: {
|
|
296
|
+
type: "text",
|
|
297
|
+
parts: [JSON.stringify(event.data.toolArgs)]
|
|
298
|
+
},
|
|
299
|
+
metadata: {
|
|
300
|
+
toolCallId: event.data.toolCallId,
|
|
301
|
+
toolName: event.data.toolName,
|
|
302
|
+
protocol: event.data.protocol
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
])]);
|
|
306
|
+
} else if (event.event === "tool_output") {
|
|
307
|
+
await _optionalChain([threadMemory, 'optionalAccess', _25 => _25.addMessagesToThread, 'call', _26 => _26(userId, threadId, [
|
|
308
|
+
{
|
|
309
|
+
messageId: _crypto.randomUUID.call(void 0, ),
|
|
310
|
+
role: "MODEL" /* MODEL */,
|
|
311
|
+
timestamp: Date.now(),
|
|
312
|
+
content: { type: "text", parts: [event.data.result] },
|
|
313
|
+
metadata: {
|
|
314
|
+
toolCallId: event.data.toolCallId,
|
|
315
|
+
toolName: event.data.toolName,
|
|
316
|
+
protocol: event.data.protocol
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
])]);
|
|
268
320
|
}
|
|
269
321
|
yield event;
|
|
270
322
|
}
|
|
271
|
-
await _optionalChain([threadMemory, 'optionalAccess',
|
|
272
|
-
{
|
|
273
|
-
role: "USER" /* USER */,
|
|
274
|
-
timestamp: queryStartAt,
|
|
275
|
-
content: { type: "text", parts: [query] }
|
|
276
|
-
},
|
|
323
|
+
await _optionalChain([threadMemory, 'optionalAccess', _27 => _27.addMessagesToThread, 'call', _28 => _28(userId, threadId, [
|
|
277
324
|
{
|
|
325
|
+
messageId: _crypto.randomUUID.call(void 0, ),
|
|
278
326
|
role: "MODEL" /* MODEL */,
|
|
279
327
|
timestamp: Date.now(),
|
|
280
328
|
content: { type: "text", parts: [finalResponseText] }
|
|
@@ -286,4 +334,4 @@ ${_optionalChain([intent, 'optionalAccess', _8 => _8.prompt]) || ""}
|
|
|
286
334
|
|
|
287
335
|
|
|
288
336
|
exports.QueryStreamService = QueryStreamService;
|
|
289
|
-
//# sourceMappingURL=chunk-
|
|
337
|
+
//# sourceMappingURL=chunk-A2ANDQNY.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/shyun/comcom/ain-agent/ain-adk/dist/cjs/chunk-A2ANDQNY.cjs","../../src/services/query-stream.service.ts"],"names":["intent"],"mappings":"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","file":"/Users/shyun/comcom/ain-agent/ain-adk/dist/cjs/chunk-A2ANDQNY.cjs","sourcesContent":[null,"import { randomUUID } from \"node:crypto\";\nimport { StatusCodes } from \"http-status-codes\";\nimport type {\n\tA2AModule,\n\tMCPModule,\n\tMemoryModule,\n\tModelModule,\n} from \"@/modules/index.js\";\nimport { type AinAgentPrompts, AinHttpError } from \"@/types/agent.js\";\nimport {\n\ttype Intent,\n\tMessageRole,\n\ttype ThreadMetadata,\n\ttype ThreadObject,\n\ttype ThreadType,\n} from \"@/types/memory.js\";\nimport type { StreamEvent } from \"@/types/stream\";\nimport {\n\ttype IA2ATool,\n\ttype IAgentTool,\n\ttype IMCPTool,\n\tTOOL_PROTOCOL_TYPE,\n} from \"@/types/tool.js\";\nimport { loggers } from \"@/utils/logger.js\";\n\n/**\n * Service for processing user queries through the agent's AI pipeline.\n *\n * Orchestrates the query processing workflow including intent detection,\n * model inference, tool execution, and response generation. Manages\n * conversation context and coordinates between different modules.\n */\nexport class QueryStreamService {\n\tprivate modelModule: ModelModule;\n\tprivate a2aModule?: A2AModule;\n\tprivate mcpModule?: MCPModule;\n\tprivate memoryModule?: MemoryModule;\n\tprivate prompts?: AinAgentPrompts;\n\n\tconstructor(\n\t\tmodelModule: ModelModule,\n\t\ta2aModule?: A2AModule,\n\t\tmcpModule?: MCPModule,\n\t\tmemoryModule?: MemoryModule,\n\t\tprompts?: AinAgentPrompts,\n\t) {\n\t\tthis.modelModule = modelModule;\n\t\tthis.a2aModule = a2aModule;\n\t\tthis.mcpModule = mcpModule;\n\t\tthis.memoryModule = memoryModule;\n\t\tthis.prompts = prompts;\n\t}\n\n\t/**\n\t * Detects the intent from context.\n\t *\n\t * @param query - The user's input query\n\t * @param thread - The thread history\n\t * @returns The detected intent\n\t */\n\tprivate async intentTriggering(\n\t\tquery: string,\n\t\tthread: ThreadObject | undefined,\n\t): Promise<Intent | undefined> {\n\t\tconst modelInstance = this.modelModule.getModel();\n\t\tconst intentMemory = this.memoryModule?.getIntentMemory();\n\t\tif (!intentMemory) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// 인텐트 목록 가져오기\n\t\tconst intents = await intentMemory.listIntents();\n\n\t\tif (intents.length === 0) {\n\t\t\tloggers.intentStream.warn(\"No intent found\");\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst intentList = intents\n\t\t\t.map((intent) => `- ${intent.name}: ${intent.description}`)\n\t\t\t.join(\"\\n\");\n\n\t\t// Convert session history to a string\n\t\tconst historyMessages = !thread\n\t\t\t? \"\"\n\t\t\t: Object.entries(thread.messages)\n\t\t\t\t\t.sort(([, a], [, b]) => a.timestamp - b.timestamp)\n\t\t\t\t\t.map(([_chatId, chat]) => {\n\t\t\t\t\t\tconst role =\n\t\t\t\t\t\t\tchat.role === \"USER\"\n\t\t\t\t\t\t\t\t? \"User\"\n\t\t\t\t\t\t\t\t: chat.role === \"MODEL\"\n\t\t\t\t\t\t\t\t\t? \"Assistant\"\n\t\t\t\t\t\t\t\t\t: \"System\";\n\t\t\t\t\t\tconst content = Array.isArray(chat.content.parts)\n\t\t\t\t\t\t\t? chat.content.parts.join(\" \")\n\t\t\t\t\t\t\t: String(chat.content.parts);\n\t\t\t\t\t\treturn `${role}: \"\"\"${content}\"\"\"`;\n\t\t\t\t\t})\n\t\t\t\t\t.join(\"\\n\");\n\n\t\tconst systemPrompt = `You are an expert in accurately identifying user intentions.\n\nAvailable intent list:\n${intentList}\n\nPlease select and answer only from the above intent list. \nPlease return only the exact intent name without any additional explanations or text.`;\n\n\t\tconst userMessage = `The following is the conversation history with the user:\n\n${historyMessages}\n\nLast user question: \"${query}\"\n\nBased on the above conversation history, please determine what the intention of the last user question is. \nPlease select and answer the most appropriate intent name from the available intent list.`;\n\n\t\tconst messages = modelInstance.generateMessages({\n\t\t\tquery: userMessage,\n\t\t\tsystemPrompt,\n\t\t});\n\n\t\tconst response = await modelInstance.fetch(messages);\n\t\tif (!response.content) {\n\t\t\tthrow new Error(\"No intent detected\");\n\t\t}\n\t\tconst intentName = response.content.trim();\n\t\tconst intent = await intentMemory.getIntentByName(intentName);\n\t\tif (!intent) {\n\t\t\tthrow new Error(`No intent found: ${intentName}`);\n\t\t}\n\t\treturn intent;\n\t}\n\n\t/**\n\t * Fulfills the detected intent by generating a streaming response.\n\t *\n\t * Manages the complete inference loop including:\n\t * - Loading prompts and conversation history\n\t * - Collecting available tools from modules\n\t * - Executing model inference with tool support\n\t * - Processing tool calls iteratively until completion\n\t * - Streaming results as Server-Sent Events\n\t *\n\t * @param query - The user's input query\n\t * @param threadId - Thread identifier for context\n\t * @param thread - Previous conversation history\n\t * @param intent - Optional detected intent with custom prompt\n\t * @returns AsyncGenerator yielding StreamEvent objects\n\t */\n\tpublic async *intentFulfilling(\n\t\tquery: string,\n\t\tthreadId: string,\n\t\tthread?: ThreadObject,\n\t\tintent?: Intent,\n\t): AsyncGenerator<StreamEvent> {\n\t\tconst systemPrompt = `\nToday is ${new Date().toLocaleDateString()}.\n\n${this.prompts?.agent || \"\"}\n\n${this.prompts?.system || \"\"}\n\n${intent?.prompt || \"\"}\n\t`.trim();\n\n\t\tconst modelInstance = this.modelModule.getModel();\n\t\tconst messages = modelInstance.generateMessages({\n\t\t\tquery,\n\t\t\tthread,\n\t\t\tsystemPrompt: systemPrompt.trim(),\n\t\t});\n\n\t\tconst tools: IAgentTool[] = [];\n\t\tthis.mcpModule && tools.push(...this.mcpModule.getTools());\n\t\tthis.a2aModule && tools.push(...(await this.a2aModule.getTools()));\n\n\t\tconst functions = modelInstance.convertToolsToFunctions(tools);\n\n\t\tconst processList: string[] = [];\n\n\t\twhile (true) {\n\t\t\tconst responseStream = await modelInstance.fetchStreamWithContextMessage(\n\t\t\t\tmessages,\n\t\t\t\tfunctions,\n\t\t\t);\n\n\t\t\tconst assembledToolCalls: {\n\t\t\t\tid: string;\n\t\t\t\ttype: \"function\";\n\t\t\t\tfunction: { name: string; arguments: string };\n\t\t\t}[] = [];\n\n\t\t\tloggers.intentStream.debug(\"messages\", { messages });\n\n\t\t\tfor await (const chunk of responseStream) {\n\t\t\t\tconst delta = chunk.delta;\n\t\t\t\tif (delta?.tool_calls) {\n\t\t\t\t\tfor (const { index, id, function: func } of delta.tool_calls) {\n\t\t\t\t\t\tassembledToolCalls[index] ??= {\n\t\t\t\t\t\t\tid: \"\",\n\t\t\t\t\t\t\ttype: \"function\",\n\t\t\t\t\t\t\tfunction: { name: \"\", arguments: \"\" },\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tif (id) assembledToolCalls[index].id = id;\n\t\t\t\t\t\tif (func?.name) assembledToolCalls[index].function.name = func.name;\n\t\t\t\t\t\tif (func?.arguments)\n\t\t\t\t\t\t\tassembledToolCalls[index].function.arguments += func.arguments;\n\t\t\t\t\t}\n\t\t\t\t} else if (chunk.delta?.content) {\n\t\t\t\t\tyield {\n\t\t\t\t\t\tevent: \"text_chunk\",\n\t\t\t\t\t\tdata: { delta: chunk.delta.content },\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tloggers.intentStream.debug(\"assembledToolCalls\", {\n\t\t\t\tassembledToolCalls,\n\t\t\t});\n\n\t\t\tif (assembledToolCalls.length > 0) {\n\t\t\t\tfor (const toolCall of assembledToolCalls) {\n\t\t\t\t\tconst toolCallId = randomUUID();\n\t\t\t\t\tconst toolName = toolCall.function.name;\n\t\t\t\t\tconst selectedTool = tools.filter((tool) => tool.id === toolName)[0];\n\n\t\t\t\t\tlet toolResult = \"\";\n\t\t\t\t\tif (\n\t\t\t\t\t\tthis.mcpModule &&\n\t\t\t\t\t\tselectedTool.protocol === TOOL_PROTOCOL_TYPE.MCP\n\t\t\t\t\t) {\n\t\t\t\t\t\tconst toolArgs = JSON.parse(toolCall.function.arguments) as\n\t\t\t\t\t\t\t| { [x: string]: unknown }\n\t\t\t\t\t\t\t| undefined;\n\t\t\t\t\t\tyield {\n\t\t\t\t\t\t\tevent: \"tool_start\",\n\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\ttoolCallId,\n\t\t\t\t\t\t\t\tprotocol: TOOL_PROTOCOL_TYPE.MCP,\n\t\t\t\t\t\t\t\ttoolName,\n\t\t\t\t\t\t\t\ttoolArgs,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t\tloggers.intent.debug(\"MCP tool call\", { toolName, toolArgs });\n\t\t\t\t\t\ttoolResult = await this.mcpModule.useTool(\n\t\t\t\t\t\t\tselectedTool as IMCPTool,\n\t\t\t\t\t\t\ttoolArgs,\n\t\t\t\t\t\t);\n\t\t\t\t\t} else if (\n\t\t\t\t\t\tthis.a2aModule &&\n\t\t\t\t\t\tselectedTool.protocol === TOOL_PROTOCOL_TYPE.A2A\n\t\t\t\t\t) {\n\t\t\t\t\t\tyield {\n\t\t\t\t\t\t\tevent: \"tool_start\",\n\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\ttoolCallId,\n\t\t\t\t\t\t\t\tprotocol: TOOL_PROTOCOL_TYPE.A2A,\n\t\t\t\t\t\t\t\ttoolName,\n\t\t\t\t\t\t\t\ttoolArgs: null,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t\tloggers.intent.debug(\"A2A tool call\", { toolName });\n\t\t\t\t\t\ttoolResult = await this.a2aModule.useTool(\n\t\t\t\t\t\t\tselectedTool as IA2ATool,\n\t\t\t\t\t\t\tquery,\n\t\t\t\t\t\t\tthreadId,\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Unrecognized tool type. It cannot be happened...\n\t\t\t\t\t\tloggers.intent.warn(\n\t\t\t\t\t\t\t`Unrecognized tool type: ${selectedTool.protocol}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tyield {\n\t\t\t\t\t\tevent: \"tool_output\",\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\ttoolCallId,\n\t\t\t\t\t\t\tprotocol: selectedTool.protocol,\n\t\t\t\t\t\t\ttoolName,\n\t\t\t\t\t\t\tresult: toolResult,\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t\tloggers.intent.debug(\"toolResult\", { toolResult });\n\n\t\t\t\t\tprocessList.push(toolResult);\n\t\t\t\t\tmodelInstance.appendMessages(messages, toolResult);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Generates a title for the conversation based on the query.\n\t *\n\t * @param query - The user's input query\n\t * @returns Promise resolving to a generated title\n\t */\n\n\tprivate async generateTitle(query: string): Promise<string> {\n\t\tconst DEFAULT_TITLE = \"New Chat\";\n\t\ttry {\n\t\t\tconst modelInstance = this.modelModule.getModel();\n\t\t\tconst messages = modelInstance.generateMessages({\n\t\t\t\tquery,\n\t\t\t\tsystemPrompt: `You are a helpful assistant that generates titles for conversations.\n Please analyze the user's query and create a concise title that accurately reflects the conversation's core topic.\n The title must be no more than 5 words long.\n Respond with only the title. Do not include any punctuation or extra explanations.`,\n\t\t\t});\n\t\t\tconst response = await modelInstance.fetch(messages);\n\t\t\treturn response.content || DEFAULT_TITLE;\n\t\t} catch (error) {\n\t\t\tloggers.intentStream.error(\"Error generating title\", {\n\t\t\t\terror,\n\t\t\t\tquery,\n\t\t\t});\n\t\t\treturn DEFAULT_TITLE;\n\t\t}\n\t}\n\n\t/**\n\t * Main entry point for processing streaming user queries.\n\t *\n\t * Handles the complete query lifecycle:\n\t * 1. Loads or creates thread from memory\n\t * 2. Detects intent from the query\n\t * 3. Fulfills the intent with streaming AI response\n\t * 4. Updates conversation history in real-time\n\t *\n\t * @param threadMetadata - Metadata containing type, userId, and optional threadId\n\t * @param threadMetadata.type - The type of thread (e.g., chat, workflow)\n\t * @param threadMetadata.userId - The user's unique identifier\n\t * @param threadMetadata.threadId - Optional thread identifier\n\t * @param query - The user's input query\n\t * @returns AsyncGenerator yielding StreamEvent objects for SSE\n\t */\n\tpublic async *handleQueryStream(\n\t\tthreadMetadata: {\n\t\t\ttype: ThreadType;\n\t\t\tuserId: string;\n\t\t\tthreadId?: string;\n\t\t},\n\t\tquery: string,\n\t): AsyncGenerator<StreamEvent> {\n\t\tconst { type, userId } = threadMetadata;\n\t\tconst queryStartAt = Date.now();\n\t\tconst threadMemory = this.memoryModule?.getThreadMemory();\n\n\t\t// 1. Load or create thread\n\t\tlet threadId = threadMetadata.threadId;\n\t\tlet thread: ThreadObject | undefined;\n\t\tif (threadId) {\n\t\t\tthread = await threadMemory?.getThread(userId, threadId);\n\t\t\tif (!thread) {\n\t\t\t\tthrow new AinHttpError(StatusCodes.NOT_FOUND, \"Thread not found\");\n\t\t\t}\n\t\t} else {\n\t\t\tthreadId = randomUUID();\n\t\t\tconst title = await this.generateTitle(query);\n\n\t\t\tconst metadata =\n\t\t\t\t(await threadMemory?.createThread(type, userId, threadId, title)) ||\n\t\t\t\t({\n\t\t\t\t\ttype,\n\t\t\t\t\tthreadId,\n\t\t\t\t\ttitle,\n\t\t\t\t\tupdatedAt: Date.now(),\n\t\t\t\t} as ThreadMetadata);\n\t\t\tloggers.intentStream.info(\"Create new thread\", { metadata });\n\t\t\tyield { event: \"thread_id\", data: metadata };\n\t\t}\n\n\t\tawait threadMemory?.addMessagesToThread(userId, threadId, [\n\t\t\t{\n\t\t\t\tmessageId: randomUUID(),\n\t\t\t\trole: MessageRole.USER,\n\t\t\t\ttimestamp: queryStartAt,\n\t\t\t\tcontent: { type: \"text\", parts: [query] },\n\t\t\t},\n\t\t]);\n\n\t\t// 2. intent triggering\n\t\tconst intent = await this.intentTriggering(query, thread);\n\n\t\t// 3. intent fulfillment\n\t\tconst stream = this.intentFulfilling(query, threadId, thread, intent);\n\n\t\tlet finalResponseText = \"\";\n\t\tfor await (const event of stream) {\n\t\t\tif (event.event === \"text_chunk\" && event.data.delta) {\n\t\t\t\tloggers.intentStream.debug(\"text_chunk\", { event });\n\t\t\t\tfinalResponseText += event.data.delta;\n\t\t\t} else if (event.event === \"tool_start\") {\n\t\t\t\tawait threadMemory?.addMessagesToThread(userId, threadId, [\n\t\t\t\t\t{\n\t\t\t\t\t\tmessageId: randomUUID(),\n\t\t\t\t\t\trole: MessageRole.MODEL,\n\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\tparts: [JSON.stringify(event.data.toolArgs)],\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\ttoolCallId: event.data.toolCallId,\n\t\t\t\t\t\t\ttoolName: event.data.toolName,\n\t\t\t\t\t\t\tprotocol: event.data.protocol,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t]);\n\t\t\t} else if (event.event === \"tool_output\") {\n\t\t\t\tawait threadMemory?.addMessagesToThread(userId, threadId, [\n\t\t\t\t\t{\n\t\t\t\t\t\tmessageId: randomUUID(),\n\t\t\t\t\t\trole: MessageRole.MODEL,\n\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t\tcontent: { type: \"text\", parts: [event.data.result] },\n\t\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\ttoolCallId: event.data.toolCallId,\n\t\t\t\t\t\t\ttoolName: event.data.toolName,\n\t\t\t\t\t\t\tprotocol: event.data.protocol,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t]);\n\t\t\t}\n\t\t\tyield event;\n\t\t}\n\n\t\tawait threadMemory?.addMessagesToThread(userId, threadId, [\n\t\t\t{\n\t\t\t\tmessageId: randomUUID(),\n\t\t\t\trole: MessageRole.MODEL,\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t\tcontent: { type: \"text\", parts: [finalResponseText] },\n\t\t\t},\n\t\t]);\n\t}\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/shyun/comcom/ain-agent/ain-adk/dist/cjs/chunk-A2I7D6JW.cjs","../../src/controllers/api/threads.api.controller.ts"],"names":[],"mappings":"AAAA;ACCA,oDAA4B;AAGrB,IAAM,oBAAA,YAAN,MAA0B;AAAA,EACxB;AAAA,EAER,WAAA,CAAY,YAAA,EAA4B;AACvC,IAAA,IAAA,CAAK,aAAA,EAAe,YAAA;AAAA,EACrB;AAAA,iBAEO,gBAAA,EAAkB,MAAA,CACxB,GAAA,EACA,GAAA,EACA,IAAA,EAAA,GACI;AACJ,IAAA,IAAI;AACH,MAAA,MAAM,EAAE,EAAA,EAAI,SAAS,EAAA,EAAI,GAAA,CAAI,MAAA;AAG7B,MAAA,MAAM,OAAA,EAAS,GAAA,CAAI,MAAA,CAAO,OAAA,GAAU,EAAA;AACpC,MAAA,MAAM,aAAA,EAAe,IAAA,CAAK,YAAA,CAAa,eAAA,CAAgB,CAAA;AACvD,MAAA,MAAM,OAAA,EAAS,sBAAM,YAAA,6BAAc,SAAA,mBAAU,MAAA,EAAQ,QAAQ,GAAA;AAC7D,MAAA,GAAA,CAAI,IAAA,CAAK,MAAM,CAAA;AAAA,IAChB,EAAA,MAAA,CAAS,KAAA,EAAO;AACf,MAAA,IAAA,CAAK,KAAK,CAAA;AAAA,IACX;AAAA,EACD,EAAA;AAAA,kBAEO,mBAAA,EAAqB,MAAA,CAC3B,GAAA,EACA,GAAA,EACA,IAAA,EAAA,GACI;AACJ,IAAA,IAAI;AACH,MAAA,MAAM,EAAE,EAAA,EAAI,SAAS,EAAA,EAAI,GAAA,CAAI,MAAA;AAC7B,MAAA,MAAM,OAAA,EAAS,GAAA,CAAI,MAAA,CAAO,OAAA,GAAU,EAAA;AACpC,MAAA,MAAM,aAAA,EAAe,IAAA,CAAK,YAAA,CAAa,eAAA,CAAgB,CAAA;AACvD,MAAA,sBAAM,YAAA,6BAAc,YAAA,qBAAa,MAAA,EAAQ,QAAQ,GAAA;AACjD,MAAA,GAAA,CAAI,MAAA,CAAO,4BAAA,CAAY,EAAE,CAAA,CAAE,IAAA,CAAK,CAAA;AAAA,IACjC,EAAA,MAAA,CAAS,KAAA,EAAO;AACf,MAAA,IAAA,CAAK,KAAK,CAAA;AAAA,IACX;AAAA,EACD,EAAA;AAAA,kBAEO,qBAAA,EAAuB,MAAA,CAC7B,IAAA,EACA,GAAA,EACA,IAAA,EAAA,GACI;AACJ,IAAA,IAAI;AACH,MAAA,MAAM,OAAA,EAAS,GAAA,CAAI,MAAA,CAAO,OAAA,GAAU,EAAA;AACpC,MAAA,MAAM,aAAA,EAAe,IAAA,CAAK,YAAA,CAAa,eAAA,CAAgB,CAAA;AACvD,MAAA,MAAM,QAAA,EAAU,sBAAM,YAAA,+BAAc,WAAA,qBAAY,MAAM,GAAA;AACtD,MAAA,GAAA,CAAI,IAAA,CAAK,OAAO,CAAA;AAAA,IACjB,EAAA,MAAA,CAAS,KAAA,EAAO;AACf,MAAA,IAAA,CAAK,KAAK,CAAA;AAAA,IACX;AAAA,EACD,EAAA;AACD,UAAA;ADnBA;AACA;AACE;AACF,kDAAC","file":"/Users/shyun/comcom/ain-agent/ain-adk/dist/cjs/chunk-A2I7D6JW.cjs","sourcesContent":[null,"import type { NextFunction, Request, Response } from \"express\";\nimport { StatusCodes } from \"http-status-codes\";\nimport type { MemoryModule } from \"@/modules/index.js\";\n\nexport class ThreadApiController {\n\tprivate memoryModule: MemoryModule;\n\n\tconstructor(memoryModule: MemoryModule) {\n\t\tthis.memoryModule = memoryModule;\n\t}\n\n\tpublic handleGetThread = async (\n\t\treq: Request,\n\t\tres: Response,\n\t\tnext: NextFunction,\n\t) => {\n\t\ttry {\n\t\t\tconst { id: threadId } = req.params as {\n\t\t\t\tid: string;\n\t\t\t};\n\t\t\tconst userId = res.locals.userId || \"\";\n\t\t\tconst threadMemory = this.memoryModule.getThreadMemory();\n\t\t\tconst thread = await threadMemory?.getThread(userId, threadId);\n\t\t\tres.json(thread);\n\t\t} catch (error) {\n\t\t\tnext(error);\n\t\t}\n\t};\n\n\tpublic handleDeleteThread = async (\n\t\treq: Request,\n\t\tres: Response,\n\t\tnext: NextFunction,\n\t) => {\n\t\ttry {\n\t\t\tconst { id: threadId } = req.params;\n\t\t\tconst userId = res.locals.userId || \"\";\n\t\t\tconst threadMemory = this.memoryModule.getThreadMemory();\n\t\t\tawait threadMemory?.deleteThread(userId, threadId);\n\t\t\tres.status(StatusCodes.OK).send();\n\t\t} catch (error) {\n\t\t\tnext(error);\n\t\t}\n\t};\n\n\tpublic handleGetUserThreads = async (\n\t\t_req: Request,\n\t\tres: Response,\n\t\tnext: NextFunction,\n\t) => {\n\t\ttry {\n\t\t\tconst userId = res.locals.userId || \"\";\n\t\t\tconst threadMemory = this.memoryModule.getThreadMemory();\n\t\t\tconst threads = await threadMemory?.listThreads(userId);\n\t\t\tres.json(threads);\n\t\t} catch (error) {\n\t\t\tnext(error);\n\t\t}\n\t};\n}\n"]}
|