@inkeep/agents-run-api 0.0.0-dev-20250917222639 → 0.0.0-dev-20250919052931
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 +585 -391
- package/dist/index.js +583 -389
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import { resourceFromAttributes } from '@opentelemetry/resources';
|
|
|
8
8
|
import { NodeSDK } from '@opentelemetry/sdk-node';
|
|
9
9
|
import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
|
|
10
10
|
import { ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions';
|
|
11
|
-
import { getLogger, getTracer, HeadersScopeSchema, getRequestExecutionContext, getAgentGraphWithDefaultAgent, contextValidationMiddleware, getFullGraph, createOrGetConversation, getActiveAgentForConversation, setActiveAgentForConversation, getAgentById, handleContextResolution, createMessage, commonGetErrorResponses, createDefaultCredentialStores, CredentialStoreRegistry, listTaskIdsByContextId, getTask, getLedgerArtifacts,
|
|
11
|
+
import { getLogger, getTracer, HeadersScopeSchema, getRequestExecutionContext, getAgentGraphWithDefaultAgent, contextValidationMiddleware, getFullGraph, createOrGetConversation, getActiveAgentForConversation, setActiveAgentForConversation, getAgentById, handleContextResolution, createMessage, commonGetErrorResponses, loggerFactory, createDefaultCredentialStores, CredentialStoreRegistry, listTaskIdsByContextId, getTask, getLedgerArtifacts, getAgentGraphById, createTask, updateTask, setSpanWithError, updateConversation, handleApiError, TaskState, setActiveAgentForThread, getConversation, getRelatedAgentsForGraph, getToolsForAgent, getDataComponentsForAgent, getArtifactComponentsForAgent, validateAndGetApiKey, getProject, ContextResolver, CredentialStuffer, MCPServerType, getCredentialReference, McpClient, getContextConfigById, getFullGraphDefinition, TemplateEngine, graphHasArtifactComponents, MCPTransportType, getExternalAgent } from '@inkeep/agents-core';
|
|
12
12
|
import { OpenAPIHono, createRoute, z as z$1 } from '@hono/zod-openapi';
|
|
13
13
|
import { trace, propagation, context, SpanStatusCode } from '@opentelemetry/api';
|
|
14
14
|
import { Hono } from 'hono';
|
|
@@ -22,7 +22,7 @@ import { streamSSE, stream } from 'hono/streaming';
|
|
|
22
22
|
import { nanoid } from 'nanoid';
|
|
23
23
|
import destr from 'destr';
|
|
24
24
|
import traverse from 'traverse';
|
|
25
|
-
import { createUIMessageStream, JsonToSseTransformStream, parsePartialJson, generateText, generateObject, tool, streamText } from 'ai';
|
|
25
|
+
import { createUIMessageStream, JsonToSseTransformStream, parsePartialJson, generateText, generateObject, tool, streamText, streamObject } from 'ai';
|
|
26
26
|
import { createAnthropic, anthropic } from '@ai-sdk/anthropic';
|
|
27
27
|
import { createGoogleGenerativeAI, google } from '@ai-sdk/google';
|
|
28
28
|
import { createOpenAI, openai } from '@ai-sdk/openai';
|
|
@@ -965,7 +965,7 @@ async function getRegisteredAgent(executionContext, credentialStoreRegistry) {
|
|
|
965
965
|
throw new Error("Agent ID is required");
|
|
966
966
|
}
|
|
967
967
|
const dbAgent = await getAgentById(dbClient_default)({
|
|
968
|
-
scopes: { tenantId, projectId },
|
|
968
|
+
scopes: { tenantId, projectId, graphId },
|
|
969
969
|
agentId
|
|
970
970
|
});
|
|
971
971
|
if (!dbAgent) {
|
|
@@ -980,6 +980,38 @@ async function getRegisteredAgent(executionContext, credentialStoreRegistry) {
|
|
|
980
980
|
apiKey
|
|
981
981
|
});
|
|
982
982
|
}
|
|
983
|
+
async function resolveModelConfig(graphId, agent) {
|
|
984
|
+
if (agent.models?.base?.model) {
|
|
985
|
+
return {
|
|
986
|
+
base: agent.models.base,
|
|
987
|
+
structuredOutput: agent.models.structuredOutput || agent.models.base,
|
|
988
|
+
summarizer: agent.models.summarizer || agent.models.base
|
|
989
|
+
};
|
|
990
|
+
}
|
|
991
|
+
const graph = await getAgentGraphById(dbClient_default)({
|
|
992
|
+
scopes: { tenantId: agent.tenantId, projectId: agent.projectId, graphId }
|
|
993
|
+
});
|
|
994
|
+
if (graph?.models?.base?.model) {
|
|
995
|
+
return {
|
|
996
|
+
base: graph.models.base,
|
|
997
|
+
structuredOutput: agent.models?.structuredOutput || graph.models.structuredOutput || graph.models.base,
|
|
998
|
+
summarizer: agent.models?.summarizer || graph.models.summarizer || graph.models.base
|
|
999
|
+
};
|
|
1000
|
+
}
|
|
1001
|
+
const project = await getProject(dbClient_default)({
|
|
1002
|
+
scopes: { tenantId: agent.tenantId, projectId: agent.projectId }
|
|
1003
|
+
});
|
|
1004
|
+
if (project?.models?.base?.model) {
|
|
1005
|
+
return {
|
|
1006
|
+
base: project.models.base,
|
|
1007
|
+
structuredOutput: agent.models?.structuredOutput || project.models.structuredOutput || project.models.base,
|
|
1008
|
+
summarizer: agent.models?.summarizer || project.models.summarizer || project.models.base
|
|
1009
|
+
};
|
|
1010
|
+
}
|
|
1011
|
+
throw new Error(
|
|
1012
|
+
"Base model configuration is required. Please configure models at the project level."
|
|
1013
|
+
);
|
|
1014
|
+
}
|
|
983
1015
|
function agentInitializingOp(sessionId, graphId) {
|
|
984
1016
|
return {
|
|
985
1017
|
type: "agent_initializing",
|
|
@@ -998,24 +1030,19 @@ function completionOp(agentId, iterations) {
|
|
|
998
1030
|
}
|
|
999
1031
|
};
|
|
1000
1032
|
}
|
|
1001
|
-
function errorOp(error,
|
|
1033
|
+
function errorOp(message, agentId, severity = "error", code) {
|
|
1002
1034
|
return {
|
|
1003
1035
|
type: "error",
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1036
|
+
message,
|
|
1037
|
+
agent: agentId,
|
|
1038
|
+
severity,
|
|
1039
|
+
code,
|
|
1040
|
+
timestamp: Date.now()
|
|
1008
1041
|
};
|
|
1009
1042
|
}
|
|
1010
1043
|
function generateToolId() {
|
|
1011
1044
|
return `tool_${nanoid(8)}`;
|
|
1012
1045
|
}
|
|
1013
|
-
function statusUpdateOp(ctx) {
|
|
1014
|
-
return {
|
|
1015
|
-
type: "status_update",
|
|
1016
|
-
ctx
|
|
1017
|
-
};
|
|
1018
|
-
}
|
|
1019
1046
|
var logger4 = getLogger("DataComponentSchema");
|
|
1020
1047
|
function jsonSchemaToZod(jsonSchema) {
|
|
1021
1048
|
if (!jsonSchema || typeof jsonSchema !== "object") {
|
|
@@ -1145,6 +1172,9 @@ var _ModelFactory = class _ModelFactory {
|
|
|
1145
1172
|
);
|
|
1146
1173
|
}
|
|
1147
1174
|
const modelSettings = config;
|
|
1175
|
+
if (!modelSettings.model) {
|
|
1176
|
+
throw new Error("Model configuration is required");
|
|
1177
|
+
}
|
|
1148
1178
|
const modelString = modelSettings.model.trim();
|
|
1149
1179
|
const { provider, modelName } = _ModelFactory.parseModelString(modelString);
|
|
1150
1180
|
logger5.debug(
|
|
@@ -1267,7 +1297,6 @@ var _ModelFactory = class _ModelFactory {
|
|
|
1267
1297
|
*/
|
|
1268
1298
|
__publicField(_ModelFactory, "SUPPORTED_PROVIDERS", ["anthropic", "openai", "google"]);
|
|
1269
1299
|
var ModelFactory = _ModelFactory;
|
|
1270
|
-
var tracer = getTracer("agents-run-api");
|
|
1271
1300
|
|
|
1272
1301
|
// src/utils/stream-registry.ts
|
|
1273
1302
|
var streamHelperRegistry = /* @__PURE__ */ new Map();
|
|
@@ -1283,6 +1312,7 @@ function getStreamHelper(requestId2) {
|
|
|
1283
1312
|
function unregisterStreamHelper(requestId2) {
|
|
1284
1313
|
streamHelperRegistry.delete(requestId2);
|
|
1285
1314
|
}
|
|
1315
|
+
var tracer = getTracer("agents-run-api");
|
|
1286
1316
|
|
|
1287
1317
|
// src/utils/graph-session.ts
|
|
1288
1318
|
var logger6 = getLogger("GraphSession");
|
|
@@ -1591,7 +1621,6 @@ var GraphSession = class {
|
|
|
1591
1621
|
}
|
|
1592
1622
|
this.isGeneratingUpdate = true;
|
|
1593
1623
|
const statusUpdateState = this.statusUpdateState;
|
|
1594
|
-
const graphId = this.graphId;
|
|
1595
1624
|
try {
|
|
1596
1625
|
const streamHelper = getStreamHelper(this.sessionId);
|
|
1597
1626
|
if (!streamHelper) {
|
|
@@ -1604,7 +1633,7 @@ var GraphSession = class {
|
|
|
1604
1633
|
}
|
|
1605
1634
|
const now = Date.now();
|
|
1606
1635
|
const elapsedTime = now - statusUpdateState.startTime;
|
|
1607
|
-
let
|
|
1636
|
+
let summaryToSend;
|
|
1608
1637
|
if (statusUpdateState.config.statusComponents && statusUpdateState.config.statusComponents.length > 0) {
|
|
1609
1638
|
const result = await this.generateStructuredStatusUpdate(
|
|
1610
1639
|
this.events.slice(statusUpdateState.lastEventCount),
|
|
@@ -1613,32 +1642,30 @@ var GraphSession = class {
|
|
|
1613
1642
|
statusUpdateState.summarizerModel,
|
|
1614
1643
|
this.previousSummaries
|
|
1615
1644
|
);
|
|
1616
|
-
if (result.
|
|
1617
|
-
for (const
|
|
1618
|
-
if (!
|
|
1645
|
+
if (result.summaries && result.summaries.length > 0) {
|
|
1646
|
+
for (const summary of result.summaries) {
|
|
1647
|
+
if (!summary || !summary.type || !summary.data || !summary.data.label || Object.keys(summary.data).length === 0) {
|
|
1619
1648
|
logger6.warn(
|
|
1620
1649
|
{
|
|
1621
1650
|
sessionId: this.sessionId,
|
|
1622
|
-
|
|
1651
|
+
summary
|
|
1623
1652
|
},
|
|
1624
1653
|
"Skipping empty or invalid structured operation"
|
|
1625
1654
|
);
|
|
1626
1655
|
continue;
|
|
1627
1656
|
}
|
|
1628
|
-
const
|
|
1629
|
-
type:
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
data
|
|
1634
|
-
|
|
1635
|
-
)
|
|
1636
|
-
}
|
|
1657
|
+
const summaryToSend2 = {
|
|
1658
|
+
type: summary.data.type || summary.type,
|
|
1659
|
+
// Preserve the actual custom type from LLM
|
|
1660
|
+
label: summary.data.label,
|
|
1661
|
+
details: Object.fromEntries(
|
|
1662
|
+
Object.entries(summary.data).filter(([key]) => !["label", "type"].includes(key))
|
|
1663
|
+
)
|
|
1637
1664
|
};
|
|
1638
|
-
await streamHelper.
|
|
1665
|
+
await streamHelper.writeSummary(summaryToSend2);
|
|
1639
1666
|
}
|
|
1640
|
-
const summaryTexts = result.
|
|
1641
|
-
(
|
|
1667
|
+
const summaryTexts = result.summaries.map(
|
|
1668
|
+
(summary) => JSON.stringify({ type: summary.type, data: summary.data })
|
|
1642
1669
|
);
|
|
1643
1670
|
this.previousSummaries.push(...summaryTexts);
|
|
1644
1671
|
if (this.statusUpdateState) {
|
|
@@ -1655,34 +1682,20 @@ var GraphSession = class {
|
|
|
1655
1682
|
this.previousSummaries
|
|
1656
1683
|
);
|
|
1657
1684
|
this.previousSummaries.push(summary);
|
|
1658
|
-
operation = statusUpdateOp({
|
|
1659
|
-
summary,
|
|
1660
|
-
eventCount: this.events.length,
|
|
1661
|
-
elapsedTime,
|
|
1662
|
-
currentPhase: "processing",
|
|
1663
|
-
activeAgent: "system",
|
|
1664
|
-
graphId,
|
|
1665
|
-
sessionId: this.sessionId
|
|
1666
|
-
});
|
|
1667
1685
|
}
|
|
1668
1686
|
if (this.previousSummaries.length > 3) {
|
|
1669
1687
|
this.previousSummaries.shift();
|
|
1670
1688
|
}
|
|
1671
|
-
|
|
1689
|
+
{
|
|
1672
1690
|
logger6.warn(
|
|
1673
1691
|
{
|
|
1674
1692
|
sessionId: this.sessionId,
|
|
1675
|
-
|
|
1693
|
+
summaryToSend
|
|
1676
1694
|
},
|
|
1677
1695
|
"Skipping empty or invalid status update operation"
|
|
1678
1696
|
);
|
|
1679
1697
|
return;
|
|
1680
1698
|
}
|
|
1681
|
-
await streamHelper.writeOperation(operation);
|
|
1682
|
-
if (this.statusUpdateState) {
|
|
1683
|
-
this.statusUpdateState.lastUpdateTime = now;
|
|
1684
|
-
this.statusUpdateState.lastEventCount = this.events.length;
|
|
1685
|
-
}
|
|
1686
1699
|
} catch (error) {
|
|
1687
1700
|
logger6.error(
|
|
1688
1701
|
{
|
|
@@ -1815,7 +1828,7 @@ ${previousSummaryContext}` : ""}
|
|
|
1815
1828
|
Activities:
|
|
1816
1829
|
${userVisibleActivities.join("\n") || "No New Activities"}
|
|
1817
1830
|
|
|
1818
|
-
|
|
1831
|
+
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".
|
|
1819
1832
|
|
|
1820
1833
|
${this.statusUpdateState?.config.prompt?.trim() || ""}`;
|
|
1821
1834
|
const prompt = basePrompt;
|
|
@@ -1828,6 +1841,9 @@ ${this.statusUpdateState?.config.prompt?.trim() || ""}`;
|
|
|
1828
1841
|
}
|
|
1829
1842
|
modelToUse = this.statusUpdateState.baseModel;
|
|
1830
1843
|
}
|
|
1844
|
+
if (!modelToUse) {
|
|
1845
|
+
throw new Error("No model configuration available");
|
|
1846
|
+
}
|
|
1831
1847
|
const model = ModelFactory.createModel(modelToUse);
|
|
1832
1848
|
const { text } = await generateText({
|
|
1833
1849
|
model,
|
|
@@ -1937,14 +1953,16 @@ Rules:
|
|
|
1937
1953
|
- Fill in data for relevant components only
|
|
1938
1954
|
- Use 'no_relevant_updates' if nothing substantially new to report. DO NOT WRITE LABELS OR USE OTHER COMPONENTS IF YOU USE THIS COMPONENT.
|
|
1939
1955
|
- Never repeat previous values, make every update EXTREMELY unique. If you cannot do that the update is not worth mentioning.
|
|
1940
|
-
- Labels MUST
|
|
1956
|
+
- Labels MUST be short 3-5 word phrases with ACTUAL information discovered. NEVER MAKE UP SOMETHING WITHOUT BACKING IT UP WITH ACTUAL INFORMATION.
|
|
1957
|
+
- 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.
|
|
1941
1958
|
- DO NOT use action words like "Searching", "Processing", "Analyzing" - state what was FOUND
|
|
1942
1959
|
- Include specific details, numbers, requirements, or insights discovered
|
|
1960
|
+
- Examples: "Admin permissions required", "Three OAuth steps found", "Token expires daily"
|
|
1943
1961
|
- You are ONE unified AI system - NEVER mention agents, transfers, delegations, or routing
|
|
1944
|
-
- CRITICAL: NEVER use the words "transfer", "delegation", "agent", "routing", or any internal system terminology in labels
|
|
1962
|
+
- 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.
|
|
1945
1963
|
- Present all operations as seamless actions by a single system
|
|
1946
1964
|
- Anonymize all internal operations so that the information appears descriptive and USER FRIENDLY. HIDE ALL INTERNAL OPERATIONS!
|
|
1947
|
-
- Bad examples: "Transferring to search agent", "Delegating task", "Routing request", "Processing request", or not using the no_relevant_updates
|
|
1965
|
+
- 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
|
|
1948
1966
|
- 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.
|
|
1949
1967
|
|
|
1950
1968
|
REMEMBER YOU CAN ONLY USE 'no_relevant_updates' ALONE! IT CANNOT BE CONCATENATED WITH OTHER STATUS UPDATES!
|
|
@@ -1960,6 +1978,9 @@ ${this.statusUpdateState?.config.prompt?.trim() || ""}`;
|
|
|
1960
1978
|
}
|
|
1961
1979
|
modelToUse = this.statusUpdateState.baseModel;
|
|
1962
1980
|
}
|
|
1981
|
+
if (!modelToUse) {
|
|
1982
|
+
throw new Error("No model configuration available");
|
|
1983
|
+
}
|
|
1963
1984
|
const model = ModelFactory.createModel(modelToUse);
|
|
1964
1985
|
const { object } = await generateObject({
|
|
1965
1986
|
model,
|
|
@@ -1977,29 +1998,29 @@ ${this.statusUpdateState?.config.prompt?.trim() || ""}`;
|
|
|
1977
1998
|
}
|
|
1978
1999
|
});
|
|
1979
2000
|
const result = object;
|
|
1980
|
-
const
|
|
2001
|
+
const summaries = [];
|
|
1981
2002
|
for (const [componentId, data] of Object.entries(result)) {
|
|
1982
2003
|
if (componentId === "no_relevant_updates") {
|
|
1983
2004
|
continue;
|
|
1984
2005
|
}
|
|
1985
2006
|
if (data && typeof data === "object" && Object.keys(data).length > 0) {
|
|
1986
|
-
|
|
2007
|
+
summaries.push({
|
|
1987
2008
|
type: componentId,
|
|
1988
2009
|
data
|
|
1989
2010
|
});
|
|
1990
2011
|
}
|
|
1991
2012
|
}
|
|
1992
2013
|
span.setAttributes({
|
|
1993
|
-
"
|
|
2014
|
+
"summaries.count": summaries.length,
|
|
1994
2015
|
"user_activities.count": userVisibleActivities.length,
|
|
1995
2016
|
"result_keys.count": Object.keys(result).length
|
|
1996
2017
|
});
|
|
1997
2018
|
span.setStatus({ code: SpanStatusCode.OK });
|
|
1998
|
-
return {
|
|
2019
|
+
return { summaries };
|
|
1999
2020
|
} catch (error) {
|
|
2000
2021
|
setSpanWithError(span, error);
|
|
2001
2022
|
logger6.error({ error }, "Failed to generate structured update, using fallback");
|
|
2002
|
-
return {
|
|
2023
|
+
return { summaries: [] };
|
|
2003
2024
|
} finally {
|
|
2004
2025
|
span.end();
|
|
2005
2026
|
}
|
|
@@ -2250,6 +2271,9 @@ Make it specific and relevant.`;
|
|
|
2250
2271
|
}
|
|
2251
2272
|
modelToUse = this.statusUpdateState.baseModel;
|
|
2252
2273
|
}
|
|
2274
|
+
if (!modelToUse) {
|
|
2275
|
+
throw new Error("No model configuration available");
|
|
2276
|
+
}
|
|
2253
2277
|
const model = ModelFactory.createModel(modelToUse);
|
|
2254
2278
|
const schema = z.object({
|
|
2255
2279
|
name: z.string().max(50).describe("Concise, descriptive name for the artifact"),
|
|
@@ -2528,6 +2552,7 @@ var _ArtifactParser = class _ArtifactParser {
|
|
|
2528
2552
|
}
|
|
2529
2553
|
for (let i = matches.length - 1; i >= 0; i--) {
|
|
2530
2554
|
const match = matches[i];
|
|
2555
|
+
if (match.index === void 0) continue;
|
|
2531
2556
|
const startIdx = match.index;
|
|
2532
2557
|
const textAfterMatch = text.slice(startIdx);
|
|
2533
2558
|
if (!textAfterMatch.includes("/>")) {
|
|
@@ -2577,7 +2602,8 @@ var _ArtifactParser = class _ArtifactParser {
|
|
|
2577
2602
|
taskId,
|
|
2578
2603
|
name: artifact.name || "Processing...",
|
|
2579
2604
|
description: artifact.description || "Name and description being generated...",
|
|
2580
|
-
|
|
2605
|
+
type: artifact.metadata?.artifactType || artifact.artifactType,
|
|
2606
|
+
// Map artifactType to type for consistency
|
|
2581
2607
|
artifactSummary: artifact.parts?.[0]?.data?.summary || {}
|
|
2582
2608
|
};
|
|
2583
2609
|
}
|
|
@@ -2594,10 +2620,11 @@ var _ArtifactParser = class _ArtifactParser {
|
|
|
2594
2620
|
let lastIndex = 0;
|
|
2595
2621
|
for (const match of matches) {
|
|
2596
2622
|
const [fullMatch, artifactId, taskId] = match;
|
|
2623
|
+
if (match.index === void 0) continue;
|
|
2597
2624
|
const matchStart = match.index;
|
|
2598
2625
|
if (matchStart > lastIndex) {
|
|
2599
2626
|
const textBefore = text.slice(lastIndex, matchStart);
|
|
2600
|
-
if (textBefore
|
|
2627
|
+
if (textBefore) {
|
|
2601
2628
|
parts.push({ kind: "text", text: textBefore });
|
|
2602
2629
|
}
|
|
2603
2630
|
}
|
|
@@ -2609,7 +2636,7 @@ var _ArtifactParser = class _ArtifactParser {
|
|
|
2609
2636
|
}
|
|
2610
2637
|
if (lastIndex < text.length) {
|
|
2611
2638
|
const remainingText = text.slice(lastIndex);
|
|
2612
|
-
if (remainingText
|
|
2639
|
+
if (remainingText) {
|
|
2613
2640
|
parts.push({ kind: "text", text: remainingText });
|
|
2614
2641
|
}
|
|
2615
2642
|
}
|
|
@@ -2719,8 +2746,9 @@ __publicField(_ArtifactParser, "INCOMPLETE_ARTIFACT_REGEX", /<(a(r(t(i(f(a(c(t(:
|
|
|
2719
2746
|
var ArtifactParser = _ArtifactParser;
|
|
2720
2747
|
|
|
2721
2748
|
// src/utils/incremental-stream-parser.ts
|
|
2722
|
-
|
|
2723
|
-
var
|
|
2749
|
+
getLogger("IncrementalStreamParser");
|
|
2750
|
+
var _IncrementalStreamParser = class _IncrementalStreamParser {
|
|
2751
|
+
// Max number of streamed component IDs to track
|
|
2724
2752
|
constructor(streamHelper, tenantId, contextId) {
|
|
2725
2753
|
__publicField(this, "buffer", "");
|
|
2726
2754
|
__publicField(this, "pendingTextBuffer", "");
|
|
@@ -2730,6 +2758,9 @@ var IncrementalStreamParser = class {
|
|
|
2730
2758
|
__publicField(this, "collectedParts", []);
|
|
2731
2759
|
__publicField(this, "contextId");
|
|
2732
2760
|
__publicField(this, "lastChunkWasToolResult", false);
|
|
2761
|
+
__publicField(this, "componentAccumulator", {});
|
|
2762
|
+
__publicField(this, "lastStreamedComponents", /* @__PURE__ */ new Map());
|
|
2763
|
+
__publicField(this, "componentSnapshots", /* @__PURE__ */ new Map());
|
|
2733
2764
|
this.streamHelper = streamHelper;
|
|
2734
2765
|
this.contextId = contextId;
|
|
2735
2766
|
this.artifactParser = new ArtifactParser(tenantId);
|
|
@@ -2744,7 +2775,7 @@ var IncrementalStreamParser = class {
|
|
|
2744
2775
|
* Process a new text chunk for text streaming (handles artifact markers)
|
|
2745
2776
|
*/
|
|
2746
2777
|
async processTextChunk(chunk) {
|
|
2747
|
-
if (this.lastChunkWasToolResult && this.buffer === "" && chunk
|
|
2778
|
+
if (this.lastChunkWasToolResult && this.buffer === "" && chunk) {
|
|
2748
2779
|
chunk = "\n\n" + chunk;
|
|
2749
2780
|
this.lastChunkWasToolResult = false;
|
|
2750
2781
|
}
|
|
@@ -2756,100 +2787,122 @@ var IncrementalStreamParser = class {
|
|
|
2756
2787
|
this.buffer = parseResult.remainingBuffer;
|
|
2757
2788
|
}
|
|
2758
2789
|
/**
|
|
2759
|
-
* Process
|
|
2790
|
+
* Process object deltas directly from Vercel AI SDK's fullStream
|
|
2791
|
+
* Accumulates components and streams them when they're stable (unchanged between deltas)
|
|
2760
2792
|
*/
|
|
2761
|
-
async
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
for (const part of parseResult.completeParts) {
|
|
2765
|
-
await this.streamPart(part);
|
|
2793
|
+
async processObjectDelta(delta) {
|
|
2794
|
+
if (!delta || typeof delta !== "object") {
|
|
2795
|
+
return;
|
|
2766
2796
|
}
|
|
2767
|
-
this.
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
const delta = part.argsTextDelta || "";
|
|
2781
|
-
if (jsonBuffer.length + delta.length > MAX_BUFFER_SIZE) {
|
|
2782
|
-
logger8.warn(
|
|
2783
|
-
{ bufferSize: jsonBuffer.length + delta.length, maxSize: MAX_BUFFER_SIZE },
|
|
2784
|
-
"JSON buffer exceeded maximum size, truncating"
|
|
2785
|
-
);
|
|
2786
|
-
jsonBuffer = jsonBuffer.slice(-MAX_BUFFER_SIZE / 2);
|
|
2797
|
+
this.componentAccumulator = this.deepMerge(this.componentAccumulator, delta);
|
|
2798
|
+
if (this.componentAccumulator.dataComponents && Array.isArray(this.componentAccumulator.dataComponents)) {
|
|
2799
|
+
const components = this.componentAccumulator.dataComponents;
|
|
2800
|
+
const currentComponentIds = new Set(components.filter((c) => c?.id).map((c) => c.id));
|
|
2801
|
+
for (const [componentId, snapshot] of this.componentSnapshots.entries()) {
|
|
2802
|
+
if (!currentComponentIds.has(componentId) && !this.lastStreamedComponents.has(componentId)) {
|
|
2803
|
+
try {
|
|
2804
|
+
const component = JSON.parse(snapshot);
|
|
2805
|
+
if (this.isComponentComplete(component)) {
|
|
2806
|
+
await this.streamComponent(component);
|
|
2807
|
+
}
|
|
2808
|
+
} catch (e) {
|
|
2809
|
+
}
|
|
2787
2810
|
}
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2811
|
+
}
|
|
2812
|
+
for (let i = 0; i < components.length; i++) {
|
|
2813
|
+
const component = components[i];
|
|
2814
|
+
if (!component?.id) continue;
|
|
2815
|
+
const componentKey = component.id;
|
|
2816
|
+
const hasBeenStreamed = this.lastStreamedComponents.has(componentKey);
|
|
2817
|
+
if (hasBeenStreamed) continue;
|
|
2818
|
+
const currentSnapshot = JSON.stringify(component);
|
|
2819
|
+
const previousSnapshot = this.componentSnapshots.get(componentKey);
|
|
2820
|
+
this.componentSnapshots.set(componentKey, currentSnapshot);
|
|
2821
|
+
if (this.componentSnapshots.size > _IncrementalStreamParser.MAX_SNAPSHOT_SIZE) {
|
|
2822
|
+
const firstKey = this.componentSnapshots.keys().next().value;
|
|
2823
|
+
if (firstKey) {
|
|
2824
|
+
this.componentSnapshots.delete(firstKey);
|
|
2798
2825
|
}
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
if (componentMatch[0].length > MAX_COMPONENT_SIZE) {
|
|
2809
|
-
logger8.warn(
|
|
2810
|
-
{
|
|
2811
|
-
size: componentMatch[0].length,
|
|
2812
|
-
maxSize: MAX_COMPONENT_SIZE
|
|
2813
|
-
},
|
|
2814
|
-
"Component exceeds size limit, skipping"
|
|
2815
|
-
);
|
|
2816
|
-
componentBuffer = "";
|
|
2817
|
-
continue;
|
|
2818
|
-
}
|
|
2819
|
-
try {
|
|
2820
|
-
const component = JSON.parse(componentMatch[0]);
|
|
2821
|
-
if (typeof component !== "object" || !component.id) {
|
|
2822
|
-
logger8.warn({ component }, "Invalid component structure, skipping");
|
|
2823
|
-
componentBuffer = "";
|
|
2824
|
-
continue;
|
|
2825
|
-
}
|
|
2826
|
-
const parts = await this.artifactParser.parseObject({
|
|
2827
|
-
dataComponents: [component]
|
|
2828
|
-
});
|
|
2829
|
-
for (const part2 of parts) {
|
|
2830
|
-
await this.streamPart(part2);
|
|
2831
|
-
}
|
|
2832
|
-
componentsStreamed++;
|
|
2833
|
-
componentBuffer = "";
|
|
2834
|
-
} catch (e) {
|
|
2835
|
-
logger8.debug({ error: e }, "Failed to parse component, continuing to accumulate");
|
|
2836
|
-
}
|
|
2837
|
-
}
|
|
2826
|
+
}
|
|
2827
|
+
if (component.name === "Text" && component.props?.text) {
|
|
2828
|
+
const previousTextContent = previousSnapshot ? JSON.parse(previousSnapshot).props?.text || "" : "";
|
|
2829
|
+
const currentTextContent = component.props.text || "";
|
|
2830
|
+
if (currentTextContent.length > previousTextContent.length) {
|
|
2831
|
+
const newText = currentTextContent.slice(previousTextContent.length);
|
|
2832
|
+
if (!this.hasStartedRole) {
|
|
2833
|
+
await this.streamHelper.writeRole("assistant");
|
|
2834
|
+
this.hasStartedRole = true;
|
|
2838
2835
|
}
|
|
2836
|
+
await this.streamHelper.streamText(newText, 50);
|
|
2837
|
+
this.collectedParts.push({
|
|
2838
|
+
kind: "text",
|
|
2839
|
+
text: newText
|
|
2840
|
+
});
|
|
2839
2841
|
}
|
|
2840
|
-
|
|
2842
|
+
continue;
|
|
2841
2843
|
}
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
const
|
|
2845
|
-
|
|
2846
|
-
await this.
|
|
2844
|
+
if (this.isComponentComplete(component)) {
|
|
2845
|
+
const currentPropsSnapshot = JSON.stringify(component.props);
|
|
2846
|
+
const previousPropsSnapshot = previousSnapshot ? JSON.stringify(JSON.parse(previousSnapshot).props) : null;
|
|
2847
|
+
if (previousPropsSnapshot === currentPropsSnapshot) {
|
|
2848
|
+
await this.streamComponent(component);
|
|
2847
2849
|
}
|
|
2848
2850
|
}
|
|
2849
|
-
break;
|
|
2850
2851
|
}
|
|
2851
2852
|
}
|
|
2852
|
-
|
|
2853
|
+
}
|
|
2854
|
+
/**
|
|
2855
|
+
* Stream a component and mark it as streamed
|
|
2856
|
+
* Note: Text components are handled separately with incremental streaming
|
|
2857
|
+
*/
|
|
2858
|
+
async streamComponent(component) {
|
|
2859
|
+
const parts = await this.artifactParser.parseObject({
|
|
2860
|
+
dataComponents: [component]
|
|
2861
|
+
});
|
|
2862
|
+
for (const part of parts) {
|
|
2863
|
+
await this.streamPart(part);
|
|
2864
|
+
}
|
|
2865
|
+
this.lastStreamedComponents.set(component.id, true);
|
|
2866
|
+
if (this.lastStreamedComponents.size > _IncrementalStreamParser.MAX_STREAMED_SIZE) {
|
|
2867
|
+
const firstKey = this.lastStreamedComponents.keys().next().value;
|
|
2868
|
+
if (firstKey) {
|
|
2869
|
+
this.lastStreamedComponents.delete(firstKey);
|
|
2870
|
+
}
|
|
2871
|
+
}
|
|
2872
|
+
this.componentSnapshots.delete(component.id);
|
|
2873
|
+
}
|
|
2874
|
+
/**
|
|
2875
|
+
* Check if a component has the basic structure required for streaming
|
|
2876
|
+
* Requires id, name, and props object with content
|
|
2877
|
+
*/
|
|
2878
|
+
isComponentComplete(component) {
|
|
2879
|
+
if (!component || !component.id || !component.name) {
|
|
2880
|
+
return false;
|
|
2881
|
+
}
|
|
2882
|
+
if (!component.props || typeof component.props !== "object") {
|
|
2883
|
+
return false;
|
|
2884
|
+
}
|
|
2885
|
+
const isArtifact = component.name === "Artifact" || component.props.artifact_id && component.props.task_id;
|
|
2886
|
+
if (isArtifact) {
|
|
2887
|
+
return Boolean(component.props.artifact_id && component.props.task_id);
|
|
2888
|
+
}
|
|
2889
|
+
return true;
|
|
2890
|
+
}
|
|
2891
|
+
/**
|
|
2892
|
+
* Deep merge helper for object deltas
|
|
2893
|
+
*/
|
|
2894
|
+
deepMerge(target, source) {
|
|
2895
|
+
if (!source) return target;
|
|
2896
|
+
if (!target) return source;
|
|
2897
|
+
const result = { ...target };
|
|
2898
|
+
for (const key in source) {
|
|
2899
|
+
if (source[key] && typeof source[key] === "object" && !Array.isArray(source[key])) {
|
|
2900
|
+
result[key] = this.deepMerge(target[key], source[key]);
|
|
2901
|
+
} else {
|
|
2902
|
+
result[key] = source[key];
|
|
2903
|
+
}
|
|
2904
|
+
}
|
|
2905
|
+
return result;
|
|
2853
2906
|
}
|
|
2854
2907
|
/**
|
|
2855
2908
|
* Legacy method for backward compatibility - defaults to text processing
|
|
@@ -2861,15 +2914,40 @@ var IncrementalStreamParser = class {
|
|
|
2861
2914
|
* Process any remaining buffer content at the end of stream
|
|
2862
2915
|
*/
|
|
2863
2916
|
async finalize() {
|
|
2864
|
-
if (this.
|
|
2917
|
+
if (this.componentAccumulator.dataComponents && Array.isArray(this.componentAccumulator.dataComponents)) {
|
|
2918
|
+
const components = this.componentAccumulator.dataComponents;
|
|
2919
|
+
for (let i = 0; i < components.length; i++) {
|
|
2920
|
+
const component = components[i];
|
|
2921
|
+
if (!component?.id) continue;
|
|
2922
|
+
const componentKey = component.id;
|
|
2923
|
+
const hasBeenStreamed = this.lastStreamedComponents.has(componentKey);
|
|
2924
|
+
if (!hasBeenStreamed && this.isComponentComplete(component) && component.name !== "Text") {
|
|
2925
|
+
const parts = await this.artifactParser.parseObject({
|
|
2926
|
+
dataComponents: [component]
|
|
2927
|
+
});
|
|
2928
|
+
for (const part of parts) {
|
|
2929
|
+
await this.streamPart(part);
|
|
2930
|
+
}
|
|
2931
|
+
this.lastStreamedComponents.set(componentKey, true);
|
|
2932
|
+
if (this.lastStreamedComponents.size > _IncrementalStreamParser.MAX_STREAMED_SIZE) {
|
|
2933
|
+
const firstKey = this.lastStreamedComponents.keys().next().value;
|
|
2934
|
+
if (firstKey) {
|
|
2935
|
+
this.lastStreamedComponents.delete(firstKey);
|
|
2936
|
+
}
|
|
2937
|
+
}
|
|
2938
|
+
this.componentSnapshots.delete(componentKey);
|
|
2939
|
+
}
|
|
2940
|
+
}
|
|
2941
|
+
}
|
|
2942
|
+
if (this.buffer) {
|
|
2865
2943
|
const part = {
|
|
2866
2944
|
kind: "text",
|
|
2867
|
-
text: this.buffer
|
|
2945
|
+
text: this.buffer
|
|
2868
2946
|
};
|
|
2869
2947
|
await this.streamPart(part);
|
|
2870
2948
|
}
|
|
2871
|
-
if (this.pendingTextBuffer
|
|
2872
|
-
const cleanedText = this.pendingTextBuffer.replace(/<\/?artifact:ref(?:\s[^>]*)?>\/?>/g, "").replace(/<\/?artifact(?:\s[^>]*)?>\/?>/g, "").replace(/<\/(?:\w+:)?artifact>/g, "")
|
|
2949
|
+
if (this.pendingTextBuffer) {
|
|
2950
|
+
const cleanedText = this.pendingTextBuffer.replace(/<\/?artifact:ref(?:\s[^>]*)?>\/?>/g, "").replace(/<\/?artifact(?:\s[^>]*)?>\/?>/g, "").replace(/<\/(?:\w+:)?artifact>/g, "");
|
|
2873
2951
|
if (cleanedText) {
|
|
2874
2952
|
this.collectedParts.push({
|
|
2875
2953
|
kind: "text",
|
|
@@ -2879,6 +2957,9 @@ var IncrementalStreamParser = class {
|
|
|
2879
2957
|
}
|
|
2880
2958
|
this.pendingTextBuffer = "";
|
|
2881
2959
|
}
|
|
2960
|
+
this.componentSnapshots.clear();
|
|
2961
|
+
this.lastStreamedComponents.clear();
|
|
2962
|
+
this.componentAccumulator = {};
|
|
2882
2963
|
}
|
|
2883
2964
|
/**
|
|
2884
2965
|
* Get all collected parts for building the final response
|
|
@@ -2925,30 +3006,6 @@ var IncrementalStreamParser = class {
|
|
|
2925
3006
|
remainingBuffer: ""
|
|
2926
3007
|
};
|
|
2927
3008
|
}
|
|
2928
|
-
/**
|
|
2929
|
-
* Parse buffer for complete JSON objects with artifact references (for object streaming)
|
|
2930
|
-
*/
|
|
2931
|
-
async parseObjectBuffer() {
|
|
2932
|
-
const completeParts = [];
|
|
2933
|
-
try {
|
|
2934
|
-
const parsed = JSON.parse(this.buffer);
|
|
2935
|
-
const parts = await this.artifactParser.parseObject(parsed);
|
|
2936
|
-
return {
|
|
2937
|
-
completeParts: parts,
|
|
2938
|
-
remainingBuffer: ""
|
|
2939
|
-
};
|
|
2940
|
-
} catch {
|
|
2941
|
-
const { complete, remaining } = this.artifactParser.parsePartialJSON(this.buffer);
|
|
2942
|
-
for (const obj of complete) {
|
|
2943
|
-
const parts = await this.artifactParser.parseObject(obj);
|
|
2944
|
-
completeParts.push(...parts);
|
|
2945
|
-
}
|
|
2946
|
-
return {
|
|
2947
|
-
completeParts,
|
|
2948
|
-
remainingBuffer: remaining
|
|
2949
|
-
};
|
|
2950
|
-
}
|
|
2951
|
-
}
|
|
2952
3009
|
/**
|
|
2953
3010
|
* Check if text might be the start of an artifact marker
|
|
2954
3011
|
*/
|
|
@@ -2969,7 +3026,7 @@ var IncrementalStreamParser = class {
|
|
|
2969
3026
|
this.pendingTextBuffer += part.text;
|
|
2970
3027
|
if (!this.artifactParser.hasIncompleteArtifact(this.pendingTextBuffer)) {
|
|
2971
3028
|
const cleanedText = this.pendingTextBuffer.replace(/<\/?artifact:ref(?:\s[^>]*)?>\/?>/g, "").replace(/<\/?artifact(?:\s[^>]*)?>\/?>/g, "").replace(/<\/(?:\w+:)?artifact>/g, "");
|
|
2972
|
-
if (cleanedText
|
|
3029
|
+
if (cleanedText) {
|
|
2973
3030
|
await this.streamHelper.streamText(cleanedText, 50);
|
|
2974
3031
|
}
|
|
2975
3032
|
this.pendingTextBuffer = "";
|
|
@@ -2977,7 +3034,7 @@ var IncrementalStreamParser = class {
|
|
|
2977
3034
|
} else if (part.kind === "data" && part.data) {
|
|
2978
3035
|
if (this.pendingTextBuffer) {
|
|
2979
3036
|
const cleanedText = this.pendingTextBuffer.replace(/<\/?artifact:ref(?:\s[^>]*)?>\/?>/g, "").replace(/<\/?artifact(?:\s[^>]*)?>\/?>/g, "").replace(/<\/(?:\w+:)?artifact>/g, "");
|
|
2980
|
-
if (cleanedText
|
|
3037
|
+
if (cleanedText) {
|
|
2981
3038
|
await this.streamHelper.streamText(cleanedText, 50);
|
|
2982
3039
|
}
|
|
2983
3040
|
this.pendingTextBuffer = "";
|
|
@@ -2991,6 +3048,11 @@ var IncrementalStreamParser = class {
|
|
|
2991
3048
|
}
|
|
2992
3049
|
}
|
|
2993
3050
|
};
|
|
3051
|
+
// Memory management constants
|
|
3052
|
+
__publicField(_IncrementalStreamParser, "MAX_SNAPSHOT_SIZE", 100);
|
|
3053
|
+
// Max number of snapshots to keep
|
|
3054
|
+
__publicField(_IncrementalStreamParser, "MAX_STREAMED_SIZE", 1e3);
|
|
3055
|
+
var IncrementalStreamParser = _IncrementalStreamParser;
|
|
2994
3056
|
|
|
2995
3057
|
// src/utils/response-formatter.ts
|
|
2996
3058
|
var logger9 = getLogger("ResponseFormatter");
|
|
@@ -4377,7 +4439,8 @@ function createDelegateToAgentTool({
|
|
|
4377
4439
|
const externalAgent = await getExternalAgent(dbClient_default)({
|
|
4378
4440
|
scopes: {
|
|
4379
4441
|
tenantId,
|
|
4380
|
-
projectId
|
|
4442
|
+
projectId,
|
|
4443
|
+
graphId
|
|
4381
4444
|
},
|
|
4382
4445
|
agentId: delegateConfig.config.id
|
|
4383
4446
|
});
|
|
@@ -4979,6 +5042,23 @@ var Agent = class {
|
|
|
4979
5042
|
__publicField(this, "credentialStoreRegistry");
|
|
4980
5043
|
this.artifactComponents = config.artifactComponents || [];
|
|
4981
5044
|
let processedDataComponents = config.dataComponents || [];
|
|
5045
|
+
if (processedDataComponents.length > 0) {
|
|
5046
|
+
processedDataComponents.push({
|
|
5047
|
+
id: "text-content",
|
|
5048
|
+
name: "Text",
|
|
5049
|
+
description: "Natural conversational text for the user - write naturally without mentioning technical details. Avoid redundancy and repetition with data components.",
|
|
5050
|
+
props: {
|
|
5051
|
+
type: "object",
|
|
5052
|
+
properties: {
|
|
5053
|
+
text: {
|
|
5054
|
+
type: "string",
|
|
5055
|
+
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."
|
|
5056
|
+
}
|
|
5057
|
+
},
|
|
5058
|
+
required: ["text"]
|
|
5059
|
+
}
|
|
5060
|
+
});
|
|
5061
|
+
}
|
|
4982
5062
|
if (this.artifactComponents.length > 0 && config.dataComponents && config.dataComponents.length > 0) {
|
|
4983
5063
|
processedDataComponents = [
|
|
4984
5064
|
ArtifactReferenceSchema.getDataComponent(config.tenantId, config.projectId),
|
|
@@ -5249,8 +5329,12 @@ var Agent = class {
|
|
|
5249
5329
|
async getMcpTool(tool4) {
|
|
5250
5330
|
const credentialReferenceId = tool4.credentialReferenceId;
|
|
5251
5331
|
const toolsForAgent = await getToolsForAgent(dbClient_default)({
|
|
5252
|
-
scopes: {
|
|
5253
|
-
|
|
5332
|
+
scopes: {
|
|
5333
|
+
tenantId: this.config.tenantId,
|
|
5334
|
+
projectId: this.config.projectId,
|
|
5335
|
+
graphId: this.config.graphId,
|
|
5336
|
+
agentId: this.config.id
|
|
5337
|
+
}
|
|
5254
5338
|
});
|
|
5255
5339
|
const selectedTools = toolsForAgent.data.find((t) => t.toolId === tool4.id)?.selectedTools || void 0;
|
|
5256
5340
|
let serverConfig;
|
|
@@ -5397,9 +5481,9 @@ var Agent = class {
|
|
|
5397
5481
|
const graphDefinition = await getFullGraphDefinition(dbClient_default)({
|
|
5398
5482
|
scopes: {
|
|
5399
5483
|
tenantId: this.config.tenantId,
|
|
5400
|
-
projectId: this.config.projectId
|
|
5401
|
-
|
|
5402
|
-
|
|
5484
|
+
projectId: this.config.projectId,
|
|
5485
|
+
graphId: this.config.graphId
|
|
5486
|
+
}
|
|
5403
5487
|
});
|
|
5404
5488
|
return graphDefinition?.graphPrompt || void 0;
|
|
5405
5489
|
} catch (error) {
|
|
@@ -5421,14 +5505,16 @@ var Agent = class {
|
|
|
5421
5505
|
const graphDefinition = await getFullGraphDefinition(dbClient_default)({
|
|
5422
5506
|
scopes: {
|
|
5423
5507
|
tenantId: this.config.tenantId,
|
|
5424
|
-
projectId: this.config.projectId
|
|
5425
|
-
|
|
5426
|
-
|
|
5508
|
+
projectId: this.config.projectId,
|
|
5509
|
+
graphId: this.config.graphId
|
|
5510
|
+
}
|
|
5427
5511
|
});
|
|
5428
5512
|
if (!graphDefinition) {
|
|
5429
5513
|
return false;
|
|
5430
5514
|
}
|
|
5431
|
-
return
|
|
5515
|
+
return Object.values(graphDefinition.agents).some(
|
|
5516
|
+
(agent) => "artifactComponents" in agent && agent.artifactComponents && agent.artifactComponents.length > 0
|
|
5517
|
+
);
|
|
5432
5518
|
} catch (error) {
|
|
5433
5519
|
logger15.warn(
|
|
5434
5520
|
{
|
|
@@ -5456,7 +5542,8 @@ Key requirements:
|
|
|
5456
5542
|
- Mix artifact references throughout your dataComponents array
|
|
5457
5543
|
- Each artifact reference must use EXACT IDs from tool outputs
|
|
5458
5544
|
- Reference artifacts that directly support the adjacent information
|
|
5459
|
-
- Follow the pattern: Data \u2192 Supporting Artifact \u2192 Next Data \u2192 Next Artifact
|
|
5545
|
+
- Follow the pattern: Data \u2192 Supporting Artifact \u2192 Next Data \u2192 Next Artifact
|
|
5546
|
+
- IMPORTANT: In Text components, write naturally as if having a conversation - do NOT mention components, schemas, JSON, structured data, or any technical implementation details`;
|
|
5460
5547
|
}
|
|
5461
5548
|
if (hasDataComponents && !hasArtifactComponents) {
|
|
5462
5549
|
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.
|
|
@@ -5464,7 +5551,8 @@ Key requirements:
|
|
|
5464
5551
|
Key requirements:
|
|
5465
5552
|
- Use the exact component structure and property names
|
|
5466
5553
|
- Fill in all relevant data from the research
|
|
5467
|
-
- Ensure data is organized logically and completely
|
|
5554
|
+
- Ensure data is organized logically and completely
|
|
5555
|
+
- IMPORTANT: In Text components, write naturally as if having a conversation - do NOT mention components, schemas, JSON, structured data, or any technical implementation details`;
|
|
5468
5556
|
}
|
|
5469
5557
|
if (!hasDataComponents && hasArtifactComponents) {
|
|
5470
5558
|
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.
|
|
@@ -5474,7 +5562,7 @@ Key requirements:
|
|
|
5474
5562
|
- Reference artifacts that support your response
|
|
5475
5563
|
- Never make up or modify artifact IDs`;
|
|
5476
5564
|
}
|
|
5477
|
-
return `Generate the final response based on the research above.`;
|
|
5565
|
+
return `Generate the final response based on the research above. Write naturally as if having a conversation.`;
|
|
5478
5566
|
}
|
|
5479
5567
|
async buildSystemPrompt(runtimeContext, excludeDataComponents = false) {
|
|
5480
5568
|
const conversationId = runtimeContext?.metadata?.conversationId || runtimeContext?.contextId;
|
|
@@ -5625,9 +5713,9 @@ Key requirements:
|
|
|
5625
5713
|
return await graphHasArtifactComponents(dbClient_default)({
|
|
5626
5714
|
scopes: {
|
|
5627
5715
|
tenantId: this.config.tenantId,
|
|
5628
|
-
projectId: this.config.projectId
|
|
5629
|
-
|
|
5630
|
-
|
|
5716
|
+
projectId: this.config.projectId,
|
|
5717
|
+
graphId: this.config.graphId
|
|
5718
|
+
}
|
|
5631
5719
|
});
|
|
5632
5720
|
} catch (error) {
|
|
5633
5721
|
logger15.error(
|
|
@@ -5973,35 +6061,94 @@ ${output}`;
|
|
|
5973
6061
|
this.getStructuredOutputModel()
|
|
5974
6062
|
);
|
|
5975
6063
|
const phase2TimeoutMs = structuredModelSettings.maxDuration ? structuredModelSettings.maxDuration * 1e3 : CONSTANTS.PHASE_2_TIMEOUT_MS;
|
|
5976
|
-
const
|
|
5977
|
-
|
|
5978
|
-
|
|
5979
|
-
|
|
5980
|
-
|
|
5981
|
-
|
|
5982
|
-
|
|
5983
|
-
|
|
5984
|
-
|
|
5985
|
-
|
|
5986
|
-
|
|
5987
|
-
|
|
5988
|
-
|
|
5989
|
-
|
|
5990
|
-
|
|
5991
|
-
|
|
5992
|
-
|
|
5993
|
-
|
|
5994
|
-
|
|
5995
|
-
|
|
6064
|
+
const shouldStreamPhase2 = this.getStreamingHelper();
|
|
6065
|
+
if (shouldStreamPhase2) {
|
|
6066
|
+
const streamResult = streamObject({
|
|
6067
|
+
...structuredModelSettings,
|
|
6068
|
+
messages: [
|
|
6069
|
+
{ role: "user", content: userMessage },
|
|
6070
|
+
...reasoningFlow,
|
|
6071
|
+
{
|
|
6072
|
+
role: "user",
|
|
6073
|
+
content: await this.buildPhase2SystemPrompt()
|
|
6074
|
+
}
|
|
6075
|
+
],
|
|
6076
|
+
schema: z.object({
|
|
6077
|
+
dataComponents: z.array(dataComponentsSchema)
|
|
6078
|
+
}),
|
|
6079
|
+
experimental_telemetry: {
|
|
6080
|
+
isEnabled: true,
|
|
6081
|
+
functionId: this.config.id,
|
|
6082
|
+
recordInputs: true,
|
|
6083
|
+
recordOutputs: true,
|
|
6084
|
+
metadata: {
|
|
6085
|
+
phase: "structured_generation"
|
|
6086
|
+
}
|
|
6087
|
+
},
|
|
6088
|
+
abortSignal: AbortSignal.timeout(phase2TimeoutMs)
|
|
6089
|
+
});
|
|
6090
|
+
const streamHelper = this.getStreamingHelper();
|
|
6091
|
+
if (!streamHelper) {
|
|
6092
|
+
throw new Error("Stream helper is unexpectedly undefined in streaming context");
|
|
6093
|
+
}
|
|
6094
|
+
const parser = new IncrementalStreamParser(
|
|
6095
|
+
streamHelper,
|
|
6096
|
+
this.config.tenantId,
|
|
6097
|
+
contextId
|
|
6098
|
+
);
|
|
6099
|
+
for await (const delta of streamResult.partialObjectStream) {
|
|
6100
|
+
if (delta) {
|
|
6101
|
+
await parser.processObjectDelta(delta);
|
|
5996
6102
|
}
|
|
5997
|
-
}
|
|
5998
|
-
|
|
5999
|
-
|
|
6000
|
-
|
|
6001
|
-
|
|
6002
|
-
|
|
6003
|
-
|
|
6004
|
-
|
|
6103
|
+
}
|
|
6104
|
+
await parser.finalize();
|
|
6105
|
+
const structuredResponse = await streamResult;
|
|
6106
|
+
const collectedParts = parser.getCollectedParts();
|
|
6107
|
+
if (collectedParts.length > 0) {
|
|
6108
|
+
response.formattedContent = {
|
|
6109
|
+
parts: collectedParts.map((part) => ({
|
|
6110
|
+
kind: part.kind,
|
|
6111
|
+
...part.kind === "text" && { text: part.text },
|
|
6112
|
+
...part.kind === "data" && { data: part.data }
|
|
6113
|
+
}))
|
|
6114
|
+
};
|
|
6115
|
+
}
|
|
6116
|
+
response = {
|
|
6117
|
+
...response,
|
|
6118
|
+
object: structuredResponse.object
|
|
6119
|
+
};
|
|
6120
|
+
textResponse = JSON.stringify(structuredResponse.object, null, 2);
|
|
6121
|
+
} else {
|
|
6122
|
+
const structuredResponse = await generateObject({
|
|
6123
|
+
...structuredModelSettings,
|
|
6124
|
+
messages: [
|
|
6125
|
+
{ role: "user", content: userMessage },
|
|
6126
|
+
...reasoningFlow,
|
|
6127
|
+
{
|
|
6128
|
+
role: "user",
|
|
6129
|
+
content: await this.buildPhase2SystemPrompt()
|
|
6130
|
+
}
|
|
6131
|
+
],
|
|
6132
|
+
schema: z.object({
|
|
6133
|
+
dataComponents: z.array(dataComponentsSchema)
|
|
6134
|
+
}),
|
|
6135
|
+
experimental_telemetry: {
|
|
6136
|
+
isEnabled: true,
|
|
6137
|
+
functionId: this.config.id,
|
|
6138
|
+
recordInputs: true,
|
|
6139
|
+
recordOutputs: true,
|
|
6140
|
+
metadata: {
|
|
6141
|
+
phase: "structured_generation"
|
|
6142
|
+
}
|
|
6143
|
+
},
|
|
6144
|
+
abortSignal: AbortSignal.timeout(phase2TimeoutMs)
|
|
6145
|
+
});
|
|
6146
|
+
response = {
|
|
6147
|
+
...response,
|
|
6148
|
+
object: structuredResponse.object
|
|
6149
|
+
};
|
|
6150
|
+
textResponse = JSON.stringify(structuredResponse.object, null, 2);
|
|
6151
|
+
}
|
|
6005
6152
|
} else {
|
|
6006
6153
|
textResponse = response.text || "";
|
|
6007
6154
|
}
|
|
@@ -6046,39 +6193,6 @@ ${output}`;
|
|
|
6046
6193
|
});
|
|
6047
6194
|
}
|
|
6048
6195
|
};
|
|
6049
|
-
async function resolveModelConfig(graphId, agent) {
|
|
6050
|
-
if (agent.models?.base?.model) {
|
|
6051
|
-
return {
|
|
6052
|
-
base: agent.models.base,
|
|
6053
|
-
structuredOutput: agent.models.structuredOutput || agent.models.base,
|
|
6054
|
-
summarizer: agent.models.summarizer || agent.models.base
|
|
6055
|
-
};
|
|
6056
|
-
}
|
|
6057
|
-
const graph = await getAgentGraph(dbClient_default)({
|
|
6058
|
-
scopes: { tenantId: agent.tenantId, projectId: agent.projectId },
|
|
6059
|
-
graphId
|
|
6060
|
-
});
|
|
6061
|
-
if (graph?.models?.base?.model) {
|
|
6062
|
-
return {
|
|
6063
|
-
base: graph.models.base,
|
|
6064
|
-
structuredOutput: agent.models?.structuredOutput || graph.models.structuredOutput || graph.models.base,
|
|
6065
|
-
summarizer: agent.models?.summarizer || graph.models.summarizer || graph.models.base
|
|
6066
|
-
};
|
|
6067
|
-
}
|
|
6068
|
-
const project = await getProject(dbClient_default)({
|
|
6069
|
-
scopes: { tenantId: agent.tenantId, projectId: agent.projectId }
|
|
6070
|
-
});
|
|
6071
|
-
if (project?.models?.base?.model) {
|
|
6072
|
-
return {
|
|
6073
|
-
base: project.models.base,
|
|
6074
|
-
structuredOutput: agent.models?.structuredOutput || project.models.structuredOutput || project.models.base,
|
|
6075
|
-
summarizer: agent.models?.summarizer || project.models.summarizer || project.models.base
|
|
6076
|
-
};
|
|
6077
|
-
}
|
|
6078
|
-
throw new Error(
|
|
6079
|
-
"Base model configuration is required. Please configure models at the project level."
|
|
6080
|
-
);
|
|
6081
|
-
}
|
|
6082
6196
|
|
|
6083
6197
|
// src/agents/generateTaskHandler.ts
|
|
6084
6198
|
function parseEmbeddedJson(data) {
|
|
@@ -6114,31 +6228,34 @@ var createTaskHandler = (config, credentialStoreRegistry) => {
|
|
|
6114
6228
|
getRelatedAgentsForGraph(dbClient_default)({
|
|
6115
6229
|
scopes: {
|
|
6116
6230
|
tenantId: config.tenantId,
|
|
6117
|
-
projectId: config.projectId
|
|
6231
|
+
projectId: config.projectId,
|
|
6232
|
+
graphId: config.graphId
|
|
6118
6233
|
},
|
|
6119
|
-
graphId: config.graphId,
|
|
6120
6234
|
agentId: config.agentId
|
|
6121
6235
|
}),
|
|
6122
6236
|
getToolsForAgent(dbClient_default)({
|
|
6123
6237
|
scopes: {
|
|
6124
6238
|
tenantId: config.tenantId,
|
|
6125
|
-
projectId: config.projectId
|
|
6126
|
-
|
|
6127
|
-
|
|
6239
|
+
projectId: config.projectId,
|
|
6240
|
+
graphId: config.graphId,
|
|
6241
|
+
agentId: config.agentId
|
|
6242
|
+
}
|
|
6128
6243
|
}),
|
|
6129
6244
|
getDataComponentsForAgent(dbClient_default)({
|
|
6130
6245
|
scopes: {
|
|
6131
6246
|
tenantId: config.tenantId,
|
|
6132
|
-
projectId: config.projectId
|
|
6133
|
-
|
|
6134
|
-
|
|
6247
|
+
projectId: config.projectId,
|
|
6248
|
+
graphId: config.graphId,
|
|
6249
|
+
agentId: config.agentId
|
|
6250
|
+
}
|
|
6135
6251
|
}),
|
|
6136
6252
|
getArtifactComponentsForAgent(dbClient_default)({
|
|
6137
6253
|
scopes: {
|
|
6138
6254
|
tenantId: config.tenantId,
|
|
6139
|
-
projectId: config.projectId
|
|
6140
|
-
|
|
6141
|
-
|
|
6255
|
+
projectId: config.projectId,
|
|
6256
|
+
graphId: config.graphId,
|
|
6257
|
+
agentId: config.agentId
|
|
6258
|
+
}
|
|
6142
6259
|
})
|
|
6143
6260
|
]);
|
|
6144
6261
|
logger16.info({ toolsForAgent, internalRelations, externalRelations }, "agent stuff");
|
|
@@ -6146,13 +6263,16 @@ var createTaskHandler = (config, credentialStoreRegistry) => {
|
|
|
6146
6263
|
internalRelations.map(async (relation) => {
|
|
6147
6264
|
try {
|
|
6148
6265
|
const relatedAgent = await getAgentById(dbClient_default)({
|
|
6149
|
-
scopes: {
|
|
6266
|
+
scopes: {
|
|
6267
|
+
tenantId: config.tenantId,
|
|
6268
|
+
projectId: config.projectId,
|
|
6269
|
+
graphId: config.graphId
|
|
6270
|
+
},
|
|
6150
6271
|
agentId: relation.id
|
|
6151
6272
|
});
|
|
6152
6273
|
if (relatedAgent) {
|
|
6153
6274
|
const relatedAgentRelations = await getRelatedAgentsForGraph(dbClient_default)({
|
|
6154
|
-
scopes: { tenantId: config.tenantId, projectId: config.projectId },
|
|
6155
|
-
graphId: config.graphId,
|
|
6275
|
+
scopes: { tenantId: config.tenantId, projectId: config.projectId, graphId: config.graphId },
|
|
6156
6276
|
agentId: relation.id
|
|
6157
6277
|
});
|
|
6158
6278
|
const enhancedDescription = generateDescriptionWithTransfers(
|
|
@@ -6375,16 +6495,17 @@ var createTaskHandlerConfig = async (params) => {
|
|
|
6375
6495
|
const agent = await getAgentById(dbClient_default)({
|
|
6376
6496
|
scopes: {
|
|
6377
6497
|
tenantId: params.tenantId,
|
|
6378
|
-
projectId: params.projectId
|
|
6498
|
+
projectId: params.projectId,
|
|
6499
|
+
graphId: params.graphId
|
|
6379
6500
|
},
|
|
6380
6501
|
agentId: params.agentId
|
|
6381
6502
|
});
|
|
6382
|
-
const agentGraph = await
|
|
6503
|
+
const agentGraph = await getAgentGraphById(dbClient_default)({
|
|
6383
6504
|
scopes: {
|
|
6384
6505
|
tenantId: params.tenantId,
|
|
6385
|
-
projectId: params.projectId
|
|
6386
|
-
|
|
6387
|
-
|
|
6506
|
+
projectId: params.projectId,
|
|
6507
|
+
graphId: params.graphId
|
|
6508
|
+
}
|
|
6388
6509
|
});
|
|
6389
6510
|
if (!agent) {
|
|
6390
6511
|
throw new Error(`Agent not found: ${params.agentId}`);
|
|
@@ -6423,10 +6544,14 @@ async function hydrateGraph({
|
|
|
6423
6544
|
apiKey
|
|
6424
6545
|
}) {
|
|
6425
6546
|
try {
|
|
6547
|
+
if (!dbGraph.defaultAgentId) {
|
|
6548
|
+
throw new Error(`Graph ${dbGraph.id} does not have a default agent configured`);
|
|
6549
|
+
}
|
|
6426
6550
|
const defaultAgent = await getAgentById(dbClient_default)({
|
|
6427
6551
|
scopes: {
|
|
6428
6552
|
tenantId: dbGraph.tenantId,
|
|
6429
|
-
projectId: dbGraph.projectId
|
|
6553
|
+
projectId: dbGraph.projectId,
|
|
6554
|
+
graphId: dbGraph.id
|
|
6430
6555
|
},
|
|
6431
6556
|
agentId: dbGraph.defaultAgentId
|
|
6432
6557
|
});
|
|
@@ -6481,7 +6606,7 @@ async function hydrateGraph({
|
|
|
6481
6606
|
}
|
|
6482
6607
|
async function getRegisteredGraph(executionContext) {
|
|
6483
6608
|
const { tenantId, projectId, graphId, baseUrl, apiKey } = executionContext;
|
|
6484
|
-
const dbGraph = await
|
|
6609
|
+
const dbGraph = await getAgentGraphById(dbClient_default)({ scopes: { tenantId, projectId, graphId } });
|
|
6485
6610
|
if (!dbGraph) {
|
|
6486
6611
|
return null;
|
|
6487
6612
|
}
|
|
@@ -6539,6 +6664,7 @@ app.openapi(
|
|
|
6539
6664
|
);
|
|
6540
6665
|
const executionContext = getRequestExecutionContext(c);
|
|
6541
6666
|
const { tenantId, projectId, graphId, agentId } = executionContext;
|
|
6667
|
+
console.dir("executionContext", executionContext);
|
|
6542
6668
|
if (agentId) {
|
|
6543
6669
|
logger17.info(
|
|
6544
6670
|
{
|
|
@@ -6626,8 +6752,7 @@ app.post("/a2a", async (c) => {
|
|
|
6626
6752
|
"graph-level a2a endpoint"
|
|
6627
6753
|
);
|
|
6628
6754
|
const graph = await getAgentGraphWithDefaultAgent(dbClient_default)({
|
|
6629
|
-
scopes: { tenantId, projectId }
|
|
6630
|
-
graphId
|
|
6755
|
+
scopes: { tenantId, projectId, graphId }
|
|
6631
6756
|
});
|
|
6632
6757
|
if (!graph) {
|
|
6633
6758
|
return c.json(
|
|
@@ -6639,6 +6764,16 @@ app.post("/a2a", async (c) => {
|
|
|
6639
6764
|
404
|
|
6640
6765
|
);
|
|
6641
6766
|
}
|
|
6767
|
+
if (!graph.defaultAgentId) {
|
|
6768
|
+
return c.json(
|
|
6769
|
+
{
|
|
6770
|
+
jsonrpc: "2.0",
|
|
6771
|
+
error: { code: -32004, message: "Graph does not have a default agent configured" },
|
|
6772
|
+
id: null
|
|
6773
|
+
},
|
|
6774
|
+
400
|
|
6775
|
+
);
|
|
6776
|
+
}
|
|
6642
6777
|
executionContext.agentId = graph.defaultAgentId;
|
|
6643
6778
|
const credentialStores = c.get("credentialStores");
|
|
6644
6779
|
const defaultAgent = await getRegisteredAgent(executionContext, credentialStores);
|
|
@@ -6683,7 +6818,7 @@ var SSEStreamHelper = class {
|
|
|
6683
6818
|
this.timestamp = timestamp;
|
|
6684
6819
|
// Stream queuing for proper event ordering
|
|
6685
6820
|
__publicField(this, "isTextStreaming", false);
|
|
6686
|
-
__publicField(this, "
|
|
6821
|
+
__publicField(this, "queuedEvents", []);
|
|
6687
6822
|
}
|
|
6688
6823
|
/**
|
|
6689
6824
|
* Write the initial role message
|
|
@@ -6748,9 +6883,10 @@ var SSEStreamHelper = class {
|
|
|
6748
6883
|
await this.writeContent(JSON.stringify(data));
|
|
6749
6884
|
}
|
|
6750
6885
|
/**
|
|
6751
|
-
* Write error message
|
|
6886
|
+
* Write error message or error event
|
|
6752
6887
|
*/
|
|
6753
|
-
async writeError(
|
|
6888
|
+
async writeError(error) {
|
|
6889
|
+
const errorMessage = typeof error === "string" ? error : error.message;
|
|
6754
6890
|
await this.writeContent(`
|
|
6755
6891
|
|
|
6756
6892
|
${errorMessage}`);
|
|
@@ -6774,22 +6910,6 @@ ${errorMessage}`);
|
|
|
6774
6910
|
})
|
|
6775
6911
|
});
|
|
6776
6912
|
}
|
|
6777
|
-
/**
|
|
6778
|
-
* Write the final [DONE] message
|
|
6779
|
-
*/
|
|
6780
|
-
async writeDone() {
|
|
6781
|
-
await this.stream.writeSSE({
|
|
6782
|
-
data: "[DONE]"
|
|
6783
|
-
});
|
|
6784
|
-
}
|
|
6785
|
-
/**
|
|
6786
|
-
* Complete the stream with finish reason and done message
|
|
6787
|
-
*/
|
|
6788
|
-
async complete(finishReason = "stop") {
|
|
6789
|
-
await this.flushQueuedOperations();
|
|
6790
|
-
await this.writeCompletion(finishReason);
|
|
6791
|
-
await this.writeDone();
|
|
6792
|
-
}
|
|
6793
6913
|
async writeData(type, data) {
|
|
6794
6914
|
await this.stream.writeSSE({
|
|
6795
6915
|
data: JSON.stringify({
|
|
@@ -6808,16 +6928,23 @@ ${errorMessage}`);
|
|
|
6808
6928
|
})
|
|
6809
6929
|
});
|
|
6810
6930
|
}
|
|
6811
|
-
async
|
|
6812
|
-
if (
|
|
6813
|
-
|
|
6814
|
-
type:
|
|
6815
|
-
|
|
6816
|
-
|
|
6817
|
-
|
|
6931
|
+
async writeSummary(summary) {
|
|
6932
|
+
if (this.isTextStreaming) {
|
|
6933
|
+
this.queuedEvents.push({
|
|
6934
|
+
type: "data-summary",
|
|
6935
|
+
event: summary
|
|
6936
|
+
});
|
|
6937
|
+
return;
|
|
6818
6938
|
}
|
|
6939
|
+
await this.flushQueuedOperations();
|
|
6940
|
+
await this.writeData("data-summary", summary);
|
|
6941
|
+
}
|
|
6942
|
+
async writeOperation(operation) {
|
|
6819
6943
|
if (this.isTextStreaming) {
|
|
6820
|
-
this.
|
|
6944
|
+
this.queuedEvents.push({
|
|
6945
|
+
type: "data-operation",
|
|
6946
|
+
event: operation
|
|
6947
|
+
});
|
|
6821
6948
|
return;
|
|
6822
6949
|
}
|
|
6823
6950
|
await this.flushQueuedOperations();
|
|
@@ -6827,15 +6954,31 @@ ${errorMessage}`);
|
|
|
6827
6954
|
* Flush all queued operations in order after text streaming completes
|
|
6828
6955
|
*/
|
|
6829
6956
|
async flushQueuedOperations() {
|
|
6830
|
-
if (this.
|
|
6957
|
+
if (this.queuedEvents.length === 0) {
|
|
6831
6958
|
return;
|
|
6832
6959
|
}
|
|
6833
|
-
const
|
|
6834
|
-
this.
|
|
6835
|
-
for (const
|
|
6836
|
-
await this.writeData(
|
|
6960
|
+
const eventsToFlush = [...this.queuedEvents];
|
|
6961
|
+
this.queuedEvents = [];
|
|
6962
|
+
for (const event of eventsToFlush) {
|
|
6963
|
+
await this.writeData(event.type, event.event);
|
|
6837
6964
|
}
|
|
6838
6965
|
}
|
|
6966
|
+
/**
|
|
6967
|
+
* Write the final [DONE] message
|
|
6968
|
+
*/
|
|
6969
|
+
async writeDone() {
|
|
6970
|
+
await this.stream.writeSSE({
|
|
6971
|
+
data: "[DONE]"
|
|
6972
|
+
});
|
|
6973
|
+
}
|
|
6974
|
+
/**
|
|
6975
|
+
* Complete the stream with finish reason and done message
|
|
6976
|
+
*/
|
|
6977
|
+
async complete(finishReason = "stop") {
|
|
6978
|
+
await this.flushQueuedOperations();
|
|
6979
|
+
await this.writeCompletion(finishReason);
|
|
6980
|
+
await this.writeDone();
|
|
6981
|
+
}
|
|
6839
6982
|
};
|
|
6840
6983
|
function createSSEStreamHelper(stream2, requestId2, timestamp) {
|
|
6841
6984
|
return new SSEStreamHelper(stream2, requestId2, timestamp);
|
|
@@ -6855,7 +6998,7 @@ var _VercelDataStreamHelper = class _VercelDataStreamHelper {
|
|
|
6855
6998
|
__publicField(this, "isCompleted", false);
|
|
6856
6999
|
// Stream queuing for proper event ordering
|
|
6857
7000
|
__publicField(this, "isTextStreaming", false);
|
|
6858
|
-
__publicField(this, "
|
|
7001
|
+
__publicField(this, "queuedEvents", []);
|
|
6859
7002
|
// Timing tracking for text sequences (text-end to text-start gap)
|
|
6860
7003
|
__publicField(this, "lastTextEndTimestamp", 0);
|
|
6861
7004
|
__publicField(this, "TEXT_GAP_THRESHOLD", 50);
|
|
@@ -6967,15 +7110,24 @@ var _VercelDataStreamHelper = class _VercelDataStreamHelper {
|
|
|
6967
7110
|
data
|
|
6968
7111
|
});
|
|
6969
7112
|
}
|
|
6970
|
-
async writeError(
|
|
7113
|
+
async writeError(error) {
|
|
6971
7114
|
if (this.isCompleted) {
|
|
6972
7115
|
console.warn("Attempted to write error to completed stream");
|
|
6973
7116
|
return;
|
|
6974
7117
|
}
|
|
6975
|
-
|
|
6976
|
-
|
|
6977
|
-
|
|
6978
|
-
|
|
7118
|
+
if (typeof error === "string") {
|
|
7119
|
+
this.writer.write({
|
|
7120
|
+
type: "error",
|
|
7121
|
+
message: error,
|
|
7122
|
+
severity: "error",
|
|
7123
|
+
timestamp: Date.now()
|
|
7124
|
+
});
|
|
7125
|
+
} else {
|
|
7126
|
+
this.writer.write({
|
|
7127
|
+
...error,
|
|
7128
|
+
type: "error"
|
|
7129
|
+
});
|
|
7130
|
+
}
|
|
6979
7131
|
}
|
|
6980
7132
|
async streamData(data) {
|
|
6981
7133
|
await this.writeContent(JSON.stringify(data));
|
|
@@ -6987,20 +7139,6 @@ var _VercelDataStreamHelper = class _VercelDataStreamHelper {
|
|
|
6987
7139
|
}
|
|
6988
7140
|
this.writer.merge(stream2);
|
|
6989
7141
|
}
|
|
6990
|
-
async writeCompletion(_finishReason = "stop") {
|
|
6991
|
-
}
|
|
6992
|
-
async writeDone() {
|
|
6993
|
-
}
|
|
6994
|
-
/**
|
|
6995
|
-
* Complete the stream and clean up all memory
|
|
6996
|
-
* This is the primary cleanup point to prevent memory leaks between requests
|
|
6997
|
-
*/
|
|
6998
|
-
async complete() {
|
|
6999
|
-
if (this.isCompleted) return;
|
|
7000
|
-
await this.flushQueuedOperations();
|
|
7001
|
-
this.isCompleted = true;
|
|
7002
|
-
this.cleanup();
|
|
7003
|
-
}
|
|
7004
7142
|
/**
|
|
7005
7143
|
* Clean up all memory allocations
|
|
7006
7144
|
* Should be called when the stream helper is no longer needed
|
|
@@ -7014,7 +7152,7 @@ var _VercelDataStreamHelper = class _VercelDataStreamHelper {
|
|
|
7014
7152
|
this.sentItems.clear();
|
|
7015
7153
|
this.completedItems.clear();
|
|
7016
7154
|
this.textId = null;
|
|
7017
|
-
this.
|
|
7155
|
+
this.queuedEvents = [];
|
|
7018
7156
|
this.isTextStreaming = false;
|
|
7019
7157
|
}
|
|
7020
7158
|
/**
|
|
@@ -7080,7 +7218,9 @@ var _VercelDataStreamHelper = class _VercelDataStreamHelper {
|
|
|
7080
7218
|
if (this.writer && !this.isCompleted) {
|
|
7081
7219
|
this.writer.write({
|
|
7082
7220
|
type: "error",
|
|
7083
|
-
|
|
7221
|
+
message: `Stream terminated: ${reason}`,
|
|
7222
|
+
severity: "error",
|
|
7223
|
+
timestamp: Date.now()
|
|
7084
7224
|
});
|
|
7085
7225
|
}
|
|
7086
7226
|
} catch (e) {
|
|
@@ -7103,23 +7243,33 @@ var _VercelDataStreamHelper = class _VercelDataStreamHelper {
|
|
|
7103
7243
|
isCompleted: this.isCompleted
|
|
7104
7244
|
};
|
|
7105
7245
|
}
|
|
7246
|
+
async writeSummary(summary) {
|
|
7247
|
+
if (this.isCompleted) {
|
|
7248
|
+
console.warn("Attempted to write summary to completed stream");
|
|
7249
|
+
return;
|
|
7250
|
+
}
|
|
7251
|
+
const now = Date.now();
|
|
7252
|
+
const gapFromLastTextEnd = this.lastTextEndTimestamp > 0 ? now - this.lastTextEndTimestamp : Number.MAX_SAFE_INTEGER;
|
|
7253
|
+
if (this.isTextStreaming || gapFromLastTextEnd < this.TEXT_GAP_THRESHOLD) {
|
|
7254
|
+
this.queuedEvents.push({ type: "data-summary", event: summary });
|
|
7255
|
+
return;
|
|
7256
|
+
}
|
|
7257
|
+
await this.flushQueuedOperations();
|
|
7258
|
+
await this.writer.write({
|
|
7259
|
+
id: "id" in summary ? summary.id : void 0,
|
|
7260
|
+
type: "data-summary",
|
|
7261
|
+
data: summary
|
|
7262
|
+
});
|
|
7263
|
+
}
|
|
7106
7264
|
async writeOperation(operation) {
|
|
7107
7265
|
if (this.isCompleted) {
|
|
7108
7266
|
console.warn("Attempted to write operation to completed stream");
|
|
7109
7267
|
return;
|
|
7110
7268
|
}
|
|
7111
|
-
if (operation.type === "status_update" && operation.ctx.label) {
|
|
7112
|
-
operation = {
|
|
7113
|
-
type: operation.type,
|
|
7114
|
-
label: operation.ctx.label,
|
|
7115
|
-
// Preserve the label for the UI
|
|
7116
|
-
ctx: operation.ctx.data
|
|
7117
|
-
};
|
|
7118
|
-
}
|
|
7119
7269
|
const now = Date.now();
|
|
7120
7270
|
const gapFromLastTextEnd = this.lastTextEndTimestamp > 0 ? now - this.lastTextEndTimestamp : Number.MAX_SAFE_INTEGER;
|
|
7121
7271
|
if (this.isTextStreaming || gapFromLastTextEnd < this.TEXT_GAP_THRESHOLD) {
|
|
7122
|
-
this.
|
|
7272
|
+
this.queuedEvents.push({ type: "data-operation", event: operation });
|
|
7123
7273
|
return;
|
|
7124
7274
|
}
|
|
7125
7275
|
await this.flushQueuedOperations();
|
|
@@ -7133,19 +7283,33 @@ var _VercelDataStreamHelper = class _VercelDataStreamHelper {
|
|
|
7133
7283
|
* Flush all queued operations in order after text streaming completes
|
|
7134
7284
|
*/
|
|
7135
7285
|
async flushQueuedOperations() {
|
|
7136
|
-
if (this.
|
|
7286
|
+
if (this.queuedEvents.length === 0) {
|
|
7137
7287
|
return;
|
|
7138
7288
|
}
|
|
7139
|
-
const
|
|
7140
|
-
this.
|
|
7141
|
-
for (const
|
|
7289
|
+
const eventsToFlush = [...this.queuedEvents];
|
|
7290
|
+
this.queuedEvents = [];
|
|
7291
|
+
for (const event of eventsToFlush) {
|
|
7142
7292
|
this.writer.write({
|
|
7143
|
-
id: "id" in
|
|
7144
|
-
type:
|
|
7145
|
-
data:
|
|
7293
|
+
id: "id" in event.event ? event.event.id : void 0,
|
|
7294
|
+
type: event.type,
|
|
7295
|
+
data: event.event
|
|
7146
7296
|
});
|
|
7147
7297
|
}
|
|
7148
7298
|
}
|
|
7299
|
+
async writeCompletion(_finishReason = "stop") {
|
|
7300
|
+
}
|
|
7301
|
+
async writeDone() {
|
|
7302
|
+
}
|
|
7303
|
+
/**
|
|
7304
|
+
* Complete the stream and clean up all memory
|
|
7305
|
+
* This is the primary cleanup point to prevent memory leaks between requests
|
|
7306
|
+
*/
|
|
7307
|
+
async complete() {
|
|
7308
|
+
if (this.isCompleted) return;
|
|
7309
|
+
await this.flushQueuedOperations();
|
|
7310
|
+
this.isCompleted = true;
|
|
7311
|
+
this.cleanup();
|
|
7312
|
+
}
|
|
7149
7313
|
};
|
|
7150
7314
|
// Memory management - focused on connection completion cleanup
|
|
7151
7315
|
__publicField(_VercelDataStreamHelper, "MAX_BUFFER_SIZE", 5 * 1024 * 1024);
|
|
@@ -7158,6 +7322,7 @@ var MCPStreamHelper = class {
|
|
|
7158
7322
|
__publicField(this, "capturedText", "");
|
|
7159
7323
|
__publicField(this, "capturedData", []);
|
|
7160
7324
|
__publicField(this, "capturedOperations", []);
|
|
7325
|
+
__publicField(this, "capturedSummaries", []);
|
|
7161
7326
|
__publicField(this, "hasError", false);
|
|
7162
7327
|
__publicField(this, "errorMessage", "");
|
|
7163
7328
|
__publicField(this, "sessionId");
|
|
@@ -7176,18 +7341,27 @@ var MCPStreamHelper = class {
|
|
|
7176
7341
|
async streamData(data) {
|
|
7177
7342
|
this.capturedData.push(data);
|
|
7178
7343
|
}
|
|
7344
|
+
async streamSummary(summary) {
|
|
7345
|
+
this.capturedSummaries.push(summary);
|
|
7346
|
+
}
|
|
7347
|
+
async streamOperation(operation) {
|
|
7348
|
+
this.capturedOperations.push(operation);
|
|
7349
|
+
}
|
|
7179
7350
|
async writeData(_type, data) {
|
|
7180
7351
|
this.capturedData.push(data);
|
|
7181
7352
|
}
|
|
7182
|
-
async
|
|
7183
|
-
this.
|
|
7184
|
-
this.errorMessage = errorMessage;
|
|
7185
|
-
}
|
|
7186
|
-
async complete() {
|
|
7353
|
+
async writeSummary(summary) {
|
|
7354
|
+
this.capturedSummaries.push(summary);
|
|
7187
7355
|
}
|
|
7188
7356
|
async writeOperation(operation) {
|
|
7189
7357
|
this.capturedOperations.push(operation);
|
|
7190
7358
|
}
|
|
7359
|
+
async writeError(error) {
|
|
7360
|
+
this.hasError = true;
|
|
7361
|
+
this.errorMessage = typeof error === "string" ? error : error.message;
|
|
7362
|
+
}
|
|
7363
|
+
async complete() {
|
|
7364
|
+
}
|
|
7191
7365
|
/**
|
|
7192
7366
|
* Get the captured response for MCP tool result
|
|
7193
7367
|
*/
|
|
@@ -7204,6 +7378,8 @@ var MCPStreamHelper = class {
|
|
|
7204
7378
|
function createMCPStreamHelper() {
|
|
7205
7379
|
return new MCPStreamHelper();
|
|
7206
7380
|
}
|
|
7381
|
+
|
|
7382
|
+
// src/handlers/executionHandler.ts
|
|
7207
7383
|
var logger19 = getLogger("ExecutionHandler");
|
|
7208
7384
|
var ExecutionHandler = class {
|
|
7209
7385
|
constructor() {
|
|
@@ -7232,7 +7408,7 @@ var ExecutionHandler = class {
|
|
|
7232
7408
|
logger19.info({ sessionId: requestId2, graphId }, "Created GraphSession for message execution");
|
|
7233
7409
|
let graphConfig = null;
|
|
7234
7410
|
try {
|
|
7235
|
-
graphConfig = await getFullGraph(dbClient_default)({ scopes: { tenantId, projectId
|
|
7411
|
+
graphConfig = await getFullGraph(dbClient_default)({ scopes: { tenantId, projectId, graphId } });
|
|
7236
7412
|
if (graphConfig?.statusUpdates && graphConfig.statusUpdates.enabled !== false) {
|
|
7237
7413
|
graphSessionManager.initializeStatusUpdates(
|
|
7238
7414
|
requestId2,
|
|
@@ -7386,7 +7562,6 @@ var ExecutionHandler = class {
|
|
|
7386
7562
|
if (errorCount >= this.MAX_ERRORS) {
|
|
7387
7563
|
const errorMessage2 = `Maximum error limit (${this.MAX_ERRORS}) reached`;
|
|
7388
7564
|
logger19.error({ maxErrors: this.MAX_ERRORS, errorCount }, errorMessage2);
|
|
7389
|
-
await sseHelper.writeError(errorMessage2);
|
|
7390
7565
|
await sseHelper.writeOperation(errorOp(errorMessage2, currentAgentId || "system"));
|
|
7391
7566
|
if (task) {
|
|
7392
7567
|
await updateTask(dbClient_default)({
|
|
@@ -7527,7 +7702,6 @@ var ExecutionHandler = class {
|
|
|
7527
7702
|
if (errorCount >= this.MAX_ERRORS) {
|
|
7528
7703
|
const errorMessage2 = `Maximum error limit (${this.MAX_ERRORS}) reached`;
|
|
7529
7704
|
logger19.error({ maxErrors: this.MAX_ERRORS, errorCount }, errorMessage2);
|
|
7530
|
-
await sseHelper.writeError(errorMessage2);
|
|
7531
7705
|
await sseHelper.writeOperation(errorOp(errorMessage2, currentAgentId || "system"));
|
|
7532
7706
|
if (task) {
|
|
7533
7707
|
await updateTask(dbClient_default)({
|
|
@@ -7549,7 +7723,6 @@ var ExecutionHandler = class {
|
|
|
7549
7723
|
}
|
|
7550
7724
|
const errorMessage = `Maximum transfer limit (${maxTransfers}) reached without completion`;
|
|
7551
7725
|
logger19.error({ maxTransfers, iterations }, errorMessage);
|
|
7552
|
-
await sseHelper.writeError(errorMessage);
|
|
7553
7726
|
await sseHelper.writeOperation(errorOp(errorMessage, currentAgentId || "system"));
|
|
7554
7727
|
if (task) {
|
|
7555
7728
|
await updateTask(dbClient_default)({
|
|
@@ -7570,8 +7743,7 @@ var ExecutionHandler = class {
|
|
|
7570
7743
|
} catch (error) {
|
|
7571
7744
|
logger19.error({ error }, "Error in execution handler");
|
|
7572
7745
|
const errorMessage = error instanceof Error ? error.message : "Unknown execution error";
|
|
7573
|
-
await sseHelper.
|
|
7574
|
-
await sseHelper.writeOperation(errorOp(errorMessage, currentAgentId || "system"));
|
|
7746
|
+
await sseHelper.writeOperation(errorOp(`Execution error: ${errorMessage}`, currentAgentId || "system"));
|
|
7575
7747
|
if (task) {
|
|
7576
7748
|
await updateTask(dbClient_default)({
|
|
7577
7749
|
taskId: task.id,
|
|
@@ -7733,8 +7905,7 @@ app2.openapi(chatCompletionsRoute, async (c) => {
|
|
|
7733
7905
|
const body = c.get("requestBody") || {};
|
|
7734
7906
|
const conversationId = body.conversationId || nanoid();
|
|
7735
7907
|
const fullGraph = await getFullGraph(dbClient_default)({
|
|
7736
|
-
scopes: { tenantId, projectId }
|
|
7737
|
-
graphId
|
|
7908
|
+
scopes: { tenantId, projectId, graphId }
|
|
7738
7909
|
});
|
|
7739
7910
|
let agentGraph;
|
|
7740
7911
|
let defaultAgentId;
|
|
@@ -7751,8 +7922,7 @@ app2.openapi(chatCompletionsRoute, async (c) => {
|
|
|
7751
7922
|
defaultAgentId = fullGraph.defaultAgentId || firstAgentId;
|
|
7752
7923
|
} else {
|
|
7753
7924
|
agentGraph = await getAgentGraphWithDefaultAgent(dbClient_default)({
|
|
7754
|
-
scopes: { tenantId, projectId }
|
|
7755
|
-
graphId
|
|
7925
|
+
scopes: { tenantId, projectId, graphId }
|
|
7756
7926
|
});
|
|
7757
7927
|
if (!agentGraph) {
|
|
7758
7928
|
return c.json({ error: "Agent graph not found" }, 404);
|
|
@@ -7781,7 +7951,7 @@ app2.openapi(chatCompletionsRoute, async (c) => {
|
|
|
7781
7951
|
}
|
|
7782
7952
|
const agentId = activeAgent?.activeAgentId || defaultAgentId;
|
|
7783
7953
|
const agentInfo = await getAgentById(dbClient_default)({
|
|
7784
|
-
scopes: { tenantId, projectId },
|
|
7954
|
+
scopes: { tenantId, projectId, graphId },
|
|
7785
7955
|
agentId
|
|
7786
7956
|
});
|
|
7787
7957
|
if (!agentInfo) {
|
|
@@ -7789,18 +7959,19 @@ app2.openapi(chatCompletionsRoute, async (c) => {
|
|
|
7789
7959
|
}
|
|
7790
7960
|
const validatedContext = c.get("validatedContext") || body.requestContext || {};
|
|
7791
7961
|
const credentialStores = c.get("credentialStores");
|
|
7792
|
-
await handleContextResolution(
|
|
7962
|
+
await handleContextResolution({
|
|
7793
7963
|
tenantId,
|
|
7794
7964
|
projectId,
|
|
7795
|
-
conversationId,
|
|
7796
7965
|
graphId,
|
|
7797
|
-
|
|
7798
|
-
|
|
7966
|
+
conversationId,
|
|
7967
|
+
requestContext: validatedContext,
|
|
7968
|
+
dbClient: dbClient_default,
|
|
7799
7969
|
credentialStores
|
|
7800
|
-
);
|
|
7970
|
+
});
|
|
7801
7971
|
logger20.info(
|
|
7802
7972
|
{
|
|
7803
7973
|
tenantId,
|
|
7974
|
+
projectId,
|
|
7804
7975
|
graphId,
|
|
7805
7976
|
conversationId,
|
|
7806
7977
|
defaultAgentId,
|
|
@@ -7859,8 +8030,8 @@ app2.openapi(chatCompletionsRoute, async (c) => {
|
|
|
7859
8030
|
`Execution completed: ${result.success ? "success" : "failed"} after ${result.iterations} iterations`
|
|
7860
8031
|
);
|
|
7861
8032
|
if (!result.success) {
|
|
7862
|
-
await sseHelper.
|
|
7863
|
-
"Sorry, I was unable to process your request at this time. Please try again."
|
|
8033
|
+
await sseHelper.writeOperation(
|
|
8034
|
+
errorOp("Sorry, I was unable to process your request at this time. Please try again.", "system")
|
|
7864
8035
|
);
|
|
7865
8036
|
}
|
|
7866
8037
|
await sseHelper.complete();
|
|
@@ -7940,6 +8111,7 @@ app3.openapi(chatDataStreamRoute, async (c) => {
|
|
|
7940
8111
|
try {
|
|
7941
8112
|
const executionContext = getRequestExecutionContext(c);
|
|
7942
8113
|
const { tenantId, projectId, graphId } = executionContext;
|
|
8114
|
+
loggerFactory.getLogger("chatDataStream").debug({ tenantId, projectId, graphId }, "Extracted chatDataStream parameters");
|
|
7943
8115
|
const body = c.get("requestBody") || {};
|
|
7944
8116
|
const conversationId = body.conversationId || nanoid();
|
|
7945
8117
|
const activeSpan = trace.getActiveSpan();
|
|
@@ -7952,14 +8124,16 @@ app3.openapi(chatDataStreamRoute, async (c) => {
|
|
|
7952
8124
|
});
|
|
7953
8125
|
}
|
|
7954
8126
|
const agentGraph = await getAgentGraphWithDefaultAgent(dbClient_default)({
|
|
7955
|
-
scopes: { tenantId, projectId }
|
|
7956
|
-
graphId
|
|
8127
|
+
scopes: { tenantId, projectId, graphId }
|
|
7957
8128
|
});
|
|
7958
8129
|
if (!agentGraph) {
|
|
7959
8130
|
return c.json({ error: "Agent graph not found" }, 404);
|
|
7960
8131
|
}
|
|
7961
8132
|
const defaultAgentId = agentGraph.defaultAgentId;
|
|
7962
8133
|
const graphName = agentGraph.name;
|
|
8134
|
+
if (!defaultAgentId) {
|
|
8135
|
+
return c.json({ error: "Graph does not have a default agent configured" }, 400);
|
|
8136
|
+
}
|
|
7963
8137
|
const activeAgent = await getActiveAgentForConversation(dbClient_default)({
|
|
7964
8138
|
scopes: { tenantId, projectId },
|
|
7965
8139
|
conversationId
|
|
@@ -7973,7 +8147,7 @@ app3.openapi(chatDataStreamRoute, async (c) => {
|
|
|
7973
8147
|
}
|
|
7974
8148
|
const agentId = activeAgent?.activeAgentId || defaultAgentId;
|
|
7975
8149
|
const agentInfo = await getAgentById(dbClient_default)({
|
|
7976
|
-
scopes: { tenantId, projectId },
|
|
8150
|
+
scopes: { tenantId, projectId, graphId },
|
|
7977
8151
|
agentId
|
|
7978
8152
|
});
|
|
7979
8153
|
if (!agentInfo) {
|
|
@@ -7981,15 +8155,15 @@ app3.openapi(chatDataStreamRoute, async (c) => {
|
|
|
7981
8155
|
}
|
|
7982
8156
|
const validatedContext = c.get("validatedContext") || body.requestContext || {};
|
|
7983
8157
|
const credentialStores = c.get("credentialStores");
|
|
7984
|
-
await handleContextResolution(
|
|
8158
|
+
await handleContextResolution({
|
|
7985
8159
|
tenantId,
|
|
7986
8160
|
projectId,
|
|
7987
|
-
conversationId,
|
|
7988
8161
|
graphId,
|
|
7989
|
-
|
|
7990
|
-
|
|
8162
|
+
conversationId,
|
|
8163
|
+
requestContext: validatedContext,
|
|
8164
|
+
dbClient: dbClient_default,
|
|
7991
8165
|
credentialStores
|
|
7992
|
-
);
|
|
8166
|
+
});
|
|
7993
8167
|
const lastUserMessage = body.messages.filter((m) => m.role === "user").slice(-1)[0];
|
|
7994
8168
|
const userText = typeof lastUserMessage?.content === "string" ? lastUserMessage.content : lastUserMessage?.parts?.map((p) => p.text).join("") || "";
|
|
7995
8169
|
logger21.info({ userText, lastUserMessage }, "userText");
|
|
@@ -8031,11 +8205,11 @@ app3.openapi(chatDataStreamRoute, async (c) => {
|
|
|
8031
8205
|
sseHelper: streamHelper
|
|
8032
8206
|
});
|
|
8033
8207
|
if (!result.success) {
|
|
8034
|
-
await streamHelper.
|
|
8208
|
+
await streamHelper.writeOperation(errorOp("Unable to process request", "system"));
|
|
8035
8209
|
}
|
|
8036
8210
|
} catch (err) {
|
|
8037
8211
|
logger21.error({ err }, "Streaming error");
|
|
8038
|
-
await streamHelper.
|
|
8212
|
+
await streamHelper.writeOperation(errorOp("Internal server error", "system"));
|
|
8039
8213
|
} finally {
|
|
8040
8214
|
if ("cleanup" in streamHelper && typeof streamHelper.cleanup === "function") {
|
|
8041
8215
|
streamHelper.cleanup();
|
|
@@ -8258,8 +8432,7 @@ var getServer = async (requestContext, executionContext, conversationId, credent
|
|
|
8258
8432
|
const { tenantId, projectId, graphId } = executionContext;
|
|
8259
8433
|
setupTracing(conversationId, tenantId, graphId);
|
|
8260
8434
|
const agentGraph = await getAgentGraphWithDefaultAgent(dbClient_default)({
|
|
8261
|
-
scopes: { tenantId, projectId }
|
|
8262
|
-
graphId
|
|
8435
|
+
scopes: { tenantId, projectId, graphId }
|
|
8263
8436
|
});
|
|
8264
8437
|
if (!agentGraph) {
|
|
8265
8438
|
throw new Error("Agent graph not found");
|
|
@@ -8279,9 +8452,20 @@ var getServer = async (requestContext, executionContext, conversationId, credent
|
|
|
8279
8452
|
},
|
|
8280
8453
|
async ({ query }) => {
|
|
8281
8454
|
try {
|
|
8455
|
+
if (!agentGraph.defaultAgentId) {
|
|
8456
|
+
return {
|
|
8457
|
+
content: [
|
|
8458
|
+
{
|
|
8459
|
+
type: "text",
|
|
8460
|
+
text: `Graph does not have a default agent configured`
|
|
8461
|
+
}
|
|
8462
|
+
],
|
|
8463
|
+
isError: true
|
|
8464
|
+
};
|
|
8465
|
+
}
|
|
8282
8466
|
const defaultAgentId = agentGraph.defaultAgentId;
|
|
8283
8467
|
const agentInfo = await getAgentById(dbClient_default)({
|
|
8284
|
-
scopes: { tenantId, projectId },
|
|
8468
|
+
scopes: { tenantId, projectId, graphId },
|
|
8285
8469
|
agentId: defaultAgentId
|
|
8286
8470
|
});
|
|
8287
8471
|
if (!agentInfo) {
|
|
@@ -8295,18 +8479,19 @@ var getServer = async (requestContext, executionContext, conversationId, credent
|
|
|
8295
8479
|
isError: true
|
|
8296
8480
|
};
|
|
8297
8481
|
}
|
|
8298
|
-
const resolvedContext = await handleContextResolution(
|
|
8482
|
+
const resolvedContext = await handleContextResolution({
|
|
8299
8483
|
tenantId,
|
|
8300
8484
|
projectId,
|
|
8301
|
-
conversationId,
|
|
8302
8485
|
graphId,
|
|
8486
|
+
conversationId,
|
|
8303
8487
|
requestContext,
|
|
8304
|
-
dbClient_default,
|
|
8488
|
+
dbClient: dbClient_default,
|
|
8305
8489
|
credentialStores
|
|
8306
|
-
);
|
|
8490
|
+
});
|
|
8307
8491
|
logger22.info(
|
|
8308
8492
|
{
|
|
8309
8493
|
tenantId,
|
|
8494
|
+
projectId,
|
|
8310
8495
|
graphId,
|
|
8311
8496
|
conversationId,
|
|
8312
8497
|
hasContextConfig: !!agentGraph.contextConfigId,
|
|
@@ -8368,8 +8553,7 @@ var handleInitializationRequest = async (body, executionContext, validatedContex
|
|
|
8368
8553
|
logger22.info({ body }, "Received initialization request");
|
|
8369
8554
|
const sessionId = nanoid();
|
|
8370
8555
|
const agentGraph = await getAgentGraphWithDefaultAgent(dbClient_default)({
|
|
8371
|
-
scopes: { tenantId, projectId }
|
|
8372
|
-
graphId
|
|
8556
|
+
scopes: { tenantId, projectId, graphId }
|
|
8373
8557
|
});
|
|
8374
8558
|
if (!agentGraph) {
|
|
8375
8559
|
return c.json(
|
|
@@ -8381,6 +8565,16 @@ var handleInitializationRequest = async (body, executionContext, validatedContex
|
|
|
8381
8565
|
{ status: 404 }
|
|
8382
8566
|
);
|
|
8383
8567
|
}
|
|
8568
|
+
if (!agentGraph.defaultAgentId) {
|
|
8569
|
+
return c.json(
|
|
8570
|
+
{
|
|
8571
|
+
jsonrpc: "2.0",
|
|
8572
|
+
error: { code: -32001, message: "Graph does not have a default agent configured" },
|
|
8573
|
+
id: body.id || null
|
|
8574
|
+
},
|
|
8575
|
+
{ status: 400 }
|
|
8576
|
+
);
|
|
8577
|
+
}
|
|
8384
8578
|
const conversation = await createOrGetConversation(dbClient_default)({
|
|
8385
8579
|
id: sessionId,
|
|
8386
8580
|
tenantId,
|