@inkeep/agents-run-api 0.23.4 → 0.23.5

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 (3) hide show
  1. package/dist/index.cjs +485 -476
  2. package/dist/index.js +484 -475
  3. package/package.json +2 -2
package/dist/index.cjs CHANGED
@@ -9149,326 +9149,334 @@ var Agent = class {
9149
9149
  }
9150
9150
  }
9151
9151
  async generate(userMessage, runtimeContext) {
9152
- return tracer.startActiveSpan("agent.generate", async (span) => {
9153
- const contextId = runtimeContext?.contextId || "default";
9154
- const taskId = runtimeContext?.metadata?.taskId || "unknown";
9155
- const streamRequestId = runtimeContext?.metadata?.streamRequestId;
9156
- const sessionId = streamRequestId || "fallback-session";
9157
- try {
9158
- this.streamRequestId = streamRequestId;
9159
- this.streamHelper = streamRequestId ? getStreamHelper(streamRequestId) : void 0;
9160
- const conversationId = runtimeContext?.metadata?.conversationId;
9161
- if (conversationId) {
9162
- this.setConversationId(conversationId);
9163
- }
9164
- const [
9165
- mcpTools,
9166
- systemPrompt,
9167
- thinkingSystemPrompt,
9168
- functionTools,
9169
- relationTools,
9170
- defaultTools
9171
- ] = await tracer.startActiveSpan(
9172
- "agent.load_tools",
9173
- {
9174
- attributes: {
9175
- "subAgent.name": this.config.name,
9176
- "session.id": sessionId
9177
- }
9178
- },
9179
- async (childSpan) => {
9180
- try {
9181
- const result = await Promise.all([
9182
- this.getMcpTools(sessionId, streamRequestId),
9183
- this.buildSystemPrompt(runtimeContext, false),
9184
- // Normal prompt with data components
9185
- this.buildSystemPrompt(runtimeContext, true),
9186
- // Thinking prompt without data components
9187
- this.getFunctionTools(sessionId, streamRequestId),
9188
- Promise.resolve(this.getRelationTools(runtimeContext, sessionId)),
9189
- this.getDefaultTools(streamRequestId)
9190
- ]);
9191
- childSpan.setStatus({ code: api.SpanStatusCode.OK });
9192
- return result;
9193
- } catch (err) {
9194
- const errorObj = err instanceof Error ? err : new Error(String(err));
9195
- agentsCore.setSpanWithError(childSpan, errorObj);
9196
- throw err;
9197
- } finally {
9198
- childSpan.end();
9199
- }
9200
- }
9201
- );
9202
- const allTools = {
9203
- ...mcpTools,
9204
- ...functionTools,
9205
- ...relationTools,
9206
- ...defaultTools
9207
- };
9208
- const sanitizedTools = this.sanitizeToolsForAISDK(allTools);
9209
- let conversationHistory = "";
9210
- const historyConfig = this.config.conversationHistoryConfig ?? createDefaultConversationHistoryConfig();
9211
- if (historyConfig && historyConfig.mode !== "none") {
9212
- if (historyConfig.mode === "full") {
9213
- conversationHistory = await getFormattedConversationHistory({
9214
- tenantId: this.config.tenantId,
9215
- projectId: this.config.projectId,
9216
- conversationId: contextId,
9217
- currentMessage: userMessage,
9218
- options: historyConfig,
9219
- filters: {}
9220
- });
9221
- } else if (historyConfig.mode === "scoped") {
9222
- conversationHistory = await getFormattedConversationHistory({
9223
- tenantId: this.config.tenantId,
9224
- projectId: this.config.projectId,
9225
- conversationId: contextId,
9226
- currentMessage: userMessage,
9227
- options: historyConfig,
9228
- filters: {
9229
- subAgentId: this.config.id,
9230
- taskId
9231
- }
9232
- });
9233
- }
9152
+ return tracer.startActiveSpan(
9153
+ "agent.generate",
9154
+ {
9155
+ attributes: {
9156
+ "subagent.id": this.config.id,
9157
+ "subagent.name": this.config.name
9234
9158
  }
9235
- const primaryModelSettings = this.getPrimaryModel();
9236
- const modelSettings = ModelFactory.prepareGenerationConfig(primaryModelSettings);
9237
- let response;
9238
- let textResponse;
9239
- const hasStructuredOutput = this.config.dataComponents && this.config.dataComponents.length > 0;
9240
- const shouldStreamPhase1 = this.getStreamingHelper() && !hasStructuredOutput;
9241
- const MAX_ALLOWED_TIMEOUT_MS = 6e5;
9242
- const configuredTimeout = modelSettings.maxDuration ? Math.min(modelSettings.maxDuration * 1e3, MAX_ALLOWED_TIMEOUT_MS) : shouldStreamPhase1 ? CONSTANTS.PHASE_1_TIMEOUT_MS : CONSTANTS.NON_STREAMING_PHASE_1_TIMEOUT_MS;
9243
- const timeoutMs = Math.min(configuredTimeout, MAX_ALLOWED_TIMEOUT_MS);
9244
- if (modelSettings.maxDuration && modelSettings.maxDuration * 1e3 > MAX_ALLOWED_TIMEOUT_MS) {
9245
- logger19.warn(
9159
+ },
9160
+ async (span) => {
9161
+ const contextId = runtimeContext?.contextId || "default";
9162
+ const taskId = runtimeContext?.metadata?.taskId || "unknown";
9163
+ const streamRequestId = runtimeContext?.metadata?.streamRequestId;
9164
+ const sessionId = streamRequestId || "fallback-session";
9165
+ try {
9166
+ this.streamRequestId = streamRequestId;
9167
+ this.streamHelper = streamRequestId ? getStreamHelper(streamRequestId) : void 0;
9168
+ const conversationId = runtimeContext?.metadata?.conversationId;
9169
+ if (conversationId) {
9170
+ this.setConversationId(conversationId);
9171
+ }
9172
+ const [
9173
+ mcpTools,
9174
+ systemPrompt,
9175
+ thinkingSystemPrompt,
9176
+ functionTools,
9177
+ relationTools,
9178
+ defaultTools
9179
+ ] = await tracer.startActiveSpan(
9180
+ "agent.load_tools",
9246
9181
  {
9247
- requestedTimeout: modelSettings.maxDuration * 1e3,
9248
- appliedTimeout: timeoutMs,
9249
- maxAllowed: MAX_ALLOWED_TIMEOUT_MS
9250
- },
9251
- "Requested timeout exceeded maximum allowed, capping to 10 minutes"
9252
- );
9253
- }
9254
- const phase1SystemPrompt = hasStructuredOutput ? thinkingSystemPrompt : systemPrompt;
9255
- const messages = [];
9256
- messages.push({ role: "system", content: phase1SystemPrompt });
9257
- if (conversationHistory.trim() !== "") {
9258
- messages.push({ role: "user", content: conversationHistory });
9259
- }
9260
- messages.push({
9261
- role: "user",
9262
- content: userMessage
9263
- });
9264
- if (shouldStreamPhase1) {
9265
- const streamConfig = {
9266
- ...modelSettings,
9267
- toolChoice: "auto"
9268
- // Allow natural text + tools
9269
- };
9270
- const streamResult = ai.streamText({
9271
- ...streamConfig,
9272
- messages,
9273
- tools: sanitizedTools,
9274
- stopWhen: async ({ steps }) => {
9275
- const last = steps.at(-1);
9276
- if (last && "text" in last && last.text) {
9277
- try {
9278
- await agentSessionManager.recordEvent(
9279
- this.getStreamRequestId(),
9280
- "agent_reasoning",
9281
- this.config.id,
9282
- {
9283
- parts: [{ type: "text", content: last.text }]
9284
- }
9285
- );
9286
- } catch (error) {
9287
- logger19.debug({ error }, "Failed to track agent reasoning");
9288
- }
9289
- }
9290
- if (steps.length >= 2) {
9291
- const previousStep = steps[steps.length - 2];
9292
- if (previousStep && "toolCalls" in previousStep && previousStep.toolCalls) {
9293
- const hasTransferCall = previousStep.toolCalls.some(
9294
- (tc) => tc.toolName.startsWith("transfer_to_")
9295
- );
9296
- if (hasTransferCall && "toolResults" in previousStep && previousStep.toolResults) {
9297
- return true;
9298
- }
9299
- }
9182
+ attributes: {
9183
+ "subAgent.name": this.config.name,
9184
+ "session.id": sessionId
9300
9185
  }
9301
- return steps.length >= this.getMaxGenerationSteps();
9302
9186
  },
9303
- experimental_telemetry: {
9304
- isEnabled: true,
9305
- functionId: this.config.id,
9306
- recordInputs: true,
9307
- recordOutputs: true
9308
- },
9309
- abortSignal: AbortSignal.timeout(timeoutMs)
9310
- });
9311
- const streamHelper = this.getStreamingHelper();
9312
- if (!streamHelper) {
9313
- throw new Error("Stream helper is unexpectedly undefined in streaming context");
9314
- }
9315
- const session = toolSessionManager.getSession(sessionId);
9316
- const artifactParserOptions = {
9317
- sessionId,
9318
- taskId: session?.taskId,
9319
- projectId: session?.projectId,
9320
- artifactComponents: this.artifactComponents,
9321
- streamRequestId: this.getStreamRequestId(),
9322
- subAgentId: this.config.id
9323
- };
9324
- const parser = new IncrementalStreamParser(
9325
- streamHelper,
9326
- this.config.tenantId,
9327
- contextId,
9328
- artifactParserOptions
9187
+ async (childSpan) => {
9188
+ try {
9189
+ const result = await Promise.all([
9190
+ this.getMcpTools(sessionId, streamRequestId),
9191
+ this.buildSystemPrompt(runtimeContext, false),
9192
+ // Normal prompt with data components
9193
+ this.buildSystemPrompt(runtimeContext, true),
9194
+ // Thinking prompt without data components
9195
+ this.getFunctionTools(sessionId, streamRequestId),
9196
+ Promise.resolve(this.getRelationTools(runtimeContext, sessionId)),
9197
+ this.getDefaultTools(streamRequestId)
9198
+ ]);
9199
+ childSpan.setStatus({ code: api.SpanStatusCode.OK });
9200
+ return result;
9201
+ } catch (err) {
9202
+ const errorObj = err instanceof Error ? err : new Error(String(err));
9203
+ agentsCore.setSpanWithError(childSpan, errorObj);
9204
+ throw err;
9205
+ } finally {
9206
+ childSpan.end();
9207
+ }
9208
+ }
9329
9209
  );
9330
- for await (const event of streamResult.fullStream) {
9331
- switch (event.type) {
9332
- case "text-delta":
9333
- await parser.processTextChunk(event.text);
9334
- break;
9335
- case "tool-call":
9336
- parser.markToolResult();
9337
- break;
9338
- case "tool-result":
9339
- parser.markToolResult();
9340
- break;
9341
- case "finish":
9342
- if (event.finishReason === "tool-calls") {
9343
- parser.markToolResult();
9344
- }
9345
- break;
9346
- case "error":
9347
- if (event.error instanceof Error) {
9348
- throw event.error;
9349
- } else {
9350
- const errorMessage = event.error?.error?.message;
9351
- throw new Error(errorMessage);
9210
+ const allTools = {
9211
+ ...mcpTools,
9212
+ ...functionTools,
9213
+ ...relationTools,
9214
+ ...defaultTools
9215
+ };
9216
+ const sanitizedTools = this.sanitizeToolsForAISDK(allTools);
9217
+ let conversationHistory = "";
9218
+ const historyConfig = this.config.conversationHistoryConfig ?? createDefaultConversationHistoryConfig();
9219
+ if (historyConfig && historyConfig.mode !== "none") {
9220
+ if (historyConfig.mode === "full") {
9221
+ conversationHistory = await getFormattedConversationHistory({
9222
+ tenantId: this.config.tenantId,
9223
+ projectId: this.config.projectId,
9224
+ conversationId: contextId,
9225
+ currentMessage: userMessage,
9226
+ options: historyConfig,
9227
+ filters: {}
9228
+ });
9229
+ } else if (historyConfig.mode === "scoped") {
9230
+ conversationHistory = await getFormattedConversationHistory({
9231
+ tenantId: this.config.tenantId,
9232
+ projectId: this.config.projectId,
9233
+ conversationId: contextId,
9234
+ currentMessage: userMessage,
9235
+ options: historyConfig,
9236
+ filters: {
9237
+ subAgentId: this.config.id,
9238
+ taskId
9352
9239
  }
9240
+ });
9353
9241
  }
9354
9242
  }
9355
- await parser.finalize();
9356
- response = await streamResult;
9357
- const collectedParts = parser.getCollectedParts();
9358
- if (collectedParts.length > 0) {
9359
- response.formattedContent = {
9360
- parts: collectedParts.map((part) => ({
9361
- kind: part.kind,
9362
- ...part.kind === "text" && { text: part.text },
9363
- ...part.kind === "data" && { data: part.data }
9364
- }))
9365
- };
9243
+ const primaryModelSettings = this.getPrimaryModel();
9244
+ const modelSettings = ModelFactory.prepareGenerationConfig(primaryModelSettings);
9245
+ let response;
9246
+ let textResponse;
9247
+ const hasStructuredOutput = this.config.dataComponents && this.config.dataComponents.length > 0;
9248
+ const shouldStreamPhase1 = this.getStreamingHelper() && !hasStructuredOutput;
9249
+ const MAX_ALLOWED_TIMEOUT_MS = 6e5;
9250
+ const configuredTimeout = modelSettings.maxDuration ? Math.min(modelSettings.maxDuration * 1e3, MAX_ALLOWED_TIMEOUT_MS) : shouldStreamPhase1 ? CONSTANTS.PHASE_1_TIMEOUT_MS : CONSTANTS.NON_STREAMING_PHASE_1_TIMEOUT_MS;
9251
+ const timeoutMs = Math.min(configuredTimeout, MAX_ALLOWED_TIMEOUT_MS);
9252
+ if (modelSettings.maxDuration && modelSettings.maxDuration * 1e3 > MAX_ALLOWED_TIMEOUT_MS) {
9253
+ logger19.warn(
9254
+ {
9255
+ requestedTimeout: modelSettings.maxDuration * 1e3,
9256
+ appliedTimeout: timeoutMs,
9257
+ maxAllowed: MAX_ALLOWED_TIMEOUT_MS
9258
+ },
9259
+ "Requested timeout exceeded maximum allowed, capping to 10 minutes"
9260
+ );
9366
9261
  }
9367
- const streamedContent = parser.getAllStreamedContent();
9368
- if (streamedContent.length > 0) {
9369
- response.streamedContent = {
9370
- parts: streamedContent.map((part) => ({
9371
- kind: part.kind,
9372
- ...part.kind === "text" && { text: part.text },
9373
- ...part.kind === "data" && { data: part.data }
9374
- }))
9375
- };
9262
+ const phase1SystemPrompt = hasStructuredOutput ? thinkingSystemPrompt : systemPrompt;
9263
+ const messages = [];
9264
+ messages.push({ role: "system", content: phase1SystemPrompt });
9265
+ if (conversationHistory.trim() !== "") {
9266
+ messages.push({ role: "user", content: conversationHistory });
9376
9267
  }
9377
- } else {
9378
- let genConfig;
9379
- if (hasStructuredOutput) {
9380
- genConfig = {
9381
- ...modelSettings,
9382
- toolChoice: "required"
9383
- // Force tool usage, prevent text generation
9384
- };
9385
- } else {
9386
- genConfig = {
9268
+ messages.push({
9269
+ role: "user",
9270
+ content: userMessage
9271
+ });
9272
+ if (shouldStreamPhase1) {
9273
+ const streamConfig = {
9387
9274
  ...modelSettings,
9388
9275
  toolChoice: "auto"
9389
- // Allow both tools and text generation
9276
+ // Allow natural text + tools
9390
9277
  };
9391
- }
9392
- response = await ai.generateText({
9393
- ...genConfig,
9394
- messages,
9395
- tools: sanitizedTools,
9396
- stopWhen: async ({ steps }) => {
9397
- const last = steps.at(-1);
9398
- if (last && "text" in last && last.text) {
9399
- try {
9400
- await agentSessionManager.recordEvent(
9401
- this.getStreamRequestId(),
9402
- "agent_reasoning",
9403
- this.config.id,
9404
- {
9405
- parts: [{ type: "text", content: last.text }]
9406
- }
9407
- );
9408
- } catch (error) {
9409
- logger19.debug({ error }, "Failed to track agent reasoning");
9278
+ const streamResult = ai.streamText({
9279
+ ...streamConfig,
9280
+ messages,
9281
+ tools: sanitizedTools,
9282
+ stopWhen: async ({ steps }) => {
9283
+ const last = steps.at(-1);
9284
+ if (last && "text" in last && last.text) {
9285
+ try {
9286
+ await agentSessionManager.recordEvent(
9287
+ this.getStreamRequestId(),
9288
+ "agent_reasoning",
9289
+ this.config.id,
9290
+ {
9291
+ parts: [{ type: "text", content: last.text }]
9292
+ }
9293
+ );
9294
+ } catch (error) {
9295
+ logger19.debug({ error }, "Failed to track agent reasoning");
9296
+ }
9410
9297
  }
9411
- }
9412
- if (steps.length >= 2) {
9413
- const previousStep = steps[steps.length - 2];
9414
- if (previousStep && "toolCalls" in previousStep && previousStep.toolCalls) {
9415
- const hasStopTool = previousStep.toolCalls.some(
9416
- (tc) => tc.toolName.startsWith("transfer_to_") || tc.toolName === "thinking_complete"
9417
- );
9418
- if (hasStopTool && "toolResults" in previousStep && previousStep.toolResults) {
9419
- return true;
9298
+ if (steps.length >= 2) {
9299
+ const previousStep = steps[steps.length - 2];
9300
+ if (previousStep && "toolCalls" in previousStep && previousStep.toolCalls) {
9301
+ const hasTransferCall = previousStep.toolCalls.some(
9302
+ (tc) => tc.toolName.startsWith("transfer_to_")
9303
+ );
9304
+ if (hasTransferCall && "toolResults" in previousStep && previousStep.toolResults) {
9305
+ return true;
9306
+ }
9420
9307
  }
9421
9308
  }
9309
+ return steps.length >= this.getMaxGenerationSteps();
9310
+ },
9311
+ experimental_telemetry: {
9312
+ isEnabled: true,
9313
+ functionId: this.config.id,
9314
+ recordInputs: true,
9315
+ recordOutputs: true
9316
+ },
9317
+ abortSignal: AbortSignal.timeout(timeoutMs)
9318
+ });
9319
+ const streamHelper = this.getStreamingHelper();
9320
+ if (!streamHelper) {
9321
+ throw new Error("Stream helper is unexpectedly undefined in streaming context");
9322
+ }
9323
+ const session = toolSessionManager.getSession(sessionId);
9324
+ const artifactParserOptions = {
9325
+ sessionId,
9326
+ taskId: session?.taskId,
9327
+ projectId: session?.projectId,
9328
+ artifactComponents: this.artifactComponents,
9329
+ streamRequestId: this.getStreamRequestId(),
9330
+ subAgentId: this.config.id
9331
+ };
9332
+ const parser = new IncrementalStreamParser(
9333
+ streamHelper,
9334
+ this.config.tenantId,
9335
+ contextId,
9336
+ artifactParserOptions
9337
+ );
9338
+ for await (const event of streamResult.fullStream) {
9339
+ switch (event.type) {
9340
+ case "text-delta":
9341
+ await parser.processTextChunk(event.text);
9342
+ break;
9343
+ case "tool-call":
9344
+ parser.markToolResult();
9345
+ break;
9346
+ case "tool-result":
9347
+ parser.markToolResult();
9348
+ break;
9349
+ case "finish":
9350
+ if (event.finishReason === "tool-calls") {
9351
+ parser.markToolResult();
9352
+ }
9353
+ break;
9354
+ case "error":
9355
+ if (event.error instanceof Error) {
9356
+ throw event.error;
9357
+ } else {
9358
+ const errorMessage = event.error?.error?.message;
9359
+ throw new Error(errorMessage);
9360
+ }
9422
9361
  }
9423
- return steps.length >= this.getMaxGenerationSteps();
9424
- },
9425
- experimental_telemetry: {
9426
- isEnabled: true,
9427
- functionId: this.config.id,
9428
- recordInputs: true,
9429
- recordOutputs: true,
9430
- metadata: {
9431
- phase: "planning"
9432
- }
9433
- },
9434
- abortSignal: AbortSignal.timeout(timeoutMs)
9435
- });
9436
- }
9437
- if (response.steps) {
9438
- const resolvedSteps = await response.steps;
9439
- response = { ...response, steps: resolvedSteps };
9440
- }
9441
- if (hasStructuredOutput && !hasToolCallWithPrefix("transfer_to_")(response)) {
9442
- const thinkingCompleteCall = response.steps?.flatMap((s) => s.toolCalls || [])?.find((tc) => tc.toolName === "thinking_complete");
9443
- if (thinkingCompleteCall) {
9444
- const reasoningFlow = [];
9445
- if (response.steps) {
9446
- response.steps.forEach((step) => {
9447
- if (step.toolCalls && step.toolResults) {
9448
- step.toolCalls.forEach((call, index) => {
9449
- const result = step.toolResults[index];
9450
- if (result) {
9451
- const storedResult = toolSessionManager.getToolResult(
9452
- sessionId,
9453
- result.toolCallId
9454
- );
9455
- const toolName = storedResult?.toolName || call.toolName;
9456
- if (toolName === "thinking_complete") {
9457
- return;
9362
+ }
9363
+ await parser.finalize();
9364
+ response = await streamResult;
9365
+ const collectedParts = parser.getCollectedParts();
9366
+ if (collectedParts.length > 0) {
9367
+ response.formattedContent = {
9368
+ parts: collectedParts.map((part) => ({
9369
+ kind: part.kind,
9370
+ ...part.kind === "text" && { text: part.text },
9371
+ ...part.kind === "data" && { data: part.data }
9372
+ }))
9373
+ };
9374
+ }
9375
+ const streamedContent = parser.getAllStreamedContent();
9376
+ if (streamedContent.length > 0) {
9377
+ response.streamedContent = {
9378
+ parts: streamedContent.map((part) => ({
9379
+ kind: part.kind,
9380
+ ...part.kind === "text" && { text: part.text },
9381
+ ...part.kind === "data" && { data: part.data }
9382
+ }))
9383
+ };
9384
+ }
9385
+ } else {
9386
+ let genConfig;
9387
+ if (hasStructuredOutput) {
9388
+ genConfig = {
9389
+ ...modelSettings,
9390
+ toolChoice: "required"
9391
+ // Force tool usage, prevent text generation
9392
+ };
9393
+ } else {
9394
+ genConfig = {
9395
+ ...modelSettings,
9396
+ toolChoice: "auto"
9397
+ // Allow both tools and text generation
9398
+ };
9399
+ }
9400
+ response = await ai.generateText({
9401
+ ...genConfig,
9402
+ messages,
9403
+ tools: sanitizedTools,
9404
+ stopWhen: async ({ steps }) => {
9405
+ const last = steps.at(-1);
9406
+ if (last && "text" in last && last.text) {
9407
+ try {
9408
+ await agentSessionManager.recordEvent(
9409
+ this.getStreamRequestId(),
9410
+ "agent_reasoning",
9411
+ this.config.id,
9412
+ {
9413
+ parts: [{ type: "text", content: last.text }]
9458
9414
  }
9459
- const actualResult = storedResult?.result || result.result || result;
9460
- const actualArgs = storedResult?.args || call.args;
9461
- const cleanResult = actualResult && typeof actualResult === "object" && !Array.isArray(actualResult) ? Object.fromEntries(
9462
- Object.entries(actualResult).filter(
9463
- ([key]) => key !== "_structureHints"
9464
- )
9465
- ) : actualResult;
9466
- const input = actualArgs ? JSON.stringify(actualArgs, null, 2) : "No input";
9467
- const output = typeof cleanResult === "string" ? cleanResult : JSON.stringify(cleanResult, null, 2);
9468
- let structureHintsFormatted = "";
9469
- if (actualResult?._structureHints && this.artifactComponents && this.artifactComponents.length > 0) {
9470
- const hints = actualResult._structureHints;
9471
- structureHintsFormatted = `
9415
+ );
9416
+ } catch (error) {
9417
+ logger19.debug({ error }, "Failed to track agent reasoning");
9418
+ }
9419
+ }
9420
+ if (steps.length >= 2) {
9421
+ const previousStep = steps[steps.length - 2];
9422
+ if (previousStep && "toolCalls" in previousStep && previousStep.toolCalls) {
9423
+ const hasStopTool = previousStep.toolCalls.some(
9424
+ (tc) => tc.toolName.startsWith("transfer_to_") || tc.toolName === "thinking_complete"
9425
+ );
9426
+ if (hasStopTool && "toolResults" in previousStep && previousStep.toolResults) {
9427
+ return true;
9428
+ }
9429
+ }
9430
+ }
9431
+ return steps.length >= this.getMaxGenerationSteps();
9432
+ },
9433
+ experimental_telemetry: {
9434
+ isEnabled: true,
9435
+ functionId: this.config.id,
9436
+ recordInputs: true,
9437
+ recordOutputs: true,
9438
+ metadata: {
9439
+ phase: "planning"
9440
+ }
9441
+ },
9442
+ abortSignal: AbortSignal.timeout(timeoutMs)
9443
+ });
9444
+ }
9445
+ if (response.steps) {
9446
+ const resolvedSteps = await response.steps;
9447
+ response = { ...response, steps: resolvedSteps };
9448
+ }
9449
+ if (hasStructuredOutput && !hasToolCallWithPrefix("transfer_to_")(response)) {
9450
+ const thinkingCompleteCall = response.steps?.flatMap((s) => s.toolCalls || [])?.find((tc) => tc.toolName === "thinking_complete");
9451
+ if (thinkingCompleteCall) {
9452
+ const reasoningFlow = [];
9453
+ if (response.steps) {
9454
+ response.steps.forEach((step) => {
9455
+ if (step.toolCalls && step.toolResults) {
9456
+ step.toolCalls.forEach((call, index) => {
9457
+ const result = step.toolResults[index];
9458
+ if (result) {
9459
+ const storedResult = toolSessionManager.getToolResult(
9460
+ sessionId,
9461
+ result.toolCallId
9462
+ );
9463
+ const toolName = storedResult?.toolName || call.toolName;
9464
+ if (toolName === "thinking_complete") {
9465
+ return;
9466
+ }
9467
+ const actualResult = storedResult?.result || result.result || result;
9468
+ const actualArgs = storedResult?.args || call.args;
9469
+ const cleanResult = actualResult && typeof actualResult === "object" && !Array.isArray(actualResult) ? Object.fromEntries(
9470
+ Object.entries(actualResult).filter(
9471
+ ([key]) => key !== "_structureHints"
9472
+ )
9473
+ ) : actualResult;
9474
+ const input = actualArgs ? JSON.stringify(actualArgs, null, 2) : "No input";
9475
+ const output = typeof cleanResult === "string" ? cleanResult : JSON.stringify(cleanResult, null, 2);
9476
+ let structureHintsFormatted = "";
9477
+ if (actualResult?._structureHints && this.artifactComponents && this.artifactComponents.length > 0) {
9478
+ const hints = actualResult._structureHints;
9479
+ structureHintsFormatted = `
9472
9480
  ### \u{1F4CA} Structure Hints for Artifact Creation
9473
9481
 
9474
9482
  **Terminal Field Paths (${hints.terminalPaths?.length || 0} found):**
@@ -9492,8 +9500,8 @@ ${hints.commonFields?.map((field) => ` \u2022 ${field}`).join("\n") || " None
9492
9500
 
9493
9501
  **Forbidden Syntax:** ${hints.forbiddenSyntax || "Use these paths for artifact base selectors."}
9494
9502
  `;
9495
- }
9496
- const formattedResult = `## Tool: ${call.toolName}
9503
+ }
9504
+ const formattedResult = `## Tool: ${call.toolName}
9497
9505
 
9498
9506
  ### \u{1F527} TOOL_CALL_ID: ${result.toolCallId}
9499
9507
 
@@ -9502,130 +9510,61 @@ ${input}
9502
9510
 
9503
9511
  ### Output
9504
9512
  ${output}${structureHintsFormatted}`;
9505
- reasoningFlow.push({
9506
- role: "assistant",
9507
- content: formattedResult
9508
- });
9509
- }
9510
- });
9511
- }
9512
- });
9513
- }
9514
- const componentSchemas = [];
9515
- if (this.config.dataComponents && this.config.dataComponents.length > 0) {
9516
- this.config.dataComponents.forEach((dc) => {
9517
- const propsSchema = jsonSchemaToZod(dc.props);
9518
- componentSchemas.push(
9519
- z6.z.object({
9520
- id: z6.z.string(),
9521
- name: z6.z.literal(dc.name),
9522
- props: propsSchema
9523
- })
9524
- );
9525
- });
9526
- }
9527
- if (this.artifactComponents.length > 0) {
9528
- const artifactCreateSchemas = ArtifactCreateSchema.getSchemas(
9529
- this.artifactComponents
9530
- );
9531
- componentSchemas.push(...artifactCreateSchemas);
9532
- componentSchemas.push(ArtifactReferenceSchema.getSchema());
9533
- }
9534
- let dataComponentsSchema;
9535
- if (componentSchemas.length === 1) {
9536
- dataComponentsSchema = componentSchemas[0];
9537
- } else {
9538
- dataComponentsSchema = z6.z.union(
9539
- componentSchemas
9540
- );
9541
- }
9542
- const structuredModelSettings = ModelFactory.prepareGenerationConfig(
9543
- this.getStructuredOutputModel()
9544
- );
9545
- const phase2TimeoutMs = structuredModelSettings.maxDuration ? structuredModelSettings.maxDuration * 1e3 : CONSTANTS.PHASE_2_TIMEOUT_MS;
9546
- const shouldStreamPhase2 = this.getStreamingHelper();
9547
- if (shouldStreamPhase2) {
9548
- const phase2Messages = [
9549
- {
9550
- role: "system",
9551
- content: await this.buildPhase2SystemPrompt(runtimeContext)
9552
- }
9553
- ];
9554
- if (conversationHistory.trim() !== "") {
9555
- phase2Messages.push({ role: "user", content: conversationHistory });
9556
- }
9557
- phase2Messages.push({ role: "user", content: userMessage });
9558
- phase2Messages.push(...reasoningFlow);
9559
- const streamResult = ai.streamObject({
9560
- ...structuredModelSettings,
9561
- messages: phase2Messages,
9562
- schema: z6.z.object({
9563
- dataComponents: z6.z.array(dataComponentsSchema)
9564
- }),
9565
- experimental_telemetry: {
9566
- isEnabled: true,
9567
- functionId: this.config.id,
9568
- recordInputs: true,
9569
- recordOutputs: true,
9570
- metadata: {
9571
- phase: "structured_generation"
9513
+ reasoningFlow.push({
9514
+ role: "assistant",
9515
+ content: formattedResult
9516
+ });
9517
+ }
9518
+ });
9572
9519
  }
9573
- },
9574
- abortSignal: AbortSignal.timeout(phase2TimeoutMs)
9575
- });
9576
- const streamHelper = this.getStreamingHelper();
9577
- if (!streamHelper) {
9578
- throw new Error("Stream helper is unexpectedly undefined in streaming context");
9520
+ });
9579
9521
  }
9580
- const session = toolSessionManager.getSession(sessionId);
9581
- const artifactParserOptions = {
9582
- sessionId,
9583
- taskId: session?.taskId,
9584
- projectId: session?.projectId,
9585
- artifactComponents: this.artifactComponents,
9586
- streamRequestId: this.getStreamRequestId(),
9587
- subAgentId: this.config.id
9588
- };
9589
- const parser = new IncrementalStreamParser(
9590
- streamHelper,
9591
- this.config.tenantId,
9592
- contextId,
9593
- artifactParserOptions
9594
- );
9595
- for await (const delta of streamResult.partialObjectStream) {
9596
- if (delta) {
9597
- await parser.processObjectDelta(delta);
9598
- }
9522
+ const componentSchemas = [];
9523
+ if (this.config.dataComponents && this.config.dataComponents.length > 0) {
9524
+ this.config.dataComponents.forEach((dc) => {
9525
+ const propsSchema = jsonSchemaToZod(dc.props);
9526
+ componentSchemas.push(
9527
+ z6.z.object({
9528
+ id: z6.z.string(),
9529
+ name: z6.z.literal(dc.name),
9530
+ props: propsSchema
9531
+ })
9532
+ );
9533
+ });
9599
9534
  }
9600
- await parser.finalize();
9601
- const structuredResponse = await streamResult;
9602
- const collectedParts = parser.getCollectedParts();
9603
- if (collectedParts.length > 0) {
9604
- response.formattedContent = {
9605
- parts: collectedParts.map((part) => ({
9606
- kind: part.kind,
9607
- ...part.kind === "text" && { text: part.text },
9608
- ...part.kind === "data" && { data: part.data }
9609
- }))
9610
- };
9535
+ if (this.artifactComponents.length > 0) {
9536
+ const artifactCreateSchemas = ArtifactCreateSchema.getSchemas(
9537
+ this.artifactComponents
9538
+ );
9539
+ componentSchemas.push(...artifactCreateSchemas);
9540
+ componentSchemas.push(ArtifactReferenceSchema.getSchema());
9611
9541
  }
9612
- response = {
9613
- ...response,
9614
- object: structuredResponse.object
9615
- };
9616
- textResponse = JSON.stringify(structuredResponse.object, null, 2);
9617
- } else {
9618
- const { withJsonPostProcessing: withJsonPostProcessing2 } = await Promise.resolve().then(() => (init_json_postprocessor(), json_postprocessor_exports));
9619
- const phase2Messages = [
9620
- { role: "system", content: await this.buildPhase2SystemPrompt(runtimeContext) }
9621
- ];
9622
- if (conversationHistory.trim() !== "") {
9623
- phase2Messages.push({ role: "user", content: conversationHistory });
9542
+ let dataComponentsSchema;
9543
+ if (componentSchemas.length === 1) {
9544
+ dataComponentsSchema = componentSchemas[0];
9545
+ } else {
9546
+ dataComponentsSchema = z6.z.union(
9547
+ componentSchemas
9548
+ );
9624
9549
  }
9625
- phase2Messages.push({ role: "user", content: userMessage });
9626
- phase2Messages.push(...reasoningFlow);
9627
- const structuredResponse = await ai.generateObject(
9628
- withJsonPostProcessing2({
9550
+ const structuredModelSettings = ModelFactory.prepareGenerationConfig(
9551
+ this.getStructuredOutputModel()
9552
+ );
9553
+ const phase2TimeoutMs = structuredModelSettings.maxDuration ? structuredModelSettings.maxDuration * 1e3 : CONSTANTS.PHASE_2_TIMEOUT_MS;
9554
+ const shouldStreamPhase2 = this.getStreamingHelper();
9555
+ if (shouldStreamPhase2) {
9556
+ const phase2Messages = [
9557
+ {
9558
+ role: "system",
9559
+ content: await this.buildPhase2SystemPrompt(runtimeContext)
9560
+ }
9561
+ ];
9562
+ if (conversationHistory.trim() !== "") {
9563
+ phase2Messages.push({ role: "user", content: conversationHistory });
9564
+ }
9565
+ phase2Messages.push({ role: "user", content: userMessage });
9566
+ phase2Messages.push(...reasoningFlow);
9567
+ const streamResult = ai.streamObject({
9629
9568
  ...structuredModelSettings,
9630
9569
  messages: phase2Messages,
9631
9570
  schema: z6.z.object({
@@ -9641,65 +9580,135 @@ ${output}${structureHintsFormatted}`;
9641
9580
  }
9642
9581
  },
9643
9582
  abortSignal: AbortSignal.timeout(phase2TimeoutMs)
9644
- })
9645
- );
9646
- response = {
9647
- ...response,
9648
- object: structuredResponse.object
9649
- };
9650
- textResponse = JSON.stringify(structuredResponse.object, null, 2);
9583
+ });
9584
+ const streamHelper = this.getStreamingHelper();
9585
+ if (!streamHelper) {
9586
+ throw new Error("Stream helper is unexpectedly undefined in streaming context");
9587
+ }
9588
+ const session = toolSessionManager.getSession(sessionId);
9589
+ const artifactParserOptions = {
9590
+ sessionId,
9591
+ taskId: session?.taskId,
9592
+ projectId: session?.projectId,
9593
+ artifactComponents: this.artifactComponents,
9594
+ streamRequestId: this.getStreamRequestId(),
9595
+ subAgentId: this.config.id
9596
+ };
9597
+ const parser = new IncrementalStreamParser(
9598
+ streamHelper,
9599
+ this.config.tenantId,
9600
+ contextId,
9601
+ artifactParserOptions
9602
+ );
9603
+ for await (const delta of streamResult.partialObjectStream) {
9604
+ if (delta) {
9605
+ await parser.processObjectDelta(delta);
9606
+ }
9607
+ }
9608
+ await parser.finalize();
9609
+ const structuredResponse = await streamResult;
9610
+ const collectedParts = parser.getCollectedParts();
9611
+ if (collectedParts.length > 0) {
9612
+ response.formattedContent = {
9613
+ parts: collectedParts.map((part) => ({
9614
+ kind: part.kind,
9615
+ ...part.kind === "text" && { text: part.text },
9616
+ ...part.kind === "data" && { data: part.data }
9617
+ }))
9618
+ };
9619
+ }
9620
+ response = {
9621
+ ...response,
9622
+ object: structuredResponse.object
9623
+ };
9624
+ textResponse = JSON.stringify(structuredResponse.object, null, 2);
9625
+ } else {
9626
+ const { withJsonPostProcessing: withJsonPostProcessing2 } = await Promise.resolve().then(() => (init_json_postprocessor(), json_postprocessor_exports));
9627
+ const phase2Messages = [
9628
+ { role: "system", content: await this.buildPhase2SystemPrompt(runtimeContext) }
9629
+ ];
9630
+ if (conversationHistory.trim() !== "") {
9631
+ phase2Messages.push({ role: "user", content: conversationHistory });
9632
+ }
9633
+ phase2Messages.push({ role: "user", content: userMessage });
9634
+ phase2Messages.push(...reasoningFlow);
9635
+ const structuredResponse = await ai.generateObject(
9636
+ withJsonPostProcessing2({
9637
+ ...structuredModelSettings,
9638
+ messages: phase2Messages,
9639
+ schema: z6.z.object({
9640
+ dataComponents: z6.z.array(dataComponentsSchema)
9641
+ }),
9642
+ experimental_telemetry: {
9643
+ isEnabled: true,
9644
+ functionId: this.config.id,
9645
+ recordInputs: true,
9646
+ recordOutputs: true,
9647
+ metadata: {
9648
+ phase: "structured_generation"
9649
+ }
9650
+ },
9651
+ abortSignal: AbortSignal.timeout(phase2TimeoutMs)
9652
+ })
9653
+ );
9654
+ response = {
9655
+ ...response,
9656
+ object: structuredResponse.object
9657
+ };
9658
+ textResponse = JSON.stringify(structuredResponse.object, null, 2);
9659
+ }
9660
+ } else {
9661
+ textResponse = response.text || "";
9651
9662
  }
9652
9663
  } else {
9653
- textResponse = response.text || "";
9664
+ textResponse = response.steps[response.steps.length - 1].text || "";
9654
9665
  }
9655
- } else {
9656
- textResponse = response.steps[response.steps.length - 1].text || "";
9657
- }
9658
- span.setStatus({ code: api.SpanStatusCode.OK });
9659
- span.end();
9660
- let formattedContent = response.formattedContent || null;
9661
- if (!formattedContent) {
9662
- const session = toolSessionManager.getSession(sessionId);
9663
- const responseFormatter = new ResponseFormatter(this.config.tenantId, {
9664
- sessionId,
9665
- taskId: session?.taskId,
9666
- projectId: session?.projectId,
9667
- contextId,
9668
- artifactComponents: this.artifactComponents,
9669
- streamRequestId: this.getStreamRequestId(),
9670
- subAgentId: this.config.id
9671
- });
9672
- if (response.object) {
9673
- formattedContent = await responseFormatter.formatObjectResponse(
9674
- response.object,
9675
- contextId
9676
- );
9677
- } else if (textResponse) {
9678
- formattedContent = await responseFormatter.formatResponse(textResponse, contextId);
9666
+ span.setStatus({ code: api.SpanStatusCode.OK });
9667
+ span.end();
9668
+ let formattedContent = response.formattedContent || null;
9669
+ if (!formattedContent) {
9670
+ const session = toolSessionManager.getSession(sessionId);
9671
+ const responseFormatter = new ResponseFormatter(this.config.tenantId, {
9672
+ sessionId,
9673
+ taskId: session?.taskId,
9674
+ projectId: session?.projectId,
9675
+ contextId,
9676
+ artifactComponents: this.artifactComponents,
9677
+ streamRequestId: this.getStreamRequestId(),
9678
+ subAgentId: this.config.id
9679
+ });
9680
+ if (response.object) {
9681
+ formattedContent = await responseFormatter.formatObjectResponse(
9682
+ response.object,
9683
+ contextId
9684
+ );
9685
+ } else if (textResponse) {
9686
+ formattedContent = await responseFormatter.formatResponse(textResponse, contextId);
9687
+ }
9679
9688
  }
9689
+ const formattedResponse = {
9690
+ ...response,
9691
+ formattedContent
9692
+ };
9693
+ if (streamRequestId) {
9694
+ const generationType = response.object ? "object_generation" : "text_generation";
9695
+ agentSessionManager.recordEvent(streamRequestId, "agent_generate", this.config.id, {
9696
+ parts: (formattedContent?.parts || []).map((part) => ({
9697
+ type: part.kind === "text" ? "text" : part.kind === "data" ? "tool_result" : "text",
9698
+ content: part.text || JSON.stringify(part.data)
9699
+ })),
9700
+ generationType
9701
+ });
9702
+ }
9703
+ return formattedResponse;
9704
+ } catch (error) {
9705
+ const errorToThrow = error instanceof Error ? error : new Error(String(error));
9706
+ agentsCore.setSpanWithError(span, errorToThrow);
9707
+ span.end();
9708
+ throw errorToThrow;
9680
9709
  }
9681
- const formattedResponse = {
9682
- ...response,
9683
- formattedContent
9684
- };
9685
- if (streamRequestId) {
9686
- const generationType = response.object ? "object_generation" : "text_generation";
9687
- agentSessionManager.recordEvent(streamRequestId, "agent_generate", this.config.id, {
9688
- parts: (formattedContent?.parts || []).map((part) => ({
9689
- type: part.kind === "text" ? "text" : part.kind === "data" ? "tool_result" : "text",
9690
- content: part.text || JSON.stringify(part.data)
9691
- })),
9692
- generationType
9693
- });
9694
- }
9695
- return formattedResponse;
9696
- } catch (error) {
9697
- const errorToThrow = error instanceof Error ? error : new Error(String(error));
9698
- agentsCore.setSpanWithError(span, errorToThrow);
9699
- span.end();
9700
- throw errorToThrow;
9701
9710
  }
9702
- });
9711
+ );
9703
9712
  }
9704
9713
  };
9705
9714