@inkeep/agents-api 0.45.3 → 0.46.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/.well-known/workflow/v1/flow.cjs +44 -44
  2. package/dist/.well-known/workflow/v1/flow.cjs.debug.json +2 -2
  3. package/dist/.well-known/workflow/v1/manifest.debug.json +14 -14
  4. package/dist/.well-known/workflow/v1/step.cjs +166 -158
  5. package/dist/.well-known/workflow/v1/step.cjs.debug.json +2 -2
  6. package/dist/createApp.d.ts +2 -2
  7. package/dist/domains/evals/routes/datasetTriggers.d.ts +2 -2
  8. package/dist/domains/evals/routes/index.d.ts +2 -2
  9. package/dist/domains/evals/workflow/routes.d.ts +2 -2
  10. package/dist/domains/manage/index.js +4 -2
  11. package/dist/domains/manage/routes/availableAgents.d.ts +2 -2
  12. package/dist/domains/manage/routes/availableAgents.js +2 -2
  13. package/dist/domains/manage/routes/conversations.d.ts +2 -2
  14. package/dist/domains/manage/routes/index.d.ts +2 -2
  15. package/dist/domains/manage/routes/invitations.d.ts +2 -2
  16. package/dist/domains/manage/routes/invitations.js +59 -0
  17. package/dist/domains/manage/routes/mcp.d.ts +2 -2
  18. package/dist/domains/manage/routes/passwordResetLinks.d.ts +10 -0
  19. package/dist/domains/manage/routes/passwordResetLinks.js +61 -0
  20. package/dist/domains/manage/routes/signoz.d.ts +2 -2
  21. package/dist/domains/manage/routes/users.d.ts +10 -0
  22. package/dist/domains/manage/routes/users.js +78 -0
  23. package/dist/domains/mcp/routes/mcp.d.ts +2 -2
  24. package/dist/domains/run/agents/Agent.d.ts +41 -15
  25. package/dist/domains/run/agents/Agent.js +127 -281
  26. package/dist/domains/run/agents/generateTaskHandler.js +10 -5
  27. package/dist/domains/run/agents/types.d.ts +2 -1
  28. package/dist/domains/run/agents/versions/v1/{Phase1Config.d.ts → PromptConfig.d.ts} +5 -4
  29. package/dist/domains/run/agents/versions/v1/{Phase1Config.js → PromptConfig.js} +36 -19
  30. package/dist/factory.d.ts +58 -24
  31. package/dist/index.d.ts +128 -94
  32. package/dist/middleware/evalsAuth.d.ts +2 -2
  33. package/dist/middleware/manageAuth.d.ts +2 -2
  34. package/dist/middleware/projectAccess.d.ts +2 -2
  35. package/dist/middleware/projectConfig.d.ts +3 -3
  36. package/dist/middleware/requirePermission.d.ts +2 -2
  37. package/dist/middleware/runAuth.d.ts +4 -4
  38. package/dist/middleware/sessionAuth.d.ts +3 -3
  39. package/dist/middleware/tenantAccess.d.ts +2 -2
  40. package/dist/middleware/tracing.d.ts +3 -3
  41. package/dist/templates/v1/prompt/system-prompt.js +5 -0
  42. package/dist/templates/v1/{phase1 → prompt}/tool.js +1 -1
  43. package/dist/templates/v1/shared/artifact-retrieval-guidance.js +1 -1
  44. package/dist/templates/v1/{phase2 → shared}/data-component.js +1 -1
  45. package/dist/templates/v1/{phase2 → shared}/data-components.js +1 -1
  46. package/package.json +5 -5
  47. package/dist/domains/manage/routes/userOrganizations.d.ts +0 -10
  48. package/dist/domains/manage/routes/userOrganizations.js +0 -29
  49. package/dist/domains/run/agents/versions/v1/Phase2Config.d.ts +0 -33
  50. package/dist/domains/run/agents/versions/v1/Phase2Config.js +0 -341
  51. package/dist/templates/v1/phase1/system-prompt.js +0 -5
  52. package/dist/templates/v1/phase1/thinking-preparation.js +0 -5
  53. package/dist/templates/v1/phase2/system-prompt.js +0 -5
@@ -2,7 +2,7 @@ import { getLogger as getLogger$1 } from "../../../logger.js";
2
2
  import { env } from "../../../env.js";
3
3
  import manageDbPool_default from "../../../data/db/manageDbPool.js";
4
4
  import runDbClient_default from "../../../data/db/runDbClient.js";
5
- import { AGENT_EXECUTION_MAX_GENERATION_STEPS, FUNCTION_TOOL_EXECUTION_TIMEOUT_MS_DEFAULT, FUNCTION_TOOL_SANDBOX_VCPUS_DEFAULT, LLM_GENERATION_FIRST_CALL_TIMEOUT_MS_NON_STREAMING, LLM_GENERATION_FIRST_CALL_TIMEOUT_MS_STREAMING, LLM_GENERATION_MAX_ALLOWED_TIMEOUT_MS, LLM_GENERATION_SUBSEQUENT_CALL_TIMEOUT_MS } from "../constants/execution-limits/index.js";
5
+ import { AGENT_EXECUTION_MAX_GENERATION_STEPS, FUNCTION_TOOL_EXECUTION_TIMEOUT_MS_DEFAULT, FUNCTION_TOOL_SANDBOX_VCPUS_DEFAULT, LLM_GENERATION_FIRST_CALL_TIMEOUT_MS_STREAMING, LLM_GENERATION_MAX_ALLOWED_TIMEOUT_MS } from "../constants/execution-limits/index.js";
6
6
  import { toolSessionManager } from "./ToolSessionManager.js";
7
7
  import { getCompressionConfigForModel } from "../utils/model-context-utils.js";
8
8
  import { setSpanWithError as setSpanWithError$1, tracer } from "../utils/tracer.js";
