@agentfield/sdk 0.1.143-rc.3 → 0.1.143-rc.4

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.d.ts CHANGED
@@ -334,6 +334,8 @@ declare class AIClient {
334
334
  private readonly config;
335
335
  private rateLimiter?;
336
336
  constructor(config?: AIConfig);
337
+ /** Prompt-template overrides configured on this agent, if any (issue #229). */
338
+ get promptTemplates(): AIConfig['promptTemplates'];
337
339
  generate<T>(prompt: string, options: AIRequestOptions & {
338
340
  schema: ZodSchema<T>;
339
341
  }): Promise<T>;
@@ -1137,6 +1139,85 @@ declare class DidInterface {
1137
1139
  exportAuditTrail(filters?: AuditTrailFilters): Promise<AuditTrailExport>;
1138
1140
  }
1139
1141
 
1142
+ /**
1143
+ * Configurable templates for the text and tool-message framing the SDK injects
1144
+ * into LLM calls (issue #229).
1145
+ *
1146
+ * Field names line up with the Python SDK's `PromptTemplates` and the Go SDK's
1147
+ * `PromptConfig` (`toolCallLimitReached`, `toolErrorFormatter`,
1148
+ * `toolResultFormatter`). Defaults reproduce the SDK's prior output exactly, so
1149
+ * a reasoner that never sets `promptTemplates` sees no change.
1150
+ *
1151
+ * The TypeScript SDK uses the Vercel AI SDK's native structured output
1152
+ * (`generateObject`) and injects no schema instruction, so, unlike Python,
1153
+ * there is no `schemaInstruction` field here.
1154
+ */
1155
+ /** Formats a failed tool call before it is returned to the model. */
1156
+ type ToolErrorFormatter = (toolName: string, error: string) => unknown;
1157
+ /** Formats a successful tool call before it is returned to the model. */
1158
+ type ToolResultFormatter = (toolName: string, result: unknown) => unknown;
1159
+ interface PromptTemplates {
1160
+ /**
1161
+ * Optional system prompt describing how to use tools, appended after the
1162
+ * caller's system prompt. Undefined means nothing is injected (the default),
1163
+ * so existing `tools=` calls are unchanged; set it to opt in.
1164
+ */
1165
+ toolSystemPrompt?: string;
1166
+ /** Message returned to the model when the tool-call limit is reached. */
1167
+ toolCallLimitReached?: string;
1168
+ /**
1169
+ * Formats a failed tool call `(toolName, error)` before it is sent back to
1170
+ * the model. Return a string to send verbatim, or any value to be returned
1171
+ * as-is (the AI SDK serializes it).
1172
+ */
1173
+ toolErrorFormatter?: ToolErrorFormatter;
1174
+ /**
1175
+ * Formats a successful tool call `(toolName, result)` before it is sent back
1176
+ * to the model. Return a string to send verbatim, or any value to be
1177
+ * returned as-is.
1178
+ */
1179
+ toolResultFormatter?: ToolResultFormatter;
1180
+ }
1181
+ declare const DEFAULT_TOOL_CALL_LIMIT_REACHED = "Tool call limit reached. Please provide a final response.";
1182
+ /** Default tool-error framing: the prior `{ error, tool }` object. */
1183
+ declare const defaultToolErrorFormatter: ToolErrorFormatter;
1184
+ /** Default tool-result framing: the raw result, unframed. */
1185
+ declare const defaultToolResultFormatter: ToolResultFormatter;
1186
+ /** A fully-populated set of templates with every default filled in. */
1187
+ interface ResolvedPromptTemplates {
1188
+ toolSystemPrompt?: string;
1189
+ toolCallLimitReached: string;
1190
+ toolErrorFormatter: ToolErrorFormatter;
1191
+ toolResultFormatter: ToolResultFormatter;
1192
+ }
1193
+ /**
1194
+ * Merges a partial override over the built-in defaults. An undefined field
1195
+ * (or an undefined `overrides`) keeps the default; `toolSystemPrompt` stays
1196
+ * undefined unless explicitly set.
1197
+ */
1198
+ declare function resolvePromptTemplates(overrides?: Partial<PromptTemplates>): ResolvedPromptTemplates;
1199
+ /**
1200
+ * Cross-SDK message-source taxonomy, shared with the Python and Go SDKs so a
1201
+ * trace tagged in one SDK reads the same in another (issue #229).
1202
+ * `sdk.schema_instruction` exists only in the Python SDK (which injects it;
1203
+ * TypeScript uses native structured output).
1204
+ */
1205
+ type MessageSource = 'user' | 'assistant' | 'sdk.tool_system_prompt' | 'sdk.tool_result' | 'sdk.tool_error' | 'sdk.tool_limit';
1206
+ declare const TRACE_SOURCE_USER = "user";
1207
+ declare const TRACE_SOURCE_ASSISTANT = "assistant";
1208
+ declare const TRACE_SOURCE_TOOL_SYSTEM_PROMPT = "sdk.tool_system_prompt";
1209
+ declare const TRACE_SOURCE_TOOL_RESULT = "sdk.tool_result";
1210
+ declare const TRACE_SOURCE_TOOL_ERROR = "sdk.tool_error";
1211
+ declare const TRACE_SOURCE_TOOL_LIMIT = "sdk.tool_limit";
1212
+ /**
1213
+ * Tags a message the loop sent with where it came from. `message` references
1214
+ * the wire content (not a reshaped copy); `source` uses the taxonomy above.
1215
+ */
1216
+ interface TracedMessage {
1217
+ message: unknown;
1218
+ source: MessageSource;
1219
+ }
1220
+
1140
1221
  /**
1141
1222
  * Tool calling support for AgentField agents.
1142
1223
  *
@@ -1163,6 +1244,11 @@ interface ToolCallConfig {
1163
1244
  agentIds?: string[];
1164
1245
  /** Filter by health status (default: "healthy"). */
1165
1246
  healthStatus?: string;
1247
+ /**
1248
+ * Overridable text and tool-message framing. Defaults reproduce the SDK's
1249
+ * prior output byte-for-byte (issue #229).
1250
+ */
1251
+ promptTemplates?: Partial<PromptTemplates>;
1166
1252
  }
