@meetsmore-oss/use-ai-server 1.9.3 → 1.9.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.
package/dist/index.js CHANGED
@@ -114107,6 +114107,28 @@ function applyCacheBreakpoints(messages, cacheBreakpoint, model) {
114107
114107
  }
114108
114108
 
114109
114109
  // src/agents/AISDKAgent.ts
114110
+ function classifyApiError(error40) {
114111
+ let errorCode = ErrorCode.UNKNOWN_ERROR;
114112
+ const errorMessage = error40 instanceof Error ? error40.message : "Unknown error";
114113
+ const isAPIError = (err) => typeof err === "object" && err !== null;
114114
+ if (isAPIError(error40)) {
114115
+ const isOverloaded = error40.statusCode === 529 || error40.data?.error?.type === "overloaded_error" || error40.message && error40.message.toLowerCase().includes("overload");
114116
+ if (isOverloaded) {
114117
+ errorCode = ErrorCode.API_OVERLOADED;
114118
+ }
114119
+ if (error40.statusCode === 429) {
114120
+ errorCode = ErrorCode.RATE_LIMITED;
114121
+ }
114122
+ }
114123
+ return { errorCode, errorMessage };
114124
+ }
114125
+
114126
+ class AbortError extends Error {
114127
+ constructor() {
114128
+ super("Run aborted by user");
114129
+ this.name = "AbortError";
114130
+ }
114131
+ }
114110
114132
  var DEFAULT_MAX_OUTPUT_TOKENS = 4096;
114111
114133
  var DEFAULT_MAX_STEPS = 10;
114112
114134
 
@@ -114141,324 +114163,397 @@ class AISDKAgent {
114141
114163
  await flushTelemetry();
114142
114164
  }
