@inkeep/agents-api 0.42.0 → 0.44.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.
- package/dist/.well-known/workflow/v1/manifest.debug.json +6 -6
- package/dist/.well-known/workflow/v1/step.cjs +220467 -203416
- package/dist/_virtual/rolldown_runtime.js +7 -0
- package/dist/createApp.js +47 -17
- package/dist/domains/evals/api/.well-known/workflow/v1/flow.d.ts +4 -0
- package/dist/domains/evals/api/.well-known/workflow/v1/flow.js +12 -0
- package/dist/domains/evals/api/.well-known/workflow/v1/step.d.ts +4 -0
- package/dist/domains/evals/api/.well-known/workflow/v1/step.js +12 -0
- package/dist/domains/evals/routes/datasetTriggers.d.ts +2 -2
- package/dist/domains/evals/routes/index.d.ts +2 -2
- package/dist/domains/evals/scripts/build-workflow.js +2 -2
- package/dist/domains/evals/workflow/world.js +3 -2
- package/dist/domains/manage/index.js +6 -2
- package/dist/domains/manage/routes/agent.js +7 -4
- package/dist/domains/manage/routes/agentFull.js +9 -6
- package/dist/domains/manage/routes/apiKeys.js +1 -2
- package/dist/domains/manage/routes/artifactComponents.js +5 -5
- package/dist/domains/manage/routes/cliAuth.js +3 -3
- package/dist/domains/manage/routes/contextConfigs.js +5 -5
- package/dist/domains/manage/routes/conversations.d.ts +2 -2
- package/dist/domains/manage/routes/credentialStores.js +2 -2
- package/dist/domains/manage/routes/credentials.js +6 -7
- package/dist/domains/manage/routes/dataComponents.js +6 -7
- package/dist/domains/manage/routes/externalAgents.js +1 -2
- package/dist/domains/manage/routes/github.d.ts +16 -0
- package/dist/domains/manage/routes/github.js +511 -0
- package/dist/domains/manage/routes/index.d.ts +2 -2
- package/dist/domains/manage/routes/index.js +4 -0
- package/dist/domains/manage/routes/invitations.js +1 -1
- package/dist/domains/manage/routes/mcp.d.ts +2 -2
- package/dist/domains/manage/routes/{agentToolRelations.d.ts → mcpToolGithubAccess.d.ts} +1 -1
- package/dist/domains/manage/routes/mcpToolGithubAccess.js +205 -0
- package/dist/domains/manage/routes/playgroundToken.js +1 -2
- package/dist/domains/manage/routes/projectFull.js +33 -11
- package/dist/domains/manage/routes/projectGithubAccess.d.ts +9 -0
- package/dist/domains/manage/routes/projectGithubAccess.js +167 -0
- package/dist/domains/manage/routes/projectMembers.js +12 -44
- package/dist/domains/manage/routes/projectPermissions.js +11 -11
- package/dist/domains/manage/routes/projects.js +15 -18
- package/dist/domains/manage/routes/signoz.d.ts +2 -2
- package/dist/domains/manage/routes/signoz.js +7 -4
- package/dist/domains/manage/routes/subAgentArtifactComponents.js +5 -5
- package/dist/domains/manage/routes/subAgentDataComponents.js +5 -5
- package/dist/domains/manage/routes/subAgentExternalAgentRelations.js +5 -5
- package/dist/domains/manage/routes/subAgentFunctionTools.js +5 -5
- package/dist/domains/manage/routes/subAgentRelations.js +6 -6
- package/dist/domains/manage/routes/subAgentTeamAgentRelations.js +6 -6
- package/dist/domains/manage/routes/subAgentToolRelations.js +6 -6
- package/dist/domains/manage/routes/subAgents.js +5 -5
- package/dist/domains/manage/routes/tools.js +28 -5
- package/dist/domains/manage/routes/triggers.js +49 -24
- package/dist/domains/manage/routes/userOrganizations.js +4 -4
- package/dist/domains/manage/routes/userProjectMemberships.d.ts +9 -0
- package/dist/domains/manage/routes/userProjectMemberships.js +44 -0
- package/dist/domains/mcp/routes/mcp.d.ts +7 -0
- package/dist/domains/mcp/routes/mcp.js +45 -0
- package/dist/domains/run/agents/Agent.d.ts +1 -0
- package/dist/domains/run/agents/Agent.js +235 -45
- package/dist/domains/run/agents/relationTools.d.ts +2 -2
- package/dist/domains/run/constants/execution-limits/defaults.d.ts +1 -1
- package/dist/domains/run/constants/execution-limits/defaults.js +1 -1
- package/dist/domains/run/constants/execution-limits/index.d.ts +1 -1
- package/dist/domains/run/context/ContextFetcher.js +8 -7
- package/dist/domains/run/context/validation.d.ts +1 -1
- package/dist/domains/run/handlers/executionHandler.js +143 -79
- package/dist/domains/run/routes/agents.js +1 -1
- package/dist/domains/run/routes/chat.js +47 -1
- package/dist/domains/run/routes/chatDataStream.js +107 -14
- package/dist/domains/run/routes/webhooks.js +40 -348
- package/dist/domains/run/services/AgentSession.d.ts +3 -0
- package/dist/domains/run/services/AgentSession.js +14 -1
- package/dist/domains/run/services/ToolApprovalUiBus.d.ts +28 -0
- package/dist/domains/run/services/ToolApprovalUiBus.js +44 -0
- package/dist/domains/run/services/TriggerService.d.ts +31 -0
- package/dist/domains/run/services/TriggerService.js +545 -0
- package/dist/domains/run/tools/NativeSandboxExecutor.d.ts +3 -2
- package/dist/domains/run/tools/NativeSandboxExecutor.js +76 -48
- package/dist/domains/run/tools/SandboxExecutorFactory.d.ts +11 -1
- package/dist/domains/run/tools/SandboxExecutorFactory.js +27 -3
- package/dist/domains/run/tools/VercelSandboxExecutor.d.ts +3 -11
- package/dist/domains/run/tools/VercelSandboxExecutor.js +137 -127
- package/dist/domains/run/tools/sandbox-utils.js +1 -1
- package/dist/domains/run/types/executionContext.js +3 -1
- package/dist/domains/run/utils/stream-helpers.d.ts +134 -0
- package/dist/domains/run/utils/stream-helpers.js +182 -0
- package/dist/domains/run/utils/token-estimator.d.ts +2 -2
- package/dist/env.d.ts +12 -2
- package/dist/env.js +37 -32
- package/dist/factory.d.ts +31 -31
- package/dist/factory.js +4 -10
- package/dist/index.d.ts +30 -29
- package/dist/index.js +3 -5
- package/dist/middleware/branchScopedDb.d.ts +1 -1
- package/dist/middleware/cors.js +1 -1
- package/dist/middleware/evalsAuth.d.ts +2 -2
- package/dist/middleware/manageAuth.d.ts +2 -2
- package/dist/middleware/projectAccess.d.ts +4 -20
- package/dist/middleware/projectAccess.js +7 -49
- package/dist/middleware/projectConfig.d.ts +3 -3
- package/dist/middleware/ref.d.ts +1 -1
- package/dist/middleware/requirePermission.d.ts +2 -2
- package/dist/middleware/requirePermission.js +1 -2
- package/dist/middleware/runAuth.d.ts +4 -4
- package/dist/middleware/sessionAuth.d.ts +3 -3
- package/dist/middleware/sessionAuth.js +1 -2
- package/dist/middleware/tenantAccess.d.ts +2 -2
- package/dist/middleware/tenantAccess.js +4 -4
- package/dist/middleware/tracing.d.ts +3 -3
- package/dist/openapi.d.ts +36 -1
- package/dist/openapi.js +40 -95
- package/dist/routes/healthChecks.d.ts +10 -0
- package/dist/routes/healthChecks.js +75 -0
- package/dist/types/app.d.ts +2 -0
- package/dist/types/runExecutionContext.js +3 -1
- package/dist/utils/healthChecks.d.ts +8 -0
- package/dist/utils/healthChecks.js +38 -0
- package/dist/utils/signozHelpers.d.ts +2 -2
- package/dist/utils/signozHelpers.js +15 -3
- package/package.json +8 -9
- package/dist/domains/evals/services/startEvaluation.d.ts +0 -19
- package/dist/domains/evals/services/startEvaluation.js +0 -18
- package/dist/domains/index.d.ts +0 -4
- package/dist/domains/index.js +0 -5
- package/dist/domains/manage/routes/agentToolRelations.js +0 -289
- package/dist/domains/run/agents/ModelFactory.d.ts +0 -63
- package/dist/domains/run/agents/ModelFactory.js +0 -194
- package/dist/domains/run/data/agent.d.ts +0 -7
- package/dist/domains/run/data/agent.js +0 -67
- package/dist/domains/run/services/evaluationRunConfigMatcher.d.ts +0 -4
- package/dist/domains/run/services/evaluationRunConfigMatcher.js +0 -7
- package/dist/domains/run/utils/cleanup.d.ts +0 -21
- package/dist/domains/run/utils/cleanup.js +0 -59
- package/dist/initialization.d.ts +0 -6
- package/dist/initialization.js +0 -65
- package/dist/utils/tempApiKeys.d.ts +0 -17
- package/dist/utils/tempApiKeys.js +0 -26
- package/dist/utils/workflowApiHelpers.d.ts +0 -1
- package/dist/utils/workflowApiHelpers.js +0 -1
|
@@ -207,30 +207,45 @@ var ExecutionHandler = class {
|
|
|
207
207
|
fullResponse: messageResponse
|
|
208
208
|
}, `No response from agent ${currentAgentId} on iteration ${iterations} (error ${errorCount}/${this.MAX_ERRORS})`);
|
|
209
209
|
if (errorCount >= this.MAX_ERRORS) {
|
|
210
|
-
const errorMessage
|
|
210
|
+
const errorMessage = `Maximum error limit (${this.MAX_ERRORS}) reached`;
|
|
211
211
|
logger.error({
|
|
212
212
|
maxErrors: this.MAX_ERRORS,
|
|
213
213
|
errorCount
|
|
214
|
-
}, errorMessage
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
214
|
+
}, errorMessage);
|
|
215
|
+
return tracer.startActiveSpan("execution_handler.execute", {}, async (span) => {
|
|
216
|
+
try {
|
|
217
|
+
span.setAttributes({
|
|
218
|
+
"ai.response.content": `Hmm.. It seems I might be having some issues right now. Please clear the chat and try again.`,
|
|
219
|
+
"ai.response.timestamp": (/* @__PURE__ */ new Date()).toISOString(),
|
|
220
|
+
"subAgent.name": agent?.subAgents[currentAgentId]?.name,
|
|
221
|
+
"subAgent.id": currentAgentId
|
|
222
|
+
});
|
|
223
|
+
setSpanWithError(span, new Error(errorMessage));
|
|
224
|
+
await sseHelper.writeOperation(errorOp(errorMessage, currentAgentId || "system"));
|
|
225
|
+
if (task) await updateTask(runDbClient_default)({
|
|
226
|
+
taskId: task.id,
|
|
227
|
+
data: {
|
|
228
|
+
status: "failed",
|
|
229
|
+
metadata: {
|
|
230
|
+
...task.metadata,
|
|
231
|
+
failed_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
232
|
+
error: errorMessage
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
await agentSessionManager.endSession(requestId);
|
|
237
|
+
unregisterStreamHelper(requestId);
|
|
238
|
+
return {
|
|
239
|
+
success: false,
|
|
240
|
+
error: errorMessage,
|
|
241
|
+
iterations
|
|
242
|
+
};
|
|
243
|
+
} finally {
|
|
244
|
+
span.end();
|
|
245
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
246
|
+
await flushBatchProcessor();
|
|
225
247
|
}
|
|
226
248
|
});
|
|
227
|
-
await agentSessionManager.endSession(requestId);
|
|
228
|
-
unregisterStreamHelper(requestId);
|
|
229
|
-
return {
|
|
230
|
-
success: false,
|
|
231
|
-
error: errorMessage$1,
|
|
232
|
-
iterations
|
|
233
|
-
};
|
|
234
249
|
}
|
|
235
250
|
continue;
|
|
236
251
|
}
|
|
@@ -392,12 +407,75 @@ var ExecutionHandler = class {
|
|
|
392
407
|
errorCount
|
|
393
408
|
}, `No valid response or transfer on iteration ${iterations} (error ${errorCount}/${this.MAX_ERRORS})`);
|
|
394
409
|
if (errorCount >= this.MAX_ERRORS) {
|
|
395
|
-
const errorMessage
|
|
410
|
+
const errorMessage = `Maximum error limit (${this.MAX_ERRORS}) reached`;
|
|
396
411
|
logger.error({
|
|
397
412
|
maxErrors: this.MAX_ERRORS,
|
|
398
413
|
errorCount
|
|
399
|
-
}, errorMessage
|
|
400
|
-
|
|
414
|
+
}, errorMessage);
|
|
415
|
+
return tracer.startActiveSpan("execution_handler.execute", {}, async (span) => {
|
|
416
|
+
try {
|
|
417
|
+
span.setAttributes({
|
|
418
|
+
"ai.response.content": "Hmm.. It seems I might be having some issues right now. Please clear the chat and try again.",
|
|
419
|
+
"ai.response.timestamp": (/* @__PURE__ */ new Date()).toISOString(),
|
|
420
|
+
"subAgent.name": agent?.subAgents[currentAgentId]?.name,
|
|
421
|
+
"subAgent.id": currentAgentId
|
|
422
|
+
});
|
|
423
|
+
setSpanWithError(span, new Error(errorMessage));
|
|
424
|
+
await sseHelper.writeOperation(errorOp(errorMessage, currentAgentId || "system"));
|
|
425
|
+
if (task) await updateTask(runDbClient_default)({
|
|
426
|
+
taskId: task.id,
|
|
427
|
+
data: {
|
|
428
|
+
status: "failed",
|
|
429
|
+
metadata: {
|
|
430
|
+
...task.metadata,
|
|
431
|
+
failed_at: /* @__PURE__ */ new Date(),
|
|
432
|
+
error: errorMessage
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
await agentSessionManager.endSession(requestId);
|
|
437
|
+
unregisterStreamHelper(requestId);
|
|
438
|
+
if (!params.datasetRunId) triggerConversationEvaluation({
|
|
439
|
+
tenantId,
|
|
440
|
+
projectId,
|
|
441
|
+
conversationId,
|
|
442
|
+
resolvedRef
|
|
443
|
+
}).catch((evalError) => {
|
|
444
|
+
logger.error({
|
|
445
|
+
error: evalError,
|
|
446
|
+
conversationId,
|
|
447
|
+
tenantId,
|
|
448
|
+
projectId
|
|
449
|
+
}, "Failed to trigger conversation evaluation (non-blocking)");
|
|
450
|
+
});
|
|
451
|
+
return {
|
|
452
|
+
success: false,
|
|
453
|
+
error: errorMessage,
|
|
454
|
+
iterations
|
|
455
|
+
};
|
|
456
|
+
} finally {
|
|
457
|
+
span.end();
|
|
458
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
459
|
+
await flushBatchProcessor();
|
|
460
|
+
}
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
const maxTransfersErrorMessage = `Maximum transfer limit (${maxTransfers}) reached without completion`;
|
|
465
|
+
logger.error({
|
|
466
|
+
maxTransfers,
|
|
467
|
+
iterations
|
|
468
|
+
}, maxTransfersErrorMessage);
|
|
469
|
+
return tracer.startActiveSpan("execution_handler.execute", {}, async (span) => {
|
|
470
|
+
try {
|
|
471
|
+
span.setAttributes({
|
|
472
|
+
"ai.response.content": "Hmm.. It seems I might be having some issues right now. Please clear the chat and try again.",
|
|
473
|
+
"ai.response.timestamp": (/* @__PURE__ */ new Date()).toISOString(),
|
|
474
|
+
"subAgent.name": agent?.subAgents[currentAgentId]?.name,
|
|
475
|
+
"subAgent.id": currentAgentId
|
|
476
|
+
});
|
|
477
|
+
setSpanWithError(span, new Error(maxTransfersErrorMessage));
|
|
478
|
+
await sseHelper.writeOperation(errorOp(maxTransfersErrorMessage, currentAgentId || "system"));
|
|
401
479
|
if (task) await updateTask(runDbClient_default)({
|
|
402
480
|
taskId: task.id,
|
|
403
481
|
data: {
|
|
@@ -405,78 +483,64 @@ var ExecutionHandler = class {
|
|
|
405
483
|
metadata: {
|
|
406
484
|
...task.metadata,
|
|
407
485
|
failed_at: /* @__PURE__ */ new Date(),
|
|
408
|
-
error:
|
|
486
|
+
error: maxTransfersErrorMessage
|
|
409
487
|
}
|
|
410
488
|
}
|
|
411
489
|
});
|
|
412
490
|
await agentSessionManager.endSession(requestId);
|
|
413
491
|
unregisterStreamHelper(requestId);
|
|
414
|
-
if (!params.datasetRunId) triggerConversationEvaluation({
|
|
415
|
-
tenantId,
|
|
416
|
-
projectId,
|
|
417
|
-
conversationId,
|
|
418
|
-
resolvedRef
|
|
419
|
-
}).catch((error) => {
|
|
420
|
-
logger.error({
|
|
421
|
-
error,
|
|
422
|
-
conversationId,
|
|
423
|
-
tenantId,
|
|
424
|
-
projectId
|
|
425
|
-
}, "Failed to trigger conversation evaluation (non-blocking)");
|
|
426
|
-
});
|
|
427
492
|
return {
|
|
428
493
|
success: false,
|
|
429
|
-
error:
|
|
494
|
+
error: maxTransfersErrorMessage,
|
|
430
495
|
iterations
|
|
431
496
|
};
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
maxTransfers,
|
|
437
|
-
iterations
|
|
438
|
-
}, errorMessage);
|
|
439
|
-
await sseHelper.writeOperation(errorOp(errorMessage, currentAgentId || "system"));
|
|
440
|
-
if (task) await updateTask(runDbClient_default)({
|
|
441
|
-
taskId: task.id,
|
|
442
|
-
data: {
|
|
443
|
-
status: "failed",
|
|
444
|
-
metadata: {
|
|
445
|
-
...task.metadata,
|
|
446
|
-
failed_at: /* @__PURE__ */ new Date(),
|
|
447
|
-
error: errorMessage
|
|
448
|
-
}
|
|
497
|
+
} finally {
|
|
498
|
+
span.end();
|
|
499
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
500
|
+
await flushBatchProcessor();
|
|
449
501
|
}
|
|
450
502
|
});
|
|
451
|
-
await agentSessionManager.endSession(requestId);
|
|
452
|
-
unregisterStreamHelper(requestId);
|
|
453
|
-
return {
|
|
454
|
-
success: false,
|
|
455
|
-
error: errorMessage,
|
|
456
|
-
iterations
|
|
457
|
-
};
|
|
458
503
|
} catch (error) {
|
|
459
|
-
logger.error({ error }, "Error in execution handler");
|
|
460
504
|
const errorMessage = error instanceof Error ? error.message : "Unknown execution error";
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
505
|
+
const errorStack = error instanceof Error ? error.stack : void 0;
|
|
506
|
+
logger.error({
|
|
507
|
+
errorMessage,
|
|
508
|
+
errorStack
|
|
509
|
+
}, "Error in execution handler");
|
|
510
|
+
return tracer.startActiveSpan("execution_handler.execute", {}, async (span) => {
|
|
511
|
+
try {
|
|
512
|
+
span.setAttributes({
|
|
513
|
+
"ai.response.content": "Hmm.. It seems I might be having some issues right now. Please clear the chat and try again.",
|
|
514
|
+
"ai.response.timestamp": (/* @__PURE__ */ new Date()).toISOString(),
|
|
515
|
+
"subAgent.name": agent?.subAgents[currentAgentId]?.name,
|
|
516
|
+
"subAgent.id": currentAgentId
|
|
517
|
+
});
|
|
518
|
+
setSpanWithError(span, error instanceof Error ? error : new Error(errorMessage));
|
|
519
|
+
await sseHelper.writeOperation(errorOp(`Execution error: ${errorMessage}`, currentAgentId || "system"));
|
|
520
|
+
if (task) await updateTask(runDbClient_default)({
|
|
521
|
+
taskId: task.id,
|
|
522
|
+
data: {
|
|
523
|
+
status: "failed",
|
|
524
|
+
metadata: {
|
|
525
|
+
...task.metadata,
|
|
526
|
+
failed_at: /* @__PURE__ */ new Date(),
|
|
527
|
+
error: errorMessage
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
});
|
|
531
|
+
await agentSessionManager.endSession(requestId);
|
|
532
|
+
unregisterStreamHelper(requestId);
|
|
533
|
+
return {
|
|
534
|
+
success: false,
|
|
535
|
+
error: errorMessage,
|
|
536
|
+
iterations
|
|
537
|
+
};
|
|
538
|
+
} finally {
|
|
539
|
+
span.end();
|
|
540
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
541
|
+
await flushBatchProcessor();
|
|
471
542
|
}
|
|
472
543
|
});
|
|
473
|
-
await agentSessionManager.endSession(requestId);
|
|
474
|
-
unregisterStreamHelper(requestId);
|
|
475
|
-
return {
|
|
476
|
-
success: false,
|
|
477
|
-
error: errorMessage,
|
|
478
|
-
iterations
|
|
479
|
-
};
|
|
480
544
|
}
|
|
481
545
|
}
|
|
482
546
|
};
|
|
@@ -3,6 +3,7 @@ import runDbClient_default from "../../../data/db/runDbClient.js";
|
|
|
3
3
|
import { contextValidationMiddleware } from "../context/validation.js";
|
|
4
4
|
import { handleContextResolution } from "../context/context.js";
|
|
5
5
|
import "../context/index.js";
|
|
6
|
+
import { toolApprovalUiBus } from "../services/ToolApprovalUiBus.js";
|
|
6
7
|
import { errorOp } from "../utils/agent-operations.js";
|
|
7
8
|
import { createSSEStreamHelper } from "../utils/stream-helpers.js";
|
|
8
9
|
import { ExecutionHandler } from "../handlers/executionHandler.js";
|
|
@@ -17,7 +18,7 @@ const logger = getLogger$1("completionsHandler");
|
|
|
17
18
|
const chatCompletionsRoute = createRoute({
|
|
18
19
|
method: "post",
|
|
19
20
|
path: "/completions",
|
|
20
|
-
tags: ["
|
|
21
|
+
tags: ["Chat"],
|
|
21
22
|
summary: "Create chat completion",
|
|
22
23
|
description: "Creates a new chat completion with streaming SSE response using the configured agent",
|
|
23
24
|
security: [{ bearerAuth: [] }],
|
|
@@ -222,9 +223,50 @@ app.openapi(chatCompletionsRoute, async (c) => {
|
|
|
222
223
|
"database.operation": "insert"
|
|
223
224
|
});
|
|
224
225
|
return streamSSE(c, async (stream$1) => {
|
|
226
|
+
const chunkString = (s, size = 16) => {
|
|
227
|
+
const out = [];
|
|
228
|
+
for (let i = 0; i < s.length; i += size) out.push(s.slice(i, i + size));
|
|
229
|
+
return out;
|
|
230
|
+
};
|
|
231
|
+
let unsubscribe;
|
|
225
232
|
try {
|
|
226
233
|
const sseHelper = createSSEStreamHelper(stream$1, requestId, timestamp);
|
|
227
234
|
await sseHelper.writeRole();
|
|
235
|
+
const seenToolCalls = /* @__PURE__ */ new Set();
|
|
236
|
+
const seenOutputs = /* @__PURE__ */ new Set();
|
|
237
|
+
unsubscribe = toolApprovalUiBus.subscribe(requestId, async (event) => {
|
|
238
|
+
if (event.type === "approval-needed") {
|
|
239
|
+
if (seenToolCalls.has(event.toolCallId)) return;
|
|
240
|
+
seenToolCalls.add(event.toolCallId);
|
|
241
|
+
await sseHelper.writeToolInputStart({
|
|
242
|
+
toolCallId: event.toolCallId,
|
|
243
|
+
toolName: event.toolName
|
|
244
|
+
});
|
|
245
|
+
const inputText = JSON.stringify(event.input ?? {});
|
|
246
|
+
for (const part of chunkString(inputText, 16)) await sseHelper.writeToolInputDelta({
|
|
247
|
+
toolCallId: event.toolCallId,
|
|
248
|
+
inputTextDelta: part
|
|
249
|
+
});
|
|
250
|
+
await sseHelper.writeToolInputAvailable({
|
|
251
|
+
toolCallId: event.toolCallId,
|
|
252
|
+
toolName: event.toolName,
|
|
253
|
+
input: event.input ?? {},
|
|
254
|
+
providerMetadata: event.providerMetadata
|
|
255
|
+
});
|
|
256
|
+
await sseHelper.writeToolApprovalRequest({
|
|
257
|
+
approvalId: event.approvalId,
|
|
258
|
+
toolCallId: event.toolCallId
|
|
259
|
+
});
|
|
260
|
+
} else if (event.type === "approval-resolved") {
|
|
261
|
+
if (seenOutputs.has(event.toolCallId)) return;
|
|
262
|
+
seenOutputs.add(event.toolCallId);
|
|
263
|
+
if (event.approved) await sseHelper.writeToolOutputAvailable({
|
|
264
|
+
toolCallId: event.toolCallId,
|
|
265
|
+
output: { status: "approved" }
|
|
266
|
+
});
|
|
267
|
+
else await sseHelper.writeToolOutputDenied({ toolCallId: event.toolCallId });
|
|
268
|
+
}
|
|
269
|
+
});
|
|
228
270
|
logger.info({ subAgentId }, "Starting execution");
|
|
229
271
|
const emitOperations = c.req.header("x-emit-operations") === "true";
|
|
230
272
|
const forwardedHeaders = {};
|
|
@@ -275,6 +317,10 @@ app.openapi(chatCompletionsRoute, async (c) => {
|
|
|
275
317
|
} catch (streamError) {
|
|
276
318
|
logger.error({ streamError }, "Failed to write error to stream");
|
|
277
319
|
}
|
|
320
|
+
} finally {
|
|
321
|
+
try {
|
|
322
|
+
unsubscribe?.();
|
|
323
|
+
} catch (_e) {}
|
|
278
324
|
}
|
|
279
325
|
});
|
|
280
326
|
});
|
|
@@ -4,6 +4,7 @@ import { contextValidationMiddleware } from "../context/validation.js";
|
|
|
4
4
|
import { handleContextResolution } from "../context/context.js";
|
|
5
5
|
import "../context/index.js";
|
|
6
6
|
import { pendingToolApprovalManager } from "../services/PendingToolApprovalManager.js";
|
|
7
|
+
import { toolApprovalUiBus } from "../services/ToolApprovalUiBus.js";
|
|
7
8
|
import { errorOp } from "../utils/agent-operations.js";
|
|
8
9
|
import { createBufferingStreamHelper, createVercelStreamHelper } from "../utils/stream-helpers.js";
|
|
9
10
|
import { ExecutionHandler } from "../handlers/executionHandler.js";
|
|
@@ -19,7 +20,7 @@ const logger = getLogger$1("chatDataStream");
|
|
|
19
20
|
const chatDataStreamRoute = createRoute({
|
|
20
21
|
method: "post",
|
|
21
22
|
path: "/chat",
|
|
22
|
-
tags: ["
|
|
23
|
+
tags: ["Chat"],
|
|
23
24
|
summary: "Chat (Vercel Streaming Protocol)",
|
|
24
25
|
description: "Chat completion endpoint streaming with Vercel data stream protocol.",
|
|
25
26
|
security: [{ bearerAuth: [] }],
|
|
@@ -34,16 +35,31 @@ const chatDataStreamRoute = createRoute({
|
|
|
34
35
|
"tool"
|
|
35
36
|
]),
|
|
36
37
|
content: z.any(),
|
|
37
|
-
parts: z.array(z.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
38
|
+
parts: z.array(z.union([
|
|
39
|
+
z.object({
|
|
40
|
+
type: z.union([z.enum([
|
|
41
|
+
"text",
|
|
42
|
+
"image",
|
|
43
|
+
"audio",
|
|
44
|
+
"video",
|
|
45
|
+
"file"
|
|
46
|
+
]), z.string().regex(/^data-/, "Type must start with \"data-\"")]),
|
|
47
|
+
text: z.string().optional()
|
|
48
|
+
}),
|
|
49
|
+
z.object({
|
|
50
|
+
type: z.string().regex(/^tool-/, "Type must start with \"tool-\""),
|
|
51
|
+
toolCallId: z.string(),
|
|
52
|
+
state: z.any(),
|
|
53
|
+
approval: z.object({
|
|
54
|
+
id: z.string(),
|
|
55
|
+
approved: z.boolean().optional(),
|
|
56
|
+
reason: z.string().optional()
|
|
57
|
+
}).optional(),
|
|
58
|
+
input: z.any().optional(),
|
|
59
|
+
callProviderMetadata: z.any().optional()
|
|
60
|
+
}),
|
|
61
|
+
z.object({ type: z.literal("step-start") })
|
|
62
|
+
])).optional()
|
|
47
63
|
})),
|
|
48
64
|
id: z.string().optional(),
|
|
49
65
|
conversationId: z.string().optional(),
|
|
@@ -74,7 +90,39 @@ app.openapi(chatDataStreamRoute, async (c) => {
|
|
|
74
90
|
agentId
|
|
75
91
|
}, "Extracted chatDataStream parameters");
|
|
76
92
|
const body = c.get("requestBody") || {};
|
|
77
|
-
const
|
|
93
|
+
const approvalPart = (body.messages || []).flatMap((m) => m?.parts || []).find((p) => p?.state === "approval-responded" && typeof p?.toolCallId === "string");
|
|
94
|
+
const isApprovalResponse = !!approvalPart;
|
|
95
|
+
const conversationId = isApprovalResponse ? body.conversationId : body.conversationId || getConversationId();
|
|
96
|
+
if (isApprovalResponse) {
|
|
97
|
+
if (!conversationId) return c.json({
|
|
98
|
+
success: false,
|
|
99
|
+
error: "conversationId is required for approval response"
|
|
100
|
+
}, 400);
|
|
101
|
+
const toolCallId = approvalPart.toolCallId;
|
|
102
|
+
const approved = !!approvalPart.approval?.approved;
|
|
103
|
+
const reason = approvalPart.approval?.reason;
|
|
104
|
+
if (!await getConversation(runDbClient_default)({
|
|
105
|
+
scopes: {
|
|
106
|
+
tenantId,
|
|
107
|
+
projectId
|
|
108
|
+
},
|
|
109
|
+
conversationId
|
|
110
|
+
})) return c.json({
|
|
111
|
+
success: false,
|
|
112
|
+
error: "Conversation not found"
|
|
113
|
+
}, 404);
|
|
114
|
+
if (!(approved ? pendingToolApprovalManager.approveToolCall(toolCallId) : pendingToolApprovalManager.denyToolCall(toolCallId, reason))) return c.json({
|
|
115
|
+
success: true,
|
|
116
|
+
toolCallId,
|
|
117
|
+
approved,
|
|
118
|
+
alreadyProcessed: true
|
|
119
|
+
});
|
|
120
|
+
return c.json({
|
|
121
|
+
success: true,
|
|
122
|
+
toolCallId,
|
|
123
|
+
approved
|
|
124
|
+
});
|
|
125
|
+
}
|
|
78
126
|
const targetTenantId = c.req.header("x-target-tenant-id");
|
|
79
127
|
const targetProjectId = c.req.header("x-target-project-id");
|
|
80
128
|
const targetAgentId = c.req.header("x-target-agent-id");
|
|
@@ -227,16 +275,58 @@ app.openapi(chatDataStreamRoute, async (c) => {
|
|
|
227
275
|
}
|
|
228
276
|
const dataStream = createUIMessageStream({ execute: async ({ writer }) => {
|
|
229
277
|
const streamHelper = createVercelStreamHelper(writer);
|
|
278
|
+
let unsubscribe;
|
|
230
279
|
try {
|
|
231
280
|
const emitOperations = c.req.header("x-emit-operations") === "true";
|
|
232
281
|
const executionHandler = new ExecutionHandler();
|
|
233
282
|
const datasetRunId = c.req.header("x-inkeep-dataset-run-id");
|
|
283
|
+
const requestId = `chatds-${Date.now()}`;
|
|
284
|
+
const chunkString = (s, size = 16) => {
|
|
285
|
+
const out = [];
|
|
286
|
+
for (let i = 0; i < s.length; i += size) out.push(s.slice(i, i + size));
|
|
287
|
+
return out;
|
|
288
|
+
};
|
|
289
|
+
const seenToolCalls = /* @__PURE__ */ new Set();
|
|
290
|
+
const seenOutputs = /* @__PURE__ */ new Set();
|
|
291
|
+
unsubscribe = toolApprovalUiBus.subscribe(requestId, async (event) => {
|
|
292
|
+
if (event.type === "approval-needed") {
|
|
293
|
+
if (seenToolCalls.has(event.toolCallId)) return;
|
|
294
|
+
seenToolCalls.add(event.toolCallId);
|
|
295
|
+
await streamHelper.writeToolInputStart({
|
|
296
|
+
toolCallId: event.toolCallId,
|
|
297
|
+
toolName: event.toolName
|
|
298
|
+
});
|
|
299
|
+
const inputText = JSON.stringify(event.input ?? {});
|
|
300
|
+
for (const part of chunkString(inputText, 16)) await streamHelper.writeToolInputDelta({
|
|
301
|
+
toolCallId: event.toolCallId,
|
|
302
|
+
inputTextDelta: part
|
|
303
|
+
});
|
|
304
|
+
await streamHelper.writeToolInputAvailable({
|
|
305
|
+
toolCallId: event.toolCallId,
|
|
306
|
+
toolName: event.toolName,
|
|
307
|
+
input: event.input ?? {},
|
|
308
|
+
providerMetadata: event.providerMetadata
|
|
309
|
+
});
|
|
310
|
+
await streamHelper.writeToolApprovalRequest({
|
|
311
|
+
approvalId: event.approvalId,
|
|
312
|
+
toolCallId: event.toolCallId
|
|
313
|
+
});
|
|
314
|
+
} else if (event.type === "approval-resolved") {
|
|
315
|
+
if (seenOutputs.has(event.toolCallId)) return;
|
|
316
|
+
seenOutputs.add(event.toolCallId);
|
|
317
|
+
if (event.approved) await streamHelper.writeToolOutputAvailable({
|
|
318
|
+
toolCallId: event.toolCallId,
|
|
319
|
+
output: { status: "approved" }
|
|
320
|
+
});
|
|
321
|
+
else await streamHelper.writeToolOutputDenied({ toolCallId: event.toolCallId });
|
|
322
|
+
}
|
|
323
|
+
});
|
|
234
324
|
if (!(await executionHandler.execute({
|
|
235
325
|
executionContext,
|
|
236
326
|
conversationId,
|
|
237
327
|
userMessage: userText,
|
|
238
328
|
initialAgentId: subAgentId,
|
|
239
|
-
requestId
|
|
329
|
+
requestId,
|
|
240
330
|
sseHelper: streamHelper,
|
|
241
331
|
emitOperations,
|
|
242
332
|
datasetRunId: datasetRunId || void 0,
|
|
@@ -246,6 +336,9 @@ app.openapi(chatDataStreamRoute, async (c) => {
|
|
|
246
336
|
logger.error({ err }, "Streaming error");
|
|
247
337
|
await streamHelper.writeOperation(errorOp("Internal server error", "system"));
|
|
248
338
|
} finally {
|
|
339
|
+
try {
|
|
340
|
+
unsubscribe?.();
|
|
341
|
+
} catch (_e) {}
|
|
249
342
|
if ("cleanup" in streamHelper && typeof streamHelper.cleanup === "function") streamHelper.cleanup();
|
|
250
343
|
}
|
|
251
344
|
} });
|
|
@@ -272,7 +365,7 @@ app.openapi(chatDataStreamRoute, async (c) => {
|
|
|
272
365
|
const toolApprovalRoute = createRoute({
|
|
273
366
|
method: "post",
|
|
274
367
|
path: "/tool-approvals",
|
|
275
|
-
tags: ["
|
|
368
|
+
tags: ["Chat"],
|
|
276
369
|
summary: "Approve or deny tool execution",
|
|
277
370
|
description: "Handle user approval/denial of tool execution requests during conversations",
|
|
278
371
|
security: [{ bearerAuth: [] }],
|