1167
1253
  interface ToolCallRecord {
1168
1254
  toolName: string;
@@ -1177,6 +1263,12 @@ interface ToolCallTrace {
1177
1263
  totalTurns: number;
1178
1264
  totalToolCalls: number;
1179
1265
  finalResponse?: string;
1266
+ /**
1267
+ * Each message the loop sent, tagged with its source. Optional and additive
1268
+ * so callers that build a ToolCallTrace in their own tests are unaffected
1269
+ * (issue #229).
1270
+ */
1271
+ messages?: TracedMessage[];
1180
1272
  }
1181
1273
  /**
1182
1274
  * Options for tool-calling in ctx.ai().
@@ -1714,6 +1806,11 @@ interface AIConfig {
1714
1806
  rateLimitJitterFactor?: number;
1715
1807
  rateLimitCircuitBreakerThreshold?: number;
1716
1808
  rateLimitCircuitBreakerTimeout?: number;
1809
+ /**
1810
+ * Overridable templates for text and tool-message framing the SDK injects
1811
+ * into LLM calls. Merged over the defaults per call (issue #229).
1812
+ */
1813
+ promptTemplates?: Partial<PromptTemplates>;
1717
1814
  }
1718
1815
  interface MemoryConfig {
1719
1816
  defaultScope?: MemoryScope;
@@ -3186,4 +3283,4 @@ declare function simulateSchedule<R>(handler: (ctx: SimulatedContext) => R | Pro
3186
3283
  */
3187
3284
  declare function loadFixture(source: string): Record<string, unknown>;
3188
3285
 
3189
- export { ACTIVE_STATUSES, AIClient, type AIConfig, type AIEmbeddingOptions, type AIRequestOptions, type AIStream, type AIToolRequestOptions, Agent, type AgentCapability, type AgentConfig, type AgentHandler, AgentRouter, type AgentRouterOptions, type AgentState, ApprovalClient, type ApprovalDecision, type ApprovalRequestResponse, ApprovalResult, type ApprovalStatusResponse, Audio, type AudioOutput, type AudioRequest, type AuditTrailExport, type AuditTrailFilters, type Awaitable, type BinaryResolver, CANONICAL_STATUSES, type CompactCapability, type CompactDiscoveryResponse, type CostEntry, type CostEntryInit, CostTracker, DEFAULT_HARNESS_PROVIDER, DIDAuthenticator, type DIDIdentity, type DIDIdentityPackage, type DIDRegistrationRequest, type DIDRegistrationResponse, type DeploymentType, DidClient, DidInterface, DidManager, type DidResolver, type DiscoveryFormat, type DiscoveryOptions, type DiscoveryPagination, type DiscoveryResponse, type DiscoveryResult, type EventTriggerBinding, type EventTriggerSpec, ExecutionContext, type ExecutionCredential, type ExecutionLogAttributes, type ExecutionLogBatchPayload, type ExecutionLogContext, type ExecutionLogEmitOptions, type ExecutionLogEntry, type ExecutionLogLevel, type ExecutionLogTransport, type ExecutionLogTransportPayload, type ExecutionLogWireEntry, ExecutionLogger, type ExecutionLoggerOptions, type ExecutionMetadata, ExecutionStatus, type ExecutionStatusValue, File, type FileOutput, type GenerateCredentialOptions, type GenerateCredentialParams, HARNESS_PROVIDER_ENV_VAR, HEADER_CALLER_DID, HEADER_DID_NONCE, HEADER_DID_SIGNATURE, HEADER_DID_TIMESTAMP, type HarnessConfig, type HarnessDoctorOptions, type HarnessOptions, type HarnessProvider, type HarnessProviderName, HarnessProviderUnavailable, type HarnessResult, HarnessRunner, type HealthStatus, Image, type ImageOutput, type ImageRequest, JWE_ALG, JWE_ENC, KEY_AGREEMENT_TYPE, MODEL_VARIANT_SEP, type MediaProvider, MediaProviderError, type MediaResponse, MediaRouter, type MemoryChangeEvent, MemoryClient, MemoryClientBase, type MemoryConfig, MemoryEventClient, type MemoryEventHandler, type MemoryEventHistoryOptions, type MemoryEventSubscriptionOptions, MemoryInterface, type MemoryRequestMetadata, type MemoryRequestOptions, type MemoryScope, type MemoryWatchHandler, type Metrics, type ModelVariant, type MultimodalContent, MultimodalResponse, OpenRouterMediaProvider, type OpenRouterMediaProviderOptions, PauseClock, PauseManager, type Payload, PayloadEncryptionError, type ProviderHealth, RateLimitError, type RateLimiterOptions, type RawExecutionContext, type RawResult, RealtimeSession, type ReasonerCapability, ReasonerContext, type ReasonerDefinition, type ReasonerHandler, type ReasonerOptions, type RequestApprovalPayload, SUPPORTED_PROVIDERS, SUPPORTED_PROVIDER_NAMES, SUPPORTED_SESSION_TRANSPORTS, type ScheduleTriggerBinding, type ScheduleTriggerSpec, type ServerlessAdapter, type ServerlessEvent, type ServerlessResponse, type SessionDefinition, type SessionOptions, type SessionProvider, type SessionTransport, type SessionTransportCapability, SessionTransportError, type SessionTurn, type SimulateScheduleOptions, type SimulateTriggerOptions, type SimulatedContext, type SkillCapability, SkillContext, type SkillDefinition, type SkillHandler, type SkillOptions, StatelessRateLimiter, TERMINAL_STATUSES, Text, type ToolCallConfig, type ToolCallRecord, type ToolCallTrace, type ToolsOption, type TriggerBinding, type TriggerContext, type TriggerEnvelope, type TurnDetection, USAGE_ENVELOPE_KEY, type UnwrapResult, type UsageEntryWire, type UsageSummaryWire, type VectorSearchOptions, type VectorSearchResult, type VersionProbe, Video, type VideoFrameImage, type VideoInputReference, type VideoRequest, type WaitForApprovalOptions, type WorkflowCredential, type WorkflowMetadata, type WorkflowProgressOptions, WorkflowReporter, type WrapperProbe, type ZodSchema, applyTriggerTransform, attachUsageToSyncResult, audioFromBase64, audioFromBuffer, audioFromFile, audioFromUrl, audioMediaType, buildProvider, buildSessionDefinition, buildToolConfig, capabilitiesToTools, capabilityToMetadataTool, capabilityToTool, createExecutionLogger, createHarnessResult, createMetrics, createMultimodalResponse, createRawResult, decrypt, decryptToString, deriveProvider, encryptForDid, encryptToJwk, ensureCliAvailable, eventTrigger, executeToolCallLoop, extractKeyAgreementJwk, fileFromBase64, fileFromBuffer, fileFromPath, fileFromUrl, findExecutable, generateX25519KeyPair, getCurrentContext, getCurrentSkillContext, guessUrlMimeType, harnessDoctor, imageFromBase64, imageFromBuffer, imageFromFile, imageFromUrl, installApprovalWebhookRoute, isActive, isExecutionLogBatchPayload, isTerminal, isTriggerEnvelope, loadFixture, normalizeExecutionLogEntry, normalizeSessionTransportValue, normalizeStatus, normalizeTurnDetection, resolveModelAndVariant, resolveProviderName, scheduleTrigger, serializeExecutionLogEntry, simulateSchedule, simulateTrigger, splitModelVariant, text, triggerToPayload, unwrapEnvelope, usageSummaryOrNull, validateSessionTransport, videoFromBase64, videoFromBuffer, videoFromFile, videoFromUrl };
3286
+ export { ACTIVE_STATUSES, AIClient, type AIConfig, type AIEmbeddingOptions, type AIRequestOptions, type AIStream, type AIToolRequestOptions, Agent, type AgentCapability, type AgentConfig, type AgentHandler, AgentRouter, type AgentRouterOptions, type AgentState, ApprovalClient, type ApprovalDecision, type ApprovalRequestResponse, ApprovalResult, type ApprovalStatusResponse, Audio, type AudioOutput, type AudioRequest, type AuditTrailExport, type AuditTrailFilters, type Awaitable, type BinaryResolver, CANONICAL_STATUSES, type CompactCapability, type CompactDiscoveryResponse, type CostEntry, type CostEntryInit, CostTracker, DEFAULT_HARNESS_PROVIDER, DEFAULT_TOOL_CALL_LIMIT_REACHED, DIDAuthenticator, type DIDIdentity, type DIDIdentityPackage, type DIDRegistrationRequest, type DIDRegistrationResponse, type DeploymentType, DidClient, DidInterface, DidManager, type DidResolver, type DiscoveryFormat, type DiscoveryOptions, type DiscoveryPagination, type DiscoveryResponse, type DiscoveryResult, type EventTriggerBinding, type EventTriggerSpec, ExecutionContext, type ExecutionCredential, type ExecutionLogAttributes, type ExecutionLogBatchPayload, type ExecutionLogContext, type ExecutionLogEmitOptions, type ExecutionLogEntry, type ExecutionLogLevel, type ExecutionLogTransport, type ExecutionLogTransportPayload, type ExecutionLogWireEntry, ExecutionLogger, type ExecutionLoggerOptions, type ExecutionMetadata, ExecutionStatus, type ExecutionStatusValue, File, type FileOutput, type GenerateCredentialOptions, type GenerateCredentialParams, HARNESS_PROVIDER_ENV_VAR, HEADER_CALLER_DID, HEADER_DID_NONCE, HEADER_DID_SIGNATURE, HEADER_DID_TIMESTAMP, type HarnessConfig, type HarnessDoctorOptions, type HarnessOptions, type HarnessProvider, type HarnessProviderName, HarnessProviderUnavailable, type HarnessResult, HarnessRunner, type HealthStatus, Image, type ImageOutput, type ImageRequest, JWE_ALG, JWE_ENC, KEY_AGREEMENT_TYPE, MODEL_VARIANT_SEP, type MediaProvider, MediaProviderError, type MediaResponse, MediaRouter, type MemoryChangeEvent, MemoryClient, MemoryClientBase, type MemoryConfig, MemoryEventClient, type MemoryEventHandler, type MemoryEventHistoryOptions, type MemoryEventSubscriptionOptions, MemoryInterface, type MemoryRequestMetadata, type MemoryRequestOptions, type MemoryScope, type MemoryWatchHandler, type MessageSource, type Metrics, type ModelVariant, type MultimodalContent, MultimodalResponse, OpenRouterMediaProvider, type OpenRouterMediaProviderOptions, PauseClock, PauseManager, type Payload, PayloadEncryptionError, type PromptTemplates, type ProviderHealth, RateLimitError, type RateLimiterOptions, type RawExecutionContext, type RawResult, RealtimeSession, type ReasonerCapability, ReasonerContext, type ReasonerDefinition, type ReasonerHandler, type ReasonerOptions, type RequestApprovalPayload, type ResolvedPromptTemplates, SUPPORTED_PROVIDERS, SUPPORTED_PROVIDER_NAMES, SUPPORTED_SESSION_TRANSPORTS, type ScheduleTriggerBinding, type ScheduleTriggerSpec, type ServerlessAdapter, type ServerlessEvent, type ServerlessResponse, type SessionDefinition, type SessionOptions, type SessionProvider, type SessionTransport, type SessionTransportCapability, SessionTransportError, type SessionTurn, type SimulateScheduleOptions, type SimulateTriggerOptions, type SimulatedContext, type SkillCapability, SkillContext, type SkillDefinition, type SkillHandler, type SkillOptions, StatelessRateLimiter, TERMINAL_STATUSES, TRACE_SOURCE_ASSISTANT, TRACE_SOURCE_TOOL_ERROR, TRACE_SOURCE_TOOL_LIMIT, TRACE_SOURCE_TOOL_RESULT, TRACE_SOURCE_TOOL_SYSTEM_PROMPT, TRACE_SOURCE_USER, Text, type ToolCallConfig, type ToolCallRecord, type ToolCallTrace, type ToolErrorFormatter, type ToolResultFormatter, type ToolsOption, type TracedMessage, type TriggerBinding, type TriggerContext, type TriggerEnvelope, type TurnDetection, USAGE_ENVELOPE_KEY, type UnwrapResult, type UsageEntryWire, type UsageSummaryWire, type VectorSearchOptions, type VectorSearchResult, type VersionProbe, Video, type VideoFrameImage, type VideoInputReference, type VideoRequest, type WaitForApprovalOptions, type WorkflowCredential, type WorkflowMetadata, type WorkflowProgressOptions, WorkflowReporter, type WrapperProbe, type ZodSchema, applyTriggerTransform, attachUsageToSyncResult, audioFromBase64, audioFromBuffer, audioFromFile, audioFromUrl, audioMediaType, buildProvider, buildSessionDefinition, buildToolConfig, capabilitiesToTools, capabilityToMetadataTool, capabilityToTool, createExecutionLogger, createHarnessResult, createMetrics, createMultimodalResponse, createRawResult, decrypt, decryptToString, defaultToolErrorFormatter, defaultToolResultFormatter, deriveProvider, encryptForDid, encryptToJwk, ensureCliAvailable, eventTrigger, executeToolCallLoop, extractKeyAgreementJwk, fileFromBase64, fileFromBuffer, fileFromPath, fileFromUrl, findExecutable, generateX25519KeyPair, getCurrentContext, getCurrentSkillContext, guessUrlMimeType, harnessDoctor, imageFromBase64, imageFromBuffer, imageFromFile, imageFromUrl, installApprovalWebhookRoute, isActive, isExecutionLogBatchPayload, isTerminal, isTriggerEnvelope, loadFixture, normalizeExecutionLogEntry, normalizeSessionTransportValue, normalizeStatus, normalizeTurnDetection, resolveModelAndVariant, resolvePromptTemplates, resolveProviderName, scheduleTrigger, serializeExecutionLogEntry, simulateSchedule, simulateTrigger, splitModelVariant, text, triggerToPayload, unwrapEnvelope, usageSummaryOrNull, validateSessionTransport, videoFromBase64, videoFromBuffer, videoFromFile, videoFromUrl };
package/dist/index.js CHANGED
@@ -2968,6 +2968,29 @@ function recordAiSdkUsage(params) {
2968
2968
  }
2969
2969
  }
2970
2970
 
2971
+ // src/ai/PromptTemplates.ts
2972
+ var DEFAULT_TOOL_CALL_LIMIT_REACHED = "Tool call limit reached. Please provide a final response.";
2973
+ var defaultToolErrorFormatter = (toolName, error) => ({
2974
+ error,
2975
+ tool: toolName
2976
+ });
2977
+ var defaultToolResultFormatter = (_toolName, result) => result;
2978
+ function resolvePromptTemplates(overrides) {
2979
+ const limit = overrides?.toolCallLimitReached;
2980
+ return {
2981
+ toolSystemPrompt: overrides?.toolSystemPrompt,
2982
+ toolCallLimitReached: limit && limit.length > 0 ? limit : DEFAULT_TOOL_CALL_LIMIT_REACHED,
2983
+ toolErrorFormatter: overrides?.toolErrorFormatter ?? defaultToolErrorFormatter,
2984
+ toolResultFormatter: overrides?.toolResultFormatter ?? defaultToolResultFormatter
2985
+ };
2986
+ }
2987
+ var TRACE_SOURCE_USER = "user";
2988
+ var TRACE_SOURCE_ASSISTANT = "assistant";
2989
+ var TRACE_SOURCE_TOOL_SYSTEM_PROMPT = "sdk.tool_system_prompt";
2990
+ var TRACE_SOURCE_TOOL_RESULT = "sdk.tool_result";
2991
+ var TRACE_SOURCE_TOOL_ERROR = "sdk.tool_error";
2992
+ var TRACE_SOURCE_TOOL_LIMIT = "sdk.tool_limit";
2993
+
2971
2994
  // src/ai/ToolCalling.ts
2972
2995
  var DEFAULT_MAX_TURNS = 10;
2973
2996
  var DEFAULT_MAX_TOOL_CALLS = 25;
@@ -3095,7 +3118,8 @@ function isToolCallConfig(obj) {
3095
3118
  "healthStatus",
3096
3119
  "fallbackBroadening",
3097
3120
  "maxCandidateTools",
3098
- "maxHydratedTools"
3121
+ "maxHydratedTools",
3122
+ "promptTemplates"
3099
3123
  ];
3100
3124
  return typeof obj === "object" && !Array.isArray(obj) && keys.some((k) => k in obj);
3101
3125
  }
