@inkeep/agents-run-api 0.2.1 → 0.3.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/index.cjs
CHANGED
|
@@ -2,11 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var fs = require('fs');
|
|
6
|
-
var path = require('path');
|
|
7
|
-
var dotenv = require('dotenv');
|
|
8
|
-
var z5 = require('zod');
|
|
9
5
|
var agentsCore = require('@inkeep/agents-core');
|
|
6
|
+
var z5 = require('zod');
|
|
10
7
|
var nanoid = require('nanoid');
|
|
11
8
|
var autoInstrumentationsNode = require('@opentelemetry/auto-instrumentations-node');
|
|
12
9
|
var baggageSpanProcessor = require('@opentelemetry/baggage-span-processor');
|
|
@@ -17,6 +14,7 @@ var resources = require('@opentelemetry/resources');
|
|
|
17
14
|
var sdkNode = require('@opentelemetry/sdk-node');
|
|
18
15
|
var sdkTraceBase = require('@opentelemetry/sdk-trace-base');
|
|
19
16
|
var semanticConventions = require('@opentelemetry/semantic-conventions');
|
|
17
|
+
var otel = require('@hono/otel');
|
|
20
18
|
var zodOpenapi = require('@hono/zod-openapi');
|
|
21
19
|
var api = require('@opentelemetry/api');
|
|
22
20
|
var hono = require('hono');
|
|
@@ -37,31 +35,9 @@ var mcp_js = require('@modelcontextprotocol/sdk/server/mcp.js');
|
|
|
37
35
|
var streamableHttp_js = require('@modelcontextprotocol/sdk/server/streamableHttp.js');
|
|
38
36
|
var v3 = require('zod/v3');
|
|
39
37
|
var fetchToNode = require('fetch-to-node');
|
|
40
|
-
var otel = require('@hono/otel');
|
|
41
38
|
|
|
42
39
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
43
40
|
|
|
44
|
-
function _interopNamespace(e) {
|
|
45
|
-
if (e && e.__esModule) return e;
|
|
46
|
-
var n = Object.create(null);
|
|
47
|
-
if (e) {
|
|
48
|
-
Object.keys(e).forEach(function (k) {
|
|
49
|
-
if (k !== 'default') {
|
|
50
|
-
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
51
|
-
Object.defineProperty(n, k, d.get ? d : {
|
|
52
|
-
enumerable: true,
|
|
53
|
-
get: function () { return e[k]; }
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
n.default = e;
|
|
59
|
-
return Object.freeze(n);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
var fs__default = /*#__PURE__*/_interopDefault(fs);
|
|
63
|
-
var path__default = /*#__PURE__*/_interopDefault(path);
|
|
64
|
-
var dotenv__namespace = /*#__PURE__*/_interopNamespace(dotenv);
|
|
65
41
|
var z5__default = /*#__PURE__*/_interopDefault(z5);
|
|
66
42
|
var destr__default = /*#__PURE__*/_interopDefault(destr);
|
|
67
43
|
var traverse__default = /*#__PURE__*/_interopDefault(traverse);
|
|
@@ -78,31 +54,14 @@ var __export = (target, all) => {
|
|
|
78
54
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
79
55
|
};
|
|
80
56
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
81
|
-
var
|
|
57
|
+
var envSchema, parseEnv, env;
|
|
82
58
|
var init_env = __esm({
|
|
83
59
|
"src/env.ts"() {
|
|
84
|
-
|
|
85
|
-
z5.z.enum(["development", "production"]).default("development");
|
|
86
|
-
environmentSchema = z5.z.enum(["development", "pentest", "production", "test"]);
|
|
87
|
-
criticalEnv = z5.z.object({
|
|
88
|
-
ENVIRONMENT: environmentSchema
|
|
89
|
-
}).parse(process.env);
|
|
90
|
-
loadEnvFile = () => {
|
|
91
|
-
const envPath = path__default.default.resolve(process.cwd(), `.env.${criticalEnv.ENVIRONMENT}.nonsecret`);
|
|
92
|
-
if (fs__default.default.existsSync(envPath)) {
|
|
93
|
-
const envConfig = dotenv__namespace.parse(fs__default.default.readFileSync(envPath));
|
|
94
|
-
for (const k in envConfig) {
|
|
95
|
-
if (!(k in process.env)) {
|
|
96
|
-
process.env[k] = envConfig[k];
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
};
|
|
101
|
-
loadEnvFile();
|
|
60
|
+
agentsCore.loadEnvironmentFiles();
|
|
102
61
|
envSchema = z5.z.object({
|
|
103
62
|
NODE_ENV: z5.z.enum(["development", "production", "test"]).optional(),
|
|
104
63
|
ENVIRONMENT: z5.z.enum(["development", "production", "pentest", "test"]).optional().default("development"),
|
|
105
|
-
DB_FILE_NAME: z5.z.string()
|
|
64
|
+
DB_FILE_NAME: z5.z.string(),
|
|
106
65
|
AGENTS_RUN_API_URL: z5.z.string().optional().default("http://localhost:3003"),
|
|
107
66
|
LOG_LEVEL: z5.z.enum(["trace", "debug", "info", "warn", "error"]).optional().default("debug"),
|
|
108
67
|
NANGO_SECRET_KEY: z5.z.string().optional(),
|
|
@@ -356,9 +315,9 @@ var sdk = new sdkNode.NodeSDK({
|
|
|
356
315
|
requestHook: (span) => {
|
|
357
316
|
const method = span.attributes?.["http.request.method"];
|
|
358
317
|
const host = span.attributes?.["server.address"];
|
|
359
|
-
const
|
|
360
|
-
if (method &&
|
|
361
|
-
span.updateName(host ? `${method} ${host}${
|
|
318
|
+
const path = span.attributes?.["url.path"];
|
|
319
|
+
if (method && path)
|
|
320
|
+
span.updateName(host ? `${method} ${host}${path}` : `${method} ${path}`);
|
|
362
321
|
}
|
|
363
322
|
}
|
|
364
323
|
})
|
|
@@ -1267,7 +1226,7 @@ async function getRegisteredAgent(executionContext, credentialStoreRegistry) {
|
|
|
1267
1226
|
throw new Error("Agent ID is required");
|
|
1268
1227
|
}
|
|
1269
1228
|
const dbAgent = await agentsCore.getAgentById(dbClient_default)({
|
|
1270
|
-
scopes: { tenantId, projectId },
|
|
1229
|
+
scopes: { tenantId, projectId, graphId },
|
|
1271
1230
|
agentId
|
|
1272
1231
|
});
|
|
1273
1232
|
if (!dbAgent) {
|
|
@@ -1286,6 +1245,41 @@ async function getRegisteredAgent(executionContext, credentialStoreRegistry) {
|
|
|
1286
1245
|
// src/agents/generateTaskHandler.ts
|
|
1287
1246
|
init_dbClient();
|
|
1288
1247
|
|
|
1248
|
+
// src/utils/model-resolver.ts
|
|
1249
|
+
init_dbClient();
|
|
1250
|
+
async function resolveModelConfig(graphId, agent) {
|
|
1251
|
+
if (agent.models?.base?.model) {
|
|
1252
|
+
return {
|
|
1253
|
+
base: agent.models.base,
|
|
1254
|
+
structuredOutput: agent.models.structuredOutput || agent.models.base,
|
|
1255
|
+
summarizer: agent.models.summarizer || agent.models.base
|
|
1256
|
+
};
|
|
1257
|
+
}
|
|
1258
|
+
const graph = await agentsCore.getAgentGraphById(dbClient_default)({
|
|
1259
|
+
scopes: { tenantId: agent.tenantId, projectId: agent.projectId, graphId }
|
|
1260
|
+
});
|
|
1261
|
+
if (graph?.models?.base?.model) {
|
|
1262
|
+
return {
|
|
1263
|
+
base: graph.models.base,
|
|
1264
|
+
structuredOutput: agent.models?.structuredOutput || graph.models.structuredOutput || graph.models.base,
|
|
1265
|
+
summarizer: agent.models?.summarizer || graph.models.summarizer || graph.models.base
|
|
1266
|
+
};
|
|
1267
|
+
}
|
|
1268
|
+
const project = await agentsCore.getProject(dbClient_default)({
|
|
1269
|
+
scopes: { tenantId: agent.tenantId, projectId: agent.projectId }
|
|
1270
|
+
});
|
|
1271
|
+
if (project?.models?.base?.model) {
|
|
1272
|
+
return {
|
|
1273
|
+
base: project.models.base,
|
|
1274
|
+
structuredOutput: agent.models?.structuredOutput || project.models.structuredOutput || project.models.base,
|
|
1275
|
+
summarizer: agent.models?.summarizer || project.models.summarizer || project.models.base
|
|
1276
|
+
};
|
|
1277
|
+
}
|
|
1278
|
+
throw new Error(
|
|
1279
|
+
"Base model configuration is required. Please configure models at the project level."
|
|
1280
|
+
);
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1289
1283
|
// src/agents/Agent.ts
|
|
1290
1284
|
init_conversations();
|
|
1291
1285
|
init_dbClient();
|
|
@@ -1307,24 +1301,19 @@ function completionOp(agentId, iterations) {
|
|
|
1307
1301
|
}
|
|
1308
1302
|
};
|
|
1309
1303
|
}
|
|
1310
|
-
function errorOp(error,
|
|
1304
|
+
function errorOp(message, agentId, severity = "error", code) {
|
|
1311
1305
|
return {
|
|
1312
1306
|
type: "error",
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1307
|
+
message,
|
|
1308
|
+
agent: agentId,
|
|
1309
|
+
severity,
|
|
1310
|
+
code,
|
|
1311
|
+
timestamp: Date.now()
|
|
1317
1312
|
};
|
|
1318
1313
|
}
|
|
1319
1314
|
function generateToolId() {
|
|
1320
1315
|
return `tool_${nanoid.nanoid(8)}`;
|
|
1321
1316
|
}
|
|
1322
|
-
function statusUpdateOp(ctx) {
|
|
1323
|
-
return {
|
|
1324
|
-
type: "status_update",
|
|
1325
|
-
ctx
|
|
1326
|
-
};
|
|
1327
|
-
}
|
|
1328
1317
|
var logger4 = agentsCore.getLogger("DataComponentSchema");
|
|
1329
1318
|
function jsonSchemaToZod(jsonSchema) {
|
|
1330
1319
|
if (!jsonSchema || typeof jsonSchema !== "object") {
|
|
@@ -1414,14 +1403,14 @@ var _ModelFactory = class _ModelFactory {
|
|
|
1414
1403
|
/**
|
|
1415
1404
|
* Create a provider instance with custom configuration
|
|
1416
1405
|
*/
|
|
1417
|
-
static createProvider(provider,
|
|
1406
|
+
static createProvider(provider, config) {
|
|
1418
1407
|
switch (provider) {
|
|
1419
1408
|
case "anthropic":
|
|
1420
|
-
return anthropic.createAnthropic(
|
|
1409
|
+
return anthropic.createAnthropic(config);
|
|
1421
1410
|
case "openai":
|
|
1422
|
-
return openai.createOpenAI(
|
|
1411
|
+
return openai.createOpenAI(config);
|
|
1423
1412
|
case "google":
|
|
1424
|
-
return google.createGoogleGenerativeAI(
|
|
1413
|
+
return google.createGoogleGenerativeAI(config);
|
|
1425
1414
|
default:
|
|
1426
1415
|
throw new Error(`Unsupported provider: ${provider}`);
|
|
1427
1416
|
}
|
|
@@ -1447,13 +1436,16 @@ var _ModelFactory = class _ModelFactory {
|
|
|
1447
1436
|
* Create a language model instance from configuration
|
|
1448
1437
|
* Throws error if no config provided - models must be configured at project level
|
|
1449
1438
|
*/
|
|
1450
|
-
static createModel(
|
|
1451
|
-
if (!
|
|
1439
|
+
static createModel(config) {
|
|
1440
|
+
if (!config?.model?.trim()) {
|
|
1452
1441
|
throw new Error(
|
|
1453
1442
|
"Model configuration is required. Please configure models at the project level."
|
|
1454
1443
|
);
|
|
1455
1444
|
}
|
|
1456
|
-
const modelSettings =
|
|
1445
|
+
const modelSettings = config;
|
|
1446
|
+
if (!modelSettings.model) {
|
|
1447
|
+
throw new Error("Model configuration is required");
|
|
1448
|
+
}
|
|
1457
1449
|
const modelString = modelSettings.model.trim();
|
|
1458
1450
|
const { provider, modelName } = _ModelFactory.parseModelString(modelString);
|
|
1459
1451
|
logger5.debug(
|
|
@@ -1550,19 +1542,19 @@ var _ModelFactory = class _ModelFactory {
|
|
|
1550
1542
|
* Validate model settingsuration
|
|
1551
1543
|
* Basic validation only - let AI SDK handle parameter-specific validation
|
|
1552
1544
|
*/
|
|
1553
|
-
static validateConfig(
|
|
1545
|
+
static validateConfig(config) {
|
|
1554
1546
|
const errors = [];
|
|
1555
|
-
if (!
|
|
1547
|
+
if (!config.model) {
|
|
1556
1548
|
errors.push("Model name is required");
|
|
1557
1549
|
}
|
|
1558
|
-
if (
|
|
1559
|
-
if (
|
|
1550
|
+
if (config.providerOptions) {
|
|
1551
|
+
if (config.providerOptions.apiKey) {
|
|
1560
1552
|
errors.push(
|
|
1561
1553
|
"API keys should not be stored in provider options. Use environment variables (ANTHROPIC_API_KEY, OPENAI_API_KEY) or credential store instead."
|
|
1562
1554
|
);
|
|
1563
1555
|
}
|
|
1564
|
-
if (
|
|
1565
|
-
const maxDuration =
|
|
1556
|
+
if (config.providerOptions.maxDuration !== void 0) {
|
|
1557
|
+
const maxDuration = config.providerOptions.maxDuration;
|
|
1566
1558
|
if (typeof maxDuration !== "number" || maxDuration <= 0) {
|
|
1567
1559
|
errors.push("maxDuration must be a positive number (in seconds)");
|
|
1568
1560
|
}
|
|
@@ -1580,7 +1572,6 @@ var ModelFactory = _ModelFactory;
|
|
|
1580
1572
|
// src/utils/graph-session.ts
|
|
1581
1573
|
init_conversations();
|
|
1582
1574
|
init_dbClient();
|
|
1583
|
-
var tracer = agentsCore.getTracer("agents-run-api");
|
|
1584
1575
|
|
|
1585
1576
|
// src/utils/stream-registry.ts
|
|
1586
1577
|
var streamHelperRegistry = /* @__PURE__ */ new Map();
|
|
@@ -1596,6 +1587,7 @@ function getStreamHelper(requestId2) {
|
|
|
1596
1587
|
function unregisterStreamHelper(requestId2) {
|
|
1597
1588
|
streamHelperRegistry.delete(requestId2);
|
|
1598
1589
|
}
|
|
1590
|
+
var tracer = agentsCore.getTracer("agents-run-api");
|
|
1599
1591
|
|
|
1600
1592
|
// src/utils/graph-session.ts
|
|
1601
1593
|
var logger6 = agentsCore.getLogger("GraphSession");
|
|
@@ -1627,7 +1619,7 @@ var GraphSession = class {
|
|
|
1627
1619
|
/**
|
|
1628
1620
|
* Initialize status updates for this session
|
|
1629
1621
|
*/
|
|
1630
|
-
initializeStatusUpdates(
|
|
1622
|
+
initializeStatusUpdates(config, summarizerModel, baseModel) {
|
|
1631
1623
|
const now = Date.now();
|
|
1632
1624
|
this.statusUpdateState = {
|
|
1633
1625
|
lastUpdateTime: now,
|
|
@@ -1636,9 +1628,9 @@ var GraphSession = class {
|
|
|
1636
1628
|
summarizerModel,
|
|
1637
1629
|
baseModel,
|
|
1638
1630
|
config: {
|
|
1639
|
-
numEvents:
|
|
1640
|
-
timeInSeconds:
|
|
1641
|
-
...
|
|
1631
|
+
numEvents: config.numEvents || 1,
|
|
1632
|
+
timeInSeconds: config.timeInSeconds || 2,
|
|
1633
|
+
...config
|
|
1642
1634
|
}
|
|
1643
1635
|
};
|
|
1644
1636
|
if (this.statusUpdateState.config.timeInSeconds) {
|
|
@@ -1904,7 +1896,6 @@ var GraphSession = class {
|
|
|
1904
1896
|
}
|
|
1905
1897
|
this.isGeneratingUpdate = true;
|
|
1906
1898
|
const statusUpdateState = this.statusUpdateState;
|
|
1907
|
-
const graphId = this.graphId;
|
|
1908
1899
|
try {
|
|
1909
1900
|
const streamHelper = getStreamHelper(this.sessionId);
|
|
1910
1901
|
if (!streamHelper) {
|
|
@@ -1917,7 +1908,7 @@ var GraphSession = class {
|
|
|
1917
1908
|
}
|
|
1918
1909
|
const now = Date.now();
|
|
1919
1910
|
const elapsedTime = now - statusUpdateState.startTime;
|
|
1920
|
-
let
|
|
1911
|
+
let summaryToSend;
|
|
1921
1912
|
if (statusUpdateState.config.statusComponents && statusUpdateState.config.statusComponents.length > 0) {
|
|
1922
1913
|
const result = await this.generateStructuredStatusUpdate(
|
|
1923
1914
|
this.events.slice(statusUpdateState.lastEventCount),
|
|
@@ -1926,32 +1917,30 @@ var GraphSession = class {
|
|
|
1926
1917
|
statusUpdateState.summarizerModel,
|
|
1927
1918
|
this.previousSummaries
|
|
1928
1919
|
);
|
|
1929
|
-
if (result.
|
|
1930
|
-
for (const
|
|
1931
|
-
if (!
|
|
1920
|
+
if (result.summaries && result.summaries.length > 0) {
|
|
1921
|
+
for (const summary of result.summaries) {
|
|
1922
|
+
if (!summary || !summary.type || !summary.data || !summary.data.label || Object.keys(summary.data).length === 0) {
|
|
1932
1923
|
logger6.warn(
|
|
1933
1924
|
{
|
|
1934
1925
|
sessionId: this.sessionId,
|
|
1935
|
-
|
|
1926
|
+
summary
|
|
1936
1927
|
},
|
|
1937
1928
|
"Skipping empty or invalid structured operation"
|
|
1938
1929
|
);
|
|
1939
1930
|
continue;
|
|
1940
1931
|
}
|
|
1941
|
-
const
|
|
1942
|
-
type:
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
data
|
|
1947
|
-
|
|
1948
|
-
)
|
|
1949
|
-
}
|
|
1932
|
+
const summaryToSend2 = {
|
|
1933
|
+
type: summary.data.type || summary.type,
|
|
1934
|
+
// Preserve the actual custom type from LLM
|
|
1935
|
+
label: summary.data.label,
|
|
1936
|
+
details: Object.fromEntries(
|
|
1937
|
+
Object.entries(summary.data).filter(([key]) => !["label", "type"].includes(key))
|
|
1938
|
+
)
|
|
1950
1939
|
};
|
|
1951
|
-
await streamHelper.
|
|
1940
|
+
await streamHelper.writeSummary(summaryToSend2);
|
|
1952
1941
|
}
|
|
1953
|
-
const summaryTexts = result.
|
|
1954
|
-
(
|
|
1942
|
+
const summaryTexts = result.summaries.map(
|
|
1943
|
+
(summary) => JSON.stringify({ type: summary.type, data: summary.data })
|
|
1955
1944
|
);
|
|
1956
1945
|
this.previousSummaries.push(...summaryTexts);
|
|
1957
1946
|
if (this.statusUpdateState) {
|
|
@@ -1968,34 +1957,20 @@ var GraphSession = class {
|
|
|
1968
1957
|
this.previousSummaries
|
|
1969
1958
|
);
|
|
1970
1959
|
this.previousSummaries.push(summary);
|
|
1971
|
-
operation = statusUpdateOp({
|
|
1972
|
-
summary,
|
|
1973
|
-
eventCount: this.events.length,
|
|
1974
|
-
elapsedTime,
|
|
1975
|
-
currentPhase: "processing",
|
|
1976
|
-
activeAgent: "system",
|
|
1977
|
-
graphId,
|
|
1978
|
-
sessionId: this.sessionId
|
|
1979
|
-
});
|
|
1980
1960
|
}
|
|
1981
1961
|
if (this.previousSummaries.length > 3) {
|
|
1982
1962
|
this.previousSummaries.shift();
|
|
1983
1963
|
}
|
|
1984
|
-
|
|
1964
|
+
{
|
|
1985
1965
|
logger6.warn(
|
|
1986
1966
|
{
|
|
1987
1967
|
sessionId: this.sessionId,
|
|
1988
|
-
|
|
1968
|
+
summaryToSend
|
|
1989
1969
|
},
|
|
1990
1970
|
"Skipping empty or invalid status update operation"
|
|
1991
1971
|
);
|
|
1992
1972
|
return;
|
|
1993
1973
|
}
|
|
1994
|
-
await streamHelper.writeOperation(operation);
|
|
1995
|
-
if (this.statusUpdateState) {
|
|
1996
|
-
this.statusUpdateState.lastUpdateTime = now;
|
|
1997
|
-
this.statusUpdateState.lastEventCount = this.events.length;
|
|
1998
|
-
}
|
|
1999
1974
|
} catch (error) {
|
|
2000
1975
|
logger6.error(
|
|
2001
1976
|
{
|
|
@@ -2128,7 +2103,7 @@ ${previousSummaryContext}` : ""}
|
|
|
2128
2103
|
Activities:
|
|
2129
2104
|
${userVisibleActivities.join("\n") || "No New Activities"}
|
|
2130
2105
|
|
|
2131
|
-
|
|
2106
|
+
Create a short 3-5 word label describing the ACTUAL finding. Use sentence case (only capitalize the first word and proper nouns). Examples: "Found admin permissions needed", "Identified three channel types", "OAuth token required".
|
|
2132
2107
|
|
|
2133
2108
|
${this.statusUpdateState?.config.prompt?.trim() || ""}`;
|
|
2134
2109
|
const prompt = basePrompt;
|
|
@@ -2141,6 +2116,9 @@ ${this.statusUpdateState?.config.prompt?.trim() || ""}`;
|
|
|
2141
2116
|
}
|
|
2142
2117
|
modelToUse = this.statusUpdateState.baseModel;
|
|
2143
2118
|
}
|
|
2119
|
+
if (!modelToUse) {
|
|
2120
|
+
throw new Error("No model configuration available");
|
|
2121
|
+
}
|
|
2144
2122
|
const model = ModelFactory.createModel(modelToUse);
|
|
2145
2123
|
const { text } = await ai.generateText({
|
|
2146
2124
|
model,
|
|
@@ -2250,14 +2228,16 @@ Rules:
|
|
|
2250
2228
|
- Fill in data for relevant components only
|
|
2251
2229
|
- Use 'no_relevant_updates' if nothing substantially new to report. DO NOT WRITE LABELS OR USE OTHER COMPONENTS IF YOU USE THIS COMPONENT.
|
|
2252
2230
|
- Never repeat previous values, make every update EXTREMELY unique. If you cannot do that the update is not worth mentioning.
|
|
2253
|
-
- Labels MUST
|
|
2231
|
+
- Labels MUST be short 3-5 word phrases with ACTUAL information discovered. NEVER MAKE UP SOMETHING WITHOUT BACKING IT UP WITH ACTUAL INFORMATION.
|
|
2232
|
+
- Use sentence case: only capitalize the first word and proper nouns (e.g., "Admin permissions required", not "Admin Permissions Required"). ALWAYS capitalize the first word of the label.
|
|
2254
2233
|
- DO NOT use action words like "Searching", "Processing", "Analyzing" - state what was FOUND
|
|
2255
2234
|
- Include specific details, numbers, requirements, or insights discovered
|
|
2235
|
+
- Examples: "Admin permissions required", "Three OAuth steps found", "Token expires daily"
|
|
2256
2236
|
- You are ONE unified AI system - NEVER mention agents, transfers, delegations, or routing
|
|
2257
|
-
- CRITICAL: NEVER use the words "transfer", "delegation", "agent", "routing", or any internal system terminology in labels
|
|
2237
|
+
- CRITICAL: NEVER use the words "transfer", "delegation", "agent", "routing", "artifact", or any internal system terminology in labels or any names of agents, tools, or systems.
|
|
2258
2238
|
- Present all operations as seamless actions by a single system
|
|
2259
2239
|
- Anonymize all internal operations so that the information appears descriptive and USER FRIENDLY. HIDE ALL INTERNAL OPERATIONS!
|
|
2260
|
-
- Bad examples: "Transferring to search agent", "Delegating task", "Routing request", "Processing request", or not using the no_relevant_updates
|
|
2240
|
+
- Bad examples: "Transferring to search agent", "continuing transfer to qa agent", "Delegating task", "Routing request", "Processing request", "Artifact found", "Artifact saved", or not using the no_relevant_updates
|
|
2261
2241
|
- Good examples: "Slack bot needs admin privileges", "Found 3-step OAuth flow required", "Channel limit is 500 per workspace", or use the no_relevant_updates component if nothing new to report.
|
|
2262
2242
|
|
|
2263
2243
|
REMEMBER YOU CAN ONLY USE 'no_relevant_updates' ALONE! IT CANNOT BE CONCATENATED WITH OTHER STATUS UPDATES!
|
|
@@ -2273,6 +2253,9 @@ ${this.statusUpdateState?.config.prompt?.trim() || ""}`;
|
|
|
2273
2253
|
}
|
|
2274
2254
|
modelToUse = this.statusUpdateState.baseModel;
|
|
2275
2255
|
}
|
|
2256
|
+
if (!modelToUse) {
|
|
2257
|
+
throw new Error("No model configuration available");
|
|
2258
|
+
}
|
|
2276
2259
|
const model = ModelFactory.createModel(modelToUse);
|
|
2277
2260
|
const { object } = await ai.generateObject({
|
|
2278
2261
|
model,
|
|
@@ -2290,29 +2273,29 @@ ${this.statusUpdateState?.config.prompt?.trim() || ""}`;
|
|
|
2290
2273
|
}
|
|
2291
2274
|
});
|
|
2292
2275
|
const result = object;
|
|
2293
|
-
const
|
|
2276
|
+
const summaries = [];
|
|
2294
2277
|
for (const [componentId, data] of Object.entries(result)) {
|
|
2295
2278
|
if (componentId === "no_relevant_updates") {
|
|
2296
2279
|
continue;
|
|
2297
2280
|
}
|
|
2298
2281
|
if (data && typeof data === "object" && Object.keys(data).length > 0) {
|
|
2299
|
-
|
|
2282
|
+
summaries.push({
|
|
2300
2283
|
type: componentId,
|
|
2301
2284
|
data
|
|
2302
2285
|
});
|
|
2303
2286
|
}
|
|
2304
2287
|
}
|
|
2305
2288
|
span.setAttributes({
|
|
2306
|
-
"
|
|
2289
|
+
"summaries.count": summaries.length,
|
|
2307
2290
|
"user_activities.count": userVisibleActivities.length,
|
|
2308
2291
|
"result_keys.count": Object.keys(result).length
|
|
2309
2292
|
});
|
|
2310
2293
|
span.setStatus({ code: api.SpanStatusCode.OK });
|
|
2311
|
-
return {
|
|
2294
|
+
return { summaries };
|
|
2312
2295
|
} catch (error) {
|
|
2313
2296
|
agentsCore.setSpanWithError(span, error);
|
|
2314
2297
|
logger6.error({ error }, "Failed to generate structured update, using fallback");
|
|
2315
|
-
return {
|
|
2298
|
+
return { summaries: [] };
|
|
2316
2299
|
} finally {
|
|
2317
2300
|
span.end();
|
|
2318
2301
|
}
|
|
@@ -2563,6 +2546,9 @@ Make it specific and relevant.`;
|
|
|
2563
2546
|
}
|
|
2564
2547
|
modelToUse = this.statusUpdateState.baseModel;
|
|
2565
2548
|
}
|
|
2549
|
+
if (!modelToUse) {
|
|
2550
|
+
throw new Error("No model configuration available");
|
|
2551
|
+
}
|
|
2566
2552
|
const model = ModelFactory.createModel(modelToUse);
|
|
2567
2553
|
const schema = z5.z.object({
|
|
2568
2554
|
name: z5.z.string().max(50).describe("Concise, descriptive name for the artifact"),
|
|
@@ -2731,10 +2717,10 @@ var GraphSessionManager = class {
|
|
|
2731
2717
|
/**
|
|
2732
2718
|
* Initialize status updates for a session
|
|
2733
2719
|
*/
|
|
2734
|
-
initializeStatusUpdates(sessionId,
|
|
2720
|
+
initializeStatusUpdates(sessionId, config, summarizerModel) {
|
|
2735
2721
|
const session = this.sessions.get(sessionId);
|
|
2736
2722
|
if (session) {
|
|
2737
|
-
session.initializeStatusUpdates(
|
|
2723
|
+
session.initializeStatusUpdates(config, summarizerModel);
|
|
2738
2724
|
} else {
|
|
2739
2725
|
logger6.error(
|
|
2740
2726
|
{
|
|
@@ -2844,6 +2830,7 @@ var _ArtifactParser = class _ArtifactParser {
|
|
|
2844
2830
|
}
|
|
2845
2831
|
for (let i = matches.length - 1; i >= 0; i--) {
|
|
2846
2832
|
const match = matches[i];
|
|
2833
|
+
if (match.index === void 0) continue;
|
|
2847
2834
|
const startIdx = match.index;
|
|
2848
2835
|
const textAfterMatch = text.slice(startIdx);
|
|
2849
2836
|
if (!textAfterMatch.includes("/>")) {
|
|
@@ -2893,7 +2880,8 @@ var _ArtifactParser = class _ArtifactParser {
|
|
|
2893
2880
|
taskId,
|
|
2894
2881
|
name: artifact.name || "Processing...",
|
|
2895
2882
|
description: artifact.description || "Name and description being generated...",
|
|
2896
|
-
|
|
2883
|
+
type: artifact.metadata?.artifactType || artifact.artifactType,
|
|
2884
|
+
// Map artifactType to type for consistency
|
|
2897
2885
|
artifactSummary: artifact.parts?.[0]?.data?.summary || {}
|
|
2898
2886
|
};
|
|
2899
2887
|
}
|
|
@@ -2910,10 +2898,11 @@ var _ArtifactParser = class _ArtifactParser {
|
|
|
2910
2898
|
let lastIndex = 0;
|
|
2911
2899
|
for (const match of matches) {
|
|
2912
2900
|
const [fullMatch, artifactId, taskId] = match;
|
|
2901
|
+
if (match.index === void 0) continue;
|
|
2913
2902
|
const matchStart = match.index;
|
|
2914
2903
|
if (matchStart > lastIndex) {
|
|
2915
2904
|
const textBefore = text.slice(lastIndex, matchStart);
|
|
2916
|
-
if (textBefore
|
|
2905
|
+
if (textBefore) {
|
|
2917
2906
|
parts.push({ kind: "text", text: textBefore });
|
|
2918
2907
|
}
|
|
2919
2908
|
}
|
|
@@ -2925,7 +2914,7 @@ var _ArtifactParser = class _ArtifactParser {
|
|
|
2925
2914
|
}
|
|
2926
2915
|
if (lastIndex < text.length) {
|
|
2927
2916
|
const remainingText = text.slice(lastIndex);
|
|
2928
|
-
if (remainingText
|
|
2917
|
+
if (remainingText) {
|
|
2929
2918
|
parts.push({ kind: "text", text: remainingText });
|
|
2930
2919
|
}
|
|
2931
2920
|
}
|
|
@@ -3035,8 +3024,9 @@ __publicField(_ArtifactParser, "INCOMPLETE_ARTIFACT_REGEX", /<(a(r(t(i(f(a(c(t(:
|
|
|
3035
3024
|
var ArtifactParser = _ArtifactParser;
|
|
3036
3025
|
|
|
3037
3026
|
// src/utils/incremental-stream-parser.ts
|
|
3038
|
-
|
|
3039
|
-
var
|
|
3027
|
+
agentsCore.getLogger("IncrementalStreamParser");
|
|
3028
|
+
var _IncrementalStreamParser = class _IncrementalStreamParser {
|
|
3029
|
+
// Max number of streamed component IDs to track
|
|
3040
3030
|
constructor(streamHelper, tenantId, contextId) {
|
|
3041
3031
|
__publicField(this, "buffer", "");
|
|
3042
3032
|
__publicField(this, "pendingTextBuffer", "");
|
|
@@ -3046,6 +3036,9 @@ var IncrementalStreamParser = class {
|
|
|
3046
3036
|
__publicField(this, "collectedParts", []);
|
|
3047
3037
|
__publicField(this, "contextId");
|
|
3048
3038
|
__publicField(this, "lastChunkWasToolResult", false);
|
|
3039
|
+
__publicField(this, "componentAccumulator", {});
|
|
3040
|
+
__publicField(this, "lastStreamedComponents", /* @__PURE__ */ new Map());
|
|
3041
|
+
__publicField(this, "componentSnapshots", /* @__PURE__ */ new Map());
|
|
3049
3042
|
this.streamHelper = streamHelper;
|
|
3050
3043
|
this.contextId = contextId;
|
|
3051
3044
|
this.artifactParser = new ArtifactParser(tenantId);
|
|
@@ -3060,7 +3053,7 @@ var IncrementalStreamParser = class {
|
|
|
3060
3053
|
* Process a new text chunk for text streaming (handles artifact markers)
|
|
3061
3054
|
*/
|
|
3062
3055
|
async processTextChunk(chunk) {
|
|
3063
|
-
if (this.lastChunkWasToolResult && this.buffer === "" && chunk
|
|
3056
|
+
if (this.lastChunkWasToolResult && this.buffer === "" && chunk) {
|
|
3064
3057
|
chunk = "\n\n" + chunk;
|
|
3065
3058
|
this.lastChunkWasToolResult = false;
|
|
3066
3059
|
}
|
|
@@ -3072,100 +3065,122 @@ var IncrementalStreamParser = class {
|
|
|
3072
3065
|
this.buffer = parseResult.remainingBuffer;
|
|
3073
3066
|
}
|
|
3074
3067
|
/**
|
|
3075
|
-
* Process
|
|
3068
|
+
* Process object deltas directly from Vercel AI SDK's fullStream
|
|
3069
|
+
* Accumulates components and streams them when they're stable (unchanged between deltas)
|
|
3076
3070
|
*/
|
|
3077
|
-
async
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
for (const part of parseResult.completeParts) {
|
|
3081
|
-
await this.streamPart(part);
|
|
3071
|
+
async processObjectDelta(delta) {
|
|
3072
|
+
if (!delta || typeof delta !== "object") {
|
|
3073
|
+
return;
|
|
3082
3074
|
}
|
|
3083
|
-
this.
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
const delta = part.argsTextDelta || "";
|
|
3097
|
-
if (jsonBuffer.length + delta.length > MAX_BUFFER_SIZE) {
|
|
3098
|
-
logger8.warn(
|
|
3099
|
-
{ bufferSize: jsonBuffer.length + delta.length, maxSize: MAX_BUFFER_SIZE },
|
|
3100
|
-
"JSON buffer exceeded maximum size, truncating"
|
|
3101
|
-
);
|
|
3102
|
-
jsonBuffer = jsonBuffer.slice(-MAX_BUFFER_SIZE / 2);
|
|
3075
|
+
this.componentAccumulator = this.deepMerge(this.componentAccumulator, delta);
|
|
3076
|
+
if (this.componentAccumulator.dataComponents && Array.isArray(this.componentAccumulator.dataComponents)) {
|
|
3077
|
+
const components = this.componentAccumulator.dataComponents;
|
|
3078
|
+
const currentComponentIds = new Set(components.filter((c) => c?.id).map((c) => c.id));
|
|
3079
|
+
for (const [componentId, snapshot] of this.componentSnapshots.entries()) {
|
|
3080
|
+
if (!currentComponentIds.has(componentId) && !this.lastStreamedComponents.has(componentId)) {
|
|
3081
|
+
try {
|
|
3082
|
+
const component = JSON.parse(snapshot);
|
|
3083
|
+
if (this.isComponentComplete(component)) {
|
|
3084
|
+
await this.streamComponent(component);
|
|
3085
|
+
}
|
|
3086
|
+
} catch (e) {
|
|
3087
|
+
}
|
|
3103
3088
|
}
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3089
|
+
}
|
|
3090
|
+
for (let i = 0; i < components.length; i++) {
|
|
3091
|
+
const component = components[i];
|
|
3092
|
+
if (!component?.id) continue;
|
|
3093
|
+
const componentKey = component.id;
|
|
3094
|
+
const hasBeenStreamed = this.lastStreamedComponents.has(componentKey);
|
|
3095
|
+
if (hasBeenStreamed) continue;
|
|
3096
|
+
const currentSnapshot = JSON.stringify(component);
|
|
3097
|
+
const previousSnapshot = this.componentSnapshots.get(componentKey);
|
|
3098
|
+
this.componentSnapshots.set(componentKey, currentSnapshot);
|
|
3099
|
+
if (this.componentSnapshots.size > _IncrementalStreamParser.MAX_SNAPSHOT_SIZE) {
|
|
3100
|
+
const firstKey = this.componentSnapshots.keys().next().value;
|
|
3101
|
+
if (firstKey) {
|
|
3102
|
+
this.componentSnapshots.delete(firstKey);
|
|
3114
3103
|
}
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
if (componentMatch[0].length > MAX_COMPONENT_SIZE) {
|
|
3125
|
-
logger8.warn(
|
|
3126
|
-
{
|
|
3127
|
-
size: componentMatch[0].length,
|
|
3128
|
-
maxSize: MAX_COMPONENT_SIZE
|
|
3129
|
-
},
|
|
3130
|
-
"Component exceeds size limit, skipping"
|
|
3131
|
-
);
|
|
3132
|
-
componentBuffer = "";
|
|
3133
|
-
continue;
|
|
3134
|
-
}
|
|
3135
|
-
try {
|
|
3136
|
-
const component = JSON.parse(componentMatch[0]);
|
|
3137
|
-
if (typeof component !== "object" || !component.id) {
|
|
3138
|
-
logger8.warn({ component }, "Invalid component structure, skipping");
|
|
3139
|
-
componentBuffer = "";
|
|
3140
|
-
continue;
|
|
3141
|
-
}
|
|
3142
|
-
const parts = await this.artifactParser.parseObject({
|
|
3143
|
-
dataComponents: [component]
|
|
3144
|
-
});
|
|
3145
|
-
for (const part2 of parts) {
|
|
3146
|
-
await this.streamPart(part2);
|
|
3147
|
-
}
|
|
3148
|
-
componentsStreamed++;
|
|
3149
|
-
componentBuffer = "";
|
|
3150
|
-
} catch (e) {
|
|
3151
|
-
logger8.debug({ error: e }, "Failed to parse component, continuing to accumulate");
|
|
3152
|
-
}
|
|
3153
|
-
}
|
|
3104
|
+
}
|
|
3105
|
+
if (component.name === "Text" && component.props?.text) {
|
|
3106
|
+
const previousTextContent = previousSnapshot ? JSON.parse(previousSnapshot).props?.text || "" : "";
|
|
3107
|
+
const currentTextContent = component.props.text || "";
|
|
3108
|
+
if (currentTextContent.length > previousTextContent.length) {
|
|
3109
|
+
const newText = currentTextContent.slice(previousTextContent.length);
|
|
3110
|
+
if (!this.hasStartedRole) {
|
|
3111
|
+
await this.streamHelper.writeRole("assistant");
|
|
3112
|
+
this.hasStartedRole = true;
|
|
3154
3113
|
}
|
|
3114
|
+
await this.streamHelper.streamText(newText, 50);
|
|
3115
|
+
this.collectedParts.push({
|
|
3116
|
+
kind: "text",
|
|
3117
|
+
text: newText
|
|
3118
|
+
});
|
|
3155
3119
|
}
|
|
3156
|
-
|
|
3120
|
+
continue;
|
|
3157
3121
|
}
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
const
|
|
3161
|
-
|
|
3162
|
-
await this.
|
|
3122
|
+
if (this.isComponentComplete(component)) {
|
|
3123
|
+
const currentPropsSnapshot = JSON.stringify(component.props);
|
|
3124
|
+
const previousPropsSnapshot = previousSnapshot ? JSON.stringify(JSON.parse(previousSnapshot).props) : null;
|
|
3125
|
+
if (previousPropsSnapshot === currentPropsSnapshot) {
|
|
3126
|
+
await this.streamComponent(component);
|
|
3163
3127
|
}
|
|
3164
3128
|
}
|
|
3165
|
-
break;
|
|
3166
3129
|
}
|
|
3167
3130
|
}
|
|
3168
|
-
|
|
3131
|
+
}
|
|
3132
|
+
/**
|
|
3133
|
+
* Stream a component and mark it as streamed
|
|
3134
|
+
* Note: Text components are handled separately with incremental streaming
|
|
3135
|
+
*/
|
|
3136
|
+
async streamComponent(component) {
|
|
3137
|
+
const parts = await this.artifactParser.parseObject({
|
|
3138
|
+
dataComponents: [component]
|
|
3139
|
+
});
|
|
3140
|
+
for (const part of parts) {
|
|
3141
|
+
await this.streamPart(part);
|
|
3142
|
+
}
|
|
3143
|
+
this.lastStreamedComponents.set(component.id, true);
|
|
3144
|
+
if (this.lastStreamedComponents.size > _IncrementalStreamParser.MAX_STREAMED_SIZE) {
|
|
3145
|
+
const firstKey = this.lastStreamedComponents.keys().next().value;
|
|
3146
|
+
if (firstKey) {
|
|
3147
|
+
this.lastStreamedComponents.delete(firstKey);
|
|
3148
|
+
}
|
|
3149
|
+
}
|
|
3150
|
+
this.componentSnapshots.delete(component.id);
|
|
3151
|
+
}
|
|
3152
|
+
/**
|
|
3153
|
+
* Check if a component has the basic structure required for streaming
|
|
3154
|
+
* Requires id, name, and props object with content
|
|
3155
|
+
*/
|
|
3156
|
+
isComponentComplete(component) {
|
|
3157
|
+
if (!component || !component.id || !component.name) {
|
|
3158
|
+
return false;
|
|
3159
|
+
}
|
|
3160
|
+
if (!component.props || typeof component.props !== "object") {
|
|
3161
|
+
return false;
|
|
3162
|
+
}
|
|
3163
|
+
const isArtifact = component.name === "Artifact" || component.props.artifact_id && component.props.task_id;
|
|
3164
|
+
if (isArtifact) {
|
|
3165
|
+
return Boolean(component.props.artifact_id && component.props.task_id);
|
|
3166
|
+
}
|
|
3167
|
+
return true;
|
|
3168
|
+
}
|
|
3169
|
+
/**
|
|
3170
|
+
* Deep merge helper for object deltas
|
|
3171
|
+
*/
|
|
3172
|
+
deepMerge(target, source) {
|
|
3173
|
+
if (!source) return target;
|
|
3174
|
+
if (!target) return source;
|
|
3175
|
+
const result = { ...target };
|
|
3176
|
+
for (const key in source) {
|
|
3177
|
+
if (source[key] && typeof source[key] === "object" && !Array.isArray(source[key])) {
|
|
3178
|
+
result[key] = this.deepMerge(target[key], source[key]);
|
|
3179
|
+
} else {
|
|
3180
|
+
result[key] = source[key];
|
|
3181
|
+
}
|
|
3182
|
+
}
|
|
3183
|
+
return result;
|
|
3169
3184
|
}
|
|
3170
3185
|
/**
|
|
3171
3186
|
* Legacy method for backward compatibility - defaults to text processing
|
|
@@ -3177,15 +3192,40 @@ var IncrementalStreamParser = class {
|
|
|
3177
3192
|
* Process any remaining buffer content at the end of stream
|
|
3178
3193
|
*/
|
|
3179
3194
|
async finalize() {
|
|
3180
|
-
if (this.
|
|
3195
|
+
if (this.componentAccumulator.dataComponents && Array.isArray(this.componentAccumulator.dataComponents)) {
|
|
3196
|
+
const components = this.componentAccumulator.dataComponents;
|
|
3197
|
+
for (let i = 0; i < components.length; i++) {
|
|
3198
|
+
const component = components[i];
|
|
3199
|
+
if (!component?.id) continue;
|
|
3200
|
+
const componentKey = component.id;
|
|
3201
|
+
const hasBeenStreamed = this.lastStreamedComponents.has(componentKey);
|
|
3202
|
+
if (!hasBeenStreamed && this.isComponentComplete(component) && component.name !== "Text") {
|
|
3203
|
+
const parts = await this.artifactParser.parseObject({
|
|
3204
|
+
dataComponents: [component]
|
|
3205
|
+
});
|
|
3206
|
+
for (const part of parts) {
|
|
3207
|
+
await this.streamPart(part);
|
|
3208
|
+
}
|
|
3209
|
+
this.lastStreamedComponents.set(componentKey, true);
|
|
3210
|
+
if (this.lastStreamedComponents.size > _IncrementalStreamParser.MAX_STREAMED_SIZE) {
|
|
3211
|
+
const firstKey = this.lastStreamedComponents.keys().next().value;
|
|
3212
|
+
if (firstKey) {
|
|
3213
|
+
this.lastStreamedComponents.delete(firstKey);
|
|
3214
|
+
}
|
|
3215
|
+
}
|
|
3216
|
+
this.componentSnapshots.delete(componentKey);
|
|
3217
|
+
}
|
|
3218
|
+
}
|
|
3219
|
+
}
|
|
3220
|
+
if (this.buffer) {
|
|
3181
3221
|
const part = {
|
|
3182
3222
|
kind: "text",
|
|
3183
|
-
text: this.buffer
|
|
3223
|
+
text: this.buffer
|
|
3184
3224
|
};
|
|
3185
3225
|
await this.streamPart(part);
|
|
3186
3226
|
}
|
|
3187
|
-
if (this.pendingTextBuffer
|
|
3188
|
-
const cleanedText = this.pendingTextBuffer.replace(/<\/?artifact:ref(?:\s[^>]*)?>\/?>/g, "").replace(/<\/?artifact(?:\s[^>]*)?>\/?>/g, "").replace(/<\/(?:\w+:)?artifact>/g, "")
|
|
3227
|
+
if (this.pendingTextBuffer) {
|
|
3228
|
+
const cleanedText = this.pendingTextBuffer.replace(/<\/?artifact:ref(?:\s[^>]*)?>\/?>/g, "").replace(/<\/?artifact(?:\s[^>]*)?>\/?>/g, "").replace(/<\/(?:\w+:)?artifact>/g, "");
|
|
3189
3229
|
if (cleanedText) {
|
|
3190
3230
|
this.collectedParts.push({
|
|
3191
3231
|
kind: "text",
|
|
@@ -3195,6 +3235,9 @@ var IncrementalStreamParser = class {
|
|
|
3195
3235
|
}
|
|
3196
3236
|
this.pendingTextBuffer = "";
|
|
3197
3237
|
}
|
|
3238
|
+
this.componentSnapshots.clear();
|
|
3239
|
+
this.lastStreamedComponents.clear();
|
|
3240
|
+
this.componentAccumulator = {};
|
|
3198
3241
|
}
|
|
3199
3242
|
/**
|
|
3200
3243
|
* Get all collected parts for building the final response
|
|
@@ -3241,30 +3284,6 @@ var IncrementalStreamParser = class {
|
|
|
3241
3284
|
remainingBuffer: ""
|
|
3242
3285
|
};
|
|
3243
3286
|
}
|
|
3244
|
-
/**
|
|
3245
|
-
* Parse buffer for complete JSON objects with artifact references (for object streaming)
|
|
3246
|
-
*/
|
|
3247
|
-
async parseObjectBuffer() {
|
|
3248
|
-
const completeParts = [];
|
|
3249
|
-
try {
|
|
3250
|
-
const parsed = JSON.parse(this.buffer);
|
|
3251
|
-
const parts = await this.artifactParser.parseObject(parsed);
|
|
3252
|
-
return {
|
|
3253
|
-
completeParts: parts,
|
|
3254
|
-
remainingBuffer: ""
|
|
3255
|
-
};
|
|
3256
|
-
} catch {
|
|
3257
|
-
const { complete, remaining } = this.artifactParser.parsePartialJSON(this.buffer);
|
|
3258
|
-
for (const obj of complete) {
|
|
3259
|
-
const parts = await this.artifactParser.parseObject(obj);
|
|
3260
|
-
completeParts.push(...parts);
|
|
3261
|
-
}
|
|
3262
|
-
return {
|
|
3263
|
-
completeParts,
|
|
3264
|
-
remainingBuffer: remaining
|
|
3265
|
-
};
|
|
3266
|
-
}
|
|
3267
|
-
}
|
|
3268
3287
|
/**
|
|
3269
3288
|
* Check if text might be the start of an artifact marker
|
|
3270
3289
|
*/
|
|
@@ -3285,7 +3304,7 @@ var IncrementalStreamParser = class {
|
|
|
3285
3304
|
this.pendingTextBuffer += part.text;
|
|
3286
3305
|
if (!this.artifactParser.hasIncompleteArtifact(this.pendingTextBuffer)) {
|
|
3287
3306
|
const cleanedText = this.pendingTextBuffer.replace(/<\/?artifact:ref(?:\s[^>]*)?>\/?>/g, "").replace(/<\/?artifact(?:\s[^>]*)?>\/?>/g, "").replace(/<\/(?:\w+:)?artifact>/g, "");
|
|
3288
|
-
if (cleanedText
|
|
3307
|
+
if (cleanedText) {
|
|
3289
3308
|
await this.streamHelper.streamText(cleanedText, 50);
|
|
3290
3309
|
}
|
|
3291
3310
|
this.pendingTextBuffer = "";
|
|
@@ -3293,7 +3312,7 @@ var IncrementalStreamParser = class {
|
|
|
3293
3312
|
} else if (part.kind === "data" && part.data) {
|
|
3294
3313
|
if (this.pendingTextBuffer) {
|
|
3295
3314
|
const cleanedText = this.pendingTextBuffer.replace(/<\/?artifact:ref(?:\s[^>]*)?>\/?>/g, "").replace(/<\/?artifact(?:\s[^>]*)?>\/?>/g, "").replace(/<\/(?:\w+:)?artifact>/g, "");
|
|
3296
|
-
if (cleanedText
|
|
3315
|
+
if (cleanedText) {
|
|
3297
3316
|
await this.streamHelper.streamText(cleanedText, 50);
|
|
3298
3317
|
}
|
|
3299
3318
|
this.pendingTextBuffer = "";
|
|
@@ -3307,6 +3326,11 @@ var IncrementalStreamParser = class {
|
|
|
3307
3326
|
}
|
|
3308
3327
|
}
|
|
3309
3328
|
};
|
|
3329
|
+
// Memory management constants
|
|
3330
|
+
__publicField(_IncrementalStreamParser, "MAX_SNAPSHOT_SIZE", 100);
|
|
3331
|
+
// Max number of snapshots to keep
|
|
3332
|
+
__publicField(_IncrementalStreamParser, "MAX_STREAMED_SIZE", 1e3);
|
|
3333
|
+
var IncrementalStreamParser = _IncrementalStreamParser;
|
|
3310
3334
|
|
|
3311
3335
|
// src/utils/response-formatter.ts
|
|
3312
3336
|
var logger9 = agentsCore.getLogger("ResponseFormatter");
|
|
@@ -3598,7 +3622,7 @@ function analyzeSelectorFailure(data, selector) {
|
|
|
3598
3622
|
if (keyNestingMap.has(part)) {
|
|
3599
3623
|
const allPaths = keyNestingMap.get(part);
|
|
3600
3624
|
const relevantPaths = allPaths.filter(
|
|
3601
|
-
(
|
|
3625
|
+
(path) => path.includes(validPath) || validPath === ""
|
|
3602
3626
|
);
|
|
3603
3627
|
if (relevantPaths.length > 0) {
|
|
3604
3628
|
suggestions.push(`"${part}" exists at: ${relevantPaths.slice(0, 3).join(", ")}`);
|
|
@@ -3615,7 +3639,7 @@ function analyzeSelectorFailure(data, selector) {
|
|
|
3615
3639
|
analysis.push("PATH VALID BUT FILTER FAILED");
|
|
3616
3640
|
const allPaths = keyNestingMap.get(targetKey);
|
|
3617
3641
|
const deeperPaths = allPaths.filter(
|
|
3618
|
-
(
|
|
3642
|
+
(path) => path.length > selector.replace(/\[.*?\]/g, "").length
|
|
3619
3643
|
);
|
|
3620
3644
|
if (deeperPaths.length > 0) {
|
|
3621
3645
|
suggestions.push(
|
|
@@ -4116,17 +4140,17 @@ var A2AClient = class {
|
|
|
4116
4140
|
* Retry utility functions
|
|
4117
4141
|
*/
|
|
4118
4142
|
async retry(fetchFn) {
|
|
4119
|
-
const
|
|
4120
|
-
if (!
|
|
4143
|
+
const config = this.options.retryConfig;
|
|
4144
|
+
if (!config || config.strategy === "none") {
|
|
4121
4145
|
return await fetchFn();
|
|
4122
4146
|
}
|
|
4123
|
-
const statusCodes =
|
|
4147
|
+
const statusCodes = config.statusCodes || DEFAULT_RETRY_STATUS_CODES;
|
|
4124
4148
|
return this.retryBackoff(
|
|
4125
4149
|
this.wrapFetcher(fetchFn, {
|
|
4126
4150
|
statusCodes,
|
|
4127
|
-
retryConnectionErrors: !!
|
|
4151
|
+
retryConnectionErrors: !!config.retryConnectionErrors
|
|
4128
4152
|
}),
|
|
4129
|
-
|
|
4153
|
+
config.backoff ?? DEFAULT_BACKOFF
|
|
4130
4154
|
);
|
|
4131
4155
|
}
|
|
4132
4156
|
wrapFetcher(fn, options) {
|
|
@@ -4591,25 +4615,25 @@ var A2AClient = class {
|
|
|
4591
4615
|
init_conversations();
|
|
4592
4616
|
init_dbClient();
|
|
4593
4617
|
var logger13 = agentsCore.getLogger("relationships Tools");
|
|
4594
|
-
var generateTransferToolDescription = (
|
|
4595
|
-
return `Hand off the conversation to agent ${
|
|
4618
|
+
var generateTransferToolDescription = (config) => {
|
|
4619
|
+
return `Hand off the conversation to agent ${config.id}.
|
|
4596
4620
|
|
|
4597
4621
|
Agent Information:
|
|
4598
|
-
- ID: ${
|
|
4599
|
-
- Name: ${
|
|
4600
|
-
- Description: ${
|
|
4622
|
+
- ID: ${config.id}
|
|
4623
|
+
- Name: ${config.name ?? "No name provided"}
|
|
4624
|
+
- Description: ${config.description ?? "No description provided"}
|
|
4601
4625
|
|
|
4602
|
-
Hand off the conversation to agent ${
|
|
4626
|
+
Hand off the conversation to agent ${config.id} when the user's request would be better handled by this specialized agent.`;
|
|
4603
4627
|
};
|
|
4604
|
-
var generateDelegateToolDescription = (
|
|
4628
|
+
var generateDelegateToolDescription = (config) => {
|
|
4605
4629
|
return `Delegate a specific task to another agent.
|
|
4606
4630
|
|
|
4607
4631
|
Agent Information:
|
|
4608
|
-
- ID: ${
|
|
4609
|
-
- Name: ${
|
|
4610
|
-
- Description: ${
|
|
4632
|
+
- ID: ${config.id}
|
|
4633
|
+
- Name: ${config.name}
|
|
4634
|
+
- Description: ${config.description || "No description provided"}
|
|
4611
4635
|
|
|
4612
|
-
Delegate a specific task to agent ${
|
|
4636
|
+
Delegate a specific task to agent ${config.id} when it seems like the agent can do relevant work.`;
|
|
4613
4637
|
};
|
|
4614
4638
|
var createTransferToAgentTool = ({
|
|
4615
4639
|
transferConfig,
|
|
@@ -4695,7 +4719,8 @@ function createDelegateToAgentTool({
|
|
|
4695
4719
|
const externalAgent = await agentsCore.getExternalAgent(dbClient_default)({
|
|
4696
4720
|
scopes: {
|
|
4697
4721
|
tenantId,
|
|
4698
|
-
projectId
|
|
4722
|
+
projectId,
|
|
4723
|
+
graphId
|
|
4699
4724
|
},
|
|
4700
4725
|
agentId: delegateConfig.config.id
|
|
4701
4726
|
});
|
|
@@ -4863,16 +4888,16 @@ var SystemPromptBuilder = class {
|
|
|
4863
4888
|
throw new Error(`Template loading failed: ${error}`);
|
|
4864
4889
|
}
|
|
4865
4890
|
}
|
|
4866
|
-
buildSystemPrompt(
|
|
4891
|
+
buildSystemPrompt(config) {
|
|
4867
4892
|
this.loadTemplates();
|
|
4868
|
-
this.validateTemplateVariables(
|
|
4869
|
-
return this.versionConfig.assemble(this.templates,
|
|
4893
|
+
this.validateTemplateVariables(config);
|
|
4894
|
+
return this.versionConfig.assemble(this.templates, config);
|
|
4870
4895
|
}
|
|
4871
|
-
validateTemplateVariables(
|
|
4872
|
-
if (!
|
|
4896
|
+
validateTemplateVariables(config) {
|
|
4897
|
+
if (!config) {
|
|
4873
4898
|
throw new Error("Configuration object is required");
|
|
4874
4899
|
}
|
|
4875
|
-
if (typeof
|
|
4900
|
+
if (typeof config !== "object") {
|
|
4876
4901
|
throw new Error("Configuration must be an object");
|
|
4877
4902
|
}
|
|
4878
4903
|
}
|
|
@@ -4985,20 +5010,20 @@ var V1Config = class _V1Config {
|
|
|
4985
5010
|
const firstItem = tools[0];
|
|
4986
5011
|
return "usageGuidelines" in firstItem && !("config" in firstItem);
|
|
4987
5012
|
}
|
|
4988
|
-
assemble(templates,
|
|
5013
|
+
assemble(templates, config) {
|
|
4989
5014
|
const systemPromptTemplate = templates.get("system-prompt");
|
|
4990
5015
|
if (!systemPromptTemplate) {
|
|
4991
5016
|
throw new Error("System prompt template not loaded");
|
|
4992
5017
|
}
|
|
4993
5018
|
let systemPrompt = systemPromptTemplate;
|
|
4994
|
-
systemPrompt = systemPrompt.replace("{{CORE_INSTRUCTIONS}}",
|
|
4995
|
-
const graphContextSection = this.generateGraphContextSection(
|
|
5019
|
+
systemPrompt = systemPrompt.replace("{{CORE_INSTRUCTIONS}}", config.corePrompt);
|
|
5020
|
+
const graphContextSection = this.generateGraphContextSection(config.graphPrompt);
|
|
4996
5021
|
systemPrompt = systemPrompt.replace("{{GRAPH_CONTEXT_SECTION}}", graphContextSection);
|
|
4997
|
-
const toolData = this.isToolDataArray(
|
|
4998
|
-
const hasDataComponents =
|
|
5022
|
+
const toolData = this.isToolDataArray(config.tools) ? config.tools : _V1Config.convertMcpToolsToToolData(config.tools);
|
|
5023
|
+
const hasDataComponents = config.dataComponents && config.dataComponents.length > 0;
|
|
4999
5024
|
const artifactsSection = this.generateArtifactsSection(
|
|
5000
5025
|
templates,
|
|
5001
|
-
|
|
5026
|
+
config.artifacts,
|
|
5002
5027
|
hasDataComponents
|
|
5003
5028
|
);
|
|
5004
5029
|
systemPrompt = systemPrompt.replace("{{ARTIFACTS_SECTION}}", artifactsSection);
|
|
@@ -5006,20 +5031,20 @@ var V1Config = class _V1Config {
|
|
|
5006
5031
|
systemPrompt = systemPrompt.replace("{{TOOLS_SECTION}}", toolsSection);
|
|
5007
5032
|
const dataComponentsSection = this.generateDataComponentsSection(
|
|
5008
5033
|
templates,
|
|
5009
|
-
|
|
5034
|
+
config.dataComponents
|
|
5010
5035
|
);
|
|
5011
5036
|
systemPrompt = systemPrompt.replace("{{DATA_COMPONENTS_SECTION}}", dataComponentsSection);
|
|
5012
5037
|
const thinkingPreparationSection = this.generateThinkingPreparationSection(
|
|
5013
5038
|
templates,
|
|
5014
|
-
|
|
5039
|
+
config.isThinkingPreparation
|
|
5015
5040
|
);
|
|
5016
5041
|
systemPrompt = systemPrompt.replace(
|
|
5017
5042
|
"{{THINKING_PREPARATION_INSTRUCTIONS}}",
|
|
5018
5043
|
thinkingPreparationSection
|
|
5019
5044
|
);
|
|
5020
|
-
const transferSection = this.generateTransferInstructions(
|
|
5045
|
+
const transferSection = this.generateTransferInstructions(config.hasTransferRelations);
|
|
5021
5046
|
systemPrompt = systemPrompt.replace("{{TRANSFER_INSTRUCTIONS}}", transferSection);
|
|
5022
|
-
const delegationSection = this.generateDelegationInstructions(
|
|
5047
|
+
const delegationSection = this.generateDelegationInstructions(config.hasDelegateRelations);
|
|
5023
5048
|
systemPrompt = systemPrompt.replace("{{DELEGATION_INSTRUCTIONS}}", delegationSection);
|
|
5024
5049
|
return systemPrompt;
|
|
5025
5050
|
}
|
|
@@ -5283,7 +5308,7 @@ function isValidTool(tool4) {
|
|
|
5283
5308
|
return tool4 && typeof tool4 === "object" && typeof tool4.description === "string" && tool4.inputSchema && typeof tool4.execute === "function";
|
|
5284
5309
|
}
|
|
5285
5310
|
var Agent = class {
|
|
5286
|
-
constructor(
|
|
5311
|
+
constructor(config, credentialStoreRegistry) {
|
|
5287
5312
|
__publicField(this, "config");
|
|
5288
5313
|
__publicField(this, "systemPromptBuilder", new SystemPromptBuilder("v1", new V1Config()));
|
|
5289
5314
|
__publicField(this, "responseFormatter");
|
|
@@ -5295,26 +5320,43 @@ var Agent = class {
|
|
|
5295
5320
|
__publicField(this, "isDelegatedAgent", false);
|
|
5296
5321
|
__publicField(this, "contextResolver");
|
|
5297
5322
|
__publicField(this, "credentialStoreRegistry");
|
|
5298
|
-
this.artifactComponents =
|
|
5299
|
-
let processedDataComponents =
|
|
5300
|
-
if (
|
|
5323
|
+
this.artifactComponents = config.artifactComponents || [];
|
|
5324
|
+
let processedDataComponents = config.dataComponents || [];
|
|
5325
|
+
if (processedDataComponents.length > 0) {
|
|
5326
|
+
processedDataComponents.push({
|
|
5327
|
+
id: "text-content",
|
|
5328
|
+
name: "Text",
|
|
5329
|
+
description: "Natural conversational text for the user - write naturally without mentioning technical details. Avoid redundancy and repetition with data components.",
|
|
5330
|
+
props: {
|
|
5331
|
+
type: "object",
|
|
5332
|
+
properties: {
|
|
5333
|
+
text: {
|
|
5334
|
+
type: "string",
|
|
5335
|
+
description: "Natural conversational text - respond as if having a normal conversation, never mention JSON, components, schemas, or technical implementation. Avoid redundancy and repetition with data components."
|
|
5336
|
+
}
|
|
5337
|
+
},
|
|
5338
|
+
required: ["text"]
|
|
5339
|
+
}
|
|
5340
|
+
});
|
|
5341
|
+
}
|
|
5342
|
+
if (this.artifactComponents.length > 0 && config.dataComponents && config.dataComponents.length > 0) {
|
|
5301
5343
|
processedDataComponents = [
|
|
5302
|
-
ArtifactReferenceSchema.getDataComponent(
|
|
5344
|
+
ArtifactReferenceSchema.getDataComponent(config.tenantId, config.projectId),
|
|
5303
5345
|
...processedDataComponents
|
|
5304
5346
|
];
|
|
5305
5347
|
}
|
|
5306
5348
|
this.config = {
|
|
5307
|
-
...
|
|
5349
|
+
...config,
|
|
5308
5350
|
dataComponents: processedDataComponents,
|
|
5309
5351
|
// Set default conversation history if not provided
|
|
5310
|
-
conversationHistoryConfig:
|
|
5352
|
+
conversationHistoryConfig: config.conversationHistoryConfig || createDefaultConversationHistoryConfig()
|
|
5311
5353
|
};
|
|
5312
|
-
this.responseFormatter = new ResponseFormatter(
|
|
5354
|
+
this.responseFormatter = new ResponseFormatter(config.tenantId);
|
|
5313
5355
|
this.credentialStoreRegistry = credentialStoreRegistry;
|
|
5314
5356
|
if (credentialStoreRegistry) {
|
|
5315
5357
|
this.contextResolver = new agentsCore.ContextResolver(
|
|
5316
|
-
|
|
5317
|
-
|
|
5358
|
+
config.tenantId,
|
|
5359
|
+
config.projectId,
|
|
5318
5360
|
dbClient_default,
|
|
5319
5361
|
credentialStoreRegistry
|
|
5320
5362
|
);
|
|
@@ -5567,8 +5609,12 @@ var Agent = class {
|
|
|
5567
5609
|
async getMcpTool(tool4) {
|
|
5568
5610
|
const credentialReferenceId = tool4.credentialReferenceId;
|
|
5569
5611
|
const toolsForAgent = await agentsCore.getToolsForAgent(dbClient_default)({
|
|
5570
|
-
scopes: {
|
|
5571
|
-
|
|
5612
|
+
scopes: {
|
|
5613
|
+
tenantId: this.config.tenantId,
|
|
5614
|
+
projectId: this.config.projectId,
|
|
5615
|
+
graphId: this.config.graphId,
|
|
5616
|
+
agentId: this.config.id
|
|
5617
|
+
}
|
|
5572
5618
|
});
|
|
5573
5619
|
const selectedTools = toolsForAgent.data.find((t) => t.toolId === tool4.id)?.selectedTools || void 0;
|
|
5574
5620
|
let serverConfig;
|
|
@@ -5715,9 +5761,9 @@ var Agent = class {
|
|
|
5715
5761
|
const graphDefinition = await agentsCore.getFullGraphDefinition(dbClient_default)({
|
|
5716
5762
|
scopes: {
|
|
5717
5763
|
tenantId: this.config.tenantId,
|
|
5718
|
-
projectId: this.config.projectId
|
|
5719
|
-
|
|
5720
|
-
|
|
5764
|
+
projectId: this.config.projectId,
|
|
5765
|
+
graphId: this.config.graphId
|
|
5766
|
+
}
|
|
5721
5767
|
});
|
|
5722
5768
|
return graphDefinition?.graphPrompt || void 0;
|
|
5723
5769
|
} catch (error) {
|
|
@@ -5739,14 +5785,16 @@ var Agent = class {
|
|
|
5739
5785
|
const graphDefinition = await agentsCore.getFullGraphDefinition(dbClient_default)({
|
|
5740
5786
|
scopes: {
|
|
5741
5787
|
tenantId: this.config.tenantId,
|
|
5742
|
-
projectId: this.config.projectId
|
|
5743
|
-
|
|
5744
|
-
|
|
5788
|
+
projectId: this.config.projectId,
|
|
5789
|
+
graphId: this.config.graphId
|
|
5790
|
+
}
|
|
5745
5791
|
});
|
|
5746
5792
|
if (!graphDefinition) {
|
|
5747
5793
|
return false;
|
|
5748
5794
|
}
|
|
5749
|
-
return
|
|
5795
|
+
return Object.values(graphDefinition.agents).some(
|
|
5796
|
+
(agent) => "artifactComponents" in agent && agent.artifactComponents && agent.artifactComponents.length > 0
|
|
5797
|
+
);
|
|
5750
5798
|
} catch (error) {
|
|
5751
5799
|
logger15.warn(
|
|
5752
5800
|
{
|
|
@@ -5774,7 +5822,8 @@ Key requirements:
|
|
|
5774
5822
|
- Mix artifact references throughout your dataComponents array
|
|
5775
5823
|
- Each artifact reference must use EXACT IDs from tool outputs
|
|
5776
5824
|
- Reference artifacts that directly support the adjacent information
|
|
5777
|
-
- Follow the pattern: Data \u2192 Supporting Artifact \u2192 Next Data \u2192 Next Artifact
|
|
5825
|
+
- Follow the pattern: Data \u2192 Supporting Artifact \u2192 Next Data \u2192 Next Artifact
|
|
5826
|
+
- IMPORTANT: In Text components, write naturally as if having a conversation - do NOT mention components, schemas, JSON, structured data, or any technical implementation details`;
|
|
5778
5827
|
}
|
|
5779
5828
|
if (hasDataComponents && !hasArtifactComponents) {
|
|
5780
5829
|
return `Generate the final structured JSON response using the configured data components. Organize the information from the research above into the appropriate structured format based on the available component schemas.
|
|
@@ -5782,7 +5831,8 @@ Key requirements:
|
|
|
5782
5831
|
Key requirements:
|
|
5783
5832
|
- Use the exact component structure and property names
|
|
5784
5833
|
- Fill in all relevant data from the research
|
|
5785
|
-
- Ensure data is organized logically and completely
|
|
5834
|
+
- Ensure data is organized logically and completely
|
|
5835
|
+
- IMPORTANT: In Text components, write naturally as if having a conversation - do NOT mention components, schemas, JSON, structured data, or any technical implementation details`;
|
|
5786
5836
|
}
|
|
5787
5837
|
if (!hasDataComponents && hasArtifactComponents) {
|
|
5788
5838
|
return `Generate the final structured response with artifact references based on the research above. Use the artifact reference component to cite relevant information with exact artifact_id and task_id values from the tool outputs.
|
|
@@ -5792,7 +5842,7 @@ Key requirements:
|
|
|
5792
5842
|
- Reference artifacts that support your response
|
|
5793
5843
|
- Never make up or modify artifact IDs`;
|
|
5794
5844
|
}
|
|
5795
|
-
return `Generate the final response based on the research above.`;
|
|
5845
|
+
return `Generate the final response based on the research above. Write naturally as if having a conversation.`;
|
|
5796
5846
|
}
|
|
5797
5847
|
async buildSystemPrompt(runtimeContext, excludeDataComponents = false) {
|
|
5798
5848
|
const conversationId = runtimeContext?.metadata?.conversationId || runtimeContext?.contextId;
|
|
@@ -5862,7 +5912,7 @@ Key requirements:
|
|
|
5862
5912
|
);
|
|
5863
5913
|
}
|
|
5864
5914
|
}
|
|
5865
|
-
const
|
|
5915
|
+
const config = {
|
|
5866
5916
|
corePrompt: processedPrompt,
|
|
5867
5917
|
graphPrompt,
|
|
5868
5918
|
tools: toolDefinitions,
|
|
@@ -5872,7 +5922,7 @@ Key requirements:
|
|
|
5872
5922
|
hasTransferRelations: (this.config.transferRelations?.length ?? 0) > 0,
|
|
5873
5923
|
hasDelegateRelations: (this.config.delegateRelations?.length ?? 0) > 0
|
|
5874
5924
|
};
|
|
5875
|
-
return await this.systemPromptBuilder.buildSystemPrompt(
|
|
5925
|
+
return await this.systemPromptBuilder.buildSystemPrompt(config);
|
|
5876
5926
|
}
|
|
5877
5927
|
getArtifactTools() {
|
|
5878
5928
|
return ai.tool({
|
|
@@ -5943,9 +5993,9 @@ Key requirements:
|
|
|
5943
5993
|
return await agentsCore.graphHasArtifactComponents(dbClient_default)({
|
|
5944
5994
|
scopes: {
|
|
5945
5995
|
tenantId: this.config.tenantId,
|
|
5946
|
-
projectId: this.config.projectId
|
|
5947
|
-
|
|
5948
|
-
|
|
5996
|
+
projectId: this.config.projectId,
|
|
5997
|
+
graphId: this.config.graphId
|
|
5998
|
+
}
|
|
5949
5999
|
});
|
|
5950
6000
|
} catch (error) {
|
|
5951
6001
|
logger15.error(
|
|
@@ -6291,35 +6341,94 @@ ${output}`;
|
|
|
6291
6341
|
this.getStructuredOutputModel()
|
|
6292
6342
|
);
|
|
6293
6343
|
const phase2TimeoutMs = structuredModelSettings.maxDuration ? structuredModelSettings.maxDuration * 1e3 : CONSTANTS.PHASE_2_TIMEOUT_MS;
|
|
6294
|
-
const
|
|
6295
|
-
|
|
6296
|
-
|
|
6297
|
-
|
|
6298
|
-
|
|
6299
|
-
|
|
6300
|
-
|
|
6301
|
-
|
|
6302
|
-
|
|
6303
|
-
|
|
6304
|
-
|
|
6305
|
-
|
|
6306
|
-
|
|
6307
|
-
|
|
6308
|
-
|
|
6309
|
-
|
|
6310
|
-
|
|
6311
|
-
|
|
6312
|
-
|
|
6313
|
-
|
|
6344
|
+
const shouldStreamPhase2 = this.getStreamingHelper();
|
|
6345
|
+
if (shouldStreamPhase2) {
|
|
6346
|
+
const streamResult = ai.streamObject({
|
|
6347
|
+
...structuredModelSettings,
|
|
6348
|
+
messages: [
|
|
6349
|
+
{ role: "user", content: userMessage },
|
|
6350
|
+
...reasoningFlow,
|
|
6351
|
+
{
|
|
6352
|
+
role: "user",
|
|
6353
|
+
content: await this.buildPhase2SystemPrompt()
|
|
6354
|
+
}
|
|
6355
|
+
],
|
|
6356
|
+
schema: z5.z.object({
|
|
6357
|
+
dataComponents: z5.z.array(dataComponentsSchema)
|
|
6358
|
+
}),
|
|
6359
|
+
experimental_telemetry: {
|
|
6360
|
+
isEnabled: true,
|
|
6361
|
+
functionId: this.config.id,
|
|
6362
|
+
recordInputs: true,
|
|
6363
|
+
recordOutputs: true,
|
|
6364
|
+
metadata: {
|
|
6365
|
+
phase: "structured_generation"
|
|
6366
|
+
}
|
|
6367
|
+
},
|
|
6368
|
+
abortSignal: AbortSignal.timeout(phase2TimeoutMs)
|
|
6369
|
+
});
|
|
6370
|
+
const streamHelper = this.getStreamingHelper();
|
|
6371
|
+
if (!streamHelper) {
|
|
6372
|
+
throw new Error("Stream helper is unexpectedly undefined in streaming context");
|
|
6373
|
+
}
|
|
6374
|
+
const parser = new IncrementalStreamParser(
|
|
6375
|
+
streamHelper,
|
|
6376
|
+
this.config.tenantId,
|
|
6377
|
+
contextId
|
|
6378
|
+
);
|
|
6379
|
+
for await (const delta of streamResult.partialObjectStream) {
|
|
6380
|
+
if (delta) {
|
|
6381
|
+
await parser.processObjectDelta(delta);
|
|
6314
6382
|
}
|
|
6315
|
-
}
|
|
6316
|
-
|
|
6317
|
-
|
|
6318
|
-
|
|
6319
|
-
|
|
6320
|
-
|
|
6321
|
-
|
|
6322
|
-
|
|
6383
|
+
}
|
|
6384
|
+
await parser.finalize();
|
|
6385
|
+
const structuredResponse = await streamResult;
|
|
6386
|
+
const collectedParts = parser.getCollectedParts();
|
|
6387
|
+
if (collectedParts.length > 0) {
|
|
6388
|
+
response.formattedContent = {
|
|
6389
|
+
parts: collectedParts.map((part) => ({
|
|
6390
|
+
kind: part.kind,
|
|
6391
|
+
...part.kind === "text" && { text: part.text },
|
|
6392
|
+
...part.kind === "data" && { data: part.data }
|
|
6393
|
+
}))
|
|
6394
|
+
};
|
|
6395
|
+
}
|
|
6396
|
+
response = {
|
|
6397
|
+
...response,
|
|
6398
|
+
object: structuredResponse.object
|
|
6399
|
+
};
|
|
6400
|
+
textResponse = JSON.stringify(structuredResponse.object, null, 2);
|
|
6401
|
+
} else {
|
|
6402
|
+
const structuredResponse = await ai.generateObject({
|
|
6403
|
+
...structuredModelSettings,
|
|
6404
|
+
messages: [
|
|
6405
|
+
{ role: "user", content: userMessage },
|
|
6406
|
+
...reasoningFlow,
|
|
6407
|
+
{
|
|
6408
|
+
role: "user",
|
|
6409
|
+
content: await this.buildPhase2SystemPrompt()
|
|
6410
|
+
}
|
|
6411
|
+
],
|
|
6412
|
+
schema: z5.z.object({
|
|
6413
|
+
dataComponents: z5.z.array(dataComponentsSchema)
|
|
6414
|
+
}),
|
|
6415
|
+
experimental_telemetry: {
|
|
6416
|
+
isEnabled: true,
|
|
6417
|
+
functionId: this.config.id,
|
|
6418
|
+
recordInputs: true,
|
|
6419
|
+
recordOutputs: true,
|
|
6420
|
+
metadata: {
|
|
6421
|
+
phase: "structured_generation"
|
|
6422
|
+
}
|
|
6423
|
+
},
|
|
6424
|
+
abortSignal: AbortSignal.timeout(phase2TimeoutMs)
|
|
6425
|
+
});
|
|
6426
|
+
response = {
|
|
6427
|
+
...response,
|
|
6428
|
+
object: structuredResponse.object
|
|
6429
|
+
};
|
|
6430
|
+
textResponse = JSON.stringify(structuredResponse.object, null, 2);
|
|
6431
|
+
}
|
|
6323
6432
|
} else {
|
|
6324
6433
|
textResponse = response.text || "";
|
|
6325
6434
|
}
|
|
@@ -6365,42 +6474,6 @@ ${output}`;
|
|
|
6365
6474
|
}
|
|
6366
6475
|
};
|
|
6367
6476
|
|
|
6368
|
-
// src/utils/model-resolver.ts
|
|
6369
|
-
init_dbClient();
|
|
6370
|
-
async function resolveModelConfig(graphId, agent) {
|
|
6371
|
-
if (agent.models?.base?.model) {
|
|
6372
|
-
return {
|
|
6373
|
-
base: agent.models.base,
|
|
6374
|
-
structuredOutput: agent.models.structuredOutput || agent.models.base,
|
|
6375
|
-
summarizer: agent.models.summarizer || agent.models.base
|
|
6376
|
-
};
|
|
6377
|
-
}
|
|
6378
|
-
const graph = await agentsCore.getAgentGraph(dbClient_default)({
|
|
6379
|
-
scopes: { tenantId: agent.tenantId, projectId: agent.projectId },
|
|
6380
|
-
graphId
|
|
6381
|
-
});
|
|
6382
|
-
if (graph?.models?.base?.model) {
|
|
6383
|
-
return {
|
|
6384
|
-
base: graph.models.base,
|
|
6385
|
-
structuredOutput: agent.models?.structuredOutput || graph.models.structuredOutput || graph.models.base,
|
|
6386
|
-
summarizer: agent.models?.summarizer || graph.models.summarizer || graph.models.base
|
|
6387
|
-
};
|
|
6388
|
-
}
|
|
6389
|
-
const project = await agentsCore.getProject(dbClient_default)({
|
|
6390
|
-
scopes: { tenantId: agent.tenantId, projectId: agent.projectId }
|
|
6391
|
-
});
|
|
6392
|
-
if (project?.models?.base?.model) {
|
|
6393
|
-
return {
|
|
6394
|
-
base: project.models.base,
|
|
6395
|
-
structuredOutput: agent.models?.structuredOutput || project.models.structuredOutput || project.models.base,
|
|
6396
|
-
summarizer: agent.models?.summarizer || project.models.summarizer || project.models.base
|
|
6397
|
-
};
|
|
6398
|
-
}
|
|
6399
|
-
throw new Error(
|
|
6400
|
-
"Base model configuration is required. Please configure models at the project level."
|
|
6401
|
-
);
|
|
6402
|
-
}
|
|
6403
|
-
|
|
6404
6477
|
// src/agents/generateTaskHandler.ts
|
|
6405
6478
|
function parseEmbeddedJson(data) {
|
|
6406
6479
|
return traverse__default.default(data).map(function(x) {
|
|
@@ -6413,7 +6486,7 @@ function parseEmbeddedJson(data) {
|
|
|
6413
6486
|
});
|
|
6414
6487
|
}
|
|
6415
6488
|
var logger16 = agentsCore.getLogger("generateTaskHandler");
|
|
6416
|
-
var createTaskHandler = (
|
|
6489
|
+
var createTaskHandler = (config, credentialStoreRegistry) => {
|
|
6417
6490
|
return async (task) => {
|
|
6418
6491
|
try {
|
|
6419
6492
|
const userMessage = task.input.parts.filter((part) => part.text).map((part) => part.text).join(" ");
|
|
@@ -6434,32 +6507,35 @@ var createTaskHandler = (config2, credentialStoreRegistry) => {
|
|
|
6434
6507
|
] = await Promise.all([
|
|
6435
6508
|
agentsCore.getRelatedAgentsForGraph(dbClient_default)({
|
|
6436
6509
|
scopes: {
|
|
6437
|
-
tenantId:
|
|
6438
|
-
projectId:
|
|
6510
|
+
tenantId: config.tenantId,
|
|
6511
|
+
projectId: config.projectId,
|
|
6512
|
+
graphId: config.graphId
|
|
6439
6513
|
},
|
|
6440
|
-
|
|
6441
|
-
agentId: config2.agentId
|
|
6514
|
+
agentId: config.agentId
|
|
6442
6515
|
}),
|
|
6443
6516
|
agentsCore.getToolsForAgent(dbClient_default)({
|
|
6444
6517
|
scopes: {
|
|
6445
|
-
tenantId:
|
|
6446
|
-
projectId:
|
|
6447
|
-
|
|
6448
|
-
|
|
6518
|
+
tenantId: config.tenantId,
|
|
6519
|
+
projectId: config.projectId,
|
|
6520
|
+
graphId: config.graphId,
|
|
6521
|
+
agentId: config.agentId
|
|
6522
|
+
}
|
|
6449
6523
|
}),
|
|
6450
6524
|
agentsCore.getDataComponentsForAgent(dbClient_default)({
|
|
6451
6525
|
scopes: {
|
|
6452
|
-
tenantId:
|
|
6453
|
-
projectId:
|
|
6454
|
-
|
|
6455
|
-
|
|
6526
|
+
tenantId: config.tenantId,
|
|
6527
|
+
projectId: config.projectId,
|
|
6528
|
+
graphId: config.graphId,
|
|
6529
|
+
agentId: config.agentId
|
|
6530
|
+
}
|
|
6456
6531
|
}),
|
|
6457
6532
|
agentsCore.getArtifactComponentsForAgent(dbClient_default)({
|
|
6458
6533
|
scopes: {
|
|
6459
|
-
tenantId:
|
|
6460
|
-
projectId:
|
|
6461
|
-
|
|
6462
|
-
|
|
6534
|
+
tenantId: config.tenantId,
|
|
6535
|
+
projectId: config.projectId,
|
|
6536
|
+
graphId: config.graphId,
|
|
6537
|
+
agentId: config.agentId
|
|
6538
|
+
}
|
|
6463
6539
|
})
|
|
6464
6540
|
]);
|
|
6465
6541
|
logger16.info({ toolsForAgent, internalRelations, externalRelations }, "agent stuff");
|
|
@@ -6467,13 +6543,16 @@ var createTaskHandler = (config2, credentialStoreRegistry) => {
|
|
|
6467
6543
|
internalRelations.map(async (relation) => {
|
|
6468
6544
|
try {
|
|
6469
6545
|
const relatedAgent = await agentsCore.getAgentById(dbClient_default)({
|
|
6470
|
-
scopes: {
|
|
6546
|
+
scopes: {
|
|
6547
|
+
tenantId: config.tenantId,
|
|
6548
|
+
projectId: config.projectId,
|
|
6549
|
+
graphId: config.graphId
|
|
6550
|
+
},
|
|
6471
6551
|
agentId: relation.id
|
|
6472
6552
|
});
|
|
6473
6553
|
if (relatedAgent) {
|
|
6474
6554
|
const relatedAgentRelations = await agentsCore.getRelatedAgentsForGraph(dbClient_default)({
|
|
6475
|
-
scopes: { tenantId:
|
|
6476
|
-
graphId: config2.graphId,
|
|
6555
|
+
scopes: { tenantId: config.tenantId, projectId: config.projectId, graphId: config.graphId },
|
|
6477
6556
|
agentId: relation.id
|
|
6478
6557
|
});
|
|
6479
6558
|
const enhancedDescription = generateDescriptionWithTransfers(
|
|
@@ -6489,29 +6568,29 @@ var createTaskHandler = (config2, credentialStoreRegistry) => {
|
|
|
6489
6568
|
return relation;
|
|
6490
6569
|
})
|
|
6491
6570
|
);
|
|
6492
|
-
const agentPrompt = "prompt" in
|
|
6493
|
-
const models = "models" in
|
|
6494
|
-
const stopWhen = "stopWhen" in
|
|
6571
|
+
const agentPrompt = "prompt" in config.agentSchema ? config.agentSchema.prompt : "";
|
|
6572
|
+
const models = "models" in config.agentSchema ? config.agentSchema.models : void 0;
|
|
6573
|
+
const stopWhen = "stopWhen" in config.agentSchema ? config.agentSchema.stopWhen : void 0;
|
|
6495
6574
|
const agent = new Agent(
|
|
6496
6575
|
{
|
|
6497
|
-
id:
|
|
6498
|
-
tenantId:
|
|
6499
|
-
projectId:
|
|
6500
|
-
graphId:
|
|
6501
|
-
baseUrl:
|
|
6502
|
-
apiKey:
|
|
6503
|
-
name:
|
|
6504
|
-
description:
|
|
6576
|
+
id: config.agentId,
|
|
6577
|
+
tenantId: config.tenantId,
|
|
6578
|
+
projectId: config.projectId,
|
|
6579
|
+
graphId: config.graphId,
|
|
6580
|
+
baseUrl: config.baseUrl,
|
|
6581
|
+
apiKey: config.apiKey,
|
|
6582
|
+
name: config.name,
|
|
6583
|
+
description: config.description || "",
|
|
6505
6584
|
agentPrompt,
|
|
6506
6585
|
models: models || void 0,
|
|
6507
6586
|
stopWhen: stopWhen || void 0,
|
|
6508
6587
|
agentRelations: enhancedInternalRelations.map((relation) => ({
|
|
6509
6588
|
id: relation.id,
|
|
6510
|
-
tenantId:
|
|
6511
|
-
projectId:
|
|
6512
|
-
graphId:
|
|
6513
|
-
baseUrl:
|
|
6514
|
-
apiKey:
|
|
6589
|
+
tenantId: config.tenantId,
|
|
6590
|
+
projectId: config.projectId,
|
|
6591
|
+
graphId: config.graphId,
|
|
6592
|
+
baseUrl: config.baseUrl,
|
|
6593
|
+
apiKey: config.apiKey,
|
|
6515
6594
|
name: relation.name,
|
|
6516
6595
|
description: relation.description,
|
|
6517
6596
|
agentPrompt: "",
|
|
@@ -6520,12 +6599,12 @@ var createTaskHandler = (config2, credentialStoreRegistry) => {
|
|
|
6520
6599
|
transferRelations: []
|
|
6521
6600
|
})),
|
|
6522
6601
|
transferRelations: enhancedInternalRelations.filter((relation) => relation.relationType === "transfer").map((relation) => ({
|
|
6523
|
-
baseUrl:
|
|
6524
|
-
apiKey:
|
|
6602
|
+
baseUrl: config.baseUrl,
|
|
6603
|
+
apiKey: config.apiKey,
|
|
6525
6604
|
id: relation.id,
|
|
6526
|
-
tenantId:
|
|
6527
|
-
projectId:
|
|
6528
|
-
graphId:
|
|
6605
|
+
tenantId: config.tenantId,
|
|
6606
|
+
projectId: config.projectId,
|
|
6607
|
+
graphId: config.graphId,
|
|
6529
6608
|
name: relation.name,
|
|
6530
6609
|
description: relation.description,
|
|
6531
6610
|
agentPrompt: "",
|
|
@@ -6539,11 +6618,11 @@ var createTaskHandler = (config2, credentialStoreRegistry) => {
|
|
|
6539
6618
|
type: "internal",
|
|
6540
6619
|
config: {
|
|
6541
6620
|
id: relation.id,
|
|
6542
|
-
tenantId:
|
|
6543
|
-
projectId:
|
|
6544
|
-
graphId:
|
|
6545
|
-
baseUrl:
|
|
6546
|
-
apiKey:
|
|
6621
|
+
tenantId: config.tenantId,
|
|
6622
|
+
projectId: config.projectId,
|
|
6623
|
+
graphId: config.graphId,
|
|
6624
|
+
baseUrl: config.baseUrl,
|
|
6625
|
+
apiKey: config.apiKey,
|
|
6547
6626
|
name: relation.name,
|
|
6548
6627
|
description: relation.description,
|
|
6549
6628
|
agentPrompt: "",
|
|
@@ -6578,8 +6657,8 @@ var createTaskHandler = (config2, credentialStoreRegistry) => {
|
|
|
6578
6657
|
// All tools are now handled via MCP servers
|
|
6579
6658
|
dataComponents,
|
|
6580
6659
|
artifactComponents,
|
|
6581
|
-
contextConfigId:
|
|
6582
|
-
conversationHistoryConfig:
|
|
6660
|
+
contextConfigId: config.contextConfigId || void 0,
|
|
6661
|
+
conversationHistoryConfig: config.conversationHistoryConfig
|
|
6583
6662
|
},
|
|
6584
6663
|
credentialStoreRegistry
|
|
6585
6664
|
);
|
|
@@ -6592,7 +6671,7 @@ var createTaskHandler = (config2, credentialStoreRegistry) => {
|
|
|
6592
6671
|
{
|
|
6593
6672
|
taskId: task.id,
|
|
6594
6673
|
extractedContextId: contextId,
|
|
6595
|
-
agentId:
|
|
6674
|
+
agentId: config.agentId
|
|
6596
6675
|
},
|
|
6597
6676
|
"Extracted contextId from task ID for delegation"
|
|
6598
6677
|
);
|
|
@@ -6605,7 +6684,7 @@ var createTaskHandler = (config2, credentialStoreRegistry) => {
|
|
|
6605
6684
|
agent.setDelegationStatus(isDelegation);
|
|
6606
6685
|
if (isDelegation) {
|
|
6607
6686
|
logger16.info(
|
|
6608
|
-
{ agentId:
|
|
6687
|
+
{ agentId: config.agentId, taskId: task.id },
|
|
6609
6688
|
"Delegated agent - streaming disabled"
|
|
6610
6689
|
);
|
|
6611
6690
|
}
|
|
@@ -6617,7 +6696,7 @@ var createTaskHandler = (config2, credentialStoreRegistry) => {
|
|
|
6617
6696
|
threadId: contextId,
|
|
6618
6697
|
// using conversationId as threadId for now
|
|
6619
6698
|
streamRequestId,
|
|
6620
|
-
...
|
|
6699
|
+
...config.apiKey ? { apiKey: config.apiKey } : {}
|
|
6621
6700
|
}
|
|
6622
6701
|
});
|
|
6623
6702
|
const stepContents = response.steps && Array.isArray(response.steps) ? response.steps.flatMap((step) => {
|
|
@@ -6696,16 +6775,17 @@ var createTaskHandlerConfig = async (params) => {
|
|
|
6696
6775
|
const agent = await agentsCore.getAgentById(dbClient_default)({
|
|
6697
6776
|
scopes: {
|
|
6698
6777
|
tenantId: params.tenantId,
|
|
6699
|
-
projectId: params.projectId
|
|
6778
|
+
projectId: params.projectId,
|
|
6779
|
+
graphId: params.graphId
|
|
6700
6780
|
},
|
|
6701
6781
|
agentId: params.agentId
|
|
6702
6782
|
});
|
|
6703
|
-
const agentGraph = await agentsCore.
|
|
6783
|
+
const agentGraph = await agentsCore.getAgentGraphById(dbClient_default)({
|
|
6704
6784
|
scopes: {
|
|
6705
6785
|
tenantId: params.tenantId,
|
|
6706
|
-
projectId: params.projectId
|
|
6707
|
-
|
|
6708
|
-
|
|
6786
|
+
projectId: params.projectId,
|
|
6787
|
+
graphId: params.graphId
|
|
6788
|
+
}
|
|
6709
6789
|
});
|
|
6710
6790
|
if (!agent) {
|
|
6711
6791
|
throw new Error(`Agent not found: ${params.agentId}`);
|
|
@@ -6745,10 +6825,14 @@ async function hydrateGraph({
|
|
|
6745
6825
|
apiKey
|
|
6746
6826
|
}) {
|
|
6747
6827
|
try {
|
|
6828
|
+
if (!dbGraph.defaultAgentId) {
|
|
6829
|
+
throw new Error(`Graph ${dbGraph.id} does not have a default agent configured`);
|
|
6830
|
+
}
|
|
6748
6831
|
const defaultAgent = await agentsCore.getAgentById(dbClient_default)({
|
|
6749
6832
|
scopes: {
|
|
6750
6833
|
tenantId: dbGraph.tenantId,
|
|
6751
|
-
projectId: dbGraph.projectId
|
|
6834
|
+
projectId: dbGraph.projectId,
|
|
6835
|
+
graphId: dbGraph.id
|
|
6752
6836
|
},
|
|
6753
6837
|
agentId: dbGraph.defaultAgentId
|
|
6754
6838
|
});
|
|
@@ -6803,7 +6887,7 @@ async function hydrateGraph({
|
|
|
6803
6887
|
}
|
|
6804
6888
|
async function getRegisteredGraph(executionContext) {
|
|
6805
6889
|
const { tenantId, projectId, graphId, baseUrl, apiKey } = executionContext;
|
|
6806
|
-
const dbGraph = await agentsCore.
|
|
6890
|
+
const dbGraph = await agentsCore.getAgentGraphById(dbClient_default)({ scopes: { tenantId, projectId, graphId } });
|
|
6807
6891
|
if (!dbGraph) {
|
|
6808
6892
|
return null;
|
|
6809
6893
|
}
|
|
@@ -6862,6 +6946,7 @@ app.openapi(
|
|
|
6862
6946
|
);
|
|
6863
6947
|
const executionContext = agentsCore.getRequestExecutionContext(c);
|
|
6864
6948
|
const { tenantId, projectId, graphId, agentId } = executionContext;
|
|
6949
|
+
console.dir("executionContext", executionContext);
|
|
6865
6950
|
if (agentId) {
|
|
6866
6951
|
logger17.info(
|
|
6867
6952
|
{
|
|
@@ -6877,7 +6962,10 @@ app.openapi(
|
|
|
6877
6962
|
const agent = await getRegisteredAgent(executionContext, credentialStores);
|
|
6878
6963
|
logger17.info({ agent }, "agent registered: well-known agent.json");
|
|
6879
6964
|
if (!agent) {
|
|
6880
|
-
|
|
6965
|
+
throw agentsCore.createApiError({
|
|
6966
|
+
code: "not_found",
|
|
6967
|
+
message: "Agent not found"
|
|
6968
|
+
});
|
|
6881
6969
|
}
|
|
6882
6970
|
return c.json(agent.agentCard);
|
|
6883
6971
|
} else {
|
|
@@ -6892,7 +6980,10 @@ app.openapi(
|
|
|
6892
6980
|
);
|
|
6893
6981
|
const graph = await getRegisteredGraph(executionContext);
|
|
6894
6982
|
if (!graph) {
|
|
6895
|
-
|
|
6983
|
+
throw agentsCore.createApiError({
|
|
6984
|
+
code: "not_found",
|
|
6985
|
+
message: "Graph not found"
|
|
6986
|
+
});
|
|
6896
6987
|
}
|
|
6897
6988
|
return c.json(graph.agentCard);
|
|
6898
6989
|
}
|
|
@@ -6949,8 +7040,7 @@ app.post("/a2a", async (c) => {
|
|
|
6949
7040
|
"graph-level a2a endpoint"
|
|
6950
7041
|
);
|
|
6951
7042
|
const graph = await agentsCore.getAgentGraphWithDefaultAgent(dbClient_default)({
|
|
6952
|
-
scopes: { tenantId, projectId }
|
|
6953
|
-
graphId
|
|
7043
|
+
scopes: { tenantId, projectId, graphId }
|
|
6954
7044
|
});
|
|
6955
7045
|
if (!graph) {
|
|
6956
7046
|
return c.json(
|
|
@@ -6962,6 +7052,16 @@ app.post("/a2a", async (c) => {
|
|
|
6962
7052
|
404
|
|
6963
7053
|
);
|
|
6964
7054
|
}
|
|
7055
|
+
if (!graph.defaultAgentId) {
|
|
7056
|
+
return c.json(
|
|
7057
|
+
{
|
|
7058
|
+
jsonrpc: "2.0",
|
|
7059
|
+
error: { code: -32004, message: "Graph does not have a default agent configured" },
|
|
7060
|
+
id: null
|
|
7061
|
+
},
|
|
7062
|
+
400
|
|
7063
|
+
);
|
|
7064
|
+
}
|
|
6965
7065
|
executionContext.agentId = graph.defaultAgentId;
|
|
6966
7066
|
const credentialStores = c.get("credentialStores");
|
|
6967
7067
|
const defaultAgent = await getRegisteredAgent(executionContext, credentialStores);
|
|
@@ -7005,6 +7105,9 @@ function isTransferResponse(result) {
|
|
|
7005
7105
|
(artifact) => artifact.parts.some((part) => part.kind === "data" && part.data?.type === "transfer")
|
|
7006
7106
|
);
|
|
7007
7107
|
}
|
|
7108
|
+
|
|
7109
|
+
// src/handlers/executionHandler.ts
|
|
7110
|
+
init_dbClient();
|
|
7008
7111
|
var SSEStreamHelper = class {
|
|
7009
7112
|
constructor(stream2, requestId2, timestamp) {
|
|
7010
7113
|
this.stream = stream2;
|
|
@@ -7012,7 +7115,7 @@ var SSEStreamHelper = class {
|
|
|
7012
7115
|
this.timestamp = timestamp;
|
|
7013
7116
|
// Stream queuing for proper event ordering
|
|
7014
7117
|
__publicField(this, "isTextStreaming", false);
|
|
7015
|
-
__publicField(this, "
|
|
7118
|
+
__publicField(this, "queuedEvents", []);
|
|
7016
7119
|
}
|
|
7017
7120
|
/**
|
|
7018
7121
|
* Write the initial role message
|
|
@@ -7077,9 +7180,10 @@ var SSEStreamHelper = class {
|
|
|
7077
7180
|
await this.writeContent(JSON.stringify(data));
|
|
7078
7181
|
}
|
|
7079
7182
|
/**
|
|
7080
|
-
* Write error message
|
|
7183
|
+
* Write error message or error event
|
|
7081
7184
|
*/
|
|
7082
|
-
async writeError(
|
|
7185
|
+
async writeError(error) {
|
|
7186
|
+
const errorMessage = typeof error === "string" ? error : error.message;
|
|
7083
7187
|
await this.writeContent(`
|
|
7084
7188
|
|
|
7085
7189
|
${errorMessage}`);
|
|
@@ -7103,22 +7207,6 @@ ${errorMessage}`);
|
|
|
7103
7207
|
})
|
|
7104
7208
|
});
|
|
7105
7209
|
}
|
|
7106
|
-
/**
|
|
7107
|
-
* Write the final [DONE] message
|
|
7108
|
-
*/
|
|
7109
|
-
async writeDone() {
|
|
7110
|
-
await this.stream.writeSSE({
|
|
7111
|
-
data: "[DONE]"
|
|
7112
|
-
});
|
|
7113
|
-
}
|
|
7114
|
-
/**
|
|
7115
|
-
* Complete the stream with finish reason and done message
|
|
7116
|
-
*/
|
|
7117
|
-
async complete(finishReason = "stop") {
|
|
7118
|
-
await this.flushQueuedOperations();
|
|
7119
|
-
await this.writeCompletion(finishReason);
|
|
7120
|
-
await this.writeDone();
|
|
7121
|
-
}
|
|
7122
7210
|
async writeData(type, data) {
|
|
7123
7211
|
await this.stream.writeSSE({
|
|
7124
7212
|
data: JSON.stringify({
|
|
@@ -7137,16 +7225,23 @@ ${errorMessage}`);
|
|
|
7137
7225
|
})
|
|
7138
7226
|
});
|
|
7139
7227
|
}
|
|
7140
|
-
async
|
|
7141
|
-
if (
|
|
7142
|
-
|
|
7143
|
-
type:
|
|
7144
|
-
|
|
7145
|
-
|
|
7146
|
-
|
|
7228
|
+
async writeSummary(summary) {
|
|
7229
|
+
if (this.isTextStreaming) {
|
|
7230
|
+
this.queuedEvents.push({
|
|
7231
|
+
type: "data-summary",
|
|
7232
|
+
event: summary
|
|
7233
|
+
});
|
|
7234
|
+
return;
|
|
7147
7235
|
}
|
|
7236
|
+
await this.flushQueuedOperations();
|
|
7237
|
+
await this.writeData("data-summary", summary);
|
|
7238
|
+
}
|
|
7239
|
+
async writeOperation(operation) {
|
|
7148
7240
|
if (this.isTextStreaming) {
|
|
7149
|
-
this.
|
|
7241
|
+
this.queuedEvents.push({
|
|
7242
|
+
type: "data-operation",
|
|
7243
|
+
event: operation
|
|
7244
|
+
});
|
|
7150
7245
|
return;
|
|
7151
7246
|
}
|
|
7152
7247
|
await this.flushQueuedOperations();
|
|
@@ -7156,15 +7251,31 @@ ${errorMessage}`);
|
|
|
7156
7251
|
* Flush all queued operations in order after text streaming completes
|
|
7157
7252
|
*/
|
|
7158
7253
|
async flushQueuedOperations() {
|
|
7159
|
-
if (this.
|
|
7254
|
+
if (this.queuedEvents.length === 0) {
|
|
7160
7255
|
return;
|
|
7161
7256
|
}
|
|
7162
|
-
const
|
|
7163
|
-
this.
|
|
7164
|
-
for (const
|
|
7165
|
-
await this.writeData(
|
|
7257
|
+
const eventsToFlush = [...this.queuedEvents];
|
|
7258
|
+
this.queuedEvents = [];
|
|
7259
|
+
for (const event of eventsToFlush) {
|
|
7260
|
+
await this.writeData(event.type, event.event);
|
|
7166
7261
|
}
|
|
7167
7262
|
}
|
|
7263
|
+
/**
|
|
7264
|
+
* Write the final [DONE] message
|
|
7265
|
+
*/
|
|
7266
|
+
async writeDone() {
|
|
7267
|
+
await this.stream.writeSSE({
|
|
7268
|
+
data: "[DONE]"
|
|
7269
|
+
});
|
|
7270
|
+
}
|
|
7271
|
+
/**
|
|
7272
|
+
* Complete the stream with finish reason and done message
|
|
7273
|
+
*/
|
|
7274
|
+
async complete(finishReason = "stop") {
|
|
7275
|
+
await this.flushQueuedOperations();
|
|
7276
|
+
await this.writeCompletion(finishReason);
|
|
7277
|
+
await this.writeDone();
|
|
7278
|
+
}
|
|
7168
7279
|
};
|
|
7169
7280
|
function createSSEStreamHelper(stream2, requestId2, timestamp) {
|
|
7170
7281
|
return new SSEStreamHelper(stream2, requestId2, timestamp);
|
|
@@ -7184,7 +7295,7 @@ var _VercelDataStreamHelper = class _VercelDataStreamHelper {
|
|
|
7184
7295
|
__publicField(this, "isCompleted", false);
|
|
7185
7296
|
// Stream queuing for proper event ordering
|
|
7186
7297
|
__publicField(this, "isTextStreaming", false);
|
|
7187
|
-
__publicField(this, "
|
|
7298
|
+
__publicField(this, "queuedEvents", []);
|
|
7188
7299
|
// Timing tracking for text sequences (text-end to text-start gap)
|
|
7189
7300
|
__publicField(this, "lastTextEndTimestamp", 0);
|
|
7190
7301
|
__publicField(this, "TEXT_GAP_THRESHOLD", 50);
|
|
@@ -7296,15 +7407,24 @@ var _VercelDataStreamHelper = class _VercelDataStreamHelper {
|
|
|
7296
7407
|
data
|
|
7297
7408
|
});
|
|
7298
7409
|
}
|
|
7299
|
-
async writeError(
|
|
7410
|
+
async writeError(error) {
|
|
7300
7411
|
if (this.isCompleted) {
|
|
7301
7412
|
console.warn("Attempted to write error to completed stream");
|
|
7302
7413
|
return;
|
|
7303
7414
|
}
|
|
7304
|
-
|
|
7305
|
-
|
|
7306
|
-
|
|
7307
|
-
|
|
7415
|
+
if (typeof error === "string") {
|
|
7416
|
+
this.writer.write({
|
|
7417
|
+
type: "error",
|
|
7418
|
+
message: error,
|
|
7419
|
+
severity: "error",
|
|
7420
|
+
timestamp: Date.now()
|
|
7421
|
+
});
|
|
7422
|
+
} else {
|
|
7423
|
+
this.writer.write({
|
|
7424
|
+
...error,
|
|
7425
|
+
type: "error"
|
|
7426
|
+
});
|
|
7427
|
+
}
|
|
7308
7428
|
}
|
|
7309
7429
|
async streamData(data) {
|
|
7310
7430
|
await this.writeContent(JSON.stringify(data));
|
|
@@ -7316,20 +7436,6 @@ var _VercelDataStreamHelper = class _VercelDataStreamHelper {
|
|
|
7316
7436
|
}
|
|
7317
7437
|
this.writer.merge(stream2);
|
|
7318
7438
|
}
|
|
7319
|
-
async writeCompletion(_finishReason = "stop") {
|
|
7320
|
-
}
|
|
7321
|
-
async writeDone() {
|
|
7322
|
-
}
|
|
7323
|
-
/**
|
|
7324
|
-
* Complete the stream and clean up all memory
|
|
7325
|
-
* This is the primary cleanup point to prevent memory leaks between requests
|
|
7326
|
-
*/
|
|
7327
|
-
async complete() {
|
|
7328
|
-
if (this.isCompleted) return;
|
|
7329
|
-
await this.flushQueuedOperations();
|
|
7330
|
-
this.isCompleted = true;
|
|
7331
|
-
this.cleanup();
|
|
7332
|
-
}
|
|
7333
7439
|
/**
|
|
7334
7440
|
* Clean up all memory allocations
|
|
7335
7441
|
* Should be called when the stream helper is no longer needed
|
|
@@ -7343,7 +7449,7 @@ var _VercelDataStreamHelper = class _VercelDataStreamHelper {
|
|
|
7343
7449
|
this.sentItems.clear();
|
|
7344
7450
|
this.completedItems.clear();
|
|
7345
7451
|
this.textId = null;
|
|
7346
|
-
this.
|
|
7452
|
+
this.queuedEvents = [];
|
|
7347
7453
|
this.isTextStreaming = false;
|
|
7348
7454
|
}
|
|
7349
7455
|
/**
|
|
@@ -7409,7 +7515,9 @@ var _VercelDataStreamHelper = class _VercelDataStreamHelper {
|
|
|
7409
7515
|
if (this.writer && !this.isCompleted) {
|
|
7410
7516
|
this.writer.write({
|
|
7411
7517
|
type: "error",
|
|
7412
|
-
|
|
7518
|
+
message: `Stream terminated: ${reason}`,
|
|
7519
|
+
severity: "error",
|
|
7520
|
+
timestamp: Date.now()
|
|
7413
7521
|
});
|
|
7414
7522
|
}
|
|
7415
7523
|
} catch (e) {
|
|
@@ -7432,23 +7540,33 @@ var _VercelDataStreamHelper = class _VercelDataStreamHelper {
|
|
|
7432
7540
|
isCompleted: this.isCompleted
|
|
7433
7541
|
};
|
|
7434
7542
|
}
|
|
7543
|
+
async writeSummary(summary) {
|
|
7544
|
+
if (this.isCompleted) {
|
|
7545
|
+
console.warn("Attempted to write summary to completed stream");
|
|
7546
|
+
return;
|
|
7547
|
+
}
|
|
7548
|
+
const now = Date.now();
|
|
7549
|
+
const gapFromLastTextEnd = this.lastTextEndTimestamp > 0 ? now - this.lastTextEndTimestamp : Number.MAX_SAFE_INTEGER;
|
|
7550
|
+
if (this.isTextStreaming || gapFromLastTextEnd < this.TEXT_GAP_THRESHOLD) {
|
|
7551
|
+
this.queuedEvents.push({ type: "data-summary", event: summary });
|
|
7552
|
+
return;
|
|
7553
|
+
}
|
|
7554
|
+
await this.flushQueuedOperations();
|
|
7555
|
+
await this.writer.write({
|
|
7556
|
+
id: "id" in summary ? summary.id : void 0,
|
|
7557
|
+
type: "data-summary",
|
|
7558
|
+
data: summary
|
|
7559
|
+
});
|
|
7560
|
+
}
|
|
7435
7561
|
async writeOperation(operation) {
|
|
7436
7562
|
if (this.isCompleted) {
|
|
7437
7563
|
console.warn("Attempted to write operation to completed stream");
|
|
7438
7564
|
return;
|
|
7439
7565
|
}
|
|
7440
|
-
if (operation.type === "status_update" && operation.ctx.label) {
|
|
7441
|
-
operation = {
|
|
7442
|
-
type: operation.type,
|
|
7443
|
-
label: operation.ctx.label,
|
|
7444
|
-
// Preserve the label for the UI
|
|
7445
|
-
ctx: operation.ctx.data
|
|
7446
|
-
};
|
|
7447
|
-
}
|
|
7448
7566
|
const now = Date.now();
|
|
7449
7567
|
const gapFromLastTextEnd = this.lastTextEndTimestamp > 0 ? now - this.lastTextEndTimestamp : Number.MAX_SAFE_INTEGER;
|
|
7450
7568
|
if (this.isTextStreaming || gapFromLastTextEnd < this.TEXT_GAP_THRESHOLD) {
|
|
7451
|
-
this.
|
|
7569
|
+
this.queuedEvents.push({ type: "data-operation", event: operation });
|
|
7452
7570
|
return;
|
|
7453
7571
|
}
|
|
7454
7572
|
await this.flushQueuedOperations();
|
|
@@ -7462,19 +7580,33 @@ var _VercelDataStreamHelper = class _VercelDataStreamHelper {
|
|
|
7462
7580
|
* Flush all queued operations in order after text streaming completes
|
|
7463
7581
|
*/
|
|
7464
7582
|
async flushQueuedOperations() {
|
|
7465
|
-
if (this.
|
|
7583
|
+
if (this.queuedEvents.length === 0) {
|
|
7466
7584
|
return;
|
|
7467
7585
|
}
|
|
7468
|
-
const
|
|
7469
|
-
this.
|
|
7470
|
-
for (const
|
|
7586
|
+
const eventsToFlush = [...this.queuedEvents];
|
|
7587
|
+
this.queuedEvents = [];
|
|
7588
|
+
for (const event of eventsToFlush) {
|
|
7471
7589
|
this.writer.write({
|
|
7472
|
-
id: "id" in
|
|
7473
|
-
type:
|
|
7474
|
-
data:
|
|
7590
|
+
id: "id" in event.event ? event.event.id : void 0,
|
|
7591
|
+
type: event.type,
|
|
7592
|
+
data: event.event
|
|
7475
7593
|
});
|
|
7476
7594
|
}
|
|
7477
7595
|
}
|
|
7596
|
+
async writeCompletion(_finishReason = "stop") {
|
|
7597
|
+
}
|
|
7598
|
+
async writeDone() {
|
|
7599
|
+
}
|
|
7600
|
+
/**
|
|
7601
|
+
* Complete the stream and clean up all memory
|
|
7602
|
+
* This is the primary cleanup point to prevent memory leaks between requests
|
|
7603
|
+
*/
|
|
7604
|
+
async complete() {
|
|
7605
|
+
if (this.isCompleted) return;
|
|
7606
|
+
await this.flushQueuedOperations();
|
|
7607
|
+
this.isCompleted = true;
|
|
7608
|
+
this.cleanup();
|
|
7609
|
+
}
|
|
7478
7610
|
};
|
|
7479
7611
|
// Memory management - focused on connection completion cleanup
|
|
7480
7612
|
__publicField(_VercelDataStreamHelper, "MAX_BUFFER_SIZE", 5 * 1024 * 1024);
|
|
@@ -7487,6 +7619,7 @@ var MCPStreamHelper = class {
|
|
|
7487
7619
|
__publicField(this, "capturedText", "");
|
|
7488
7620
|
__publicField(this, "capturedData", []);
|
|
7489
7621
|
__publicField(this, "capturedOperations", []);
|
|
7622
|
+
__publicField(this, "capturedSummaries", []);
|
|
7490
7623
|
__publicField(this, "hasError", false);
|
|
7491
7624
|
__publicField(this, "errorMessage", "");
|
|
7492
7625
|
__publicField(this, "sessionId");
|
|
@@ -7505,18 +7638,27 @@ var MCPStreamHelper = class {
|
|
|
7505
7638
|
async streamData(data) {
|
|
7506
7639
|
this.capturedData.push(data);
|
|
7507
7640
|
}
|
|
7641
|
+
async streamSummary(summary) {
|
|
7642
|
+
this.capturedSummaries.push(summary);
|
|
7643
|
+
}
|
|
7644
|
+
async streamOperation(operation) {
|
|
7645
|
+
this.capturedOperations.push(operation);
|
|
7646
|
+
}
|
|
7508
7647
|
async writeData(_type, data) {
|
|
7509
7648
|
this.capturedData.push(data);
|
|
7510
7649
|
}
|
|
7511
|
-
async
|
|
7512
|
-
this.
|
|
7513
|
-
this.errorMessage = errorMessage;
|
|
7514
|
-
}
|
|
7515
|
-
async complete() {
|
|
7650
|
+
async writeSummary(summary) {
|
|
7651
|
+
this.capturedSummaries.push(summary);
|
|
7516
7652
|
}
|
|
7517
7653
|
async writeOperation(operation) {
|
|
7518
7654
|
this.capturedOperations.push(operation);
|
|
7519
7655
|
}
|
|
7656
|
+
async writeError(error) {
|
|
7657
|
+
this.hasError = true;
|
|
7658
|
+
this.errorMessage = typeof error === "string" ? error : error.message;
|
|
7659
|
+
}
|
|
7660
|
+
async complete() {
|
|
7661
|
+
}
|
|
7520
7662
|
/**
|
|
7521
7663
|
* Get the captured response for MCP tool result
|
|
7522
7664
|
*/
|
|
@@ -7535,7 +7677,6 @@ function createMCPStreamHelper() {
|
|
|
7535
7677
|
}
|
|
7536
7678
|
|
|
7537
7679
|
// src/handlers/executionHandler.ts
|
|
7538
|
-
init_dbClient();
|
|
7539
7680
|
var logger19 = agentsCore.getLogger("ExecutionHandler");
|
|
7540
7681
|
var ExecutionHandler = class {
|
|
7541
7682
|
constructor() {
|
|
@@ -7564,7 +7705,7 @@ var ExecutionHandler = class {
|
|
|
7564
7705
|
logger19.info({ sessionId: requestId2, graphId }, "Created GraphSession for message execution");
|
|
7565
7706
|
let graphConfig = null;
|
|
7566
7707
|
try {
|
|
7567
|
-
graphConfig = await agentsCore.getFullGraph(dbClient_default)({ scopes: { tenantId, projectId
|
|
7708
|
+
graphConfig = await agentsCore.getFullGraph(dbClient_default)({ scopes: { tenantId, projectId, graphId } });
|
|
7568
7709
|
if (graphConfig?.statusUpdates && graphConfig.statusUpdates.enabled !== false) {
|
|
7569
7710
|
graphSessionManager.initializeStatusUpdates(
|
|
7570
7711
|
requestId2,
|
|
@@ -7718,7 +7859,6 @@ var ExecutionHandler = class {
|
|
|
7718
7859
|
if (errorCount >= this.MAX_ERRORS) {
|
|
7719
7860
|
const errorMessage2 = `Maximum error limit (${this.MAX_ERRORS}) reached`;
|
|
7720
7861
|
logger19.error({ maxErrors: this.MAX_ERRORS, errorCount }, errorMessage2);
|
|
7721
|
-
await sseHelper.writeError(errorMessage2);
|
|
7722
7862
|
await sseHelper.writeOperation(errorOp(errorMessage2, currentAgentId || "system"));
|
|
7723
7863
|
if (task) {
|
|
7724
7864
|
await agentsCore.updateTask(dbClient_default)({
|
|
@@ -7859,7 +7999,6 @@ var ExecutionHandler = class {
|
|
|
7859
7999
|
if (errorCount >= this.MAX_ERRORS) {
|
|
7860
8000
|
const errorMessage2 = `Maximum error limit (${this.MAX_ERRORS}) reached`;
|
|
7861
8001
|
logger19.error({ maxErrors: this.MAX_ERRORS, errorCount }, errorMessage2);
|
|
7862
|
-
await sseHelper.writeError(errorMessage2);
|
|
7863
8002
|
await sseHelper.writeOperation(errorOp(errorMessage2, currentAgentId || "system"));
|
|
7864
8003
|
if (task) {
|
|
7865
8004
|
await agentsCore.updateTask(dbClient_default)({
|
|
@@ -7881,7 +8020,6 @@ var ExecutionHandler = class {
|
|
|
7881
8020
|
}
|
|
7882
8021
|
const errorMessage = `Maximum transfer limit (${maxTransfers}) reached without completion`;
|
|
7883
8022
|
logger19.error({ maxTransfers, iterations }, errorMessage);
|
|
7884
|
-
await sseHelper.writeError(errorMessage);
|
|
7885
8023
|
await sseHelper.writeOperation(errorOp(errorMessage, currentAgentId || "system"));
|
|
7886
8024
|
if (task) {
|
|
7887
8025
|
await agentsCore.updateTask(dbClient_default)({
|
|
@@ -7902,8 +8040,7 @@ var ExecutionHandler = class {
|
|
|
7902
8040
|
} catch (error) {
|
|
7903
8041
|
logger19.error({ error }, "Error in execution handler");
|
|
7904
8042
|
const errorMessage = error instanceof Error ? error.message : "Unknown execution error";
|
|
7905
|
-
await sseHelper.
|
|
7906
|
-
await sseHelper.writeOperation(errorOp(errorMessage, currentAgentId || "system"));
|
|
8043
|
+
await sseHelper.writeOperation(errorOp(`Execution error: ${errorMessage}`, currentAgentId || "system"));
|
|
7907
8044
|
if (task) {
|
|
7908
8045
|
await agentsCore.updateTask(dbClient_default)({
|
|
7909
8046
|
taskId: task.id,
|
|
@@ -8065,8 +8202,7 @@ app2.openapi(chatCompletionsRoute, async (c) => {
|
|
|
8065
8202
|
const body = c.get("requestBody") || {};
|
|
8066
8203
|
const conversationId = body.conversationId || nanoid.nanoid();
|
|
8067
8204
|
const fullGraph = await agentsCore.getFullGraph(dbClient_default)({
|
|
8068
|
-
scopes: { tenantId, projectId }
|
|
8069
|
-
graphId
|
|
8205
|
+
scopes: { tenantId, projectId, graphId }
|
|
8070
8206
|
});
|
|
8071
8207
|
let agentGraph;
|
|
8072
8208
|
let defaultAgentId;
|
|
@@ -8083,16 +8219,21 @@ app2.openapi(chatCompletionsRoute, async (c) => {
|
|
|
8083
8219
|
defaultAgentId = fullGraph.defaultAgentId || firstAgentId;
|
|
8084
8220
|
} else {
|
|
8085
8221
|
agentGraph = await agentsCore.getAgentGraphWithDefaultAgent(dbClient_default)({
|
|
8086
|
-
scopes: { tenantId, projectId }
|
|
8087
|
-
graphId
|
|
8222
|
+
scopes: { tenantId, projectId, graphId }
|
|
8088
8223
|
});
|
|
8089
8224
|
if (!agentGraph) {
|
|
8090
|
-
|
|
8225
|
+
throw agentsCore.createApiError({
|
|
8226
|
+
code: "not_found",
|
|
8227
|
+
message: "Agent graph not found"
|
|
8228
|
+
});
|
|
8091
8229
|
}
|
|
8092
8230
|
defaultAgentId = agentGraph.defaultAgentId || "";
|
|
8093
8231
|
}
|
|
8094
8232
|
if (!defaultAgentId) {
|
|
8095
|
-
|
|
8233
|
+
throw agentsCore.createApiError({
|
|
8234
|
+
code: "not_found",
|
|
8235
|
+
message: "No default agent found in graph"
|
|
8236
|
+
});
|
|
8096
8237
|
}
|
|
8097
8238
|
await agentsCore.createOrGetConversation(dbClient_default)({
|
|
8098
8239
|
tenantId,
|
|
@@ -8113,26 +8254,30 @@ app2.openapi(chatCompletionsRoute, async (c) => {
|
|
|
8113
8254
|
}
|
|
8114
8255
|
const agentId = activeAgent?.activeAgentId || defaultAgentId;
|
|
8115
8256
|
const agentInfo = await agentsCore.getAgentById(dbClient_default)({
|
|
8116
|
-
scopes: { tenantId, projectId },
|
|
8257
|
+
scopes: { tenantId, projectId, graphId },
|
|
8117
8258
|
agentId
|
|
8118
8259
|
});
|
|
8119
8260
|
if (!agentInfo) {
|
|
8120
|
-
|
|
8261
|
+
throw agentsCore.createApiError({
|
|
8262
|
+
code: "not_found",
|
|
8263
|
+
message: "Agent not found"
|
|
8264
|
+
});
|
|
8121
8265
|
}
|
|
8122
8266
|
const validatedContext = c.get("validatedContext") || body.requestContext || {};
|
|
8123
8267
|
const credentialStores = c.get("credentialStores");
|
|
8124
|
-
await agentsCore.handleContextResolution(
|
|
8268
|
+
await agentsCore.handleContextResolution({
|
|
8125
8269
|
tenantId,
|
|
8126
8270
|
projectId,
|
|
8127
|
-
conversationId,
|
|
8128
8271
|
graphId,
|
|
8129
|
-
|
|
8130
|
-
|
|
8272
|
+
conversationId,
|
|
8273
|
+
requestContext: validatedContext,
|
|
8274
|
+
dbClient: dbClient_default,
|
|
8131
8275
|
credentialStores
|
|
8132
|
-
);
|
|
8276
|
+
});
|
|
8133
8277
|
logger20.info(
|
|
8134
8278
|
{
|
|
8135
8279
|
tenantId,
|
|
8280
|
+
projectId,
|
|
8136
8281
|
graphId,
|
|
8137
8282
|
conversationId,
|
|
8138
8283
|
defaultAgentId,
|
|
@@ -8174,41 +8319,69 @@ app2.openapi(chatCompletionsRoute, async (c) => {
|
|
|
8174
8319
|
});
|
|
8175
8320
|
}
|
|
8176
8321
|
return streaming.streamSSE(c, async (stream2) => {
|
|
8177
|
-
|
|
8178
|
-
|
|
8179
|
-
|
|
8180
|
-
|
|
8181
|
-
|
|
8182
|
-
|
|
8183
|
-
|
|
8184
|
-
|
|
8185
|
-
|
|
8186
|
-
|
|
8187
|
-
|
|
8188
|
-
|
|
8189
|
-
|
|
8190
|
-
|
|
8191
|
-
|
|
8192
|
-
|
|
8193
|
-
if (!result.success) {
|
|
8194
|
-
await sseHelper.writeError(
|
|
8195
|
-
"Sorry, I was unable to process your request at this time. Please try again."
|
|
8322
|
+
try {
|
|
8323
|
+
const sseHelper = createSSEStreamHelper(stream2, requestId2, timestamp);
|
|
8324
|
+
await sseHelper.writeRole();
|
|
8325
|
+
logger20.info({ agentId }, "Starting execution");
|
|
8326
|
+
const executionHandler = new ExecutionHandler();
|
|
8327
|
+
const result = await executionHandler.execute({
|
|
8328
|
+
executionContext,
|
|
8329
|
+
conversationId,
|
|
8330
|
+
userMessage,
|
|
8331
|
+
initialAgentId: agentId,
|
|
8332
|
+
requestId: requestId2,
|
|
8333
|
+
sseHelper
|
|
8334
|
+
});
|
|
8335
|
+
logger20.info(
|
|
8336
|
+
{ result },
|
|
8337
|
+
`Execution completed: ${result.success ? "success" : "failed"} after ${result.iterations} iterations`
|
|
8196
8338
|
);
|
|
8339
|
+
if (!result.success) {
|
|
8340
|
+
await sseHelper.writeOperation(
|
|
8341
|
+
errorOp(
|
|
8342
|
+
"Sorry, I was unable to process your request at this time. Please try again.",
|
|
8343
|
+
"system"
|
|
8344
|
+
)
|
|
8345
|
+
);
|
|
8346
|
+
}
|
|
8347
|
+
await sseHelper.complete();
|
|
8348
|
+
} catch (error) {
|
|
8349
|
+
logger20.error(
|
|
8350
|
+
{
|
|
8351
|
+
error: error instanceof Error ? error.message : error,
|
|
8352
|
+
stack: error instanceof Error ? error.stack : void 0
|
|
8353
|
+
},
|
|
8354
|
+
"Error during streaming execution"
|
|
8355
|
+
);
|
|
8356
|
+
try {
|
|
8357
|
+
const sseHelper = createSSEStreamHelper(stream2, requestId2, timestamp);
|
|
8358
|
+
await sseHelper.writeOperation(
|
|
8359
|
+
errorOp(
|
|
8360
|
+
"Sorry, I was unable to process your request at this time. Please try again.",
|
|
8361
|
+
"system"
|
|
8362
|
+
)
|
|
8363
|
+
);
|
|
8364
|
+
await sseHelper.complete();
|
|
8365
|
+
} catch (streamError) {
|
|
8366
|
+
logger20.error({ streamError }, "Failed to write error to stream");
|
|
8367
|
+
}
|
|
8197
8368
|
}
|
|
8198
|
-
await sseHelper.complete();
|
|
8199
8369
|
});
|
|
8200
8370
|
} catch (error) {
|
|
8201
|
-
|
|
8202
|
-
error: error instanceof Error ? error.message : error,
|
|
8203
|
-
stack: error instanceof Error ? error.stack : void 0
|
|
8204
|
-
});
|
|
8205
|
-
return c.json(
|
|
8371
|
+
logger20.error(
|
|
8206
8372
|
{
|
|
8207
|
-
error:
|
|
8208
|
-
|
|
8373
|
+
error: error instanceof Error ? error.message : error,
|
|
8374
|
+
stack: error instanceof Error ? error.stack : void 0
|
|
8209
8375
|
},
|
|
8210
|
-
|
|
8376
|
+
"Error in chat completions endpoint before streaming"
|
|
8211
8377
|
);
|
|
8378
|
+
if (error && typeof error === "object" && "status" in error) {
|
|
8379
|
+
throw error;
|
|
8380
|
+
}
|
|
8381
|
+
throw agentsCore.createApiError({
|
|
8382
|
+
code: "internal_server_error",
|
|
8383
|
+
message: error instanceof Error ? error.message : "Failed to process chat completion"
|
|
8384
|
+
});
|
|
8212
8385
|
}
|
|
8213
8386
|
});
|
|
8214
8387
|
var getMessageText = (content) => {
|
|
@@ -8275,6 +8448,7 @@ app3.openapi(chatDataStreamRoute, async (c) => {
|
|
|
8275
8448
|
try {
|
|
8276
8449
|
const executionContext = agentsCore.getRequestExecutionContext(c);
|
|
8277
8450
|
const { tenantId, projectId, graphId } = executionContext;
|
|
8451
|
+
agentsCore.loggerFactory.getLogger("chatDataStream").debug({ tenantId, projectId, graphId }, "Extracted chatDataStream parameters");
|
|
8278
8452
|
const body = c.get("requestBody") || {};
|
|
8279
8453
|
const conversationId = body.conversationId || nanoid.nanoid();
|
|
8280
8454
|
const activeSpan = api.trace.getActiveSpan();
|
|
@@ -8287,14 +8461,22 @@ app3.openapi(chatDataStreamRoute, async (c) => {
|
|
|
8287
8461
|
});
|
|
8288
8462
|
}
|
|
8289
8463
|
const agentGraph = await agentsCore.getAgentGraphWithDefaultAgent(dbClient_default)({
|
|
8290
|
-
scopes: { tenantId, projectId }
|
|
8291
|
-
graphId
|
|
8464
|
+
scopes: { tenantId, projectId, graphId }
|
|
8292
8465
|
});
|
|
8293
8466
|
if (!agentGraph) {
|
|
8294
|
-
|
|
8467
|
+
throw agentsCore.createApiError({
|
|
8468
|
+
code: "not_found",
|
|
8469
|
+
message: "Agent graph not found"
|
|
8470
|
+
});
|
|
8295
8471
|
}
|
|
8296
8472
|
const defaultAgentId = agentGraph.defaultAgentId;
|
|
8297
8473
|
const graphName = agentGraph.name;
|
|
8474
|
+
if (!defaultAgentId) {
|
|
8475
|
+
throw agentsCore.createApiError({
|
|
8476
|
+
code: "bad_request",
|
|
8477
|
+
message: "Graph does not have a default agent configured"
|
|
8478
|
+
});
|
|
8479
|
+
}
|
|
8298
8480
|
const activeAgent = await agentsCore.getActiveAgentForConversation(dbClient_default)({
|
|
8299
8481
|
scopes: { tenantId, projectId },
|
|
8300
8482
|
conversationId
|
|
@@ -8308,23 +8490,26 @@ app3.openapi(chatDataStreamRoute, async (c) => {
|
|
|
8308
8490
|
}
|
|
8309
8491
|
const agentId = activeAgent?.activeAgentId || defaultAgentId;
|
|
8310
8492
|
const agentInfo = await agentsCore.getAgentById(dbClient_default)({
|
|
8311
|
-
scopes: { tenantId, projectId },
|
|
8493
|
+
scopes: { tenantId, projectId, graphId },
|
|
8312
8494
|
agentId
|
|
8313
8495
|
});
|
|
8314
8496
|
if (!agentInfo) {
|
|
8315
|
-
|
|
8497
|
+
throw agentsCore.createApiError({
|
|
8498
|
+
code: "not_found",
|
|
8499
|
+
message: "Agent not found"
|
|
8500
|
+
});
|
|
8316
8501
|
}
|
|
8317
8502
|
const validatedContext = c.get("validatedContext") || body.requestContext || {};
|
|
8318
8503
|
const credentialStores = c.get("credentialStores");
|
|
8319
|
-
await agentsCore.handleContextResolution(
|
|
8504
|
+
await agentsCore.handleContextResolution({
|
|
8320
8505
|
tenantId,
|
|
8321
8506
|
projectId,
|
|
8322
|
-
conversationId,
|
|
8323
8507
|
graphId,
|
|
8324
|
-
|
|
8325
|
-
|
|
8508
|
+
conversationId,
|
|
8509
|
+
requestContext: validatedContext,
|
|
8510
|
+
dbClient: dbClient_default,
|
|
8326
8511
|
credentialStores
|
|
8327
|
-
);
|
|
8512
|
+
});
|
|
8328
8513
|
const lastUserMessage = body.messages.filter((m) => m.role === "user").slice(-1)[0];
|
|
8329
8514
|
const userText = typeof lastUserMessage?.content === "string" ? lastUserMessage.content : lastUserMessage?.parts?.map((p) => p.text).join("") || "";
|
|
8330
8515
|
logger21.info({ userText, lastUserMessage }, "userText");
|
|
@@ -8366,11 +8551,11 @@ app3.openapi(chatDataStreamRoute, async (c) => {
|
|
|
8366
8551
|
sseHelper: streamHelper
|
|
8367
8552
|
});
|
|
8368
8553
|
if (!result.success) {
|
|
8369
|
-
await streamHelper.
|
|
8554
|
+
await streamHelper.writeOperation(errorOp("Unable to process request", "system"));
|
|
8370
8555
|
}
|
|
8371
8556
|
} catch (err) {
|
|
8372
8557
|
logger21.error({ err }, "Streaming error");
|
|
8373
|
-
await streamHelper.
|
|
8558
|
+
await streamHelper.writeOperation(errorOp("Internal server error", "system"));
|
|
8374
8559
|
} finally {
|
|
8375
8560
|
if ("cleanup" in streamHelper && typeof streamHelper.cleanup === "function") {
|
|
8376
8561
|
streamHelper.cleanup();
|
|
@@ -8391,7 +8576,10 @@ app3.openapi(chatDataStreamRoute, async (c) => {
|
|
|
8391
8576
|
);
|
|
8392
8577
|
} catch (error) {
|
|
8393
8578
|
logger21.error({ error }, "chatDataStream error");
|
|
8394
|
-
|
|
8579
|
+
throw agentsCore.createApiError({
|
|
8580
|
+
code: "internal_server_error",
|
|
8581
|
+
message: "Failed to process chat completion"
|
|
8582
|
+
});
|
|
8395
8583
|
}
|
|
8396
8584
|
});
|
|
8397
8585
|
var chatDataStream_default = app3;
|
|
@@ -8596,8 +8784,7 @@ var getServer = async (requestContext, executionContext, conversationId, credent
|
|
|
8596
8784
|
const { tenantId, projectId, graphId } = executionContext;
|
|
8597
8785
|
setupTracing(conversationId, tenantId, graphId);
|
|
8598
8786
|
const agentGraph = await agentsCore.getAgentGraphWithDefaultAgent(dbClient_default)({
|
|
8599
|
-
scopes: { tenantId, projectId }
|
|
8600
|
-
graphId
|
|
8787
|
+
scopes: { tenantId, projectId, graphId }
|
|
8601
8788
|
});
|
|
8602
8789
|
if (!agentGraph) {
|
|
8603
8790
|
throw new Error("Agent graph not found");
|
|
@@ -8617,9 +8804,20 @@ var getServer = async (requestContext, executionContext, conversationId, credent
|
|
|
8617
8804
|
},
|
|
8618
8805
|
async ({ query }) => {
|
|
8619
8806
|
try {
|
|
8807
|
+
if (!agentGraph.defaultAgentId) {
|
|
8808
|
+
return {
|
|
8809
|
+
content: [
|
|
8810
|
+
{
|
|
8811
|
+
type: "text",
|
|
8812
|
+
text: `Graph does not have a default agent configured`
|
|
8813
|
+
}
|
|
8814
|
+
],
|
|
8815
|
+
isError: true
|
|
8816
|
+
};
|
|
8817
|
+
}
|
|
8620
8818
|
const defaultAgentId = agentGraph.defaultAgentId;
|
|
8621
8819
|
const agentInfo = await agentsCore.getAgentById(dbClient_default)({
|
|
8622
|
-
scopes: { tenantId, projectId },
|
|
8820
|
+
scopes: { tenantId, projectId, graphId },
|
|
8623
8821
|
agentId: defaultAgentId
|
|
8624
8822
|
});
|
|
8625
8823
|
if (!agentInfo) {
|
|
@@ -8633,18 +8831,19 @@ var getServer = async (requestContext, executionContext, conversationId, credent
|
|
|
8633
8831
|
isError: true
|
|
8634
8832
|
};
|
|
8635
8833
|
}
|
|
8636
|
-
const resolvedContext = await agentsCore.handleContextResolution(
|
|
8834
|
+
const resolvedContext = await agentsCore.handleContextResolution({
|
|
8637
8835
|
tenantId,
|
|
8638
8836
|
projectId,
|
|
8639
|
-
conversationId,
|
|
8640
8837
|
graphId,
|
|
8838
|
+
conversationId,
|
|
8641
8839
|
requestContext,
|
|
8642
|
-
dbClient_default,
|
|
8840
|
+
dbClient: dbClient_default,
|
|
8643
8841
|
credentialStores
|
|
8644
|
-
);
|
|
8842
|
+
});
|
|
8645
8843
|
logger22.info(
|
|
8646
8844
|
{
|
|
8647
8845
|
tenantId,
|
|
8846
|
+
projectId,
|
|
8648
8847
|
graphId,
|
|
8649
8848
|
conversationId,
|
|
8650
8849
|
hasContextConfig: !!agentGraph.contextConfigId,
|
|
@@ -8706,8 +8905,7 @@ var handleInitializationRequest = async (body, executionContext, validatedContex
|
|
|
8706
8905
|
logger22.info({ body }, "Received initialization request");
|
|
8707
8906
|
const sessionId = nanoid.nanoid();
|
|
8708
8907
|
const agentGraph = await agentsCore.getAgentGraphWithDefaultAgent(dbClient_default)({
|
|
8709
|
-
scopes: { tenantId, projectId }
|
|
8710
|
-
graphId
|
|
8908
|
+
scopes: { tenantId, projectId, graphId }
|
|
8711
8909
|
});
|
|
8712
8910
|
if (!agentGraph) {
|
|
8713
8911
|
return c.json(
|
|
@@ -8719,6 +8917,16 @@ var handleInitializationRequest = async (body, executionContext, validatedContex
|
|
|
8719
8917
|
{ status: 404 }
|
|
8720
8918
|
);
|
|
8721
8919
|
}
|
|
8920
|
+
if (!agentGraph.defaultAgentId) {
|
|
8921
|
+
return c.json(
|
|
8922
|
+
{
|
|
8923
|
+
jsonrpc: "2.0",
|
|
8924
|
+
error: { code: -32001, message: "Graph does not have a default agent configured" },
|
|
8925
|
+
id: body.id || null
|
|
8926
|
+
},
|
|
8927
|
+
{ status: 400 }
|
|
8928
|
+
);
|
|
8929
|
+
}
|
|
8722
8930
|
const conversation = await agentsCore.createOrGetConversation(dbClient_default)({
|
|
8723
8931
|
id: sessionId,
|
|
8724
8932
|
tenantId,
|
|
@@ -8915,6 +9123,8 @@ app4.delete("/", async (c) => {
|
|
|
8915
9123
|
);
|
|
8916
9124
|
});
|
|
8917
9125
|
var mcp_default = app4;
|
|
9126
|
+
|
|
9127
|
+
// src/app.ts
|
|
8918
9128
|
var logger23 = agentsCore.getLogger("agents-run-api");
|
|
8919
9129
|
function createExecutionHono(serverConfig, credentialStores) {
|
|
8920
9130
|
const app6 = new zodOpenapi.OpenAPIHono();
|
|
@@ -9139,9 +9349,9 @@ var defaultStores = agentsCore.createDefaultCredentialStores();
|
|
|
9139
9349
|
var defaultRegistry = new agentsCore.CredentialStoreRegistry(defaultStores);
|
|
9140
9350
|
var app5 = createExecutionHono(defaultConfig, defaultRegistry);
|
|
9141
9351
|
var index_default = app5;
|
|
9142
|
-
function createExecutionApp(
|
|
9143
|
-
const serverConfig =
|
|
9144
|
-
const stores =
|
|
9352
|
+
function createExecutionApp(config) {
|
|
9353
|
+
const serverConfig = config?.serverConfig ?? defaultConfig;
|
|
9354
|
+
const stores = config?.credentialStores ?? defaultStores;
|
|
9145
9355
|
const registry = new agentsCore.CredentialStoreRegistry(stores);
|
|
9146
9356
|
return createExecutionHono(serverConfig, registry);
|
|
9147
9357
|
}
|