@inkeep/agents-run-api 0.39.4 → 0.40.0

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.
Files changed (180) hide show
  1. package/dist/_virtual/_raw_/home/runner/work/agents/agents/agents-run-api/templates/v1/phase1/system-prompt.js +5 -0
  2. package/dist/_virtual/_raw_/home/runner/work/agents/agents/agents-run-api/templates/v1/phase1/thinking-preparation.js +5 -0
  3. package/dist/_virtual/_raw_/home/runner/work/agents/agents/agents-run-api/templates/v1/phase1/tool.js +5 -0
  4. package/dist/_virtual/_raw_/home/runner/work/agents/agents/agents-run-api/templates/v1/phase2/data-component.js +5 -0
  5. package/dist/_virtual/_raw_/home/runner/work/agents/agents/agents-run-api/templates/v1/phase2/data-components.js +5 -0
  6. package/dist/_virtual/_raw_/home/runner/work/agents/agents/agents-run-api/templates/v1/phase2/system-prompt.js +5 -0
  7. package/dist/_virtual/_raw_/home/runner/work/agents/agents/agents-run-api/templates/v1/shared/artifact-retrieval-guidance.js +5 -0
  8. package/dist/_virtual/_raw_/home/runner/work/agents/agents/agents-run-api/templates/v1/shared/artifact.js +5 -0
  9. package/dist/a2a/client.d.ts +184 -0
  10. package/dist/a2a/client.js +510 -0
  11. package/dist/a2a/handlers.d.ts +7 -0
  12. package/dist/a2a/handlers.js +560 -0
  13. package/dist/a2a/transfer.d.ts +22 -0
  14. package/dist/a2a/transfer.js +46 -0
  15. package/dist/a2a/types.d.ts +79 -0
  16. package/dist/a2a/types.js +22 -0
  17. package/dist/agents/Agent.d.ts +266 -0
  18. package/dist/agents/Agent.js +1927 -0
  19. package/dist/agents/ModelFactory.d.ts +63 -0
  20. package/dist/agents/ModelFactory.js +194 -0
  21. package/dist/agents/SystemPromptBuilder.d.ts +21 -0
  22. package/dist/agents/SystemPromptBuilder.js +48 -0
  23. package/dist/agents/ToolSessionManager.d.ts +63 -0
  24. package/dist/agents/ToolSessionManager.js +146 -0
  25. package/dist/agents/generateTaskHandler.d.ts +49 -0
  26. package/dist/agents/generateTaskHandler.js +521 -0
  27. package/dist/agents/relationTools.d.ts +57 -0
  28. package/dist/agents/relationTools.js +262 -0
  29. package/dist/agents/types.d.ts +28 -0
  30. package/dist/agents/types.js +1 -0
  31. package/dist/agents/versions/v1/Phase1Config.d.ts +27 -0
  32. package/dist/agents/versions/v1/Phase1Config.js +424 -0
  33. package/dist/agents/versions/v1/Phase2Config.d.ts +31 -0
  34. package/dist/agents/versions/v1/Phase2Config.js +330 -0
  35. package/dist/constants/execution-limits/defaults.d.ts +51 -0
  36. package/dist/constants/execution-limits/defaults.js +52 -0
  37. package/dist/constants/execution-limits/index.d.ts +6 -0
  38. package/dist/constants/execution-limits/index.js +21 -0
  39. package/dist/create-app.d.ts +9 -0
  40. package/dist/create-app.js +195 -0
  41. package/dist/data/agent.d.ts +7 -0
  42. package/dist/data/agent.js +72 -0
  43. package/dist/data/agents.d.ts +34 -0
  44. package/dist/data/agents.js +139 -0
  45. package/dist/data/conversations.d.ts +128 -0
  46. package/dist/data/conversations.js +522 -0
  47. package/dist/data/db/dbClient.d.ts +6 -0
  48. package/dist/data/db/dbClient.js +17 -0
  49. package/dist/env.d.ts +57 -0
  50. package/dist/env.js +1 -2
  51. package/dist/handlers/executionHandler.d.ts +39 -0
  52. package/dist/handlers/executionHandler.js +456 -0
  53. package/dist/index.d.ts +8 -29
  54. package/dist/index.js +5 -11235
  55. package/dist/instrumentation.d.ts +1 -2
  56. package/dist/instrumentation.js +66 -3
  57. package/dist/{logger2.js → logger.d.ts} +1 -2
  58. package/dist/logger.js +1 -1
  59. package/dist/middleware/api-key-auth.d.ts +26 -0
  60. package/dist/middleware/api-key-auth.js +240 -0
  61. package/dist/middleware/index.d.ts +2 -0
  62. package/dist/middleware/index.js +3 -0
  63. package/dist/openapi.d.ts +4 -0
  64. package/dist/openapi.js +54 -0
  65. package/dist/routes/agents.d.ts +12 -0
  66. package/dist/routes/agents.js +147 -0
  67. package/dist/routes/chat.d.ts +13 -0
  68. package/dist/routes/chat.js +293 -0
  69. package/dist/routes/chatDataStream.d.ts +13 -0
  70. package/dist/routes/chatDataStream.js +352 -0
  71. package/dist/routes/mcp.d.ts +13 -0
  72. package/dist/routes/mcp.js +495 -0
  73. package/dist/services/AgentSession.d.ts +356 -0
  74. package/dist/services/AgentSession.js +1208 -0
  75. package/dist/services/ArtifactParser.d.ts +105 -0
  76. package/dist/services/ArtifactParser.js +338 -0
  77. package/dist/services/ArtifactService.d.ts +123 -0
  78. package/dist/services/ArtifactService.js +612 -0
  79. package/dist/services/BaseCompressor.d.ts +183 -0
  80. package/dist/services/BaseCompressor.js +504 -0
  81. package/dist/services/ConversationCompressor.d.ts +32 -0
  82. package/dist/services/ConversationCompressor.js +91 -0
  83. package/dist/services/IncrementalStreamParser.d.ts +98 -0
  84. package/dist/services/IncrementalStreamParser.js +327 -0
  85. package/dist/services/MidGenerationCompressor.d.ts +63 -0
  86. package/dist/services/MidGenerationCompressor.js +104 -0
  87. package/dist/services/PendingToolApprovalManager.d.ts +62 -0
  88. package/dist/services/PendingToolApprovalManager.js +133 -0
  89. package/dist/services/ResponseFormatter.d.ts +39 -0
  90. package/dist/services/ResponseFormatter.js +152 -0
  91. package/dist/tools/NativeSandboxExecutor.d.ts +38 -0
  92. package/dist/tools/NativeSandboxExecutor.js +432 -0
  93. package/dist/tools/SandboxExecutorFactory.d.ts +36 -0
  94. package/dist/tools/SandboxExecutorFactory.js +80 -0
  95. package/dist/tools/VercelSandboxExecutor.d.ts +71 -0
  96. package/dist/tools/VercelSandboxExecutor.js +340 -0
  97. package/dist/tools/distill-conversation-history-tool.d.ts +62 -0
  98. package/dist/tools/distill-conversation-history-tool.js +206 -0
  99. package/dist/tools/distill-conversation-tool.d.ts +41 -0
  100. package/dist/tools/distill-conversation-tool.js +141 -0
  101. package/dist/tools/sandbox-utils.d.ts +18 -0
  102. package/dist/tools/sandbox-utils.js +53 -0
  103. package/dist/types/chat.d.ts +27 -0
  104. package/dist/types/chat.js +1 -0
  105. package/dist/types/execution-context.d.ts +46 -0
  106. package/dist/types/execution-context.js +27 -0
  107. package/dist/types/xml.d.ts +5 -0
  108. package/dist/utils/SchemaProcessor.d.ts +52 -0
  109. package/dist/utils/SchemaProcessor.js +182 -0
  110. package/dist/utils/agent-operations.d.ts +62 -0
  111. package/dist/utils/agent-operations.js +53 -0
  112. package/dist/utils/artifact-component-schema.d.ts +42 -0
  113. package/dist/utils/artifact-component-schema.js +186 -0
  114. package/dist/utils/cleanup.d.ts +21 -0
  115. package/dist/utils/cleanup.js +59 -0
  116. package/dist/utils/data-component-schema.d.ts +2 -0
  117. package/dist/utils/data-component-schema.js +3 -0
  118. package/dist/utils/default-status-schemas.d.ts +20 -0
  119. package/dist/utils/default-status-schemas.js +24 -0
  120. package/dist/utils/json-postprocessor.d.ts +13 -0
  121. package/dist/{json-postprocessor.cjs → utils/json-postprocessor.js} +1 -2
  122. package/dist/utils/model-context-utils.d.ts +39 -0
  123. package/dist/utils/model-context-utils.js +181 -0
  124. package/dist/utils/model-resolver.d.ts +6 -0
  125. package/dist/utils/model-resolver.js +34 -0
  126. package/dist/utils/schema-validation.d.ts +44 -0
  127. package/dist/utils/schema-validation.js +97 -0
  128. package/dist/utils/stream-helpers.d.ts +197 -0
  129. package/dist/utils/stream-helpers.js +518 -0
  130. package/dist/utils/stream-registry.d.ts +22 -0
  131. package/dist/utils/stream-registry.js +34 -0
  132. package/dist/utils/token-estimator.d.ts +69 -0
  133. package/dist/utils/token-estimator.js +53 -0
  134. package/dist/utils/tracer.d.ts +7 -0
  135. package/dist/utils/tracer.js +7 -0
  136. package/package.json +5 -20
  137. package/dist/SandboxExecutorFactory.cjs +0 -895
  138. package/dist/SandboxExecutorFactory.js +0 -893
  139. package/dist/SandboxExecutorFactory.js.map +0 -1
  140. package/dist/chunk-VBDAOXYI.cjs +0 -927
  141. package/dist/chunk-VBDAOXYI.js +0 -832
  142. package/dist/chunk-VBDAOXYI.js.map +0 -1
  143. package/dist/chunk.cjs +0 -34
  144. package/dist/conversations.cjs +0 -7
  145. package/dist/conversations.js +0 -7
  146. package/dist/conversations2.cjs +0 -209
  147. package/dist/conversations2.js +0 -180
  148. package/dist/conversations2.js.map +0 -1
  149. package/dist/dbClient.cjs +0 -9676
  150. package/dist/dbClient.js +0 -9670
  151. package/dist/dbClient.js.map +0 -1
  152. package/dist/dbClient2.cjs +0 -5
  153. package/dist/dbClient2.js +0 -5
  154. package/dist/env.cjs +0 -59
  155. package/dist/env.js.map +0 -1
  156. package/dist/execution-limits.cjs +0 -260
  157. package/dist/execution-limits.js +0 -63
  158. package/dist/execution-limits.js.map +0 -1
  159. package/dist/index.cjs +0 -11260
  160. package/dist/index.d.cts +0 -36
  161. package/dist/index.d.cts.map +0 -1
  162. package/dist/index.d.ts.map +0 -1
  163. package/dist/index.js.map +0 -1
  164. package/dist/instrumentation.cjs +0 -12
  165. package/dist/instrumentation.d.cts +0 -18
  166. package/dist/instrumentation.d.cts.map +0 -1
  167. package/dist/instrumentation.d.ts.map +0 -1
  168. package/dist/instrumentation2.cjs +0 -116
  169. package/dist/instrumentation2.js +0 -69
  170. package/dist/instrumentation2.js.map +0 -1
  171. package/dist/json-postprocessor.js +0 -20
  172. package/dist/json-postprocessor.js.map +0 -1
  173. package/dist/logger.cjs +0 -5
  174. package/dist/logger2.cjs +0 -1
  175. package/dist/nodefs.cjs +0 -29
  176. package/dist/nodefs.js +0 -27
  177. package/dist/nodefs.js.map +0 -1
  178. package/dist/opfs-ahp.cjs +0 -367
  179. package/dist/opfs-ahp.js +0 -368
  180. package/dist/opfs-ahp.js.map +0 -1