@@ -3138,7 +3162,7 @@ async function buildToolConfig(toolsParam, agent) {
3138
3162
  `Invalid tools parameter: expected "discover", ToolCallConfig, DiscoveryResult, capability array, or tool map, got ${typeof toolsParam}`
3139
3163
  );
3140
3164
  }
3141
- function wrapToolsWithObservability(toolMap, agent, trace, maxToolCalls, getCurrentTurn) {
3165
+ function wrapToolsWithObservability(toolMap, agent, trace, maxToolCalls, getCurrentTurn, templates, toolMessageSources) {
3142
3166
  let totalCalls = 0;
3143
3167
  const observableTools = {};
3144
3168
  for (const [name, t] of Object.entries(toolMap)) {
@@ -3146,9 +3170,13 @@ function wrapToolsWithObservability(toolMap, agent, trace, maxToolCalls, getCurr
3146
3170
  observableTools[name] = tool({
3147
3171
  description: originalTool.description ?? "",
3148
3172
  inputSchema: originalTool.inputSchema,
3149
- execute: async (args) => {
3173
+ execute: async (args, opts) => {
3150
3174
  totalCalls++;
3151
3175
  trace.totalToolCalls = totalCalls;
3176
+ const toolCallId = opts?.toolCallId;
3177
+ const recordSource = (source) => {
3178
+ if (toolCallId) toolMessageSources.set(toolCallId, source);
3179
+ };
3152
3180
  if (totalCalls > maxToolCalls) {
3153
3181
  const record2 = {
3154
3182
  toolName: name,
@@ -3158,7 +3186,9 @@ function wrapToolsWithObservability(toolMap, agent, trace, maxToolCalls, getCurr
3158
3186
  turn: getCurrentTurn()
3159
3187
  };
3160
3188
  trace.calls.push(record2);
3161
- return { error: "Tool call limit reached. Please provide a final response." };
3189
+ recordSource(TRACE_SOURCE_TOOL_LIMIT);
3190
+ const limitContent = { error: templates.toolCallLimitReached };
3191
+ return limitContent;
3162
3192
  }
3163
3193
  const record = {
3164
3194
  toolName: name,
@@ -3174,12 +3204,17 @@ function wrapToolsWithObservability(toolMap, agent, trace, maxToolCalls, getCurr
3174
3204
  record.result = result;
3175
3205
  record.latencyMs = Date.now() - start;
3176
3206
  trace.calls.push(record);
3177
- return result;
3207
+ recordSource(TRACE_SOURCE_TOOL_RESULT);
3208
+ const resultContent = templates.toolResultFormatter(name, result);
3209
+ return resultContent;
3178
3210
  } catch (err) {
3179
- record.error = err.message ?? String(err);
3211
+ const message = err.message ?? String(err);
3212
+ record.error = message;
3180
3213
  record.latencyMs = Date.now() - start;
3181
3214
  trace.calls.push(record);
3182
- return { error: record.error, tool: name };
3215
+ recordSource(TRACE_SOURCE_TOOL_ERROR);
3216
+ const errorContent = templates.toolErrorFormatter(name, message);
3217
+ return errorContent;
3183
3218
  }
3184
3219
  }
3185
3220
  });
@@ -3189,6 +3224,10 @@ function wrapToolsWithObservability(toolMap, agent, trace, maxToolCalls, getCurr
3189
3224
  async function executeToolCallLoop(agent, prompt, toolMap, config, needsLazyHydration, buildModel, options = {}, modelChoice) {
3190
3225
  const maxTurns = config.maxTurns ?? DEFAULT_MAX_TURNS;
3191
3226
  const maxToolCalls = config.maxToolCalls ?? DEFAULT_MAX_TOOL_CALLS;
3227
+ const templates = resolvePromptTemplates(config.promptTemplates);
3228
+ const effectiveSystem = templates.toolSystemPrompt ? options.system ? `${options.system}
3229
+
3230
+ ${templates.toolSystemPrompt}` : templates.toolSystemPrompt : options.system;
3192
3231
  const usageModel = modelChoice?.modelName ?? options.model;
3193
3232
  const recordLoopUsage = (result2) => {
3194
3233
  if (usageModel) {
@@ -3200,6 +3239,16 @@ async function executeToolCallLoop(agent, prompt, toolMap, config, needsLazyHydr
3200
3239
  totalTurns: 0,
3201
3240
  totalToolCalls: 0
3202
3241
  };
3242
+ if (effectiveSystem) {
3243
+ (trace.messages ??= []).push({
3244
+ message: { role: "system", content: effectiveSystem },
3245
+ source: templates.toolSystemPrompt ? TRACE_SOURCE_TOOL_SYSTEM_PROMPT : TRACE_SOURCE_USER
3246
+ });
3247
+ }
3248
+ (trace.messages ??= []).push({
3249
+ message: { role: "user", content: prompt },
3250
+ source: TRACE_SOURCE_USER
3251
+ });
3203
3252
  let activeTools = toolMap;
3204
3253
  if (needsLazyHydration) {
3205
3254
  const selectionTools = {};
@@ -3214,7 +3263,7 @@ async function executeToolCallLoop(agent, prompt, toolMap, config, needsLazyHydr
3214
3263
  const selectionResult = await generateText({
3215
3264
  model: buildModel(),
3216
3265
  prompt,
3217
- system: options.system,
3266
+ system: effectiveSystem,
3218
3267
  temperature: options.temperature,
3219
3268
  maxOutputTokens: options.maxTokens,
3220
3269
  tools: selectionTools,
@@ -3229,6 +3278,7 @@ async function executeToolCallLoop(agent, prompt, toolMap, config, needsLazyHydr
3229
3278
  }
3230
3279
  }
3231
3280
  if (selectedNames.size > 0) {
3281
+ appendResponseMessages(trace, selectionResult);
3232
3282
  const hydratedTools = await hydrateSelectedTools(
3233
3283
  agent,
3234
3284
  config,
@@ -3240,22 +3290,26 @@ async function executeToolCallLoop(agent, prompt, toolMap, config, needsLazyHydr
3240
3290
  } else {
3241
3291
  trace.totalTurns = selectionResult.steps.length;
3242
3292
  trace.finalResponse = selectionResult.text;
3293
+ appendResponseMessages(trace, selectionResult);
3243
3294
  return { text: selectionResult.text, trace };
3244
3295
  }
3245
3296
  }
3246
3297
  let currentTurn = 0;
3298
+ const toolMessageSources = /* @__PURE__ */ new Map();
3247
3299
  const { tools: observableTools } = wrapToolsWithObservability(
3248
3300
  activeTools,
3249
3301
  agent,
3250
3302
  trace,
3251
3303
  maxToolCalls,
3252
- () => currentTurn
3304
+ () => currentTurn,
3305
+ templates,
3306
+ toolMessageSources
3253
3307
  );
3254
3308
  const model = buildModel();
3255
3309
  const result = await generateText({
3256
3310
  model,
3257
3311
  prompt,
3258
- system: options.system,
3312
+ system: effectiveSystem,
3259
3313
  temperature: options.temperature,
3260
3314
  maxOutputTokens: options.maxTokens,
3261
3315
  tools: observableTools,
@@ -3268,8 +3322,53 @@ async function executeToolCallLoop(agent, prompt, toolMap, config, needsLazyHydr
3268
3322
  recordLoopUsage(result);
3269
3323
  trace.finalResponse = result.text;
3270
3324
  trace.totalTurns = result.steps.length;
3325
+ appendResponseMessages(trace, result, toolMessageSources);
3271
3326
  return { text: result.text, trace };
3272
3327
  }
3328
+ function appendResponseMessages(trace, result, toolMessageSources) {
3329
+ const responseMessages = result.response?.messages;
3330
+ if (!Array.isArray(responseMessages)) {
3331
+ return;
3332
+ }
3333
+ for (const message of responseMessages) {
3334
+ const role = message?.role;
3335
+ let source;
3336
+ if (role === "assistant") {
3337
+ source = TRACE_SOURCE_ASSISTANT;
3338
+ } else if (role === "tool") {
3339
+ source = toolSourceForMessage(message, toolMessageSources);
3340
+ } else if (role === "system") {
3341
+ source = TRACE_SOURCE_TOOL_SYSTEM_PROMPT;
3342
+ } else {
3343
+ source = TRACE_SOURCE_USER;
3344
+ }
3345
+ (trace.messages ??= []).push({ message, source });
3346
+ }
3347
+ }
3348
+ function toolSourceForMessage(message, toolMessageSources) {
3349
+ const parts = Array.isArray(message?.content) ? message.content : [];
3350
+ let sawNativeError = false;
3351
+ let fallback = TRACE_SOURCE_TOOL_RESULT;
3352
+ for (const part of parts) {
3353
+ const id = part?.toolCallId;
3354
+ if (id && toolMessageSources?.has(id)) {
3355
+ const recorded = toolMessageSources.get(id);
3356
+ if (recorded !== TRACE_SOURCE_TOOL_RESULT) {
3357
+ return recorded;
3358
+ }
3359
+ fallback = recorded;
3360
+ continue;
3361
+ }
3362
+ const outputType = part?.output?.type ?? part?.type;
3363
+ if (typeof outputType === "string" && outputType.startsWith("error")) {
3364
+ sawNativeError = true;
3365
+ }
3366
+ }
3367
+ if (sawNativeError) {
3368
+ return TRACE_SOURCE_TOOL_ERROR;
3369
+ }
3370
+ return fallback;
3371
+ }
3273
3372
 
3274
3373
  // src/context/ReasonerContext.ts
3275
3374
  var ReasonerContext = class {
@@ -3360,7 +3459,9 @@ var ReasonerContext = class {
3360
3459
  const mergedConfig = {
3361
3460
  ...config,
3362
3461
  maxTurns: options.maxTurns ?? config.maxTurns ?? 10,
3363
- maxToolCalls: options.maxToolCalls ?? config.maxToolCalls ?? 25
3462
+ maxToolCalls: options.maxToolCalls ?? config.maxToolCalls ?? 25,
3463
+ // Carry the agent's prompt-template overrides into the loop (issue #229).
3464
+ promptTemplates: this.aiClient.promptTemplates ?? config.promptTemplates
3364
3465
  };
3365
3466
  const modelChoice = typeof this.aiClient.resolveModelChoice === "function" ? this.aiClient.resolveModelChoice(options) : void 0;
3366
3467
  return executeToolCallLoop(
@@ -4060,6 +4161,10 @@ var AIClient = class {
4060
4161
  ...config
4061
4162
  };
4062
4163
  }
4164
+ /** Prompt-template overrides configured on this agent, if any (issue #229). */
4165
+ get promptTemplates() {
4166
+ return this.config.promptTemplates;
4167
+ }
4063
4168
  async generate(prompt, options = {}) {
4064
4169
  const { provider, modelName, routingProvider: routingProvider2 } = this.resolveModelChoice(options);
4065
4170
  const model = this.buildModel(options);
@@ -9579,6 +9684,6 @@ function loadFixture(source) {
9579
9684
  );
9580
9685
  }
9581
9686
 
9582
- export { ACTIVE_STATUSES, AIClient, Agent, AgentRouter, ApprovalClient, ApprovalResult, Audio, CANONICAL_STATUSES, CostTracker, DEFAULT_HARNESS_PROVIDER, DIDAuthenticator, DidClient, DidInterface, DidManager, ExecutionContext, ExecutionLogger, ExecutionStatus, File, HARNESS_PROVIDER_ENV_VAR, HEADER_CALLER_DID, HEADER_DID_NONCE, HEADER_DID_SIGNATURE, HEADER_DID_TIMESTAMP, HarnessProviderUnavailable, HarnessRunner, Image, JWE_ALG, JWE_ENC, KEY_AGREEMENT_TYPE, MODEL_VARIANT_SEP, MediaProviderError, MediaRouter, MemoryClient, MemoryClientBase, MemoryEventClient, MemoryInterface, MultimodalResponse, OpenRouterMediaProvider, PauseClock, PauseManager, PayloadEncryptionError, RateLimitError, RealtimeSession, ReasonerContext, SUPPORTED_PROVIDERS, SUPPORTED_PROVIDER_NAMES, SUPPORTED_SESSION_TRANSPORTS, SessionTransportError, SkillContext, StatelessRateLimiter, TERMINAL_STATUSES, Text, USAGE_ENVELOPE_KEY, Video, WorkflowReporter, applyTriggerTransform, attachUsageToSyncResult, audioFromBase64, audioFromBuffer, audioFromFile, audioFromUrl, audioMediaType, buildProvider, buildSessionDefinition, buildToolConfig, capabilitiesToTools, capabilityToMetadataTool, capabilityToTool, createExecutionLogger, createHarnessResult, createMetrics, createMultimodalResponse, createRawResult, decrypt, decryptToString, deriveProvider, encryptForDid, encryptToJwk, ensureCliAvailable, eventTrigger, executeToolCallLoop, extractKeyAgreementJwk, fileFromBase64, fileFromBuffer, fileFromPath, fileFromUrl, findExecutable, generateX25519KeyPair, getCurrentContext, getCurrentSkillContext, guessUrlMimeType, harnessDoctor, imageFromBase64, imageFromBuffer, imageFromFile, imageFromUrl, installApprovalWebhookRoute, isActive, isExecutionLogBatchPayload, isTerminal, isTriggerEnvelope, loadFixture, normalizeExecutionLogEntry, normalizeSessionTransportValue, normalizeStatus, normalizeTurnDetection, resolveModelAndVariant, resolveProviderName, scheduleTrigger, serializeExecutionLogEntry, simulateSchedule, simulateTrigger, splitModelVariant, text, triggerToPayload, unwrapEnvelope, usageSummaryOrNull, validateSessionTransport, videoFromBase64, videoFromBuffer, videoFromFile, videoFromUrl };
9687
+ export { ACTIVE_STATUSES, AIClient, Agent, AgentRouter, ApprovalClient, ApprovalResult, Audio, CANONICAL_STATUSES, CostTracker, DEFAULT_HARNESS_PROVIDER, DEFAULT_TOOL_CALL_LIMIT_REACHED, DIDAuthenticator, DidClient, DidInterface, DidManager, ExecutionContext, ExecutionLogger, ExecutionStatus, File, HARNESS_PROVIDER_ENV_VAR, HEADER_CALLER_DID, HEADER_DID_NONCE, HEADER_DID_SIGNATURE, HEADER_DID_TIMESTAMP, HarnessProviderUnavailable, HarnessRunner, Image, JWE_ALG, JWE_ENC, KEY_AGREEMENT_TYPE, MODEL_VARIANT_SEP, MediaProviderError, MediaRouter, MemoryClient, MemoryClientBase, MemoryEventClient, MemoryInterface, MultimodalResponse, OpenRouterMediaProvider, PauseClock, PauseManager, PayloadEncryptionError, RateLimitError, RealtimeSession, ReasonerContext, SUPPORTED_PROVIDERS, SUPPORTED_PROVIDER_NAMES, SUPPORTED_SESSION_TRANSPORTS, SessionTransportError, SkillContext, StatelessRateLimiter, TERMINAL_STATUSES, TRACE_SOURCE_ASSISTANT, TRACE_SOURCE_TOOL_ERROR, TRACE_SOURCE_TOOL_LIMIT, TRACE_SOURCE_TOOL_RESULT, TRACE_SOURCE_TOOL_SYSTEM_PROMPT, TRACE_SOURCE_USER, Text, USAGE_ENVELOPE_KEY, Video, WorkflowReporter, applyTriggerTransform, attachUsageToSyncResult, audioFromBase64, audioFromBuffer, audioFromFile, audioFromUrl, audioMediaType, buildProvider, buildSessionDefinition, buildToolConfig, capabilitiesToTools, capabilityToMetadataTool, capabilityToTool, createExecutionLogger, createHarnessResult, createMetrics, createMultimodalResponse, createRawResult, decrypt, decryptToString, defaultToolErrorFormatter, defaultToolResultFormatter, deriveProvider, encryptForDid, encryptToJwk, ensureCliAvailable, eventTrigger, executeToolCallLoop, extractKeyAgreementJwk, fileFromBase64, fileFromBuffer, fileFromPath, fileFromUrl, findExecutable, generateX25519KeyPair, getCurrentContext, getCurrentSkillContext, guessUrlMimeType, harnessDoctor, imageFromBase64, imageFromBuffer, imageFromFile, imageFromUrl, installApprovalWebhookRoute, isActive, isExecutionLogBatchPayload, isTerminal, isTriggerEnvelope, loadFixture, normalizeExecutionLogEntry, normalizeSessionTransportValue, normalizeStatus, normalizeTurnDetection, resolveModelAndVariant, resolvePromptTemplates, resolveProviderName, scheduleTrigger, serializeExecutionLogEntry, simulateSchedule, simulateTrigger, splitModelVariant, text, triggerToPayload, unwrapEnvelope, usageSummaryOrNull, validateSessionTransport, videoFromBase64, videoFromBuffer, videoFromFile, videoFromUrl };
9583
9688
  //# sourceMappingURL=index.js.map
9584
9689
  //# sourceMappingURL=index.js.map