@inkeep/agents-run-api 0.1.6 → 0.1.7
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# Inkeep
|
|
1
|
+
# Inkeep Agents Run API
|
|
2
2
|
|
|
3
|
-
The
|
|
3
|
+
The Agents Run API is responsible for runtime agent operations, including Agent-to-Agent (A2A) communication, chat completions, and MCP (Model Context Protocol) tool integrations.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
@@ -82,8 +82,8 @@ The API uses environment-based configuration with defaults for local development
|
|
|
82
82
|
|
|
83
83
|
## Integration
|
|
84
84
|
|
|
85
|
-
### With
|
|
86
|
-
The
|
|
85
|
+
### With Agents Manage API
|
|
86
|
+
The Agents Run API reads agent configurations and relationships created by the Agents Manage API but doesn't modify them during runtime.
|
|
87
87
|
|
|
88
88
|
### With MCP Tools
|
|
89
89
|
Supports multiple MCP transport types:
|
|
@@ -114,4 +114,4 @@ The API implements comprehensive error handling:
|
|
|
114
114
|
- **API Key Authentication**: Configurable authentication methods
|
|
115
115
|
- **Input Validation**: Request sanitization and type checking
|
|
116
116
|
- **CORS**: Configurable cross-origin policies
|
|
117
|
-
- **Rate Limiting**: Configurable request throttling
|
|
117
|
+
- **Rate Limiting**: Configurable request throttling
|
|
@@ -30,22 +30,17 @@ var envSchema = z.object({
|
|
|
30
30
|
NODE_ENV: z.enum(["development", "production", "test"]).optional(),
|
|
31
31
|
ENVIRONMENT: z.enum(["development", "production", "pentest", "test"]).optional().default("development"),
|
|
32
32
|
DB_FILE_NAME: z.string().default("file:../local.db"),
|
|
33
|
-
|
|
34
|
-
AGENT_BASE_URL: z.string().optional(),
|
|
33
|
+
AGENTS_RUN_API_URL: z.string().optional().default("http://localhost:3003"),
|
|
35
34
|
LOG_LEVEL: z.enum(["trace", "debug", "info", "warn", "error"]).optional().default("debug"),
|
|
36
35
|
NANGO_SECRET_KEY: z.string().optional(),
|
|
37
36
|
OPENAI_API_KEY: z.string().optional(),
|
|
38
37
|
ANTHROPIC_API_KEY: z.string(),
|
|
39
38
|
INKEEP_AGENTS_RUN_API_BYPASS_SECRET: z.string().optional(),
|
|
40
|
-
OTEL_MAX_EXPORT_BATCH_SIZE: z.coerce.number().optional()
|
|
41
|
-
OTEL_EXPORTER_OTLP_ENDPOINT: z.string().optional().default("http://localhost:14318/v1/traces")
|
|
39
|
+
OTEL_MAX_EXPORT_BATCH_SIZE: z.coerce.number().optional()
|
|
42
40
|
});
|
|
43
41
|
var parseEnv = () => {
|
|
44
42
|
try {
|
|
45
43
|
const parsedEnv = envSchema.parse(process.env);
|
|
46
|
-
if (!parsedEnv.AGENT_BASE_URL) {
|
|
47
|
-
parsedEnv.AGENT_BASE_URL = `http://localhost:${parsedEnv.PORT}`;
|
|
48
|
-
}
|
|
49
44
|
return parsedEnv;
|
|
50
45
|
} catch (error) {
|
|
51
46
|
if (error instanceof z.ZodError) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { createDefaultConversationHistoryConfig, getFormattedConversationHistory, getFullConversationContext, getScopedHistory, getUserFacingHistory, saveA2AMessageResponse } from './chunk-
|
|
1
|
+
export { createDefaultConversationHistoryConfig, getFormattedConversationHistory, getFullConversationContext, getScopedHistory, getUserFacingHistory, saveA2AMessageResponse } from './chunk-HO5J26MO.js';
|
package/dist/index.cjs
CHANGED
|
@@ -103,22 +103,17 @@ var init_env = __esm({
|
|
|
103
103
|
NODE_ENV: z5.z.enum(["development", "production", "test"]).optional(),
|
|
104
104
|
ENVIRONMENT: z5.z.enum(["development", "production", "pentest", "test"]).optional().default("development"),
|
|
105
105
|
DB_FILE_NAME: z5.z.string().default("file:../local.db"),
|
|
106
|
-
|
|
107
|
-
AGENT_BASE_URL: z5.z.string().optional(),
|
|
106
|
+
AGENTS_RUN_API_URL: z5.z.string().optional().default("http://localhost:3003"),
|
|
108
107
|
LOG_LEVEL: z5.z.enum(["trace", "debug", "info", "warn", "error"]).optional().default("debug"),
|
|
109
108
|
NANGO_SECRET_KEY: z5.z.string().optional(),
|
|
110
109
|
OPENAI_API_KEY: z5.z.string().optional(),
|
|
111
110
|
ANTHROPIC_API_KEY: z5.z.string(),
|
|
112
111
|
INKEEP_AGENTS_RUN_API_BYPASS_SECRET: z5.z.string().optional(),
|
|
113
|
-
OTEL_MAX_EXPORT_BATCH_SIZE: z5.z.coerce.number().optional()
|
|
114
|
-
OTEL_EXPORTER_OTLP_ENDPOINT: z5.z.string().optional().default("http://localhost:14318/v1/traces")
|
|
112
|
+
OTEL_MAX_EXPORT_BATCH_SIZE: z5.z.coerce.number().optional()
|
|
115
113
|
});
|
|
116
114
|
parseEnv = () => {
|
|
117
115
|
try {
|
|
118
116
|
const parsedEnv = envSchema.parse(process.env);
|
|
119
|
-
if (!parsedEnv.AGENT_BASE_URL) {
|
|
120
|
-
parsedEnv.AGENT_BASE_URL = `http://localhost:${parsedEnv.PORT}`;
|
|
121
|
-
}
|
|
122
117
|
return parsedEnv;
|
|
123
118
|
} catch (error) {
|
|
124
119
|
if (error instanceof z5.z.ZodError) {
|
|
@@ -331,8 +326,7 @@ var init_conversations = __esm({
|
|
|
331
326
|
|
|
332
327
|
// src/instrumentation.ts
|
|
333
328
|
init_env();
|
|
334
|
-
var
|
|
335
|
-
var otlpExporter = new exporterTraceOtlpProto.OTLPTraceExporter({ url: otlpUrl });
|
|
329
|
+
var otlpExporter = new exporterTraceOtlpProto.OTLPTraceExporter();
|
|
336
330
|
var FanOutSpanProcessor = class {
|
|
337
331
|
constructor(inner) {
|
|
338
332
|
this.inner = inner;
|
|
@@ -441,6 +435,10 @@ function createExecutionContext(params) {
|
|
|
441
435
|
// src/middleware/api-key-auth.ts
|
|
442
436
|
var logger2 = agentsCore.getLogger("env-key-auth");
|
|
443
437
|
var apiKeyAuth = () => factory.createMiddleware(async (c, next) => {
|
|
438
|
+
if (c.req.method === "OPTIONS") {
|
|
439
|
+
await next();
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
444
442
|
const authHeader = c.req.header("Authorization");
|
|
445
443
|
const tenantId = c.req.header("x-inkeep-tenant-id");
|
|
446
444
|
const projectId = c.req.header("x-inkeep-project-id");
|
|
@@ -576,13 +574,13 @@ function setupOpenAPIRoutes(app6) {
|
|
|
576
574
|
const document = app6.getOpenAPIDocument({
|
|
577
575
|
openapi: "3.0.0",
|
|
578
576
|
info: {
|
|
579
|
-
title: "Inkeep
|
|
577
|
+
title: "Inkeep Agents Run API",
|
|
580
578
|
version: "1.0.0",
|
|
581
|
-
description: "
|
|
579
|
+
description: "Chat completions, MCP, and A2A run endpoints in the Inkeep Agent Framework."
|
|
582
580
|
},
|
|
583
581
|
servers: [
|
|
584
582
|
{
|
|
585
|
-
url: env.
|
|
583
|
+
url: env.AGENTS_RUN_API_URL,
|
|
586
584
|
description: "Development server"
|
|
587
585
|
}
|
|
588
586
|
]
|
|
@@ -598,7 +596,7 @@ function setupOpenAPIRoutes(app6) {
|
|
|
598
596
|
"/docs",
|
|
599
597
|
swaggerUi.swaggerUI({
|
|
600
598
|
url: "/openapi.json",
|
|
601
|
-
title: "Inkeep
|
|
599
|
+
title: "Inkeep Agents Run API Documentation"
|
|
602
600
|
})
|
|
603
601
|
);
|
|
604
602
|
}
|
|
@@ -1217,11 +1215,6 @@ init_dbClient();
|
|
|
1217
1215
|
// src/agents/Agent.ts
|
|
1218
1216
|
init_conversations();
|
|
1219
1217
|
init_dbClient();
|
|
1220
|
-
|
|
1221
|
-
// package.json
|
|
1222
|
-
var package_default = {
|
|
1223
|
-
version: "0.1.6"};
|
|
1224
|
-
var tracer = agentsCore.getTracer("agents-run-api", package_default.version);
|
|
1225
1218
|
function agentInitializingOp(sessionId, graphId) {
|
|
1226
1219
|
return {
|
|
1227
1220
|
type: "agent_initializing",
|
|
@@ -1350,7 +1343,9 @@ var _ModelFactory = class _ModelFactory {
|
|
|
1350
1343
|
*/
|
|
1351
1344
|
static createModel(config2) {
|
|
1352
1345
|
if (!config2?.model?.trim()) {
|
|
1353
|
-
throw new Error(
|
|
1346
|
+
throw new Error(
|
|
1347
|
+
"Model configuration is required. Please configure models at the project level."
|
|
1348
|
+
);
|
|
1354
1349
|
}
|
|
1355
1350
|
const modelSettings = config2;
|
|
1356
1351
|
const modelString = modelSettings.model.trim();
|
|
@@ -1371,7 +1366,9 @@ var _ModelFactory = class _ModelFactory {
|
|
|
1371
1366
|
case "openai":
|
|
1372
1367
|
return _ModelFactory.createOpenAIModel(modelName, modelSettings.providerOptions);
|
|
1373
1368
|
default:
|
|
1374
|
-
throw new Error(
|
|
1369
|
+
throw new Error(
|
|
1370
|
+
`Unsupported provider: ${provider}. Supported providers are: ${_ModelFactory.SUPPORTED_PROVIDERS.join(", ")}`
|
|
1371
|
+
);
|
|
1375
1372
|
}
|
|
1376
1373
|
} catch (error) {
|
|
1377
1374
|
logger5.error(
|
|
@@ -1382,7 +1379,9 @@ var _ModelFactory = class _ModelFactory {
|
|
|
1382
1379
|
},
|
|
1383
1380
|
"Failed to create model"
|
|
1384
1381
|
);
|
|
1385
|
-
throw new Error(
|
|
1382
|
+
throw new Error(
|
|
1383
|
+
`Failed to create model ${modelString}: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
1384
|
+
);
|
|
1386
1385
|
}
|
|
1387
1386
|
}
|
|
1388
1387
|
/**
|
|
@@ -1526,6 +1525,7 @@ var ModelFactory = _ModelFactory;
|
|
|
1526
1525
|
// src/utils/graph-session.ts
|
|
1527
1526
|
init_conversations();
|
|
1528
1527
|
init_dbClient();
|
|
1528
|
+
var tracer = agentsCore.getTracer("agents-run-api");
|
|
1529
1529
|
|
|
1530
1530
|
// src/utils/stream-registry.ts
|
|
1531
1531
|
var streamHelperRegistry = /* @__PURE__ */ new Map();
|
|
@@ -1635,12 +1635,15 @@ var GraphSession = class {
|
|
|
1635
1635
|
if (eventType === "artifact_saved" && data.pendingGeneration) {
|
|
1636
1636
|
const artifactId = data.artifactId;
|
|
1637
1637
|
if (this.pendingArtifacts.size >= this.MAX_PENDING_ARTIFACTS) {
|
|
1638
|
-
logger6.warn(
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1638
|
+
logger6.warn(
|
|
1639
|
+
{
|
|
1640
|
+
sessionId: this.sessionId,
|
|
1641
|
+
artifactId,
|
|
1642
|
+
pendingCount: this.pendingArtifacts.size,
|
|
1643
|
+
maxAllowed: this.MAX_PENDING_ARTIFACTS
|
|
1644
|
+
},
|
|
1645
|
+
"Too many pending artifacts, skipping processing"
|
|
1646
|
+
);
|
|
1644
1647
|
return;
|
|
1645
1648
|
}
|
|
1646
1649
|
this.pendingArtifacts.add(artifactId);
|
|
@@ -1653,21 +1656,27 @@ var GraphSession = class {
|
|
|
1653
1656
|
this.artifactProcessingErrors.set(artifactId, errorCount);
|
|
1654
1657
|
if (errorCount >= this.MAX_ARTIFACT_RETRIES) {
|
|
1655
1658
|
this.pendingArtifacts.delete(artifactId);
|
|
1656
|
-
logger6.error(
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1659
|
+
logger6.error(
|
|
1660
|
+
{
|
|
1661
|
+
sessionId: this.sessionId,
|
|
1662
|
+
artifactId,
|
|
1663
|
+
errorCount,
|
|
1664
|
+
maxRetries: this.MAX_ARTIFACT_RETRIES,
|
|
1665
|
+
error: error instanceof Error ? error.message : "Unknown error",
|
|
1666
|
+
stack: error instanceof Error ? error.stack : void 0
|
|
1667
|
+
},
|
|
1668
|
+
"Artifact processing failed after max retries, giving up"
|
|
1669
|
+
);
|
|
1664
1670
|
} else {
|
|
1665
|
-
logger6.warn(
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
+
logger6.warn(
|
|
1672
|
+
{
|
|
1673
|
+
sessionId: this.sessionId,
|
|
1674
|
+
artifactId,
|
|
1675
|
+
errorCount,
|
|
1676
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
1677
|
+
},
|
|
1678
|
+
"Artifact processing failed, may retry"
|
|
1679
|
+
);
|
|
1671
1680
|
}
|
|
1672
1681
|
});
|
|
1673
1682
|
});
|
|
@@ -2071,7 +2080,9 @@ ${this.statusUpdateState?.config.prompt?.trim() || ""}`;
|
|
|
2071
2080
|
let modelToUse = summarizerModel;
|
|
2072
2081
|
if (!summarizerModel?.model?.trim()) {
|
|
2073
2082
|
if (!this.statusUpdateState?.baseModel?.model?.trim()) {
|
|
2074
|
-
throw new Error(
|
|
2083
|
+
throw new Error(
|
|
2084
|
+
"Either summarizer or base model is required for progress summary generation. Please configure models at the project level."
|
|
2085
|
+
);
|
|
2075
2086
|
}
|
|
2076
2087
|
modelToUse = this.statusUpdateState.baseModel;
|
|
2077
2088
|
}
|
|
@@ -2199,7 +2210,9 @@ ${this.statusUpdateState?.config.prompt?.trim() || ""}`;
|
|
|
2199
2210
|
let modelToUse = summarizerModel;
|
|
2200
2211
|
if (!summarizerModel?.model?.trim()) {
|
|
2201
2212
|
if (!this.statusUpdateState?.baseModel?.model?.trim()) {
|
|
2202
|
-
throw new Error(
|
|
2213
|
+
throw new Error(
|
|
2214
|
+
"Either summarizer or base model is required for status update generation. Please configure models at the project level."
|
|
2215
|
+
);
|
|
2203
2216
|
}
|
|
2204
2217
|
modelToUse = this.statusUpdateState.baseModel;
|
|
2205
2218
|
}
|
|
@@ -2489,7 +2502,9 @@ Make it specific and relevant.`;
|
|
|
2489
2502
|
let modelToUse = this.statusUpdateState?.summarizerModel;
|
|
2490
2503
|
if (!modelToUse?.model?.trim()) {
|
|
2491
2504
|
if (!this.statusUpdateState?.baseModel?.model?.trim()) {
|
|
2492
|
-
throw new Error(
|
|
2505
|
+
throw new Error(
|
|
2506
|
+
"Either summarizer or base model is required for artifact name generation. Please configure models at the project level."
|
|
2507
|
+
);
|
|
2493
2508
|
}
|
|
2494
2509
|
modelToUse = this.statusUpdateState.baseModel;
|
|
2495
2510
|
}
|
|
@@ -2748,7 +2763,9 @@ var _ArtifactParser = class _ArtifactParser {
|
|
|
2748
2763
|
* More robust detection that handles streaming fragments
|
|
2749
2764
|
*/
|
|
2750
2765
|
hasIncompleteArtifact(text) {
|
|
2751
|
-
return /^.*<(?:artifact(?::ref)?|a(?:r(?:t(?:i(?:f(?:a(?:c(?:t(?::(?:r(?:e(?:f)?)?)?)?)?)?)?)?)?)?)?)?$/.test(
|
|
2766
|
+
return /^.*<(?:artifact(?::ref)?|a(?:r(?:t(?:i(?:f(?:a(?:c(?:t(?::(?:r(?:e(?:f)?)?)?)?)?)?)?)?)?)?)?)?$/.test(
|
|
2767
|
+
text
|
|
2768
|
+
) || /^.*<artifact:ref(?:[^>]*)$/.test(text) || // Incomplete artifact:ref at end
|
|
2752
2769
|
this.findSafeTextBoundary(text) < text.length;
|
|
2753
2770
|
}
|
|
2754
2771
|
/**
|
|
@@ -6219,6 +6236,40 @@ ${output}`;
|
|
|
6219
6236
|
}
|
|
6220
6237
|
};
|
|
6221
6238
|
|
|
6239
|
+
// src/utils/model-resolver.ts
|
|
6240
|
+
init_dbClient();
|
|
6241
|
+
async function resolveModelConfig(graphId, agent) {
|
|
6242
|
+
if (agent.models?.base?.model) {
|
|
6243
|
+
return {
|
|
6244
|
+
base: agent.models.base,
|
|
6245
|
+
structuredOutput: agent.models.structuredOutput || agent.models.base,
|
|
6246
|
+
summarizer: agent.models.summarizer || agent.models.base
|
|
6247
|
+
};
|
|
6248
|
+
}
|
|
6249
|
+
const graph = await agentsCore.getAgentGraph(dbClient_default)({
|
|
6250
|
+
scopes: { tenantId: agent.tenantId, projectId: agent.projectId },
|
|
6251
|
+
graphId
|
|
6252
|
+
});
|
|
6253
|
+
if (graph?.models?.base?.model) {
|
|
6254
|
+
return {
|
|
6255
|
+
base: graph.models.base,
|
|
6256
|
+
structuredOutput: agent.models?.structuredOutput || graph.models.structuredOutput || graph.models.base,
|
|
6257
|
+
summarizer: agent.models?.summarizer || graph.models.summarizer || graph.models.base
|
|
6258
|
+
};
|
|
6259
|
+
}
|
|
6260
|
+
const project = await agentsCore.getProject(dbClient_default)({
|
|
6261
|
+
scopes: { tenantId: agent.tenantId, projectId: agent.projectId }
|
|
6262
|
+
});
|
|
6263
|
+
if (project?.models?.base?.model) {
|
|
6264
|
+
return {
|
|
6265
|
+
base: project.models.base,
|
|
6266
|
+
structuredOutput: agent.models?.structuredOutput || project.models.structuredOutput || project.models.base,
|
|
6267
|
+
summarizer: agent.models?.summarizer || project.models.summarizer || project.models.base
|
|
6268
|
+
};
|
|
6269
|
+
}
|
|
6270
|
+
throw new Error("Base model configuration is required. Please configure models at the project level.");
|
|
6271
|
+
}
|
|
6272
|
+
|
|
6222
6273
|
// src/agents/generateTaskHandler.ts
|
|
6223
6274
|
function parseEmbeddedJson(data) {
|
|
6224
6275
|
return traverse__default.default(data).map(function(x) {
|
|
@@ -6501,7 +6552,7 @@ var createTaskHandlerConfig = async (params) => {
|
|
|
6501
6552
|
if (!agent) {
|
|
6502
6553
|
throw new Error(`Agent not found: ${params.agentId}`);
|
|
6503
6554
|
}
|
|
6504
|
-
const effectiveModels =
|
|
6555
|
+
const effectiveModels = await resolveModelConfig(params.graphId, agent);
|
|
6505
6556
|
const effectiveConversationHistoryConfig = agent.conversationHistoryConfig || { mode: "full" };
|
|
6506
6557
|
return {
|
|
6507
6558
|
tenantId: params.tenantId,
|
|
@@ -6513,7 +6564,7 @@ var createTaskHandlerConfig = async (params) => {
|
|
|
6513
6564
|
name: agent.name,
|
|
6514
6565
|
description: agent.description,
|
|
6515
6566
|
prompt: agent.prompt,
|
|
6516
|
-
models: effectiveModels
|
|
6567
|
+
models: effectiveModels,
|
|
6517
6568
|
conversationHistoryConfig: effectiveConversationHistoryConfig || null,
|
|
6518
6569
|
stopWhen: agent.stopWhen || null,
|
|
6519
6570
|
createdAt: agent.createdAt,
|
|
@@ -7076,7 +7127,9 @@ var _VercelDataStreamHelper = class _VercelDataStreamHelper {
|
|
|
7076
7127
|
if (this.jsonBuffer.length + content.length > _VercelDataStreamHelper.MAX_BUFFER_SIZE) {
|
|
7077
7128
|
const newBuffer = this.truncateJsonBufferSafely(this.jsonBuffer);
|
|
7078
7129
|
if (newBuffer.length === this.jsonBuffer.length) {
|
|
7079
|
-
console.warn(
|
|
7130
|
+
console.warn(
|
|
7131
|
+
"VercelDataStreamHelper: Could not find safe JSON truncation point, clearing buffer"
|
|
7132
|
+
);
|
|
7080
7133
|
this.jsonBuffer = "";
|
|
7081
7134
|
this.sentItems.clear();
|
|
7082
7135
|
} else {
|
|
@@ -7484,11 +7537,17 @@ var ExecutionHandler = class {
|
|
|
7484
7537
|
);
|
|
7485
7538
|
} catch (error) {
|
|
7486
7539
|
if (error?.message?.includes("UNIQUE constraint failed") || error?.message?.includes("PRIMARY KEY constraint failed") || error?.code === "SQLITE_CONSTRAINT_PRIMARYKEY") {
|
|
7487
|
-
logger19.info(
|
|
7540
|
+
logger19.info(
|
|
7541
|
+
{ taskId, error: error.message },
|
|
7542
|
+
"Task already exists, fetching existing task"
|
|
7543
|
+
);
|
|
7488
7544
|
const existingTask = await agentsCore.getTask(dbClient_default)({ id: taskId });
|
|
7489
7545
|
if (existingTask) {
|
|
7490
7546
|
task = existingTask;
|
|
7491
|
-
logger19.info(
|
|
7547
|
+
logger19.info(
|
|
7548
|
+
{ taskId, existingTask },
|
|
7549
|
+
"Successfully reused existing task from race condition"
|
|
7550
|
+
);
|
|
7492
7551
|
} else {
|
|
7493
7552
|
logger19.error({ taskId, error }, "Task constraint failed but task not found");
|
|
7494
7553
|
throw error;
|
|
@@ -8889,15 +8948,12 @@ function createExecutionHono(serverConfig, credentialStores) {
|
|
|
8889
8948
|
app6.use(
|
|
8890
8949
|
"*",
|
|
8891
8950
|
cors.cors({
|
|
8892
|
-
origin:
|
|
8893
|
-
|
|
8894
|
-
return origin.startsWith("http://localhost:") || origin.startsWith("https://localhost:") ? origin : null;
|
|
8895
|
-
},
|
|
8951
|
+
origin: "*",
|
|
8952
|
+
// public API
|
|
8896
8953
|
allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
|
|
8897
8954
|
allowHeaders: ["*"],
|
|
8898
8955
|
exposeHeaders: ["Content-Length"],
|
|
8899
|
-
maxAge: 86400
|
|
8900
|
-
credentials: true
|
|
8956
|
+
maxAge: 86400
|
|
8901
8957
|
})
|
|
8902
8958
|
);
|
|
8903
8959
|
app6.use("/tenants/*", apiKeyAuth());
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { env, __publicField, dbClient_default, getFormattedConversationHistory, createDefaultConversationHistoryConfig, saveA2AMessageResponse } from './chunk-
|
|
1
|
+
import { env, __publicField, dbClient_default, getFormattedConversationHistory, createDefaultConversationHistoryConfig, saveA2AMessageResponse } from './chunk-HO5J26MO.js';
|
|
2
2
|
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
|
|
3
3
|
import { BaggageSpanProcessor, ALLOW_ALL_BAGGAGE_KEYS } from '@opentelemetry/baggage-span-processor';
|
|
4
4
|
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto';
|
|
5
5
|
import { NodeSDK } from '@opentelemetry/sdk-node';
|
|
6
6
|
import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-node';
|
|
7
|
-
import { getLogger as getLogger$1, getTracer, HeadersScopeSchema, getRequestExecutionContext, getAgentGraphWithDefaultAgent, contextValidationMiddleware, getFullGraph, createOrGetConversation, getActiveAgentForConversation, setActiveAgentForConversation, getAgentById, handleContextResolution, createMessage, commonGetErrorResponses, createDefaultCredentialStores, CredentialStoreRegistry, listTaskIdsByContextId, getTask, getLedgerArtifacts, getAgentGraph, createTask, updateTask, updateConversation, handleApiError, setSpanWithError, TaskState, setActiveAgentForThread, getConversation, getRelatedAgentsForGraph, getToolsForAgent, getDataComponentsForAgent, getArtifactComponentsForAgent, validateAndGetApiKey, ContextResolver, CredentialStuffer, MCPServerType, getCredentialReference, McpClient, getContextConfigById, getFullGraphDefinition, TemplateEngine, graphHasArtifactComponents, MCPTransportType, getExternalAgent } from '@inkeep/agents-core';
|
|
7
|
+
import { getLogger as getLogger$1, getTracer, HeadersScopeSchema, getRequestExecutionContext, getAgentGraphWithDefaultAgent, contextValidationMiddleware, getFullGraph, createOrGetConversation, getActiveAgentForConversation, setActiveAgentForConversation, getAgentById, handleContextResolution, createMessage, commonGetErrorResponses, createDefaultCredentialStores, CredentialStoreRegistry, listTaskIdsByContextId, getTask, getLedgerArtifacts, getAgentGraph, createTask, updateTask, updateConversation, handleApiError, setSpanWithError, TaskState, setActiveAgentForThread, getConversation, getRelatedAgentsForGraph, getToolsForAgent, getDataComponentsForAgent, getArtifactComponentsForAgent, validateAndGetApiKey, getProject, ContextResolver, CredentialStuffer, MCPServerType, getCredentialReference, McpClient, getContextConfigById, getFullGraphDefinition, TemplateEngine, graphHasArtifactComponents, MCPTransportType, getExternalAgent } from '@inkeep/agents-core';
|
|
8
8
|
import { Hono } from 'hono';
|
|
9
9
|
import { OpenAPIHono, createRoute, z as z$1 } from '@hono/zod-openapi';
|
|
10
10
|
import { trace, propagation, context, SpanStatusCode } from '@opentelemetry/api';
|
|
@@ -33,8 +33,7 @@ import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/
|
|
|
33
33
|
import { z as z$2 } from 'zod/v3';
|
|
34
34
|
import { toReqRes, toFetchResponse } from 'fetch-to-node';
|
|
35
35
|
|
|
36
|
-
var
|
|
37
|
-
var otlpExporter = new OTLPTraceExporter({ url: otlpUrl });
|
|
36
|
+
var otlpExporter = new OTLPTraceExporter();
|
|
38
37
|
var FanOutSpanProcessor = class {
|
|
39
38
|
constructor(inner) {
|
|
40
39
|
this.inner = inner;
|
|
@@ -136,6 +135,10 @@ function createExecutionContext(params) {
|
|
|
136
135
|
// src/middleware/api-key-auth.ts
|
|
137
136
|
var logger2 = getLogger$1("env-key-auth");
|
|
138
137
|
var apiKeyAuth = () => createMiddleware(async (c, next) => {
|
|
138
|
+
if (c.req.method === "OPTIONS") {
|
|
139
|
+
await next();
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
139
142
|
const authHeader = c.req.header("Authorization");
|
|
140
143
|
const tenantId = c.req.header("x-inkeep-tenant-id");
|
|
141
144
|
const projectId = c.req.header("x-inkeep-project-id");
|
|
@@ -268,13 +271,13 @@ function setupOpenAPIRoutes(app6) {
|
|
|
268
271
|
const document = app6.getOpenAPIDocument({
|
|
269
272
|
openapi: "3.0.0",
|
|
270
273
|
info: {
|
|
271
|
-
title: "Inkeep
|
|
274
|
+
title: "Inkeep Agents Run API",
|
|
272
275
|
version: "1.0.0",
|
|
273
|
-
description: "
|
|
276
|
+
description: "Chat completions, MCP, and A2A run endpoints in the Inkeep Agent Framework."
|
|
274
277
|
},
|
|
275
278
|
servers: [
|
|
276
279
|
{
|
|
277
|
-
url: env.
|
|
280
|
+
url: env.AGENTS_RUN_API_URL,
|
|
278
281
|
description: "Development server"
|
|
279
282
|
}
|
|
280
283
|
]
|
|
@@ -290,7 +293,7 @@ function setupOpenAPIRoutes(app6) {
|
|
|
290
293
|
"/docs",
|
|
291
294
|
swaggerUI({
|
|
292
295
|
url: "/openapi.json",
|
|
293
|
-
title: "Inkeep
|
|
296
|
+
title: "Inkeep Agents Run API Documentation"
|
|
294
297
|
})
|
|
295
298
|
);
|
|
296
299
|
}
|
|
@@ -899,11 +902,6 @@ async function handleTasksResubscribe(c, agent, request) {
|
|
|
899
902
|
});
|
|
900
903
|
}
|
|
901
904
|
}
|
|
902
|
-
|
|
903
|
-
// package.json
|
|
904
|
-
var package_default = {
|
|
905
|
-
version: "0.1.6"};
|
|
906
|
-
var tracer = getTracer("agents-run-api", package_default.version);
|
|
907
905
|
function agentInitializingOp(sessionId, graphId) {
|
|
908
906
|
return {
|
|
909
907
|
type: "agent_initializing",
|
|
@@ -1032,7 +1030,9 @@ var _ModelFactory = class _ModelFactory {
|
|
|
1032
1030
|
*/
|
|
1033
1031
|
static createModel(config) {
|
|
1034
1032
|
if (!config?.model?.trim()) {
|
|
1035
|
-
throw new Error(
|
|
1033
|
+
throw new Error(
|
|
1034
|
+
"Model configuration is required. Please configure models at the project level."
|
|
1035
|
+
);
|
|
1036
1036
|
}
|
|
1037
1037
|
const modelSettings = config;
|
|
1038
1038
|
const modelString = modelSettings.model.trim();
|
|
@@ -1053,7 +1053,9 @@ var _ModelFactory = class _ModelFactory {
|
|
|
1053
1053
|
case "openai":
|
|
1054
1054
|
return _ModelFactory.createOpenAIModel(modelName, modelSettings.providerOptions);
|
|
1055
1055
|
default:
|
|
1056
|
-
throw new Error(
|
|
1056
|
+
throw new Error(
|
|
1057
|
+
`Unsupported provider: ${provider}. Supported providers are: ${_ModelFactory.SUPPORTED_PROVIDERS.join(", ")}`
|
|
1058
|
+
);
|
|
1057
1059
|
}
|
|
1058
1060
|
} catch (error) {
|
|
1059
1061
|
logger5.error(
|
|
@@ -1064,7 +1066,9 @@ var _ModelFactory = class _ModelFactory {
|
|
|
1064
1066
|
},
|
|
1065
1067
|
"Failed to create model"
|
|
1066
1068
|
);
|
|
1067
|
-
throw new Error(
|
|
1069
|
+
throw new Error(
|
|
1070
|
+
`Failed to create model ${modelString}: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
1071
|
+
);
|
|
1068
1072
|
}
|
|
1069
1073
|
}
|
|
1070
1074
|
/**
|
|
@@ -1204,6 +1208,7 @@ var _ModelFactory = class _ModelFactory {
|
|
|
1204
1208
|
*/
|
|
1205
1209
|
__publicField(_ModelFactory, "SUPPORTED_PROVIDERS", ["anthropic", "openai"]);
|
|
1206
1210
|
var ModelFactory = _ModelFactory;
|
|
1211
|
+
var tracer = getTracer("agents-run-api");
|
|
1207
1212
|
|
|
1208
1213
|
// src/utils/stream-registry.ts
|
|
1209
1214
|
var streamHelperRegistry = /* @__PURE__ */ new Map();
|
|
@@ -1313,12 +1318,15 @@ var GraphSession = class {
|
|
|
1313
1318
|
if (eventType === "artifact_saved" && data.pendingGeneration) {
|
|
1314
1319
|
const artifactId = data.artifactId;
|
|
1315
1320
|
if (this.pendingArtifacts.size >= this.MAX_PENDING_ARTIFACTS) {
|
|
1316
|
-
logger6.warn(
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1321
|
+
logger6.warn(
|
|
1322
|
+
{
|
|
1323
|
+
sessionId: this.sessionId,
|
|
1324
|
+
artifactId,
|
|
1325
|
+
pendingCount: this.pendingArtifacts.size,
|
|
1326
|
+
maxAllowed: this.MAX_PENDING_ARTIFACTS
|
|
1327
|
+
},
|
|
1328
|
+
"Too many pending artifacts, skipping processing"
|
|
1329
|
+
);
|
|
1322
1330
|
return;
|
|
1323
1331
|
}
|
|
1324
1332
|
this.pendingArtifacts.add(artifactId);
|
|
@@ -1331,21 +1339,27 @@ var GraphSession = class {
|
|
|
1331
1339
|
this.artifactProcessingErrors.set(artifactId, errorCount);
|
|
1332
1340
|
if (errorCount >= this.MAX_ARTIFACT_RETRIES) {
|
|
1333
1341
|
this.pendingArtifacts.delete(artifactId);
|
|
1334
|
-
logger6.error(
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
+
logger6.error(
|
|
1343
|
+
{
|
|
1344
|
+
sessionId: this.sessionId,
|
|
1345
|
+
artifactId,
|
|
1346
|
+
errorCount,
|
|
1347
|
+
maxRetries: this.MAX_ARTIFACT_RETRIES,
|
|
1348
|
+
error: error instanceof Error ? error.message : "Unknown error",
|
|
1349
|
+
stack: error instanceof Error ? error.stack : void 0
|
|
1350
|
+
},
|
|
1351
|
+
"Artifact processing failed after max retries, giving up"
|
|
1352
|
+
);
|
|
1342
1353
|
} else {
|
|
1343
|
-
logger6.warn(
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1354
|
+
logger6.warn(
|
|
1355
|
+
{
|
|
1356
|
+
sessionId: this.sessionId,
|
|
1357
|
+
artifactId,
|
|
1358
|
+
errorCount,
|
|
1359
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
1360
|
+
},
|
|
1361
|
+
"Artifact processing failed, may retry"
|
|
1362
|
+
);
|
|
1349
1363
|
}
|
|
1350
1364
|
});
|
|
1351
1365
|
});
|
|
@@ -1749,7 +1763,9 @@ ${this.statusUpdateState?.config.prompt?.trim() || ""}`;
|
|
|
1749
1763
|
let modelToUse = summarizerModel;
|
|
1750
1764
|
if (!summarizerModel?.model?.trim()) {
|
|
1751
1765
|
if (!this.statusUpdateState?.baseModel?.model?.trim()) {
|
|
1752
|
-
throw new Error(
|
|
1766
|
+
throw new Error(
|
|
1767
|
+
"Either summarizer or base model is required for progress summary generation. Please configure models at the project level."
|
|
1768
|
+
);
|
|
1753
1769
|
}
|
|
1754
1770
|
modelToUse = this.statusUpdateState.baseModel;
|
|
1755
1771
|
}
|
|
@@ -1877,7 +1893,9 @@ ${this.statusUpdateState?.config.prompt?.trim() || ""}`;
|
|
|
1877
1893
|
let modelToUse = summarizerModel;
|
|
1878
1894
|
if (!summarizerModel?.model?.trim()) {
|
|
1879
1895
|
if (!this.statusUpdateState?.baseModel?.model?.trim()) {
|
|
1880
|
-
throw new Error(
|
|
1896
|
+
throw new Error(
|
|
1897
|
+
"Either summarizer or base model is required for status update generation. Please configure models at the project level."
|
|
1898
|
+
);
|
|
1881
1899
|
}
|
|
1882
1900
|
modelToUse = this.statusUpdateState.baseModel;
|
|
1883
1901
|
}
|
|
@@ -2135,7 +2153,7 @@ ${this.statusUpdateState?.config.prompt?.trim() || ""}`;
|
|
|
2135
2153
|
);
|
|
2136
2154
|
}
|
|
2137
2155
|
span.setAttributes({ "validation.passed": true });
|
|
2138
|
-
const { getFormattedConversationHistory: getFormattedConversationHistory2 } = await import('./conversations-
|
|
2156
|
+
const { getFormattedConversationHistory: getFormattedConversationHistory2 } = await import('./conversations-ZQXUNCNE.js');
|
|
2139
2157
|
const conversationHistory = await getFormattedConversationHistory2({
|
|
2140
2158
|
tenantId: artifactData.tenantId,
|
|
2141
2159
|
projectId: artifactData.projectId,
|
|
@@ -2167,7 +2185,9 @@ Make it specific and relevant.`;
|
|
|
2167
2185
|
let modelToUse = this.statusUpdateState?.summarizerModel;
|
|
2168
2186
|
if (!modelToUse?.model?.trim()) {
|
|
2169
2187
|
if (!this.statusUpdateState?.baseModel?.model?.trim()) {
|
|
2170
|
-
throw new Error(
|
|
2188
|
+
throw new Error(
|
|
2189
|
+
"Either summarizer or base model is required for artifact name generation. Please configure models at the project level."
|
|
2190
|
+
);
|
|
2171
2191
|
}
|
|
2172
2192
|
modelToUse = this.statusUpdateState.baseModel;
|
|
2173
2193
|
}
|
|
@@ -2423,7 +2443,9 @@ var _ArtifactParser = class _ArtifactParser {
|
|
|
2423
2443
|
* More robust detection that handles streaming fragments
|
|
2424
2444
|
*/
|
|
2425
2445
|
hasIncompleteArtifact(text) {
|
|
2426
|
-
return /^.*<(?:artifact(?::ref)?|a(?:r(?:t(?:i(?:f(?:a(?:c(?:t(?::(?:r(?:e(?:f)?)?)?)?)?)?)?)?)?)?)?)?$/.test(
|
|
2446
|
+
return /^.*<(?:artifact(?::ref)?|a(?:r(?:t(?:i(?:f(?:a(?:c(?:t(?::(?:r(?:e(?:f)?)?)?)?)?)?)?)?)?)?)?)?$/.test(
|
|
2447
|
+
text
|
|
2448
|
+
) || /^.*<artifact:ref(?:[^>]*)$/.test(text) || // Incomplete artifact:ref at end
|
|
2427
2449
|
this.findSafeTextBoundary(text) < text.length;
|
|
2428
2450
|
}
|
|
2429
2451
|
/**
|
|
@@ -5891,6 +5913,37 @@ ${output}`;
|
|
|
5891
5913
|
});
|
|
5892
5914
|
}
|
|
5893
5915
|
};
|
|
5916
|
+
async function resolveModelConfig(graphId, agent) {
|
|
5917
|
+
if (agent.models?.base?.model) {
|
|
5918
|
+
return {
|
|
5919
|
+
base: agent.models.base,
|
|
5920
|
+
structuredOutput: agent.models.structuredOutput || agent.models.base,
|
|
5921
|
+
summarizer: agent.models.summarizer || agent.models.base
|
|
5922
|
+
};
|
|
5923
|
+
}
|
|
5924
|
+
const graph = await getAgentGraph(dbClient_default)({
|
|
5925
|
+
scopes: { tenantId: agent.tenantId, projectId: agent.projectId },
|
|
5926
|
+
graphId
|
|
5927
|
+
});
|
|
5928
|
+
if (graph?.models?.base?.model) {
|
|
5929
|
+
return {
|
|
5930
|
+
base: graph.models.base,
|
|
5931
|
+
structuredOutput: agent.models?.structuredOutput || graph.models.structuredOutput || graph.models.base,
|
|
5932
|
+
summarizer: agent.models?.summarizer || graph.models.summarizer || graph.models.base
|
|
5933
|
+
};
|
|
5934
|
+
}
|
|
5935
|
+
const project = await getProject(dbClient_default)({
|
|
5936
|
+
scopes: { tenantId: agent.tenantId, projectId: agent.projectId }
|
|
5937
|
+
});
|
|
5938
|
+
if (project?.models?.base?.model) {
|
|
5939
|
+
return {
|
|
5940
|
+
base: project.models.base,
|
|
5941
|
+
structuredOutput: agent.models?.structuredOutput || project.models.structuredOutput || project.models.base,
|
|
5942
|
+
summarizer: agent.models?.summarizer || project.models.summarizer || project.models.base
|
|
5943
|
+
};
|
|
5944
|
+
}
|
|
5945
|
+
throw new Error("Base model configuration is required. Please configure models at the project level.");
|
|
5946
|
+
}
|
|
5894
5947
|
|
|
5895
5948
|
// src/agents/generateTaskHandler.ts
|
|
5896
5949
|
function parseEmbeddedJson(data) {
|
|
@@ -6174,7 +6227,7 @@ var createTaskHandlerConfig = async (params) => {
|
|
|
6174
6227
|
if (!agent) {
|
|
6175
6228
|
throw new Error(`Agent not found: ${params.agentId}`);
|
|
6176
6229
|
}
|
|
6177
|
-
const effectiveModels =
|
|
6230
|
+
const effectiveModels = await resolveModelConfig(params.graphId, agent);
|
|
6178
6231
|
const effectiveConversationHistoryConfig = agent.conversationHistoryConfig || { mode: "full" };
|
|
6179
6232
|
return {
|
|
6180
6233
|
tenantId: params.tenantId,
|
|
@@ -6186,7 +6239,7 @@ var createTaskHandlerConfig = async (params) => {
|
|
|
6186
6239
|
name: agent.name,
|
|
6187
6240
|
description: agent.description,
|
|
6188
6241
|
prompt: agent.prompt,
|
|
6189
|
-
models: effectiveModels
|
|
6242
|
+
models: effectiveModels,
|
|
6190
6243
|
conversationHistoryConfig: effectiveConversationHistoryConfig || null,
|
|
6191
6244
|
stopWhen: agent.stopWhen || null,
|
|
6192
6245
|
createdAt: agent.createdAt,
|
|
@@ -6740,7 +6793,9 @@ var _VercelDataStreamHelper = class _VercelDataStreamHelper {
|
|
|
6740
6793
|
if (this.jsonBuffer.length + content.length > _VercelDataStreamHelper.MAX_BUFFER_SIZE) {
|
|
6741
6794
|
const newBuffer = this.truncateJsonBufferSafely(this.jsonBuffer);
|
|
6742
6795
|
if (newBuffer.length === this.jsonBuffer.length) {
|
|
6743
|
-
console.warn(
|
|
6796
|
+
console.warn(
|
|
6797
|
+
"VercelDataStreamHelper: Could not find safe JSON truncation point, clearing buffer"
|
|
6798
|
+
);
|
|
6744
6799
|
this.jsonBuffer = "";
|
|
6745
6800
|
this.sentItems.clear();
|
|
6746
6801
|
} else {
|
|
@@ -7145,11 +7200,17 @@ var ExecutionHandler = class {
|
|
|
7145
7200
|
);
|
|
7146
7201
|
} catch (error) {
|
|
7147
7202
|
if (error?.message?.includes("UNIQUE constraint failed") || error?.message?.includes("PRIMARY KEY constraint failed") || error?.code === "SQLITE_CONSTRAINT_PRIMARYKEY") {
|
|
7148
|
-
logger19.info(
|
|
7203
|
+
logger19.info(
|
|
7204
|
+
{ taskId, error: error.message },
|
|
7205
|
+
"Task already exists, fetching existing task"
|
|
7206
|
+
);
|
|
7149
7207
|
const existingTask = await getTask(dbClient_default)({ id: taskId });
|
|
7150
7208
|
if (existingTask) {
|
|
7151
7209
|
task = existingTask;
|
|
7152
|
-
logger19.info(
|
|
7210
|
+
logger19.info(
|
|
7211
|
+
{ taskId, existingTask },
|
|
7212
|
+
"Successfully reused existing task from race condition"
|
|
7213
|
+
);
|
|
7153
7214
|
} else {
|
|
7154
7215
|
logger19.error({ taskId, error }, "Task constraint failed but task not found");
|
|
7155
7216
|
throw error;
|
|
@@ -8544,15 +8605,12 @@ function createExecutionHono(serverConfig, credentialStores) {
|
|
|
8544
8605
|
app6.use(
|
|
8545
8606
|
"*",
|
|
8546
8607
|
cors({
|
|
8547
|
-
origin:
|
|
8548
|
-
|
|
8549
|
-
return origin.startsWith("http://localhost:") || origin.startsWith("https://localhost:") ? origin : null;
|
|
8550
|
-
},
|
|
8608
|
+
origin: "*",
|
|
8609
|
+
// public API
|
|
8551
8610
|
allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
|
|
8552
8611
|
allowHeaders: ["*"],
|
|
8553
8612
|
exposeHeaders: ["Content-Length"],
|
|
8554
|
-
maxAge: 86400
|
|
8555
|
-
credentials: true
|
|
8613
|
+
maxAge: 86400
|
|
8556
8614
|
})
|
|
8557
8615
|
);
|
|
8558
8616
|
app6.use("/tenants/*", apiKeyAuth());
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inkeep/agents-run-api",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.1.7",
|
|
4
|
+
"description": "Agents Run API for Inkeep Agent Framework - handles chat, agent execution, and streaming",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"exports": {
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"traverse": "^0.6.11",
|
|
45
45
|
"ts-pattern": "^5.7.1",
|
|
46
46
|
"zod": "^4.1.5",
|
|
47
|
-
"@inkeep/agents-core": "^0.1.
|
|
47
|
+
"@inkeep/agents-core": "^0.1.7"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@hono/vite-dev-server": "^0.20.1",
|