@@ -0,0 +1,293 @@
1
+ import { getLogger } from "../logger.js";
2
+ import dbClient_default from "../data/db/dbClient.js";
3
+ import { errorOp } from "../utils/agent-operations.js";
4
+ import { createSSEStreamHelper } from "../utils/stream-helpers.js";
5
+ import { ExecutionHandler } from "../handlers/executionHandler.js";
6
+ import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
7
+ import { contextValidationMiddleware, createApiError, createMessage, createOrGetConversation, generateId, getActiveAgentForConversation, getAgentWithDefaultSubAgent, getConversationId, getFullAgent, getRequestExecutionContext, getSubAgentById, handleContextResolution, setActiveAgentForConversation } from "@inkeep/agents-core";
8
+ import { context, propagation, trace } from "@opentelemetry/api";
9
+ import { streamSSE } from "hono/streaming";
10
+
11
+ //#region src/routes/chat.ts
12
+ const app = new OpenAPIHono();
13
+ const logger = getLogger("completionsHandler");
14
+ const chatCompletionsRoute = createRoute({
15
+ method: "post",
16
+ path: "/completions",
17
+ tags: ["chat"],
18
+ summary: "Create chat completion",
19
+ description: "Creates a new chat completion with streaming SSE response using the configured agent",
20
+ security: [{ bearerAuth: [] }],
21
+ request: { body: { content: { "application/json": { schema: z.object({
22
+ model: z.string().describe("The model to use for the completion"),
23
+ messages: z.array(z.object({
24
+ role: z.enum([
25
+ "system",
26
+ "user",
27
+ "assistant",
28
+ "function",
29
+ "tool"
30
+ ]).describe("The role of the message"),
31
+ content: z.union([z.string(), z.array(z.strictObject({
32
+ type: z.string(),
33
+ text: z.string().optional()
34
+ }))]).describe("The message content"),
35
+ name: z.string().optional().describe("The name of the message sender")
36
+ })).describe("The conversation messages"),
37
+ temperature: z.number().optional().describe("Controls randomness (0-1)"),
38
+ top_p: z.number().optional().describe("Controls nucleus sampling"),
39
+ n: z.number().optional().describe("Number of completions to generate"),
40
+ stream: z.boolean().optional().describe("Whether to stream the response"),
41
+ max_tokens: z.number().optional().describe("Maximum tokens to generate"),
42
+ presence_penalty: z.number().optional().describe("Presence penalty (-2 to 2)"),
43
+ frequency_penalty: z.number().optional().describe("Frequency penalty (-2 to 2)"),
44
+ logit_bias: z.record(z.string(), z.number()).optional().describe("Token logit bias"),
45
+ user: z.string().optional().describe("User identifier"),
46
+ conversationId: z.string().optional().describe("Conversation ID for multi-turn chat"),
47
+ tools: z.array(z.string()).optional().describe("Available tools"),
48
+ runConfig: z.record(z.string(), z.unknown()).optional().describe("Run configuration"),
49
+ headers: z.record(z.string(), z.unknown()).optional().describe("Headers data for template processing (validated against context config schema)")
50
+ }) } } } },
51
+ responses: {
52
+ 200: {
53
+ description: "Streaming chat completion response in Server-Sent Events format",
54
+ headers: z.object({
55
+ "Content-Type": z.string().default("text/event-stream"),
56
+ "Cache-Control": z.string().default("no-cache"),
57
+ Connection: z.string().default("keep-alive")
58
+ }),
59
+ content: { "text/event-stream": { schema: z.string().describe("Server-Sent Events stream with chat completion chunks") } }
60
+ },
61
+ 400: {
62
+ description: "Invalid request context or parameters",
63
+ content: { "application/json": { schema: z.object({
64
+ error: z.string(),
65
+ details: z.array(z.object({
66
+ field: z.string(),
67
+ message: z.string(),
68
+ value: z.unknown().optional()
69
+ })).optional()
70
+ }) } }
71
+ },
72
+ 404: {
73
+ description: "Agent or agent not found",
74
+ content: { "application/json": { schema: z.object({ error: z.string() }) } }
75
+ },
76
+ 500: {
77
+ description: "Internal server error",
78
+ content: { "application/json": { schema: z.object({
79
+ error: z.string(),
80
+ message: z.string()
81
+ }) } }
82
+ }
83
+ }
84
+ });
85
+ app.use("/completions", contextValidationMiddleware(dbClient_default));
86
+ app.openapi(chatCompletionsRoute, async (c) => {
87
+ getLogger("chat").info({
88
+ path: c.req.path,
89
+ method: c.req.method,
90
+ params: c.req.param()
91
+ }, "Chat route accessed");
92
+ const otelHeaders = {
93
+ traceparent: c.req.header("traceparent"),
94
+ tracestate: c.req.header("tracestate"),
95
+ baggage: c.req.header("baggage")
96
+ };
97
+ logger.info({
98
+ otelHeaders,
99
+ path: c.req.path,
100
+ method: c.req.method
101
+ }, "OpenTelemetry headers: chat");
102
+ try {
103
+ const executionContext = getRequestExecutionContext(c);
104
+ const { tenantId, projectId, agentId } = executionContext;
105
+ getLogger("chat").debug({
106
+ tenantId,
107
+ agentId
108
+ }, "Extracted chat parameters from API key context");
109
+ const body = c.get("requestBody") || {};
110
+ const conversationId = body.conversationId || getConversationId();
111
+ const activeSpan = trace.getActiveSpan();
112
+ if (activeSpan) activeSpan.setAttributes({
113
+ "conversation.id": conversationId,
114
+ "tenant.id": tenantId,
115
+ "agent.id": agentId,
116
+ "project.id": projectId
117
+ });
118
+ let currentBag = propagation.getBaggage(context.active());
119
+ if (!currentBag) currentBag = propagation.createBaggage();
120
+ currentBag = currentBag.setEntry("conversation.id", { value: conversationId });
121
+ const ctxWithBaggage = propagation.setBaggage(context.active(), currentBag);
122
+ return await context.with(ctxWithBaggage, async () => {
123
+ const fullAgent = await getFullAgent(dbClient_default)({ scopes: {
124
+ tenantId,
125
+ projectId,
126
+ agentId
127
+ } });
128
+ let agent;
129
+ let defaultSubAgentId;
130
+ if (fullAgent) {
131
+ agent = {
132
+ id: fullAgent.id,
133
+ name: fullAgent.name,
134
+ tenantId,
135
+ projectId,
136
+ defaultSubAgentId: fullAgent.defaultSubAgentId
137
+ };
138
+ const agentKeys = Object.keys(fullAgent.subAgents || {});
139
+ const firstAgentId = agentKeys.length > 0 ? agentKeys[0] : "";
140
+ defaultSubAgentId = fullAgent.defaultSubAgentId || firstAgentId;
141
+ } else {
142
+ agent = await getAgentWithDefaultSubAgent(dbClient_default)({ scopes: {
143
+ tenantId,
144
+ projectId,
145
+ agentId
146
+ } });
147
+ if (!agent) throw createApiError({
148
+ code: "not_found",
149
+ message: "Agent not found"
150
+ });
151
+ defaultSubAgentId = agent.defaultSubAgentId || "";
152
+ }
153
+ if (!defaultSubAgentId) throw createApiError({
154
+ code: "not_found",
155
+ message: "No default agent found in agent"
156
+ });
157
+ await createOrGetConversation(dbClient_default)({
158
+ tenantId,
159
+ projectId,
160
+ id: conversationId,
161
+ activeSubAgentId: defaultSubAgentId
162
+ });
163
+ const activeAgent = await getActiveAgentForConversation(dbClient_default)({
164
+ scopes: {
165
+ tenantId,
166
+ projectId
167
+ },
168
+ conversationId
169
+ });
170
+ if (!activeAgent) setActiveAgentForConversation(dbClient_default)({
171
+ scopes: {
172
+ tenantId,
173
+ projectId
174
+ },
175
+ conversationId,
176
+ subAgentId: defaultSubAgentId
177
+ });
178
+ const subAgentId = activeAgent?.activeSubAgentId || defaultSubAgentId;
179
+ if (!await getSubAgentById(dbClient_default)({
180
+ scopes: {
181
+ tenantId,
182
+ projectId,
183
+ agentId
184
+ },
185
+ subAgentId
186
+ })) throw createApiError({
187
+ code: "not_found",
188
+ message: "Agent not found"
189
+ });
190
+ const validatedContext = c.get("validatedContext") || body.headers || {};
191
+ await handleContextResolution({
192
+ tenantId,
193
+ projectId,
194
+ agentId,
195
+ conversationId,
196
+ headers: validatedContext,
197
+ dbClient: dbClient_default,
198
+ credentialStores: c.get("credentialStores")
199
+ });
200
+ logger.info({
201
+ tenantId,
202
+ projectId,
203
+ agentId,
204
+ conversationId,
205
+ defaultSubAgentId,
206
+ activeSubAgentId: activeAgent?.activeSubAgentId || "none",
207
+ hasContextConfig: !!agent.contextConfigId,
208
+ hasHeaders: !!body.headers,
209
+ hasValidatedContext: !!validatedContext,
210
+ validatedContextKeys: Object.keys(validatedContext)
211
+ }, "parameters");
212
+ const requestId = `chatcmpl-${Date.now()}`;
213
+ const timestamp = Math.floor(Date.now() / 1e3);
214
+ const lastUserMessage = body.messages.filter((msg) => msg.role === "user").slice(-1)[0];
215
+ const userMessage = lastUserMessage ? getMessageText(lastUserMessage.content) : "";
216
+ const messageSpan = trace.getActiveSpan();
217
+ if (messageSpan) {
218
+ messageSpan.setAttributes({
219
+ "message.content": userMessage,
220
+ "message.timestamp": Date.now()
221
+ });
222
+ if (executionContext.metadata?.initiatedBy) {
223
+ messageSpan.setAttribute("user.type", executionContext.metadata.initiatedBy.type);
224
+ messageSpan.setAttribute("user.id", executionContext.metadata.initiatedBy.id);
225
+ }
226
+ }
227
+ await createMessage(dbClient_default)({
228
+ id: generateId(),
229
+ tenantId,
230
+ projectId,
231
+ conversationId,
232
+ role: "user",
233
+ content: { text: userMessage },
234
+ visibility: "user-facing",
235
+ messageType: "chat"
236
+ });
237
+ if (messageSpan) messageSpan.addEvent("user.message.stored", {
238
+ "message.id": conversationId,
239
+ "database.operation": "insert"
240
+ });
241
+ return streamSSE(c, async (stream$1) => {
242
+ try {
243
+ const sseHelper = createSSEStreamHelper(stream$1, requestId, timestamp);
244
+ await sseHelper.writeRole();
245
+ logger.info({ subAgentId }, "Starting execution");
246
+ const emitOperations = c.req.header("x-emit-operations") === "true";
247
+ const result = await new ExecutionHandler().execute({
248
+ executionContext,
249
+ conversationId,
250
+ userMessage,
251
+ initialAgentId: subAgentId,
252
+ requestId,
253
+ sseHelper,
254
+ emitOperations
255
+ });
256
+ logger.info({ result }, `Execution completed: ${result.success ? "success" : "failed"} after ${result.iterations} iterations`);
257
+ if (!result.success) await sseHelper.writeOperation(errorOp("Sorry, I was unable to process your request at this time. Please try again.", "system"));
258
+ await sseHelper.complete();
259
+ } catch (error) {
260
+ logger.error({
261
+ error: error instanceof Error ? error.message : error,
262
+ stack: error instanceof Error ? error.stack : void 0
263
+ }, "Error during streaming execution");
264
+ try {
265
+ const sseHelper = createSSEStreamHelper(stream$1, requestId, timestamp);
266
+ await sseHelper.writeOperation(errorOp("Sorry, I was unable to process your request at this time. Please try again.", "system"));
267
+ await sseHelper.complete();
268
+ } catch (streamError) {
269
+ logger.error({ streamError }, "Failed to write error to stream");
270
+ }
271
+ }
272
+ });
273
+ });
274
+ } catch (error) {
275
+ logger.error({
276
+ error: error instanceof Error ? error.message : error,
277
+ stack: error instanceof Error ? error.stack : void 0
278
+ }, "Error in chat completions endpoint before streaming");
279
+ if (error && typeof error === "object" && "status" in error) throw error;
280
+ throw createApiError({
281
+ code: "internal_server_error",
282
+ message: error instanceof Error ? error.message : "Failed to process chat completion"
283
+ });
284
+ }
285
+ });
286
+ const getMessageText = (content) => {
287
+ if (typeof content === "string") return content;
288
+ return content.filter((item) => item.type === "text" && item.text).map((item) => item.text).join(" ");
289
+ };
290
+ var chat_default = app;
291
+
292
+ //#endregion
293
+ export { chat_default as default };
@@ -0,0 +1,13 @@
1
+ import { OpenAPIHono } from "@hono/zod-openapi";
2
+ import { CredentialStoreRegistry } from "@inkeep/agents-core";
3
+
4
+ //#region src/routes/chatDataStream.d.ts
5
+ type AppVariables = {
6
+ credentialStores: CredentialStoreRegistry;
7
+ requestBody?: any;
8
+ };
9
+ declare const app: OpenAPIHono<{
10
+ Variables: AppVariables;
11
+ }, {}, "/">;
12
+ //#endregion
13
+ export { app as default };
@@ -0,0 +1,352 @@
1
+ import { getLogger } from "../logger.js";
2
+ import dbClient_default from "../data/db/dbClient.js";
3
+ import { pendingToolApprovalManager } from "../services/PendingToolApprovalManager.js";
4
+ import { errorOp } from "../utils/agent-operations.js";
5
+ import { createBufferingStreamHelper, createVercelStreamHelper } from "../utils/stream-helpers.js";
6
+ import { ExecutionHandler } from "../handlers/executionHandler.js";
7
+ import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
8
+ import { commonGetErrorResponses, contextValidationMiddleware, createApiError, createMessage, generateId, getActiveAgentForConversation, getAgentWithDefaultSubAgent, getConversation, getConversationId, getRequestExecutionContext, getSubAgentById, handleContextResolution, loggerFactory, setActiveAgentForConversation } from "@inkeep/agents-core";
9
+ import { context, propagation, trace } from "@opentelemetry/api";
10
+ import { stream } from "hono/streaming";
11
+ import { JsonToSseTransformStream, createUIMessageStream } from "ai";
12
+
13
+ //#region src/routes/chatDataStream.ts
14
+ const app = new OpenAPIHono();
15
+ const logger = getLogger("chatDataStream");
16
+ const chatDataStreamRoute = createRoute({
17
+ method: "post",
18
+ path: "/chat",
19
+ tags: ["chat"],
20
+ summary: "Chat (Vercel Streaming Protocol)",
21
+ description: "Chat completion endpoint streaming with Vercel data stream protocol.",
22
+ security: [{ bearerAuth: [] }],
23
+ request: { body: { content: { "application/json": { schema: z.object({
24
+ model: z.string().optional(),
25
+ messages: z.array(z.object({
26
+ role: z.enum([
27
+ "system",
28
+ "user",
29
+ "assistant",
30
+ "function",
31
+ "tool"
32
+ ]),
33
+ content: z.any(),
34
+ parts: z.array(z.object({
35
+ type: z.union([z.enum([
36
+ "text",
37
+ "image",
38
+ "audio",
39
+ "video",
40
+ "file"
41
+ ]), z.string().regex(/^data-/, "Type must start with \"data-\"")]),
42
+ text: z.string().optional()
43
+ })).optional()
44
+ })),
45
+ id: z.string().optional(),
46
+ conversationId: z.string().optional(),
47
+ stream: z.boolean().optional().describe("Whether to stream the response").default(true),
48
+ max_tokens: z.number().optional().describe("Maximum tokens to generate"),
49
+ headers: z.record(z.string(), z.unknown()).optional().describe("Headers data for template processing"),
50
+ runConfig: z.record(z.string(), z.unknown()).optional().describe("Run configuration")
51
+ }) } } } },
52
+ responses: {
53
+ 200: {
54
+ description: "Streamed chat completion",
55
+ headers: z.object({
56
+ "Content-Type": z.string().default("text/plain; charset=utf-8"),
57
+ "x-vercel-ai-data-stream": z.string().default("v1")
58
+ })
59
+ },
60
+ ...commonGetErrorResponses
61
+ }
62
+ });
63
+ app.use("/chat", contextValidationMiddleware(dbClient_default));
64
+ app.openapi(chatDataStreamRoute, async (c) => {
65
+ try {
66
+ const executionContext = getRequestExecutionContext(c);
67
+ const { tenantId, projectId, agentId } = executionContext;
68
+ loggerFactory.getLogger("chatDataStream").debug({
69
+ tenantId,
70
+ projectId,
71
+ agentId
72
+ }, "Extracted chatDataStream parameters");
73
+ const body = c.get("requestBody") || {};
74
+ const conversationId = body.conversationId || getConversationId();
75
+ const activeSpan = trace.getActiveSpan();
76
+ if (activeSpan) activeSpan.setAttributes({
77
+ "conversation.id": conversationId,
78
+ "tenant.id": tenantId,
79
+ "agent.id": agentId,
80
+ "project.id": projectId
81
+ });
82
+ let currentBag = propagation.getBaggage(context.active());
83
+ if (!currentBag) currentBag = propagation.createBaggage();
84
+ currentBag = currentBag.setEntry("conversation.id", { value: conversationId });
85
+ const ctxWithBaggage = propagation.setBaggage(context.active(), currentBag);
86
+ return await context.with(ctxWithBaggage, async () => {
87
+ const agent = await getAgentWithDefaultSubAgent(dbClient_default)({ scopes: {
88
+ tenantId,
89
+ projectId,
90
+ agentId
91
+ } });
92
+ if (!agent) throw createApiError({
93
+ code: "not_found",
94
+ message: "Agent not found"
95
+ });
96
+ const defaultSubAgentId = agent.defaultSubAgentId;
97
+ const agentName = agent.name;
98
+ if (!defaultSubAgentId) throw createApiError({
99
+ code: "bad_request",
100
+ message: "Agent does not have a default agent configured"
101
+ });
102
+ const activeAgent = await getActiveAgentForConversation(dbClient_default)({
103
+ scopes: {
104
+ tenantId,
105
+ projectId
106
+ },
107
+ conversationId
108
+ });
109
+ if (!activeAgent) setActiveAgentForConversation(dbClient_default)({
110
+ scopes: {
111
+ tenantId,
112
+ projectId
113
+ },
114
+ conversationId,
115
+ subAgentId: defaultSubAgentId
116
+ });
117
+ const subAgentId = activeAgent?.activeSubAgentId || defaultSubAgentId;
118
+ if (!await getSubAgentById(dbClient_default)({
119
+ scopes: {
120
+ tenantId,
121
+ projectId,
122
+ agentId
123
+ },
124
+ subAgentId
125
+ })) throw createApiError({
126
+ code: "not_found",
127
+ message: "Agent not found"
128
+ });
129
+ await handleContextResolution({
130
+ tenantId,
131
+ projectId,
132
+ agentId,
133
+ conversationId,
134
+ headers: c.get("validatedContext") || body.headers || {},
135
+ dbClient: dbClient_default,
136
+ credentialStores: c.get("credentialStores")
137
+ });
138
+ const lastUserMessage = body.messages.filter((m) => m.role === "user").slice(-1)[0];
139
+ const userText = typeof lastUserMessage?.content === "string" ? lastUserMessage.content : lastUserMessage?.parts?.map((p) => p.text).join("") || "";
140
+ logger.info({
141
+ userText,
142
+ lastUserMessage
143
+ }, "userText");
144
+ const messageSpan = trace.getActiveSpan();
145
+ if (messageSpan) {
146
+ messageSpan.setAttributes({
147
+ "message.timestamp": (/* @__PURE__ */ new Date()).toISOString(),
148
+ "message.content": userText,
149
+ "agent.name": agentName
150
+ });
151
+ if (executionContext.metadata?.initiatedBy) {
152
+ messageSpan.setAttribute("user.type", executionContext.metadata.initiatedBy.type);
153
+ messageSpan.setAttribute("user.id", executionContext.metadata.initiatedBy.id);
154
+ }
155
+ }
156
+ await createMessage(dbClient_default)({
157
+ id: generateId(),
158
+ tenantId,
159
+ projectId,
160
+ conversationId,
161
+ role: "user",
162
+ content: { text: userText },
163
+ visibility: "user-facing",
164
+ messageType: "chat"
165
+ });
166
+ if (messageSpan) messageSpan.addEvent("user.message.stored", {
167
+ "message.id": conversationId,
168
+ "database.operation": "insert"
169
+ });
170
+ if (!(body.stream !== false)) {
171
+ const emitOperations = c.req.header("x-emit-operations") === "true";
172
+ const bufferingHelper = createBufferingStreamHelper();
173
+ const result = await new ExecutionHandler().execute({
174
+ executionContext,
175
+ conversationId,
176
+ userMessage: userText,
177
+ initialAgentId: subAgentId,
178
+ requestId: `chat-${Date.now()}`,
179
+ sseHelper: bufferingHelper,
180
+ emitOperations
181
+ });
182
+ const captured = bufferingHelper.getCapturedResponse();
183
+ return c.json({
184
+ id: `chat-${Date.now()}`,
185
+ object: "chat.completion",
186
+ created: Math.floor(Date.now() / 1e3),
187
+ model: agentName,
188
+ choices: [{
189
+ index: 0,
190
+ message: {
191
+ role: "assistant",
192
+ content: captured.hasError ? captured.errorMessage : captured.text
193
+ },
194
+ finish_reason: result.success && !captured.hasError ? "stop" : "error"
195
+ }],
196
+ usage: {
197
+ prompt_tokens: 0,
198
+ completion_tokens: 0,
199
+ total_tokens: 0
200
+ }
201
+ });
202
+ }
203
+ const dataStream = createUIMessageStream({ execute: async ({ writer }) => {
204
+ const streamHelper = createVercelStreamHelper(writer);
205
+ try {
206
+ const emitOperations = c.req.header("x-emit-operations") === "true";
207
+ if (!(await new ExecutionHandler().execute({
208
+ executionContext,
209
+ conversationId,
210
+ userMessage: userText,
211
+ initialAgentId: subAgentId,
212
+ requestId: `chatds-${Date.now()}`,
213
+ sseHelper: streamHelper,
214
+ emitOperations
215
+ })).success) await streamHelper.writeOperation(errorOp("Unable to process request", "system"));
216
+ } catch (err) {
217
+ logger.error({ err }, "Streaming error");
218
+ await streamHelper.writeOperation(errorOp("Internal server error", "system"));
219
+ } finally {
220
+ if ("cleanup" in streamHelper && typeof streamHelper.cleanup === "function") streamHelper.cleanup();
221
+ }
222
+ } });
223
+ c.header("content-type", "text/event-stream");
224
+ c.header("cache-control", "no-cache");
225
+ c.header("connection", "keep-alive");
226
+ c.header("x-vercel-ai-data-stream", "v2");
227
+ c.header("x-accel-buffering", "no");
228
+ return stream(c, (stream$1) => stream$1.pipe(dataStream.pipeThrough(new JsonToSseTransformStream()).pipeThrough(new TextEncoderStream())));
229
+ });
230
+ } catch (error) {
231
+ logger.error({
232
+ error,
233
+ errorMessage: error instanceof Error ? error.message : String(error),
234
+ errorStack: error instanceof Error ? error.stack : void 0,
235
+ errorType: error?.constructor?.name
236
+ }, "chatDataStream error - DETAILED");
237
+ throw createApiError({
238
+ code: "internal_server_error",
239
+ message: "Failed to process chat completion"
240
+ });
241
+ }
242
+ });
243
+ const toolApprovalRoute = createRoute({
244
+ method: "post",
245
+ path: "/tool-approvals",
246
+ tags: ["chat"],
247
+ summary: "Approve or deny tool execution",
248
+ description: "Handle user approval/denial of tool execution requests during conversations",
249
+ security: [{ bearerAuth: [] }],
250
+ request: { body: { content: { "application/json": { schema: z.object({
251
+ conversationId: z.string().describe("The conversation ID"),
252
+ toolCallId: z.string().describe("The tool call ID to respond to"),
253
+ approved: z.boolean().describe("Whether the tool execution is approved"),
254
+ reason: z.string().optional().describe("Optional reason for the decision")
255
+ }) } } } },
256
+ responses: {
257
+ 200: {
258
+ description: "Tool approval response processed successfully",
259
+ content: { "application/json": { schema: z.object({
260
+ success: z.boolean(),
261
+ message: z.string().optional()
262
+ }) } }
263
+ },
264
+ 400: {
265
+ description: "Bad request - invalid tool call ID or conversation ID",
266
+ content: { "application/json": { schema: z.object({ error: z.string() }) } }
267
+ },
268
+ 404: {
269
+ description: "Tool call not found or already processed",
270
+ content: { "application/json": { schema: z.object({ error: z.string() }) } }
271
+ },
272
+ 500: {
273
+ description: "Internal server error",
274
+ content: { "application/json": { schema: z.object({
275
+ error: z.string(),
276
+ message: z.string()
277
+ }) } }
278
+ }
279
+ }
280
+ });
281
+ app.openapi(toolApprovalRoute, async (c) => {
282
+ return trace.getTracer("tool-approval-handler").startActiveSpan("tool_approval_request", async (span) => {
283
+ try {
284
+ const { tenantId, projectId } = getRequestExecutionContext(c);
285
+ const { conversationId, toolCallId, approved, reason } = await c.req.json();
286
+ logger.info({
287
+ conversationId,
288
+ toolCallId,
289
+ approved,
290
+ reason,
291
+ tenantId,
292
+ projectId
293
+ }, "Processing tool approval request");
294
+ if (!await getConversation(dbClient_default)({
295
+ scopes: {
296
+ tenantId,
297
+ projectId
298
+ },
299
+ conversationId
300
+ })) {
301
+ span.setStatus({
302
+ code: 1,
303
+ message: "Conversation not found"
304
+ });
305
+ return c.json({ error: "Conversation not found" }, 404);
306
+ }
307
+ let success = false;
308
+ if (approved) success = pendingToolApprovalManager.approveToolCall(toolCallId);
309
+ else success = pendingToolApprovalManager.denyToolCall(toolCallId, reason);
310
+ if (!success) {
311
+ span.setStatus({
312
+ code: 1,
313
+ message: "Tool call not found"
314
+ });
315
+ return c.json({ error: "Tool call not found or already processed" }, 404);
316
+ }
317
+ logger.info({
318
+ conversationId,
319
+ toolCallId,
320
+ approved
321
+ }, "Tool approval processed successfully");
322
+ span.setStatus({
323
+ code: 1,
324
+ message: "Success"
325
+ });
326
+ return c.json({
327
+ success: true,
328
+ message: approved ? "Tool execution approved" : "Tool execution denied"
329
+ });
330
+ } catch (error) {
331
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
332
+ logger.error({
333
+ error: errorMessage,
334
+ stack: error instanceof Error ? error.stack : void 0
335
+ }, "Failed to process tool approval");
336
+ span.setStatus({
337
+ code: 2,
338
+ message: errorMessage
339
+ });
340
+ return c.json({
341
+ error: "Internal server error",
342
+ message: errorMessage
343
+ }, 500);
344
+ } finally {
345
+ span.end();
346
+ }
347
+ });
348
+ });
349
+ var chatDataStream_default = app;
350
+
351
+ //#endregion
352
+ export { chatDataStream_default as default };
@@ -0,0 +1,13 @@
1
+ import { OpenAPIHono } from "@hono/zod-openapi";
2
+ import { CredentialStoreRegistry } from "@inkeep/agents-core";
3
+
4
+ //#region src/routes/mcp.d.ts
5
+ type AppVariables = {
6
+ credentialStores: CredentialStoreRegistry;
7
+ requestBody?: any;
8
+ };
9
+ declare const app: OpenAPIHono<{
10
+ Variables: AppVariables;
11
+ }, {}, "/">;
12
+ //#endregion
13
+ export { app as default };