114143
114165
  async run(input, events) {
114166
+ const ctx = await this.createRunContext(input);
114167
+ this.emitRunStartEvents(ctx, events);
114168
+ const span = this.startTelemetrySpan(ctx);
114169
+ try {
114170
+ this.logRunStart(ctx);
114171
+ await this.executeStepLoop(ctx, events, span);
114172
+ return this.finalizeRun(ctx, events, span);
114173
+ } catch (error40) {
114174
+ return this.handleRunError(error40, ctx, events, span);
114175
+ }
114176
+ }
114177
+ async createRunContext(input) {
114144
114178
  const { session, runId, messages, tools, state, systemPrompt: runtimeSystemPrompt, originalInput } = input;
114145
114179
  if (session.tools.length === 0 && tools.length > 0) {
114146
114180
  session.tools = tools;
114147
114181
  }
114148
114182
  const configSystemPrompt = await this.resolveSystemPrompt();
114149
114183
  const staticSystemMessages = this.buildStaticSystemMessages(configSystemPrompt, runtimeSystemPrompt);
114184
+ const sanitizedInputMessages = this.sanitizeMessages(messages);
114185
+ return {
114186
+ session,
114187
+ runId,
114188
+ messages,
114189
+ tools,
114190
+ state,
114191
+ originalInput,
114192
+ staticSystemMessages,
114193
+ streamTextStarted: false,
114194
+ finalText: "",
114195
+ currentStepNumber: 0,
114196
+ hasAnyContent: false,
114197
+ currentMessages: [...sanitizedInputMessages],
114198
+ allResponseMessages: [],
114199
+ response: null,
114200
+ lastStepHadToolCalls: false
114201
+ };
114202
+ }
114203
+ emitRunStartEvents(ctx, events) {
114150
114204
  events.emit({
114151
114205
  type: export_EventType.RUN_STARTED,
114152
- threadId: session.threadId,
114153
- runId,
114154
- input: originalInput,
114206
+ threadId: ctx.session.threadId,
114207
+ runId: ctx.runId,
114208
+ input: ctx.originalInput,
114155
114209
  timestamp: Date.now()
114156
114210
  });
114157
114211
  events.emit({
114158
114212
  type: export_EventType.MESSAGES_SNAPSHOT,
114159
- messages: originalInput.messages,
114213
+ messages: ctx.originalInput.messages,
114160
114214
  timestamp: Date.now()
114161
114215
  });
114162
114216
  events.emit({
114163
114217
  type: export_EventType.STATE_SNAPSHOT,
114164
- snapshot: state,
114218
+ snapshot: ctx.state,
114165
114219
  timestamp: Date.now()
114166
114220
  });
114167
- let streamTextStarted = false;
114168
- const span = startRunSpan({ runId, sessionId: session.clientId });
114169
- const lastUserMessage = [...messages].reverse().find((m) => m.role === "user");
114221
+ }
114222
+ startTelemetrySpan(ctx) {
114223
+ const span = startRunSpan({ runId: ctx.runId, sessionId: ctx.session.clientId });
114224
+ const lastUserMessage = [...ctx.messages].reverse().find((m) => m.role === "user");
114170
114225
  if (lastUserMessage) {
114171
114226
  span.setInput(lastUserMessage.content);
114172
114227
  }
114173
- try {
114174
- logger2.info("Sending to AI SDK model (streaming)", {
114175
- clientId: session.clientId,
114176
- messageCount: messages.length,
114177
- toolCount: tools.length
114178
- });
114179
- const sanitizedInputMessages = this.sanitizeMessages(messages);
114180
- let currentMessages = [...sanitizedInputMessages];
114181
- logger2.apiRequest({
114182
- tools: tools.map((t) => t.name),
114183
- messageCount: messages.length,
114184
- messages: messages.map((msg) => ({
114185
- role: msg.role,
114186
- preview: typeof msg.content === "string" ? msg.content.substring(0, 80) + (msg.content.length > 80 ? "..." : "") : Array.isArray(msg.content) ? `${msg.content.length} content blocks` : "complex content"
114187
- })),
114188
- systemMessages: staticSystemMessages?.map((m) => m.content.substring(0, 80) + (m.content.length > 80 ? "..." : ""))
114189
- });
114190
- let messageId = null;
114191
- let hasEmittedTextStart = false;
114192
- let finalText = "";
114193
- let currentStepNumber = 0;
114194
- let hasAnyContent = false;
114195
- let response = null;
114196
- const allResponseMessages = [];
114197
- for (let stepIteration = 0;stepIteration < this.maxSteps; stepIteration++) {
114198
- const currentTools = session.tools;
114199
- logger2.debug("Starting step iteration", {
114228
+ return span;
114229
+ }
114230
+ logRunStart(ctx) {
114231
+ logger2.info("Sending to AI SDK model (streaming)", {
114232
+ clientId: ctx.session.clientId,
114233
+ messageCount: ctx.messages.length,
114234
+ toolCount: ctx.tools.length
114235
+ });
114236
+ logger2.apiRequest({
114237
+ tools: ctx.tools.map((t) => t.name),
114238
+ messageCount: ctx.messages.length,
114239
+ messages: ctx.messages.map((msg) => ({
114240
+ role: msg.role,
114241
+ preview: typeof msg.content === "string" ? msg.content.substring(0, 80) + (msg.content.length > 80 ? "..." : "") : Array.isArray(msg.content) ? `${msg.content.length} content blocks` : "complex content"
114242
+ })),
114243
+ systemMessages: ctx.staticSystemMessages?.map((m) => m.content.substring(0, 80) + (m.content.length > 80 ? "..." : ""))
114244
+ });
114245
+ }
114246
+ async executeStepLoop(ctx, events, span) {
114247
+ for (let stepIteration = 0;stepIteration <= this.maxSteps; stepIteration++) {
114248
+ const isGracefulSummaryStep = stepIteration === this.maxSteps;
114249
+ if (isGracefulSummaryStep && !ctx.lastStepHadToolCalls)
114250
+ break;
114251
+ const stepCtx = {
114252
+ currentTools: ctx.session.tools,
114253
+ activeToolCalls: new Map,
114254
+ completedToolCalls: new Set,
114255
+ stepHadToolCalls: false,
114256
+ messageId: null,
114257
+ hasEmittedTextStart: false,
114258
+ stepFinishReason: undefined
114259
+ };
114260
+ const stateMessage = this.buildStateMessage(ctx.session.state);
114261
+ const messagesForStep = [
114262
+ ...ctx.staticSystemMessages || [],
114263
+ ...stateMessage ? [stateMessage] : [],
114264
+ ...ctx.currentMessages
114265
+ ];
114266
+ const stepConfig = {
114267
+ messages: messagesForStep,
114268
+ tools: stepCtx.currentTools.length > 0 ? this.sanitizeToolsForAPI(this.filterTools(stepCtx.currentTools), ctx.session, events) : undefined,
114269
+ metadata: {
114270
+ sessionId: ctx.session.clientId,
114271
+ threadId: ctx.session.threadId,
114272
+ runId: ctx.runId,
114273
+ ipAddress: ctx.session.ipAddress,
114274
+ toolCount: stepCtx.currentTools.length,
114200
114275
  stepIteration,
114201
- toolCount: currentTools.length,
114202
- toolNames: currentTools.map((t) => t.name)
114276
+ ...ctx.originalInput.forwardedProps?.telemetryMetadata || {}
114277
+ }
114278
+ };
114279
+ this.applyGracefulSummaryOverrides(isGracefulSummaryStep, stepConfig);
114280
+ logger2.debug("Starting step iteration", { stepIteration, ...stepConfig.metadata });
114281
+ const messagesWithCache = applyCacheBreakpoints(stepConfig.messages, this.cacheBreakpoint, this.model);
114282
+ ctx.streamTextStarted = true;
114283
+ const createStream = () => streamText({
114284
+ model: this.model,
114285
+ messages: messagesWithCache,
114286
+ tools: stepConfig.tools,
114287
+ stopWhen: stepCountIs(1),
114288
+ maxOutputTokens: this.maxOutputTokens,
114289
+ temperature: this.temperature,
114290
+ abortSignal: ctx.session.abortController?.signal,
114291
+ experimental_telemetry: span.active ? { isEnabled: true, functionId: "use-ai", metadata: stepConfig.metadata } : undefined,
114292
+ onStepFinish: ({ usage, finishReason }) => {
114293
+ logger2.debug("Step finished", { usage, finishReason, stepIteration });
114294
+ }
114295
+ });
114296
+ const stream = span.wrap(createStream);
114297
+ for await (const chunk of stream.fullStream) {
114298
+ this.processStreamChunk(chunk, ctx, stepCtx, events);
114299
+ }
114300
+ if (ctx.session.abortController?.signal.aborted) {
114301
+ span.endWithError("Run aborted by user");
114302
+ events.emit({
114303
+ type: export_EventType.RUN_ERROR,
114304
+ message: "Run aborted by user",
114305
+ timestamp: Date.now()
114203
114306
  });
114204
- const stateMessage = this.buildStateMessage(session.state);
114205
- const messagesForStep = [
114206
- ...staticSystemMessages || [],
114207
- ...stateMessage ? [stateMessage] : [],
114208
- ...currentMessages
114209
- ];
114210
- const messagesWithCache = applyCacheBreakpoints(messagesForStep, this.cacheBreakpoint, this.model);
114211
- streamTextStarted = true;
114212
- const createStream = () => streamText({
114213
- model: this.model,
114214
- messages: messagesWithCache,
114215
- tools: currentTools.length > 0 ? this.sanitizeToolsForAPI(this.filterTools(currentTools), session, events) : undefined,
114216
- stopWhen: stepCountIs(1),
114217
- maxOutputTokens: this.maxOutputTokens,
114218
- temperature: this.temperature,
114219
- abortSignal: session.abortController?.signal,
114220
- experimental_telemetry: span.active ? {
114221
- isEnabled: true,
114222
- functionId: "use-ai",
114223
- metadata: {
114224
- sessionId: session.clientId,
114225
- threadId: session.threadId,
114226
- runId,
114227
- ipAddress: session.ipAddress,
114228
- toolCount: currentTools.length,
114229
- stepIteration,
114230
- ...originalInput.forwardedProps?.telemetryMetadata || {}
114231
- }
114232
- } : undefined,
114233
- onStepFinish: ({ usage, finishReason }) => {
114234
- logger2.debug("Step finished", { usage, finishReason, stepIteration });
114235
- }
114307
+ throw new AbortError;
114308
+ }
114309
+ const response = await stream.response;
114310
+ ctx.response = response;
114311
+ const stepMessages = this.sanitizeMessages(response.messages);
114312
+ ctx.allResponseMessages.push(...stepMessages);
114313
+ ctx.currentMessages = [...ctx.currentMessages, ...stepMessages];
114314
+ if (this.handleIncompleteToolCalls(ctx, stepCtx)) {
114315
+ continue;
114316
+ }
114317
+ ctx.lastStepHadToolCalls = stepCtx.stepHadToolCalls;
114318
+ if (!stepCtx.stepHadToolCalls) {
114319
+ logger2.debug("Step had no tool calls, finishing run", { stepIteration });
114320
+ break;
114321
+ }
114322
+ logger2.debug("Continuing to next step after tool calls", {
114323
+ stepIteration,
114324
+ newMessageCount: ctx.currentMessages.length,
114325
+ updatedToolCount: ctx.session.tools.length
114326
+ });
114327
+ }
114328
+ }
114329
+ handleIncompleteToolCalls(ctx, stepCtx) {
114330
+ const incompleteToolCalls = [...stepCtx.activeToolCalls.entries()].filter(([id]) => !stepCtx.completedToolCalls.has(id)).map(([id, call]) => ({ id, ...call }));
114331
+ const recoveryMessages = buildRecoveryToolResults(incompleteToolCalls, stepCtx.stepFinishReason, this.maxOutputTokens);
114332
+ if (recoveryMessages.length === 0) {
114333
+ return false;
114334
+ }
114335
+ const sanitized = this.sanitizeMessages(recoveryMessages);
114336
+ ctx.allResponseMessages.push(...sanitized);
114337
+ ctx.currentMessages = [...ctx.currentMessages, ...sanitized];
114338
+ logger2.warn("Incomplete tool calls detected (likely maxOutputTokens exceeded)", {
114339
+ incompleteCount: incompleteToolCalls.length
114340
+ });
114341
+ return true;
114342
+ }
114343
+ processStreamChunk(chunk, ctx, stepCtx, events) {
114344
+ switch (chunk.type) {
114345
+ case "start-step": {
114346
+ events.emit({
114347
+ type: export_EventType.STEP_STARTED,
114348
+ stepName: `step-${ctx.currentStepNumber++}`,
114349
+ timestamp: Date.now()
114236
114350
  });
114237
- const stream = span.wrap(createStream);
114238
- const activeToolCalls = new Map;
114239
- let stepHadToolCalls = false;
114240
- for await (const chunk of stream.fullStream) {
114241
- switch (chunk.type) {
114242
- case "start-step": {
114243
- events.emit({
114244
- type: export_EventType.STEP_STARTED,
114245
- stepName: `step-${currentStepNumber++}`,
114246
- timestamp: Date.now()
114247
- });
114248
- break;
114249
- }
114250
- case "text-delta": {
114251
- hasAnyContent = true;
114252
- if (!hasEmittedTextStart) {
114253
- messageId = v4_default();
114254
- events.emit({
114255
- type: export_EventType.TEXT_MESSAGE_START,
114256
- messageId,
114257
- role: "assistant",
114258
- timestamp: Date.now()
114259
- });
114260
- hasEmittedTextStart = true;
114261
- }
114262
- events.emit({
114263
- type: export_EventType.TEXT_MESSAGE_CONTENT,
114264
- messageId,
114265
- delta: chunk.text,
114266
- timestamp: Date.now()
114267
- });
114268
- finalText += chunk.text;
114269
- break;
114270
- }
114271
- case "reasoning-delta": {
114272
- logger2.debug("Reasoning", { text: chunk.text });
114273
- break;
114274
- }
114275
- case "tool-input-start": {
114276
- hasAnyContent = true;
114277
- stepHadToolCalls = true;
114278
- const toolDef = currentTools.find((t) => t.name === chunk.toolName);
114279
- const annotations = getToolAnnotations(toolDef);
114280
- const toolCallStartEvent = {
114281
- type: export_EventType.TOOL_CALL_START,
114282
- toolCallId: chunk.id,
114283
- toolCallName: chunk.toolName,
114284
- parentMessageId: messageId ?? v4_default(),
114285
- timestamp: Date.now()
114286
- };
114287
- if (annotations) {
114288
- toolCallStartEvent.annotations = annotations;
114289
- }
114290
- events.emit(toolCallStartEvent);
114291
- activeToolCalls.set(chunk.id, { name: chunk.toolName, args: "" });
114292
- break;
114293
- }
114294
- case "tool-input-delta": {
114295
- const toolCall = activeToolCalls.get(chunk.id);
114296
- if (toolCall) {
114297
- toolCall.args += chunk.delta;
114298
- events.emit({
114299
- type: export_EventType.TOOL_CALL_ARGS,
114300
- toolCallId: chunk.id,
114301
- delta: chunk.delta,
114302
- timestamp: Date.now()
114303
- });
114304
- }
114305
- break;
114306
- }
114307
- case "tool-call": {
114308
- stepHadToolCalls = true;
114309
- const toolCall = activeToolCalls.get(chunk.toolCallId);
114310
- const finalArgs = JSON.stringify(chunk.input);
114311
- if (toolCall && toolCall.args.length === 0) {
114312
- events.emit({
114313
- type: export_EventType.TOOL_CALL_ARGS,
114314
- toolCallId: chunk.toolCallId,
114315
- delta: finalArgs,
114316
- timestamp: Date.now()
114317
- });
114318
- toolCall.args = finalArgs;
114319
- }
114320
- events.emit({
114321
- type: export_EventType.TOOL_CALL_END,
114322
- toolCallId: chunk.toolCallId,
114323
- timestamp: Date.now()
114324
- });
114325
- break;
114326
- }
114327
- case "tool-result": {
114328
- logger2.toolResult(chunk.toolName, JSON.stringify(chunk.output));
114329
- events.emit({
114330
- type: export_EventType.TOOL_CALL_RESULT,
114331
- messageId: v4_default(),
114332
- toolCallId: chunk.toolCallId,
114333
- content: typeof chunk.output === "string" ? chunk.output : JSON.stringify(chunk.output),
114334
- role: "tool",
114335
- timestamp: Date.now()
114336
- });
114337
- break;
114338
- }
114339
- case "finish-step": {
114340
- events.emit({
114341
- type: export_EventType.STEP_FINISHED,
114342
- stepName: `step-${currentStepNumber - 1}`,
114343
- timestamp: Date.now()
114344
- });
114345
- break;
114346
- }
114347
- case "error": {
114348
- throw chunk.error;
114349
- }
114350
- }
114351
+ return;
114352
+ }
114353
+ case "text-delta": {
114354
+ ctx.hasAnyContent = true;
114355
+ if (!stepCtx.hasEmittedTextStart) {
114356
+ stepCtx.messageId = v4_default();
114357
+ events.emit({
114358
+ type: export_EventType.TEXT_MESSAGE_START,
114359
+ messageId: stepCtx.messageId,
114360
+ role: "assistant",
114361
+ timestamp: Date.now()
114362
+ });
114363
+ stepCtx.hasEmittedTextStart = true;
114351
114364
  }
114352
- if (session.abortController?.signal.aborted) {
114353
- span.endWithError("Run aborted by user");
114365
+ events.emit({
114366
+ type: export_EventType.TEXT_MESSAGE_CONTENT,
114367
+ messageId: stepCtx.messageId,
114368
+ delta: chunk.text,
114369
+ timestamp: Date.now()
114370
+ });
114371
+ ctx.finalText += chunk.text;
114372
+ return;
114373
+ }
114374
+ case "reasoning-delta": {
114375
+ logger2.debug("Reasoning", { text: chunk.text });
114376
+ return;
114377
+ }
114378
+ case "tool-input-start": {
114379
+ ctx.hasAnyContent = true;
114380
+ stepCtx.stepHadToolCalls = true;
114381
+ if (stepCtx.messageId) {
114354
114382
  events.emit({
114355
- type: export_EventType.RUN_ERROR,
114356
- message: "Run aborted by user",
114383
+ type: export_EventType.TEXT_MESSAGE_END,
114384
+ messageId: stepCtx.messageId,
114357
114385
  timestamp: Date.now()
114358
114386
  });
114359
- return { success: false, error: "Run aborted", conversationHistory: messages };
114360
114387
  }
114361
- response = await stream.response;
114362
- const stepMessages = this.sanitizeMessages(response.messages);
114363
- allResponseMessages.push(...stepMessages);
114364
- if (!stepHadToolCalls) {
114365
- logger2.debug("Step had no tool calls, finishing run", { stepIteration });
114366
- break;
114388
+ const toolDef = stepCtx.currentTools.find((t) => t.name === chunk.toolName);
114389
+ const annotations = getToolAnnotations(toolDef);
114390
+ const parentId = stepCtx.messageId ?? v4_default();
114391
+ stepCtx.messageId = null;
114392
+ const toolCallStartEvent = {
114393
+ type: export_EventType.TOOL_CALL_START,
114394
+ toolCallId: chunk.id,
114395
+ toolCallName: chunk.toolName,
114396
+ parentMessageId: parentId,
114397
+ timestamp: Date.now()
114398
+ };
114399
+ if (annotations) {
114400
+ toolCallStartEvent.annotations = annotations;
114367
114401
  }
114368
- currentMessages = [
114369
- ...currentMessages,
114370
- ...stepMessages
114371
- ];
114372
- logger2.debug("Continuing to next step after tool calls", {
114373
- stepIteration,
114374
- newMessageCount: currentMessages.length,
114375
- updatedToolCount: session.tools.length
114376
- });
114402
+ events.emit(toolCallStartEvent);
114403
+ stepCtx.activeToolCalls.set(chunk.id, { name: chunk.toolName, args: "" });
114404
+ return;
114377
114405
  }
114378
- if (hasEmittedTextStart && messageId) {
114406
+ case "tool-input-delta": {
114407
+ const toolCall = stepCtx.activeToolCalls.get(chunk.id);
114408
+ if (toolCall) {
114409
+ toolCall.args += chunk.delta;
114410
+ events.emit({
114411
+ type: export_EventType.TOOL_CALL_ARGS,
114412
+ toolCallId: chunk.id,
114413
+ delta: chunk.delta,
114414
+ timestamp: Date.now()
114415
+ });
114416
+ }
114417
+ return;
114418
+ }
114419
+ case "tool-call": {
114420
+ stepCtx.stepHadToolCalls = true;
114421
+ stepCtx.completedToolCalls.add(chunk.toolCallId);
114422
+ const toolCall = stepCtx.activeToolCalls.get(chunk.toolCallId);
114423
+ const finalArgs = JSON.stringify(chunk.input);
114424
+ if (toolCall && toolCall.args.length === 0) {
114425
+ events.emit({
114426
+ type: export_EventType.TOOL_CALL_ARGS,
114427
+ toolCallId: chunk.toolCallId,
114428
+ delta: finalArgs,
114429
+ timestamp: Date.now()
114430
+ });
114431
+ toolCall.args = finalArgs;
114432
+ }
114379
114433
  events.emit({
114380
- type: export_EventType.TEXT_MESSAGE_END,
114381
- messageId,
114434
+ type: export_EventType.TOOL_CALL_END,
114435
+ toolCallId: chunk.toolCallId,
114382
114436
  timestamp: Date.now()
114383
114437
  });
114438
+ return;
114384
114439
  }
114385
- if (!hasAnyContent) {
114386
- span.endWithError("Empty response from AI");
114440
+ case "tool-result": {
114441
+ logger2.toolResult(chunk.toolName, JSON.stringify(chunk.output));
114387
114442
  events.emit({
114388
- type: export_EventType.RUN_ERROR,
114389
- message: "AI returned an empty response. This may be due to an ambiguous request. Please try being more specific.",
114443
+ type: export_EventType.TOOL_CALL_RESULT,
114444
+ messageId: v4_default(),
114445
+ toolCallId: chunk.toolCallId,
114446
+ content: typeof chunk.output === "string" ? chunk.output : JSON.stringify(chunk.output),
114447
+ role: "tool",
114390
114448
  timestamp: Date.now()
114391
114449
  });
114392
- return {
114393
- success: false,
114394
- error: "Empty response from AI",
114395
- conversationHistory: messages
114396
- };
114397
- }
114398
- if (!response) {
114399
- throw new Error("No response from AI SDK");
114450
+ return;
114400
114451
  }
114401
- if (finalText) {
114402
- logger2.aiResponse([finalText]);
114452
+ case "finish": {
114453
+ stepCtx.stepFinishReason = chunk.finishReason;
114454
+ return;
114403
114455
  }
114404
- span.setOutput(finalText);
114405
- const traceId = span.popTraceId();
114406
- span.end();
114407
- events.emit({
114408
- type: export_EventType.RUN_FINISHED,
114409
- threadId: session.threadId,
114410
- runId: traceId || runId,
114411
- result: finalText,
114412
- timestamp: Date.now()
114413
- });
114414
- return {
114415
- success: true,
114416
- conversationHistory: [...messages, ...allResponseMessages]
114417
- };
114418
- } catch (error40) {
114419
- span.endWithError(error40 instanceof Error ? error40.message : String(error40));
114420
- logger2.error("Error calling AI SDK model", {
114421
- error: error40 instanceof Error ? error40.message : "Unknown error",
114422
- clientId: session.clientId
114423
- });
114424
- let errorCode = ErrorCode.UNKNOWN_ERROR;
114425
- let errorMessage = error40 instanceof Error ? error40.message : "Unknown error";
114426
- const isAPIError = (err) => {
114427
- return typeof err === "object" && err !== null;
114428
- };
114429
- if (isAPIError(error40)) {
114430
- const isOverloaded = error40.statusCode === 529 || error40.data?.error?.type === "overloaded_error" || error40.message && error40.message.toLowerCase().includes("overload");
114431
- if (isOverloaded) {
114432
- errorCode = ErrorCode.API_OVERLOADED;
114433
- }
114434
- const isRateLimited = error40.statusCode === 429;
114435
- if (isRateLimited) {
114436
- errorCode = ErrorCode.RATE_LIMITED;
114456
+ case "finish-step": {
114457
+ if (stepCtx.messageId) {
114458
+ events.emit({
114459
+ type: export_EventType.TEXT_MESSAGE_END,
114460
+ messageId: stepCtx.messageId,
114461
+ timestamp: Date.now()
114462
+ });
114463
+ stepCtx.messageId = null;
114437
114464
  }
114465
+ events.emit({
114466
+ type: export_EventType.STEP_FINISHED,
114467
+ stepName: `step-${ctx.currentStepNumber - 1}`,
114468
+ timestamp: Date.now()
114469
+ });
114470
+ return;
114438
114471
  }
114439
- if (!streamTextStarted) {
114440
- const telemetryMetadata = originalInput.forwardedProps?.telemetryMetadata;
114441
- span.recordError({
114442
- runId,
114443
- errorCategory: "pre_stream_error",
114444
- errorMessage,
114445
- sessionId: session.clientId,
114446
- threadId: session.threadId,
114447
- ipAddress: session.ipAddress,
114448
- metadata: { errorCode, toolCount: tools.length, messageCount: messages.length, ...telemetryMetadata }
114472
+ case "tool-error": {
114473
+ const errorContent = chunk.error instanceof Error ? chunk.error.message : String(chunk.error);
114474
+ logger2.toolResult(chunk.toolName, `ERROR: ${errorContent}`);
114475
+ events.emit({
114476
+ type: export_EventType.TOOL_CALL_RESULT,
114477
+ messageId: v4_default(),
114478
+ toolCallId: chunk.toolCallId,
114479
+ content: JSON.stringify({ error: errorContent }),
114480
+ role: "tool",
114481
+ timestamp: Date.now()
114449
114482
  });
114483
+ return;
114484
+ }
114485
+ case "error": {
114486
+ throw chunk.error;
114450
114487
  }
114488
+ }
114489
+ }
114490
+ finalizeRun(ctx, events, span) {
114491
+ if (!ctx.hasAnyContent) {
114492
+ span.endWithError("Empty response from AI");
114451
114493
  events.emit({
114452
114494
  type: export_EventType.RUN_ERROR,
114453
- message: errorCode,
114495
+ message: "AI returned an empty response. This may be due to an ambiguous request. Please try being more specific.",
114454
114496
  timestamp: Date.now()
114455
114497
  });
114456
114498
  return {
114457
114499
  success: false,
114458
- error: errorMessage,
114459
- conversationHistory: messages
114500
+ error: "Empty response from AI",
114501
+ conversationHistory: ctx.messages
114460
114502
  };
114461
114503
  }
114504
+ if (!ctx.response) {
114505
+ throw new Error("No response from AI SDK");
114506
+ }
114507
+ if (ctx.finalText) {
114508
+ logger2.aiResponse([ctx.finalText]);
114509
+ }
114510
+ span.setOutput(ctx.finalText);
114511
+ const traceId = span.popTraceId();
114512
+ span.end();
114513
+ events.emit({
114514
+ type: export_EventType.RUN_FINISHED,
114515
+ threadId: ctx.session.threadId,
114516
+ runId: traceId || ctx.runId,
114517
+ result: ctx.finalText,
114518
+ timestamp: Date.now()
114519
+ });
114520
+ return {
114521
+ success: true,
114522
+ conversationHistory: [...ctx.messages, ...ctx.allResponseMessages]
114523
+ };
114524
+ }
114525
+ handleRunError(error40, ctx, events, span) {
114526
+ if (error40 instanceof AbortError) {
114527
+ return { success: false, error: "Run aborted", conversationHistory: ctx.messages };
114528
+ }
114529
+ span.endWithError(error40 instanceof Error ? error40.message : String(error40));
114530
+ logger2.error("Error calling AI SDK model", {
114531
+ error: error40 instanceof Error ? error40.message : "Unknown error",
114532
+ clientId: ctx.session.clientId
114533
+ });
114534
+ const { errorCode, errorMessage } = classifyApiError(error40);
114535
+ if (!ctx.streamTextStarted) {
114536
+ const telemetryMetadata = ctx.originalInput.forwardedProps?.telemetryMetadata;
114537
+ span.recordError({
114538
+ runId: ctx.runId,
114539
+ errorCategory: "pre_stream_error",
114540
+ errorMessage,
114541
+ sessionId: ctx.session.clientId,
114542
+ threadId: ctx.session.threadId,
114543
+ ipAddress: ctx.session.ipAddress,
114544
+ metadata: { errorCode, toolCount: ctx.tools.length, messageCount: ctx.messages.length, ...telemetryMetadata }
114545
+ });
114546
+ }
114547
+ events.emit({
114548
+ type: export_EventType.RUN_ERROR,
114549
+ message: errorCode,
114550
+ timestamp: Date.now()
114551
+ });
114552
+ return {
114553
+ success: false,
114554
+ error: errorMessage,
114555
+ conversationHistory: ctx.messages
114556
+ };
114462
114557
  }
114463
114558
  async resolveSystemPrompt() {
114464
114559
  if (!this.systemPrompt) {
@@ -114490,6 +114585,13 @@ class AISDKAgent {
114490
114585
  ${JSON.stringify(state, null, 2)}`
114491
114586
  };
114492
114587
  }
114588
+ applyGracefulSummaryOverrides(isGracefulSummaryStep, stepConfig) {
114589
+ if (!isGracefulSummaryStep)
114590
+ return;
114591
+ stepConfig.messages.push({ role: "user", content: "max steps reached, summarize progress" });
114592
+ stepConfig.tools = undefined;
114593
+ Object.assign(stepConfig.metadata, { toolCount: 0, gracefulSummary: true });
114594
+ }
114493
114595
  filterTools(tools) {
114494
114596
  if (!this.toolFilter) {
114495
114597
  return tools;
@@ -114632,6 +114734,35 @@ ${val.text}`
114632
114734
  }
114633
114735
  }
114634
114736
  }
114737
+ function buildRecoveryToolResults(incompleteToolCalls, stepFinishReason, maxOutputTokens) {
114738
+ if (incompleteToolCalls.length === 0 || stepFinishReason !== "length") {
114739
+ return [];
114740
+ }
114741
+ const recoveryAssistantMessage = {
114742
+ role: "assistant",
114743
+ content: incompleteToolCalls.map((toolCall) => ({
114744
+ type: "tool-call",
114745
+ toolCallId: toolCall.id,
114746
+ toolName: toolCall.name,
114747
+ input: {}
114748
+ }))
114749
+ };
114750
+ const recoveryToolResults = incompleteToolCalls.map((toolCall) => ({
114751
+ role: "tool",
114752
+ content: [
114753
+ {
114754
+ type: "tool-result",
114755
+ toolCallId: toolCall.id,
114756
+ toolName: toolCall.name,
114757
+ output: {
114758
+ type: "text",
114759
+ value: `Error: Tool call "${toolCall.name}" failed because its arguments were cut off mid-stream by the output token limit (maxOutputTokens: ${maxOutputTokens}). This call was recorded with args={} as a placeholder — retry with shorter arguments. Truncated args (first 200 chars): ${toolCall.args.substring(0, 200)}`
114760
+ }
114761
+ }
114762
+ ]
114763
+ }));
114764
+ return [recoveryAssistantMessage, ...recoveryToolResults];
114765
+ }
114635
114766
  // ../../node_modules/.bun/zod-to-json-schema@3.25.1+27912429049419a2/node_modules/zod-to-json-schema/dist/esm/Options.js
114636
114767
  var ignoreOverride2 = Symbol("Let zodToJsonSchema decide on which parser to use");
114637
114768
  var defaultOptions2 = {