@@ -23,10 +23,9 @@ import { withJsonPostProcessing } from "../utils/json-postprocessor.js";
23
23
  import { calculateBreakdownTotal, estimateTokens } from "../utils/token-estimator.js";
24
24
  import { createDelegateToAgentTool, createTransferToAgentTool } from "./relationTools.js";
25
25
  import { SystemPromptBuilder } from "./SystemPromptBuilder.js";
26
- import { Phase1Config, V1_BREAKDOWN_SCHEMA } from "./versions/v1/Phase1Config.js";
27
- import { Phase2Config } from "./versions/v1/Phase2Config.js";
26
+ import { PromptConfig, V1_BREAKDOWN_SCHEMA } from "./versions/v1/PromptConfig.js";
28
27
  import { z } from "@hono/zod-openapi";
29
- import { CredentialStuffer, JsonTransformer, MCPServerType, MCPTransportType, McpClient, ModelFactory, TemplateEngine, buildComposioMCPUrl, createMessage, generateId, getFunctionToolsForSubAgent, getLedgerArtifacts, isGithubWorkAppTool, listTaskIdsByContextId, parseEmbeddedJson, withRef } from "@inkeep/agents-core";
28
+ import { CredentialStuffer, JsonTransformer, MCPServerType, MCPTransportType, McpClient, ModelFactory, TemplateEngine, buildComposioMCPUrl, createMessage, generateId, getFunctionToolsForSubAgent, isGithubWorkAppTool, parseEmbeddedJson, withRef } from "@inkeep/agents-core";
30
29
  import { Output, generateText, streamText, tool } from "ai";
31
30
  import { SpanStatusCode, trace } from "@opentelemetry/api";
32
31
 
@@ -44,6 +43,43 @@ function hasToolCallWithPrefix(prefix) {
44
43
  };
45
44
  }
46
45
  const logger = getLogger$1("Agent");
46
+ /**
47
+ * Resolves a generation response from either `generateText` or `streamText` into
48
+ * a plain object with all needed values as own properties.
49
+ *
50
+ * **Why this exists:** The AI SDK returns class instances whose key properties
51
+ * (`text`, `steps`, `finishReason`, `output`) are prototype getters.
52
+ * `StreamTextResult` getters return `PromiseLike` values; `GenerateTextResult`
53
+ * getters return direct values. In both cases, the spread operator `{ ...result }`
54
+ * silently drops them. This function uses `Promise.resolve()` to safely resolve
55
+ * both styles, then spreads them as explicit own properties so downstream code
56
+ * (and further spreads) never loses them.
57
+ */
58
+ async function resolveGenerationResponse(response) {
59
+ const stepsValue = response.steps;
60
+ if (!stepsValue) return response;
61
+ try {
62
+ const [steps, text, finishReason, output] = await Promise.all([
63
+ Promise.resolve(stepsValue),
64
+ Promise.resolve(response.text),
65
+ Promise.resolve(response.finishReason),
66
+ Promise.resolve(response.output)
67
+ ]);
68
+ return {
69
+ ...response,
70
+ steps,
71
+ text,
72
+ finishReason,
73
+ output
74
+ };
75
+ } catch (error) {
76
+ logger.error({
77
+ error: error instanceof Error ? error.message : String(error),
78
+ responseKeys: Object.keys(response)
79
+ }, "Failed to resolve generation response properties - AI SDK response may be malformed");
80
+ throw new Error(`Failed to resolve generation response: ${error instanceof Error ? error.message : String(error)}`);
81
+ }
82
+ }
47
83
  function validateModel(modelString, modelType) {
48
84
  if (!modelString?.trim()) throw new Error(`${modelType} model is required. Please configure models at the project level.`);
49
85
  return modelString.trim();
@@ -53,7 +89,7 @@ function isValidTool(tool$1) {
53
89
  }
54
90
  var Agent = class {
55
91
  config;
56
- systemPromptBuilder = new SystemPromptBuilder("v1", new Phase1Config());
92
+ systemPromptBuilder = new SystemPromptBuilder("v1", new PromptConfig());
57
93
  credentialStuffer;
58
94
  streamHelper;
59
95
  streamRequestId;
@@ -141,7 +177,7 @@ var Agent = class {
141
177
  if (toolType === "delegation") return this.config.delegateRelations.find((relation) => this.#createRelationToolName("delegate", relation.config.id) === toolName)?.config.relationId;
142
178
  }
143
179
  /**
144
- * Get the primary model settings for text generation and thinking
180
+ * Get the primary model settings for text generation
145
181
  * Requires model to be configured at project level
146
182
  */
147
183
  getPrimaryModel() {
@@ -244,7 +280,7 @@ var Agent = class {
244
280
  if (options?.mcpServerName) attributes["ai.toolCall.mcpServerName"] = options.mcpServerName;
245
281
  activeSpan.setAttributes(attributes);
246
282
  }
247
- const isInternalToolForUi = toolName.includes("save_tool_result") || toolName.includes("thinking_complete") || toolName.startsWith("transfer_to_") || toolName.startsWith("delegate_to_");
283
+ const isInternalToolForUi = toolName.includes("save_tool_result") || toolName.startsWith("transfer_to_") || toolName.startsWith("delegate_to_");
248
284
  const needsApproval = options?.needsApproval || false;
249
285
  if (streamRequestId && streamHelper && !isInternalToolForUi) {
250
286
  const inputText = JSON.stringify(args ?? {});
@@ -1070,8 +1106,7 @@ var Agent = class {
1070
1106
  }
1071
1107
  }
1072
1108
  /**
1073
- * Build adaptive system prompt for Phase 2 structured output generation
1074
- * based on configured data components and artifact components across the agent
1109
+ * Get the client's current time formatted in their timezone
1075
1110
  */
1076
1111
  getClientCurrentTime() {
1077
1112
  const clientTimezone = this.config.forwardedHeaders?.["x-inkeep-client-timezone"];
@@ -1097,48 +1132,6 @@ var Agent = class {
1097
1132
  return;
1098
1133
  }
1099
1134
  }
1100
- async buildPhase2SystemPrompt(runtimeContext) {
1101
- const phase2Config = new Phase2Config();
1102
- const compressionConfig = getModelAwareCompressionConfig();
1103
- const hasAgentArtifactComponents = await this.hasAgentArtifactComponents() || compressionConfig.enabled;
1104
- const conversationId = runtimeContext?.metadata?.conversationId || runtimeContext?.contextId;
1105
- const resolvedContext = conversationId ? await this.getResolvedContext(conversationId) : null;
1106
- let processedPrompt = this.config.prompt || "";
1107
- if (resolvedContext && this.config.prompt) try {
1108
- processedPrompt = TemplateEngine.render(this.config.prompt, resolvedContext, {
1109
- strict: false,
1110
- preserveUnresolved: false
1111
- });
1112
- } catch (error) {
1113
- logger.error({
1114
- conversationId,
1115
- error: error instanceof Error ? error.message : "Unknown error"
1116
- }, "Failed to process agent prompt with context for Phase 2, using original");
1117
- processedPrompt = this.config.prompt;
1118
- }
1119
- const referenceTaskIds = await listTaskIdsByContextId(runDbClient_default)({ contextId: this.conversationId || "" });
1120
- const referenceArtifacts = [];
1121
- for (const taskId of referenceTaskIds) {
1122
- const artifacts = await getLedgerArtifacts(runDbClient_default)({
1123
- scopes: {
1124
- tenantId: this.config.tenantId,
1125
- projectId: this.config.projectId
1126
- },
1127
- taskId
1128
- });
1129
- referenceArtifacts.push(...artifacts);
1130
- }
1131
- const clientCurrentTime = this.getClientCurrentTime();
1132
- return phase2Config.assemblePhase2Prompt({
1133
- corePrompt: processedPrompt,
1134
- dataComponents: this.config.dataComponents || [],
1135
- artifactComponents: this.artifactComponents,
1136
- hasArtifactComponents: this.artifactComponents && this.artifactComponents.length > 0,
1137
- hasAgentArtifactComponents,
1138
- artifacts: referenceArtifacts,
1139
- clientCurrentTime
1140
- });
1141
- }
1142
1135
  async buildSystemPrompt(runtimeContext, excludeDataComponents = false) {
1143
1136
  const conversationId = runtimeContext?.metadata?.conversationId || runtimeContext?.contextId;
1144
1137
  if (conversationId) this.setConversationId(conversationId);
@@ -1193,7 +1186,6 @@ var Agent = class {
1193
1186
  ref: this.executionContext.resolvedRef
1194
1187
  });
1195
1188
  const componentDataComponents = excludeDataComponents ? [] : this.config.dataComponents || [];
1196
- const isThinkingPreparation = this.config.dataComponents && this.config.dataComponents.length > 0 && excludeDataComponents;
1197
1189
  let prompt = await this.getPrompt();
1198
1190
  if (prompt && resolvedContext) try {
1199
1191
  prompt = TemplateEngine.render(prompt, resolvedContext, {
@@ -1209,6 +1201,15 @@ var Agent = class {
1209
1201
  const shouldIncludeArtifactComponents = !excludeDataComponents;
1210
1202
  const compressionConfig = getModelAwareCompressionConfig();
1211
1203
  const hasAgentArtifactComponents = await this.hasAgentArtifactComponents() || compressionConfig.enabled;
1204
+ const hasStructuredOutput = Boolean(this.config.dataComponents && this.config.dataComponents.length > 0);
1205
+ const includeDataComponents = hasStructuredOutput && !excludeDataComponents;
1206
+ logger.info({
1207
+ agentId: this.config.id,
1208
+ hasStructuredOutput,
1209
+ excludeDataComponents,
1210
+ includeDataComponents,
1211
+ dataComponentsCount: this.config.dataComponents?.length || 0
1212
+ }, "System prompt configuration");
1212
1213
  const clientCurrentTime = this.getClientCurrentTime();
1213
1214
  const config = {
1214
1215
  corePrompt: processedPrompt,
@@ -1218,9 +1219,9 @@ var Agent = class {
1218
1219
  artifacts: referenceArtifacts,
1219
1220
  artifactComponents: shouldIncludeArtifactComponents ? this.artifactComponents : [],
1220
1221
  hasAgentArtifactComponents,
1221
- isThinkingPreparation,
1222
1222
  hasTransferRelations: (this.config.transferRelations?.length ?? 0) > 0,
1223
1223
  hasDelegateRelations: (this.config.delegateRelations?.length ?? 0) > 0,
1224
+ includeDataComponents,
1224
1225
  clientCurrentTime
1225
1226
  };
1226
1227
  return await this.systemPromptBuilder.buildSystemPrompt(config);
@@ -1252,24 +1253,10 @@ var Agent = class {
1252
1253
  }
1253
1254
  });
1254
1255
  }
1255
- createThinkingCompleteTool() {
1256
- return tool({
1257
- description: "🚨 CRITICAL: Call this tool IMMEDIATELY when you have gathered enough information to answer the user. This is MANDATORY - you CANNOT provide text responses in thinking mode, only tool calls. Call thinking_complete as soon as you have sufficient data to generate a structured response.",
1258
- inputSchema: z.object({
1259
- complete: z.boolean().describe("ALWAYS set to true - marks end of research phase"),
1260
- summary: z.string().describe("Brief summary of what information was gathered and why it is sufficient to answer the user")
1261
- }),
1262
- execute: async (params) => params
1263
- });
1264
- }
1265
1256
  async getDefaultTools(streamRequestId) {
1266
1257
  const defaultTools = {};
1267
1258
  const compressionConfig = getModelAwareCompressionConfig();
1268
1259
  if (await this.agentHasArtifactComponents() || compressionConfig.enabled) defaultTools.get_reference_artifact = this.getArtifactTools();
1269
- if (this.config.dataComponents && this.config.dataComponents.length > 0) {
1270
- const thinkingCompleteTool = this.createThinkingCompleteTool();
1271
- if (thinkingCompleteTool) defaultTools.thinking_complete = this.wrapToolWithStreaming("thinking_complete", thinkingCompleteTool, streamRequestId, "tool");
1272
- }
1273
1260
  logger.info({
1274
1261
  agentId: this.config.id,
1275
1262
  streamRequestId
@@ -1651,7 +1638,7 @@ ${typeof cleanResult === "string" ? cleanResult : JSON.stringify(cleanResult, nu
1651
1638
  } }, async (span) => {
1652
1639
  const { contextId, taskId, streamRequestId, sessionId } = this.setupGenerationContext(runtimeContext);
1653
1640
  try {
1654
- const { systemPrompt, thinkingSystemPrompt, sanitizedTools, contextBreakdown: initialContextBreakdown } = await this.loadToolsAndPrompts(sessionId, streamRequestId, runtimeContext);
1641
+ const { systemPrompt, sanitizedTools, contextBreakdown: initialContextBreakdown } = await this.loadToolsAndPrompts(sessionId, streamRequestId, runtimeContext);
1655
1642
  if (streamRequestId && this.artifactComponents.length > 0) agentSessionManager.updateArtifactComponents(streamRequestId, this.artifactComponents);
1656
1643
  const conversationId = runtimeContext?.metadata?.conversationId;
1657
1644
  if (conversationId) this.setConversationId(conversationId);
@@ -1660,50 +1647,48 @@ ${typeof cleanResult === "string" ? cleanResult : JSON.stringify(cleanResult, nu
1660
1647
  for (const componentDef of V1_BREAKDOWN_SCHEMA) breakdownAttributes[componentDef.spanAttribute] = contextBreakdown.components[componentDef.key] ?? 0;
1661
1648
  breakdownAttributes["context.breakdown.total_tokens"] = contextBreakdown.total;
1662
1649
  span.setAttributes(breakdownAttributes);
1663
- const { primaryModelSettings, modelSettings, hasStructuredOutput, shouldStreamPhase1, timeoutMs } = this.configureModelSettings();
1650
+ const { primaryModelSettings, modelSettings, hasStructuredOutput, timeoutMs } = this.configureModelSettings();
1664
1651
  let response;
1665
1652
  let textResponse;
1666
- const messages = this.buildInitialMessages(systemPrompt, thinkingSystemPrompt, hasStructuredOutput, conversationHistory, userMessage);
1653
+ const messages = this.buildInitialMessages(systemPrompt, conversationHistory, userMessage);
1667
1654
  const { originalMessageCount, compressor } = this.setupCompression(messages, sessionId, contextId, primaryModelSettings);
1668
- if (shouldStreamPhase1) {
1669
- const streamConfig = {
1670
- ...modelSettings,
1671
- toolChoice: "auto"
1672
- };
1673
- const streamResult = streamText(this.buildBaseGenerationConfig(streamConfig, messages, sanitizedTools, compressor, originalMessageCount, timeoutMs, "auto", void 0, false, contextBreakdown.total));
1674
- const parser = this.setupStreamParser(sessionId, contextId);
1675
- await this.processStreamEvents(streamResult, parser);
1676
- response = await streamResult;
1677
- response = this.formatStreamingResponse(response, parser);
1678
- } else {
1679
- const toolChoice = hasStructuredOutput ? "required" : "auto";
1680
- response = await generateText(this.buildBaseGenerationConfig(modelSettings, messages, sanitizedTools, compressor, originalMessageCount, timeoutMs, toolChoice, "planning", true, contextBreakdown.total));
1681
- }
1682
- if (response.steps) {
1683
- const resolvedSteps = await response.steps;
1684
- response = {
1685
- ...response,
1686
- steps: resolvedSteps
1687
- };
1688
- }
1689
- if (hasStructuredOutput && !hasToolCallWithPrefix("transfer_to_")(response)) if (response.steps?.flatMap((s) => s.toolCalls || [])?.find((tc) => tc.toolName === "thinking_complete")) {
1690
- const reasoningFlow = this.buildReasoningFlow(response, sessionId);
1691
- const dataComponentsSchema = this.buildDataComponentsSchema();
1692
- const structuredModelSettings = ModelFactory.prepareGenerationConfig(this.getStructuredOutputModel());
1693
- const phase2TimeoutMs = this.calculatePhase2Timeout(structuredModelSettings);
1694
- if (this.getStreamingHelper()) {
1695
- const phase2Messages = await this.buildPhase2Messages(runtimeContext, conversationHistory, userMessage, reasoningFlow);
1696
- const result = await this.executeStreamingPhase2(structuredModelSettings, phase2Messages, dataComponentsSchema, phase2TimeoutMs, sessionId, contextId, response);
1697
- response = result;
1698
- textResponse = result.textResponse;
1699
- } else {
1700
- const phase2Messages = await this.buildPhase2Messages(runtimeContext, conversationHistory, userMessage, reasoningFlow);
1701
- const result = await this.executeNonStreamingPhase2(structuredModelSettings, phase2Messages, dataComponentsSchema, phase2TimeoutMs, response);
1702
- response = result;
1703
- textResponse = result.textResponse;
1704
- }
1705
- } else textResponse = response.text || "";
1706
- else textResponse = response.steps[response.steps.length - 1].text || "";
1655
+ const streamConfig = {
1656
+ ...modelSettings,
1657
+ toolChoice: "auto"
1658
+ };
1659
+ const shouldStream = this.getStreamingHelper();
1660
+ const dataComponentsSchema = hasStructuredOutput ? this.buildDataComponentsSchema() : null;
1661
+ const baseConfig = this.buildBaseGenerationConfig(streamConfig, messages, sanitizedTools, compressor, originalMessageCount, timeoutMs, "auto", dataComponentsSchema ? "structured_generation" : void 0, contextBreakdown.total);
1662
+ const generationConfig = dataComponentsSchema ? {
1663
+ ...baseConfig,
1664
+ output: Output.object({ schema: z.object({ dataComponents: z.array(dataComponentsSchema) }) })
1665
+ } : baseConfig;
1666
+ const nonStreamingConfig = withJsonPostProcessing(generationConfig);
1667
+ logger.info({
1668
+ agentId: this.config.id,
1669
+ hasStructuredOutput,
1670
+ shouldStream
1671
+ }, "🚀 Starting generation");
1672
+ let rawResponse;
1673
+ if (shouldStream) rawResponse = await this.handleStreamGeneration(streamText(generationConfig), sessionId, contextId, !!dataComponentsSchema);
1674
+ else rawResponse = await generateText(nonStreamingConfig);
1675
+ logger.info({
1676
+ agentId: this.config.id,
1677
+ hasOutput: !!rawResponse.output,
1678
+ dataComponentsCount: rawResponse.output?.dataComponents?.length || 0,
1679
+ finishReason: rawResponse.finishReason
1680
+ }, "✅ Generation completed");
1681
+ response = await resolveGenerationResponse(rawResponse);
1682
+ if (hasStructuredOutput && response.output) {
1683
+ response.object = response.output;
1684
+ logger.info({
1685
+ agentId: this.config.id,
1686
+ dataComponentsCount: response.output?.dataComponents?.length || 0,
1687
+ dataComponentNames: response.output?.dataComponents?.map((dc) => dc.name) || []
1688
+ }, "📦 Processing response with data components");
1689
+ textResponse = JSON.stringify(response.output, null, 2);
1690
+ } else if (hasToolCallWithPrefix("transfer_to_")(response)) textResponse = response.steps[response.steps.length - 1].text || "";
1691
+ else textResponse = response.text || "";
1707
1692
  span.setStatus({ code: SpanStatusCode.OK });
1708
1693
  span.end();
1709
1694
  const formattedResponse = await this.formatFinalResponse(response, textResponse, sessionId, contextId);
@@ -1749,7 +1734,7 @@ ${typeof cleanResult === "string" ? cleanResult : JSON.stringify(cleanResult, nu
1749
1734
  * Load all tools and system prompts in parallel, then combine and sanitize them
1750
1735
  */
1751
1736
  async loadToolsAndPrompts(sessionId, streamRequestId, runtimeContext) {
1752
- const [mcpTools, systemPromptResult, thinkingSystemPromptResult, functionTools, relationTools, defaultTools] = await tracer.startActiveSpan("agent.load_tools", { attributes: {
1737
+ const [mcpTools, systemPromptResult, functionTools, relationTools, defaultTools] = await tracer.startActiveSpan("agent.load_tools", { attributes: {
1753
1738
  "subAgent.name": this.config.name,
1754
1739
  "session.id": sessionId || "none"
1755
1740
  } }, async (childSpan) => {
@@ -1757,7 +1742,6 @@ ${typeof cleanResult === "string" ? cleanResult : JSON.stringify(cleanResult, nu
1757
1742
  const result = await Promise.all([
1758
1743
  this.getMcpTools(sessionId, streamRequestId),
1759
1744
  this.buildSystemPrompt(runtimeContext, false),
1760
- this.buildSystemPrompt(runtimeContext, true),
1761
1745
  this.getFunctionTools(sessionId, streamRequestId),
1762
1746
  Promise.resolve(this.getRelationTools(runtimeContext, sessionId)),
1763
1747
  this.getDefaultTools(streamRequestId)
@@ -1772,7 +1756,6 @@ ${typeof cleanResult === "string" ? cleanResult : JSON.stringify(cleanResult, nu
1772
1756
  }
1773
1757
  });
1774
1758
  const systemPrompt = systemPromptResult.prompt;
1775
- const thinkingSystemPrompt = thinkingSystemPromptResult.prompt;
1776
1759
  const contextBreakdown = systemPromptResult.breakdown;
1777
1760
  const allTools = {
1778
1761
  ...mcpTools,
@@ -1782,7 +1765,6 @@ ${typeof cleanResult === "string" ? cleanResult : JSON.stringify(cleanResult, nu
1782
1765
  };
1783
1766
  return {
1784
1767
  systemPrompt,
1785
- thinkingSystemPrompt,
1786
1768
  sanitizedTools: this.sanitizeToolsForAISDK(allTools),
1787
1769
  contextBreakdown
1788
1770
  };
@@ -1845,11 +1827,10 @@ ${typeof cleanResult === "string" ? cleanResult : JSON.stringify(cleanResult, nu
1845
1827
  * Configure model settings, timeouts, and streaming behavior
1846
1828
  */
1847
1829
  configureModelSettings() {
1848
- const primaryModelSettings = this.getPrimaryModel();
1849
- const modelSettings = ModelFactory.prepareGenerationConfig(primaryModelSettings);
1850
1830
  const hasStructuredOutput = Boolean(this.config.dataComponents && this.config.dataComponents.length > 0);
1851
- const shouldStreamPhase1 = this.getStreamingHelper() && !hasStructuredOutput;
1852
- const configuredTimeout = modelSettings.maxDuration ? Math.min(modelSettings.maxDuration * 1e3, LLM_GENERATION_MAX_ALLOWED_TIMEOUT_MS) : shouldStreamPhase1 ? LLM_GENERATION_FIRST_CALL_TIMEOUT_MS_STREAMING : LLM_GENERATION_FIRST_CALL_TIMEOUT_MS_NON_STREAMING;
1831
+ const primaryModelSettings = hasStructuredOutput ? this.getStructuredOutputModel() : this.getPrimaryModel();
1832
+ const modelSettings = ModelFactory.prepareGenerationConfig(primaryModelSettings);
1833
+ const configuredTimeout = modelSettings.maxDuration ? Math.min(modelSettings.maxDuration * 1e3, LLM_GENERATION_MAX_ALLOWED_TIMEOUT_MS) : LLM_GENERATION_FIRST_CALL_TIMEOUT_MS_STREAMING;
1853
1834
  const timeoutMs = Math.min(configuredTimeout, LLM_GENERATION_MAX_ALLOWED_TIMEOUT_MS);
1854
1835
  if (modelSettings.maxDuration && modelSettings.maxDuration * 1e3 > LLM_GENERATION_MAX_ALLOWED_TIMEOUT_MS) logger.warn({
1855
1836
  requestedTimeout: modelSettings.maxDuration * 1e3,
@@ -1863,19 +1844,17 @@ ${typeof cleanResult === "string" ? cleanResult : JSON.stringify(cleanResult, nu
1863
1844
  maxDuration: timeoutMs / 1e3
1864
1845
  },
1865
1846
  hasStructuredOutput,
1866
- shouldStreamPhase1,
1867
1847
  timeoutMs
1868
1848
  };
1869
1849
  }
1870
1850
  /**
1871
1851
  * Build initial messages array with system prompt and user content
1872
1852
  */
1873
- buildInitialMessages(systemPrompt, thinkingSystemPrompt, hasStructuredOutput, conversationHistory, userMessage) {
1874
- const phase1SystemPrompt = hasStructuredOutput ? thinkingSystemPrompt : systemPrompt;
1853
+ buildInitialMessages(systemPrompt, conversationHistory, userMessage) {
1875
1854
  const messages = [];
1876
1855
  messages.push({
1877
1856
  role: "system",
1878
- content: phase1SystemPrompt
1857
+ content: systemPrompt
1879
1858
  });
1880
1859
  if (conversationHistory.trim() !== "") messages.push({
1881
1860
  role: "user",
@@ -1959,7 +1938,7 @@ ${typeof cleanResult === "string" ? cleanResult : JSON.stringify(cleanResult, nu
1959
1938
  }
1960
1939
  return {};
1961
1940
  }
1962
- async handleStopWhenConditions(steps, includeThinkingComplete = false) {
1941
+ async handleStopWhenConditions(steps) {
1963
1942
  const last = steps.at(-1);
1964
1943
  if (last && "text" in last && last.text) try {
1965
1944
  await agentSessionManager.recordEvent(this.getStreamRequestId(), "agent_reasoning", this.config.id, { parts: [{
@@ -1969,7 +1948,7 @@ ${typeof cleanResult === "string" ? cleanResult : JSON.stringify(cleanResult, nu
1969
1948
  } catch (error) {
1970
1949
  logger.debug({ error }, "Failed to track agent reasoning");
1971
1950
  }
1972
- if (!includeThinkingComplete && last && last.content && last.content.length > 0) {
1951
+ if (last?.content && last.content.length > 0) {
1973
1952
  const lastContent = last.content[last.content.length - 1];
1974
1953
  if (lastContent.type === "tool-error") {
1975
1954
  const error = lastContent.error;
@@ -1979,10 +1958,7 @@ ${typeof cleanResult === "string" ? cleanResult : JSON.stringify(cleanResult, nu
1979
1958
  if (steps.length >= 1) {
1980
1959
  const currentStep = steps[steps.length - 1];
1981
1960
  if (currentStep && "toolCalls" in currentStep && currentStep.toolCalls) {
1982
- const hasTransferTool = currentStep.toolCalls.some((tc) => tc.toolName.startsWith("transfer_to_"));
1983
- const hasThinkingComplete = currentStep.toolCalls.some((tc) => tc.toolName === "thinking_complete");
1984
- if (hasTransferTool) return true;
1985
- if (includeThinkingComplete && hasThinkingComplete && "toolResults" in currentStep && currentStep.toolResults) return true;
1961
+ if (currentStep.toolCalls.some((tc) => tc.toolName.startsWith("transfer_to_"))) return true;
1986
1962
  }
1987
1963
  }
1988
1964
  const maxSteps = this.getMaxGenerationSteps();
@@ -2035,7 +2011,7 @@ ${typeof cleanResult === "string" ? cleanResult : JSON.stringify(cleanResult, nu
2035
2011
  }
2036
2012
  };
2037
2013
  }
2038
- buildBaseGenerationConfig(modelSettings, messages, sanitizedTools, compressor, originalMessageCount, timeoutMs, toolChoice = "auto", phase, includeThinkingComplete = false, fullContextSize) {
2014
+ buildBaseGenerationConfig(modelSettings, messages, sanitizedTools, compressor, originalMessageCount, timeoutMs, toolChoice = "auto", phase, fullContextSize) {
2039
2015
  return {
2040
2016
  ...modelSettings,
2041
2017
  toolChoice,
@@ -2045,78 +2021,12 @@ ${typeof cleanResult === "string" ? cleanResult : JSON.stringify(cleanResult, nu
2045
2021
  return await this.handlePrepareStepCompression(stepMessages, compressor, originalMessageCount, fullContextSize);
2046
2022
  },
2047
2023
  stopWhen: async ({ steps }) => {
2048
- return await this.handleStopWhenConditions(steps, includeThinkingComplete);
2024
+ return await this.handleStopWhenConditions(steps);
2049
2025
  },
2050
2026
  experimental_telemetry: this.buildTelemetryConfig(phase),
2051
2027
  abortSignal: AbortSignal.timeout(timeoutMs)
2052
2028
  };
2053
2029
  }
2054
- buildReasoningFlow(response, sessionId) {
2055
- const reasoningFlow = [];
2056
- const compressionSummary = this.currentCompressor?.getCompressionSummary();
2057
- if (compressionSummary) {
2058
- const summaryContent = JSON.stringify(compressionSummary, null, 2);
2059
- reasoningFlow.push({
2060
- role: "assistant",
2061
- content: `## Research Summary (Compressed)\n\nBased on tool executions, here's the comprehensive summary:\n\n\`\`\`json\n${summaryContent}\n\`\`\`\n\nThis summary represents all tool execution results in compressed form. Full details are preserved in artifacts.`
2062
- });
2063
- } else if (response.steps) response.steps.forEach((step) => {
2064
- if (step.toolCalls && step.toolResults) step.toolCalls.forEach((call, index) => {
2065
- const result = step.toolResults[index];
2066
- if (result) {
2067
- const storedResult = toolSessionManager.getToolResult(sessionId, result.toolCallId);
2068
- if ((storedResult?.toolName || call.toolName) === "thinking_complete") return;
2069
- const actualResult = storedResult?.result || result.result || result;
2070
- const actualArgs = storedResult?.args || call.args;
2071
- const cleanResult = actualResult && typeof actualResult === "object" && !Array.isArray(actualResult) ? Object.fromEntries(Object.entries(actualResult).filter(([key]) => key !== "_structureHints")) : actualResult;
2072
- const input = actualArgs ? JSON.stringify(actualArgs, null, 2) : "No input";
2073
- const output = typeof cleanResult === "string" ? cleanResult : JSON.stringify(cleanResult, null, 2);
2074
- let structureHintsFormatted = "";
2075
- if (actualResult?._structureHints && this.artifactComponents && this.artifactComponents.length > 0) {
2076
- const hints = actualResult._structureHints;
2077
- structureHintsFormatted = `
2078
- ### 📊 Structure Hints for Artifact Creation
2079
-
2080
- **Terminal Field Paths (${hints.terminalPaths?.length || 0} found):**
2081
- ${hints.terminalPaths?.map((path) => ` • ${path}`).join("\n") || " None detected"}
2082
-
2083
- **Array Structures (${hints.arrayPaths?.length || 0} found):**
2084
- ${hints.arrayPaths?.map((path) => ` • ${path}`).join("\n") || " None detected"}
2085
-
2086
- **Object Structures (${hints.objectPaths?.length || 0} found):**
2087
- ${hints.objectPaths?.map((path) => ` • ${path}`).join("\n") || " None detected"}
2088
-
2089
- **Example Selectors:**
2090
- ${hints.exampleSelectors?.map((sel) => ` • ${sel}`).join("\n") || " None detected"}
2091
-
2092
- **Common Fields:**
2093
- ${hints.commonFields?.map((field) => ` • ${field}`).join("\n") || " None detected"}
2094
-
2095
- **Structure Stats:** ${hints.totalPathsFound || 0} total paths, ${hints.maxDepthFound || 0} levels deep
2096
-
2097
- **Note:** ${hints.note || "Use these paths for artifact base selectors."}
2098
-
2099
- **Forbidden Syntax:** ${hints.forbiddenSyntax || "Use these paths for artifact base selectors."}
2100
- `;
2101
- }
2102
- const formattedResult = `## Tool: ${call.toolName}
2103
-
2104
- ### 🔧 TOOL_CALL_ID: ${result.toolCallId}
2105
-
2106
- ### Input
2107
- ${input}
2108
-
2109
- ### Output
2110
- ${output}${structureHintsFormatted}`;
2111
- reasoningFlow.push({
2112
- role: "assistant",
2113
- content: formattedResult
2114
- });
2115
- }
2116
- });
2117
- });
2118
- return reasoningFlow;
2119
- }
2120
2030
  buildDataComponentsSchema() {
2121
2031
  const componentSchemas = [];
2122
2032
  this.config.dataComponents?.forEach((dc) => {
@@ -2142,75 +2052,6 @@ ${output}${structureHintsFormatted}`;
2142
2052
  }
2143
2053
  return dataComponentsSchema;
2144
2054
  }
2145
- calculatePhase2Timeout(structuredModelSettings) {
2146
- const configuredPhase2Timeout = structuredModelSettings.maxDuration ? Math.min(structuredModelSettings.maxDuration * 1e3, LLM_GENERATION_MAX_ALLOWED_TIMEOUT_MS) : LLM_GENERATION_SUBSEQUENT_CALL_TIMEOUT_MS;
2147
- const phase2TimeoutMs = Math.min(configuredPhase2Timeout, LLM_GENERATION_MAX_ALLOWED_TIMEOUT_MS);
2148
- if (structuredModelSettings.maxDuration && structuredModelSettings.maxDuration * 1e3 > LLM_GENERATION_MAX_ALLOWED_TIMEOUT_MS) logger.warn({
2149
- requestedTimeout: structuredModelSettings.maxDuration * 1e3,
2150
- appliedTimeout: phase2TimeoutMs,
2151
- maxAllowed: LLM_GENERATION_MAX_ALLOWED_TIMEOUT_MS,
2152
- phase: "structured_generation"
2153
- }, "Phase 2 requested timeout exceeded maximum allowed, capping to 10 minutes");
2154
- return phase2TimeoutMs;
2155
- }
2156
- async buildPhase2Messages(runtimeContext, conversationHistory, userMessage, reasoningFlow) {
2157
- const phase2Messages = [{
2158
- role: "system",
2159
- content: await this.buildPhase2SystemPrompt(runtimeContext)
2160
- }];
2161
- if (conversationHistory.trim() !== "") phase2Messages.push({
2162
- role: "user",
2163
- content: conversationHistory
2164
- });
2165
- phase2Messages.push({
2166
- role: "user",
2167
- content: userMessage
2168
- });
2169
- phase2Messages.push(...reasoningFlow);
2170
- if (reasoningFlow.length > 0 && reasoningFlow[reasoningFlow.length - 1]?.role === "assistant") phase2Messages.push({
2171
- role: "user",
2172
- content: "Continue with the structured response."
2173
- });
2174
- return phase2Messages;
2175
- }
2176
- async executeStreamingPhase2(structuredModelSettings, phase2Messages, dataComponentsSchema, phase2TimeoutMs, sessionId, contextId, response) {
2177
- const streamResult = streamText({
2178
- ...structuredModelSettings,
2179
- messages: phase2Messages,
2180
- output: Output.object({ schema: z.object({ dataComponents: z.array(dataComponentsSchema) }) }),
2181
- experimental_telemetry: this.buildTelemetryConfig("structured_generation"),
2182
- abortSignal: AbortSignal.timeout(phase2TimeoutMs)
2183
- });
2184
- const parser = this.setupStreamParser(sessionId, contextId);
2185
- for await (const delta of streamResult.partialOutputStream) if (delta) await parser.processObjectDelta(delta);
2186
- await parser.finalize();
2187
- const structuredResponse = await streamResult;
2188
- const collectedParts = parser.getCollectedParts();
2189
- if (collectedParts.length > 0) response.formattedContent = { parts: collectedParts.map((part) => ({
2190
- kind: part.kind,
2191
- ...part.kind === "text" && { text: part.text },
2192
- ...part.kind === "data" && { data: part.data }
2193
- })) };
2194
- return {
2195
- ...response,
2196
- object: structuredResponse.output,
2197
- textResponse: JSON.stringify(structuredResponse.output, null, 2)
2198
- };
2199
- }
2200
- async executeNonStreamingPhase2(structuredModelSettings, phase2Messages, dataComponentsSchema, phase2TimeoutMs, response) {
2201
- const structuredResponse = await generateText(withJsonPostProcessing({
2202
- ...structuredModelSettings,
2203
- messages: phase2Messages,
2204
- output: Output.object({ schema: z.object({ dataComponents: z.array(dataComponentsSchema) }) }),
2205
- experimental_telemetry: this.buildTelemetryConfig("structured_generation"),
2206
- abortSignal: AbortSignal.timeout(phase2TimeoutMs)
2207
- }));
2208
- return {
2209
- ...response,
2210
- object: structuredResponse.output,
2211
- textResponse: JSON.stringify(structuredResponse.output, null, 2)
2212
- };
2213
- }
2214
2055
  async formatFinalResponse(response, textResponse, sessionId, contextId) {
2215
2056
  let formattedContent = response.formattedContent || null;
2216
2057
  if (!formattedContent) {
@@ -2236,6 +2077,12 @@ ${output}${structureHintsFormatted}`;
2236
2077
  if (this.currentCompressor) this.currentCompressor.fullCleanup();
2237
2078
  this.currentCompressor = null;
2238
2079
  const errorToThrow = error instanceof Error ? error : new Error(String(error));
2080
+ logger.error({
2081
+ agentId: this.config.id,
2082
+ errorMessage: errorToThrow.message,
2083
+ errorStack: errorToThrow.stack,
2084
+ errorName: errorToThrow.name
2085
+ }, "❌ Generation error in Agent");
2239
2086
  setSpanWithError$1(span, errorToThrow);
2240
2087
  span.end();
2241
2088
  throw errorToThrow;
@@ -2250,6 +2097,21 @@ ${output}${structureHintsFormatted}`;
2250
2097
  this.currentCompressor = null;
2251
2098
  }
2252
2099
  }
2100
+ async handleStreamGeneration(streamResult, sessionId, contextId, hasStructuredOutput) {
2101
+ const parser = this.setupStreamParser(sessionId, contextId);
2102
+ if (hasStructuredOutput) {
2103
+ for await (const delta of streamResult.partialOutputStream) if (delta) await parser.processObjectDelta(delta);
2104
+ } else await this.processStreamEvents(streamResult, parser);
2105
+ await parser.finalize();
2106
+ const response = await streamResult;
2107
+ const collectedParts = parser.getCollectedParts();
2108
+ if (collectedParts.length > 0) response.formattedContent = { parts: collectedParts.map((part) => ({
2109
+ kind: part.kind,
2110
+ ...part.kind === "text" && { text: part.text },
2111
+ ...part.kind === "data" && { data: part.data }
2112
+ })) };
2113
+ return response;
2114
+ }
2253
2115
  async processStreamEvents(streamResult, parser) {
2254
2116
  for await (const event of streamResult.fullStream) switch (event.type) {
2255
2117
  case "text-delta":
@@ -2270,24 +2132,8 @@ ${output}${structureHintsFormatted}`;
2270
2132
  throw new Error(errorMessage);
2271
2133
  }
2272
2134
  }
2273
- await parser.finalize();
2274
- }
2275
- formatStreamingResponse(response, parser) {
2276
- const collectedParts = parser.getCollectedParts();
2277
- if (collectedParts.length > 0) response.formattedContent = { parts: collectedParts.map((part) => ({
2278
- kind: part.kind,
2279
- ...part.kind === "text" && { text: part.text },
2280
- ...part.kind === "data" && { data: part.data }
2281
- })) };
2282
- const streamedContent = parser.getAllStreamedContent();
2283
- if (streamedContent.length > 0) response.streamedContent = { parts: streamedContent.map((part) => ({
2284
- kind: part.kind,
2285
- ...part.kind === "text" && { text: part.text },
2286
- ...part.kind === "data" && { data: part.data }
2287
- })) };
2288
- return response;
2289
2135
  }
2290
2136
  };
2291
2137
 
2292
2138
  //#endregion
2293
- export { Agent, hasToolCallWithPrefix };
2139
+ export { Agent, hasToolCallWithPrefix, resolveGenerationResponse };
@@ -311,11 +311,16 @@ const createTaskHandler = (config, credentialStoreRegistry) => {
311
311
  }, "[DEBUG] Transfer validation FAILED");
312
312
  }
313
313
  }
314
- const parts = (response.formattedContent?.parts || []).map((part) => ({
315
- kind: part.kind,
316
- ...part.kind === "text" && { text: part.text },
317
- ...part.kind === "data" && { data: part.data }
318
- }));
314
+ const parts = (response.formattedContent?.parts || []).map((part) => {
315
+ if (part.kind === "data") return {
316
+ kind: "data",
317
+ data: part.data
318
+ };
319
+ return {
320
+ kind: "text",
321
+ text: part.text
322
+ };
323
+ });
319
324
  return {
320
325
  status: { state: TaskState.Completed },
321
326
  artifacts: [{