extrait 0.3.1 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -2,27 +2,37 @@ var __defProp = Object.defineProperty;
2
2
  var __getOwnPropNames = Object.getOwnPropertyNames;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __hasOwnProp = Object.prototype.hasOwnProperty;
5
- var __moduleCache = /* @__PURE__ */ new WeakMap;
5
+ function __accessProp(key) {
6
+ return this[key];
7
+ }
6
8
  var __toCommonJS = (from) => {
7
- var entry = __moduleCache.get(from), desc;
9
+ var entry = (__moduleCache ??= new WeakMap).get(from), desc;
8
10
  if (entry)
9
11
  return entry;
10
12
  entry = __defProp({}, "__esModule", { value: true });
11
- if (from && typeof from === "object" || typeof from === "function")
12
- __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
13
- get: () => from[key],
14
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
- }));
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (var key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(entry, key))
16
+ __defProp(entry, key, {
17
+ get: __accessProp.bind(from, key),
18
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
19
+ });
20
+ }
16
21
  __moduleCache.set(from, entry);
17
22
  return entry;
18
23
  };
24
+ var __moduleCache;
25
+ var __returnValue = (v) => v;
26
+ function __exportSetter(name, newValue) {
27
+ this[name] = __returnValue.bind(null, newValue);
28
+ }
19
29
  var __export = (target, all) => {
20
30
  for (var name in all)
21
31
  __defProp(target, name, {
22
32
  get: all[name],
23
33
  enumerable: true,
24
34
  configurable: true,
25
- set: (newValue) => all[name] = () => newValue
35
+ set: __exportSetter.bind(all, name)
26
36
  });
27
37
  };
28
38
 
@@ -776,45 +786,38 @@ function unwrap(schema) {
776
786
  let optional = false;
777
787
  let nullable = false;
778
788
  while (true) {
779
- const typeName = current?._def?.typeName;
789
+ const typeName = current?._def?.type;
780
790
  if (!typeName) {
781
791
  break;
782
792
  }
783
- if (typeName === "ZodOptional") {
793
+ if (typeName === "optional") {
784
794
  optional = true;
785
795
  current = current._def?.innerType ?? current;
786
796
  continue;
787
797
  }
788
- if (typeName === "ZodDefault") {
798
+ if (typeName === "default") {
789
799
  optional = true;
790
800
  current = current._def?.innerType ?? current;
791
801
  continue;
792
802
  }
793
- if (typeName === "ZodNullable") {
803
+ if (typeName === "nullable") {
794
804
  nullable = true;
795
805
  current = current._def?.innerType ?? current;
796
806
  continue;
797
807
  }
798
- if (typeName === "ZodEffects") {
799
- current = current._def?.schema ?? current;
800
- continue;
801
- }
802
- if (typeName === "ZodBranded") {
803
- current = current._def?.type ?? current;
804
- continue;
805
- }
806
- if (typeName === "ZodCatch") {
807
- current = current._def?.innerType ?? current;
808
+ if (typeName === "pipe") {
809
+ const outType = current._def?.out?._def?.type;
810
+ if (outType === "transform") {
811
+ current = current._def?.in ?? current;
812
+ } else {
813
+ current = current._def?.out ?? current;
814
+ }
808
815
  continue;
809
816
  }
810
- if (typeName === "ZodReadonly") {
817
+ if (typeName === "catch" || typeName === "readonly") {
811
818
  current = current._def?.innerType ?? current;
812
819
  continue;
813
820
  }
814
- if (typeName === "ZodPipeline") {
815
- current = current._def?.out ?? current;
816
- continue;
817
- }
818
821
  break;
819
822
  }
820
823
  return {
@@ -828,81 +831,74 @@ function formatCore(schema, depth, seen) {
828
831
  return "unknown";
829
832
  }
830
833
  seen.add(schema);
831
- const typeName = schema?._def?.typeName;
834
+ const typeName = schema?._def?.type;
832
835
  switch (typeName) {
833
- case "ZodString":
836
+ case "string":
834
837
  return "string";
835
- case "ZodNumber":
838
+ case "number":
836
839
  return isIntegerNumber(schema) ? "int" : "number";
837
- case "ZodBoolean":
840
+ case "boolean":
838
841
  return "boolean";
839
- case "ZodBigInt":
842
+ case "bigint":
840
843
  return "bigint";
841
- case "ZodDate":
844
+ case "date":
842
845
  return "Date";
843
- case "ZodUndefined":
846
+ case "undefined":
844
847
  return "undefined";
845
- case "ZodNull":
848
+ case "null":
846
849
  return "null";
847
- case "ZodAny":
850
+ case "any":
848
851
  return "any";
849
- case "ZodUnknown":
852
+ case "unknown":
850
853
  return "unknown";
851
- case "ZodNever":
854
+ case "never":
852
855
  return "never";
853
- case "ZodVoid":
856
+ case "void":
854
857
  return "void";
855
- case "ZodLiteral": {
856
- const value = schema._def?.value;
858
+ case "literal": {
859
+ const value = schema._def?.values?.[0];
857
860
  return JSON.stringify(value);
858
861
  }
859
- case "ZodEnum": {
860
- const values = schema._def?.values ?? [];
861
- return values.map((value) => JSON.stringify(value)).join(" | ") || "string";
862
- }
863
- case "ZodNativeEnum": {
864
- const values = Object.values(schema._def?.values ?? {});
865
- const unique = [...new Set(values.filter((value) => typeof value !== "string" || Number.isNaN(Number(value))))];
866
- return unique.map((value) => JSON.stringify(value)).join(" | ") || "string";
862
+ case "enum": {
863
+ const entries = schema._def?.entries;
864
+ const values = Object.values(entries ?? {});
865
+ const unique = [...new Set(values.filter((v) => typeof v !== "string" || Number.isNaN(Number(v))))];
866
+ return unique.map((v) => JSON.stringify(v)).join(" | ") || "string";
867
867
  }
868
- case "ZodArray": {
869
- const inner = formatType(schema._def?.type ?? schema, depth, seen);
868
+ case "array": {
869
+ const inner = formatType(schema._def?.element ?? schema, depth, seen);
870
870
  return requiresParentheses(inner) ? `(${inner})[]` : `${inner}[]`;
871
871
  }
872
- case "ZodTuple": {
872
+ case "tuple": {
873
873
  const items = (schema._def?.items ?? []).map((item) => formatType(item, depth, seen));
874
874
  return `[${items.join(", ")}]`;
875
875
  }
876
- case "ZodUnion": {
876
+ case "union": {
877
877
  const options = (schema._def?.options ?? []).map((option) => formatType(option, depth, seen));
878
878
  return options.join(" | ") || "unknown";
879
879
  }
880
- case "ZodDiscriminatedUnion": {
881
- const options = Array.from((schema._def?.options ?? new Map).values()).map((option) => formatType(option, depth, seen));
882
- return options.join(" | ") || "unknown";
883
- }
884
- case "ZodIntersection": {
880
+ case "intersection": {
885
881
  const left = formatType(schema._def?.left ?? schema, depth, seen);
886
882
  const right = formatType(schema._def?.right ?? schema, depth, seen);
887
883
  return `${left} & ${right}`;
888
884
  }
889
- case "ZodRecord": {
885
+ case "record": {
890
886
  const keyType = formatType(schema._def?.keyType ?? schema, depth, seen);
891
887
  const valueType = formatType(schema._def?.valueType ?? schema, depth, seen);
892
888
  return `Record<${keyType}, ${valueType}>`;
893
889
  }
894
- case "ZodMap": {
890
+ case "map": {
895
891
  const keyType = formatType(schema._def?.keyType ?? schema, depth, seen);
896
892
  const valueType = formatType(schema._def?.valueType ?? schema, depth, seen);
897
893
  return `Map<${keyType}, ${valueType}>`;
898
894
  }
899
- case "ZodSet": {
895
+ case "set": {
900
896
  const valueType = formatType(schema._def?.valueType ?? schema, depth, seen);
901
897
  return `Set<${valueType}>`;
902
898
  }
903
- case "ZodObject":
899
+ case "object":
904
900
  return formatObject(schema, depth, seen);
905
- case "ZodLazy":
901
+ case "lazy":
906
902
  return "unknown";
907
903
  default:
908
904
  return "unknown";
@@ -938,40 +934,28 @@ function requiresParentheses(typeText) {
938
934
  }
939
935
  function isIntegerNumber(schema) {
940
936
  const checks = schema._def?.checks ?? [];
941
- return checks.some((check) => check.kind === "int");
937
+ return checks.some((check) => check.isInt === true);
942
938
  }
943
939
  function readSchemaDescription(schema) {
944
940
  let current = schema;
945
- while (current?._def?.typeName) {
946
- const direct = current._def.description;
947
- if (typeof direct === "string" && direct.trim().length > 0) {
948
- return sanitizeDescription(direct);
941
+ while (current?._def?.type) {
942
+ const desc = current.description;
943
+ if (typeof desc === "string" && desc.trim().length > 0) {
944
+ return sanitizeDescription(desc);
949
945
  }
950
- const fallback = current.description;
951
- if (typeof fallback === "string" && fallback.trim().length > 0) {
952
- return sanitizeDescription(fallback);
953
- }
954
- const typeName = current._def.typeName;
955
- if (typeName === "ZodOptional" || typeName === "ZodDefault" || typeName === "ZodNullable") {
946
+ const typeName = current._def.type;
947
+ if (typeName === "optional" || typeName === "default" || typeName === "nullable") {
956
948
  current = current._def.innerType ?? current;
957
949
  continue;
958
950
  }
959
- if (typeName === "ZodEffects") {
960
- current = current._def.schema ?? current;
961
- continue;
962
- }
963
- if (typeName === "ZodBranded") {
964
- current = current._def.type ?? current;
951
+ if (typeName === "pipe") {
952
+ current = current._def.in ?? current;
965
953
  continue;
966
954
  }
967
- if (typeName === "ZodCatch" || typeName === "ZodReadonly") {
955
+ if (typeName === "catch" || typeName === "readonly") {
968
956
  current = current._def.innerType ?? current;
969
957
  continue;
970
958
  }
971
- if (typeName === "ZodPipeline") {
972
- current = current._def.out ?? current;
973
- continue;
974
- }
975
959
  break;
976
960
  }
977
961
  return;
@@ -1324,7 +1308,12 @@ async function executeMCPToolCalls(calls, toolset, context) {
1324
1308
  out.push({ call: metadata2, execution });
1325
1309
  continue;
1326
1310
  }
1327
- const args = isRecord(parsedArguments) ? parsedArguments : {};
1311
+ const rawArgs = isRecord(parsedArguments) ? parsedArguments : {};
1312
+ const args = context.request.transformToolArguments ? await context.request.transformToolArguments(rawArgs, {
1313
+ name: toolName,
1314
+ remoteName: tool.remoteName,
1315
+ clientId: tool.clientId
1316
+ }) : rawArgs;
1328
1317
  const metadata = {
1329
1318
  id: callId,
1330
1319
  type: call.type ?? "function",
@@ -1643,7 +1632,8 @@ function createOpenAICompatibleAdapter(options) {
1643
1632
  temperature: request.temperature,
1644
1633
  max_tokens: request.maxTokens,
1645
1634
  stream: true
1646
- }))
1635
+ })),
1636
+ signal: request.signal
1647
1637
  });
1648
1638
  if (!response.ok) {
1649
1639
  const message = await response.text();
@@ -1714,7 +1704,8 @@ async function completeWithChatCompletionsPassThrough(options, fetcher, path, re
1714
1704
  temperature: request.temperature,
1715
1705
  max_tokens: request.maxTokens,
1716
1706
  stream: false
1717
- }))
1707
+ })),
1708
+ signal: request.signal
1718
1709
  });
1719
1710
  if (!response.ok) {
1720
1711
  const message = await response.text();
@@ -1758,7 +1749,8 @@ async function completeWithChatCompletionsWithMCP(options, fetcher, path, reques
1758
1749
  tools: transportTools,
1759
1750
  tool_choice: request.toolChoice,
1760
1751
  parallel_tool_calls: request.parallelToolCalls
1761
- }))
1752
+ })),
1753
+ signal: request.signal
1762
1754
  });
1763
1755
  if (!response.ok) {
1764
1756
  const message = await response.text();
@@ -1823,7 +1815,8 @@ async function completeWithResponsesAPIPassThrough(options, fetcher, path, reque
1823
1815
  previous_response_id: pickString(body?.previous_response_id),
1824
1816
  temperature: request.temperature,
1825
1817
  max_output_tokens: request.maxTokens
1826
- }))
1818
+ })),
1819
+ signal: request.signal
1827
1820
  });
1828
1821
  if (!response.ok) {
1829
1822
  const message = await response.text();
@@ -1865,7 +1858,8 @@ async function completeWithResponsesAPIWithMCP(options, fetcher, path, request)
1865
1858
  tools: transportTools,
1866
1859
  tool_choice: request.toolChoice,
1867
1860
  parallel_tool_calls: request.parallelToolCalls
1868
- }))
1861
+ })),
1862
+ signal: request.signal
1869
1863
  });
1870
1864
  if (!response.ok) {
1871
1865
  const message = await response.text();
@@ -1941,7 +1935,8 @@ async function streamWithChatCompletionsWithMCP(options, fetcher, path, request,
1941
1935
  tool_choice: request.toolChoice,
1942
1936
  parallel_tool_calls: request.parallelToolCalls,
1943
1937
  stream: true
1944
- }))
1938
+ })),
1939
+ signal: request.signal
1945
1940
  });
1946
1941
  if (!response.ok) {
1947
1942
  const message = await response.text();
@@ -2043,7 +2038,8 @@ async function streamWithResponsesAPIPassThrough(options, fetcher, path, request
2043
2038
  temperature: request.temperature,
2044
2039
  max_output_tokens: request.maxTokens,
2045
2040
  stream: true
2046
- }))
2041
+ })),
2042
+ signal: request.signal
2047
2043
  });
2048
2044
  if (!response.ok) {
2049
2045
  const message = await response.text();
@@ -2125,7 +2121,8 @@ async function streamWithResponsesAPIWithMCP(options, fetcher, path, request, ca
2125
2121
  tool_choice: request.toolChoice,
2126
2122
  parallel_tool_calls: request.parallelToolCalls,
2127
2123
  stream: true
2128
- }))
2124
+ })),
2125
+ signal: request.signal
2129
2126
  });
2130
2127
  if (!response.ok) {
2131
2128
  const message = await response.text();
@@ -2243,6 +2240,12 @@ function buildHeaders(options) {
2243
2240
  };
2244
2241
  }
2245
2242
  function buildMessages(request) {
2243
+ if (Array.isArray(request.messages) && request.messages.length > 0) {
2244
+ return request.messages.map((message) => toOpenAIMessage(message));
2245
+ }
2246
+ if (typeof request.prompt !== "string" || request.prompt.trim().length === 0) {
2247
+ throw new Error("LLMRequest must include a prompt or messages.");
2248
+ }
2246
2249
  const messages = [];
2247
2250
  if (request.systemPrompt) {
2248
2251
  messages.push({ role: "system", content: request.systemPrompt });
@@ -2254,18 +2257,16 @@ function buildResponsesInput(request) {
2254
2257
  if (isRecord2(request.body) && "input" in request.body) {
2255
2258
  return request.body.input;
2256
2259
  }
2257
- const input = [];
2258
- if (request.systemPrompt) {
2259
- input.push({
2260
- role: "system",
2261
- content: request.systemPrompt
2262
- });
2260
+ if (Array.isArray(request.messages) && request.messages.length > 0) {
2261
+ return request.messages.map((message) => toOpenAIMessage(message));
2263
2262
  }
2264
- input.push({
2265
- role: "user",
2266
- content: request.prompt
2267
- });
2268
- return input;
2263
+ return buildMessages(request);
2264
+ }
2265
+ function toOpenAIMessage(message) {
2266
+ return {
2267
+ role: message.role,
2268
+ content: message.content
2269
+ };
2269
2270
  }
2270
2271
  function toResponsesTools(tools) {
2271
2272
  if (!Array.isArray(tools) || tools.length === 0) {
@@ -2677,6 +2678,7 @@ function createAnthropicCompatibleAdapter(options) {
2677
2678
  if (hasMCPClients(request.mcpClients)) {
2678
2679
  return streamWithMCPToolLoop(options, fetcher, path, request, callbacks);
2679
2680
  }
2681
+ const input = resolveAnthropicInput(request);
2680
2682
  const response = await fetcher(buildURL(options.baseURL, path), {
2681
2683
  method: "POST",
2682
2684
  headers: buildHeaders2(options),
@@ -2684,12 +2686,13 @@ function createAnthropicCompatibleAdapter(options) {
2684
2686
  ...options.defaultBody,
2685
2687
  ...request.body,
2686
2688
  model: options.model,
2687
- system: request.systemPrompt,
2688
- messages: [{ role: "user", content: request.prompt }],
2689
+ system: input.systemPrompt,
2690
+ messages: input.messages,
2689
2691
  temperature: request.temperature,
2690
2692
  max_tokens: resolveMaxTokens(request.maxTokens, options.defaultMaxTokens),
2691
2693
  stream: true
2692
- }))
2694
+ })),
2695
+ signal: request.signal
2693
2696
  });
2694
2697
  if (!response.ok) {
2695
2698
  const message = await response.text();
@@ -2735,6 +2738,7 @@ function createAnthropicCompatibleAdapter(options) {
2735
2738
  };
2736
2739
  }
2737
2740
  async function completePassThrough(options, fetcher, path, request) {
2741
+ const input = resolveAnthropicInput(request);
2738
2742
  const response = await fetcher(buildURL(options.baseURL, path), {
2739
2743
  method: "POST",
2740
2744
  headers: buildHeaders2(options),
@@ -2742,12 +2746,13 @@ async function completePassThrough(options, fetcher, path, request) {
2742
2746
  ...options.defaultBody,
2743
2747
  ...request.body,
2744
2748
  model: options.model,
2745
- system: request.systemPrompt,
2746
- messages: [{ role: "user", content: request.prompt }],
2749
+ system: input.systemPrompt,
2750
+ messages: input.messages,
2747
2751
  temperature: request.temperature,
2748
2752
  max_tokens: resolveMaxTokens(request.maxTokens, options.defaultMaxTokens),
2749
2753
  stream: false
2750
- }))
2754
+ })),
2755
+ signal: request.signal
2751
2756
  });
2752
2757
  if (!response.ok) {
2753
2758
  const message = await response.text();
@@ -2769,7 +2774,8 @@ async function completePassThrough(options, fetcher, path, request) {
2769
2774
  }
2770
2775
  async function completeWithMCPToolLoop(options, fetcher, path, request) {
2771
2776
  const maxToolRounds = normalizeMaxToolRounds(request.maxToolRounds ?? options.defaultMaxToolRounds);
2772
- let messages = [{ role: "user", content: request.prompt }];
2777
+ const input = resolveAnthropicInput(request);
2778
+ let messages = input.messages;
2773
2779
  let aggregatedUsage;
2774
2780
  let finishReason;
2775
2781
  let lastPayload;
@@ -2785,14 +2791,15 @@ async function completeWithMCPToolLoop(options, fetcher, path, request) {
2785
2791
  ...options.defaultBody,
2786
2792
  ...request.body,
2787
2793
  model: options.model,
2788
- system: request.systemPrompt,
2794
+ system: input.systemPrompt,
2789
2795
  messages,
2790
2796
  temperature: request.temperature,
2791
2797
  max_tokens: resolveMaxTokens(request.maxTokens, options.defaultMaxTokens),
2792
2798
  tools,
2793
2799
  tool_choice: toAnthropicToolChoice(request.toolChoice),
2794
2800
  stream: false
2795
- }))
2801
+ })),
2802
+ signal: request.signal
2796
2803
  });
2797
2804
  if (!response.ok) {
2798
2805
  const message = await response.text();
@@ -2851,7 +2858,8 @@ async function completeWithMCPToolLoop(options, fetcher, path, request) {
2851
2858
  }
2852
2859
  async function streamWithMCPToolLoop(options, fetcher, path, request, callbacks) {
2853
2860
  const maxToolRounds = normalizeMaxToolRounds(request.maxToolRounds ?? options.defaultMaxToolRounds);
2854
- let messages = [{ role: "user", content: request.prompt }];
2861
+ const input = resolveAnthropicInput(request);
2862
+ let messages = input.messages;
2855
2863
  let aggregatedUsage;
2856
2864
  let finishReason;
2857
2865
  let lastPayload;
@@ -2868,14 +2876,15 @@ async function streamWithMCPToolLoop(options, fetcher, path, request, callbacks)
2868
2876
  ...options.defaultBody,
2869
2877
  ...request.body,
2870
2878
  model: options.model,
2871
- system: request.systemPrompt,
2879
+ system: input.systemPrompt,
2872
2880
  messages,
2873
2881
  temperature: request.temperature,
2874
2882
  max_tokens: resolveMaxTokens(request.maxTokens, options.defaultMaxTokens),
2875
2883
  tools,
2876
2884
  tool_choice: toAnthropicToolChoice(request.toolChoice),
2877
2885
  stream: true
2878
- }))
2886
+ })),
2887
+ signal: request.signal
2879
2888
  });
2880
2889
  if (!response.ok) {
2881
2890
  const message = await response.text();
@@ -2978,6 +2987,59 @@ function buildHeaders2(options) {
2978
2987
  ...options.headers
2979
2988
  };
2980
2989
  }
2990
+ function resolveAnthropicInput(request) {
2991
+ if (Array.isArray(request.messages) && request.messages.length > 0) {
2992
+ return toAnthropicInput(request.messages);
2993
+ }
2994
+ if (typeof request.prompt !== "string" || request.prompt.trim().length === 0) {
2995
+ throw new Error("LLMRequest must include a prompt or messages.");
2996
+ }
2997
+ return {
2998
+ systemPrompt: request.systemPrompt,
2999
+ messages: [{ role: "user", content: request.prompt }]
3000
+ };
3001
+ }
3002
+ function toAnthropicInput(messages) {
3003
+ const systemParts = [];
3004
+ const normalizedMessages = [];
3005
+ let sawNonSystem = false;
3006
+ for (const message of messages) {
3007
+ if (message.role === "system") {
3008
+ if (sawNonSystem) {
3009
+ throw new Error('Anthropic-compatible messages only support "system" turns at the beginning.');
3010
+ }
3011
+ systemParts.push(stringifyAnthropicSystemContent(message.content));
3012
+ continue;
3013
+ }
3014
+ sawNonSystem = true;
3015
+ normalizedMessages.push({
3016
+ role: message.role,
3017
+ content: message.content
3018
+ });
3019
+ }
3020
+ if (normalizedMessages.length === 0) {
3021
+ throw new Error("Anthropic-compatible requests require at least one non-system message.");
3022
+ }
3023
+ return {
3024
+ systemPrompt: systemParts.length > 0 ? systemParts.join(`
3025
+
3026
+ `) : undefined,
3027
+ messages: normalizedMessages
3028
+ };
3029
+ }
3030
+ function stringifyAnthropicSystemContent(content) {
3031
+ if (typeof content === "string") {
3032
+ return content;
3033
+ }
3034
+ if (content === null || content === undefined) {
3035
+ return "";
3036
+ }
3037
+ try {
3038
+ return JSON.stringify(content, null, 2) ?? "";
3039
+ } catch {
3040
+ return String(content);
3041
+ }
3042
+ }
2981
3043
  function resolveMaxTokens(value, fallback) {
2982
3044
  const requested = toFiniteNumber(value);
2983
3045
  if (requested !== undefined && requested > 0) {
@@ -3864,17 +3926,15 @@ async function structured(adapter, schemaOrOptions, promptInput, callOptions) {
3864
3926
  const useOutdent = normalized.outdent ?? true;
3865
3927
  const resolvedPrompt = applyPromptOutdent(resolvePrompt(normalized.prompt, { mode }), useOutdent);
3866
3928
  const resolvedSystemPrompt = applyOutdentToOptionalPrompt(normalized.systemPrompt, useOutdent);
3867
- const prompt = shouldInjectFormat(resolvedPrompt.prompt, normalized.schemaInstruction) ? formatPrompt(normalized.schema, resolvedPrompt.prompt, {
3868
- schemaInstruction: normalized.schemaInstruction
3869
- }) : resolvedPrompt.prompt.trim();
3870
- const systemPrompt = mergeSystemPrompts(resolvedPrompt.systemPrompt, resolvedSystemPrompt);
3929
+ const preparedPrompt = prepareStructuredPromptPayload(resolvedPrompt, resolvedSystemPrompt, normalized.schema, normalized.schemaInstruction);
3871
3930
  const first = await executeAttempt(adapter, {
3872
- prompt,
3931
+ prompt: preparedPrompt.prompt,
3932
+ messages: preparedPrompt.messages,
3873
3933
  schema: normalized.schema,
3874
3934
  parseOptions,
3875
3935
  stream: streamConfig,
3876
3936
  request: normalized.request,
3877
- systemPrompt,
3937
+ systemPrompt: preparedPrompt.systemPrompt,
3878
3938
  observe: normalized.observe,
3879
3939
  debug: debugConfig,
3880
3940
  attemptNumber: 1,
@@ -3934,7 +3994,7 @@ async function structured(adapter, schemaOrOptions, promptInput, callOptions) {
3934
3994
  parseOptions,
3935
3995
  stream: streamConfig,
3936
3996
  request: normalized.request,
3937
- systemPrompt,
3997
+ systemPrompt: preparedPrompt.systemPrompt,
3938
3998
  observe: normalized.observe,
3939
3999
  debug: debugConfig,
3940
4000
  attemptNumber,
@@ -3996,12 +4056,15 @@ function isPromptResolver(value) {
3996
4056
  return typeof value === "object" && value !== null && "resolvePrompt" in value && typeof value.resolvePrompt === "function";
3997
4057
  }
3998
4058
  function normalizePromptPayload(value) {
3999
- if (typeof value.prompt !== "string") {
4000
- throw new Error("Structured prompt payload must include a string prompt.");
4059
+ const prompt = typeof value.prompt === "string" ? value.prompt : undefined;
4060
+ const messages = Array.isArray(value.messages) ? value.messages.filter(isLLMMessage) : undefined;
4061
+ if ((!prompt || prompt.trim().length === 0) && (!messages || messages.length === 0)) {
4062
+ throw new Error("Structured prompt payload must include a non-empty prompt or messages.");
4001
4063
  }
4002
4064
  return {
4003
- prompt: value.prompt,
4004
- systemPrompt: typeof value.systemPrompt === "string" ? value.systemPrompt : undefined
4065
+ prompt,
4066
+ systemPrompt: typeof value.systemPrompt === "string" ? value.systemPrompt : undefined,
4067
+ messages: messages && messages.length > 0 ? messages.map((message) => ({ ...message })) : undefined
4005
4068
  };
4006
4069
  }
4007
4070
  function applyPromptOutdent(payload, enabled) {
@@ -4009,10 +4072,24 @@ function applyPromptOutdent(payload, enabled) {
4009
4072
  return payload;
4010
4073
  }
4011
4074
  return {
4012
- prompt: structuredOutdent.string(payload.prompt),
4013
- systemPrompt: applyOutdentToOptionalPrompt(payload.systemPrompt, enabled)
4075
+ prompt: typeof payload.prompt === "string" ? structuredOutdent.string(payload.prompt) : undefined,
4076
+ systemPrompt: applyOutdentToOptionalPrompt(payload.systemPrompt, enabled),
4077
+ messages: payload.messages?.map((message) => ({
4078
+ ...message,
4079
+ content: typeof message.content === "string" ? structuredOutdent.string(message.content) : message.content
4080
+ }))
4014
4081
  };
4015
4082
  }
4083
+ function isLLMMessage(value) {
4084
+ if (typeof value !== "object" || value === null) {
4085
+ return false;
4086
+ }
4087
+ const candidate = value;
4088
+ if (candidate.role !== "system" && candidate.role !== "user" && candidate.role !== "assistant" && candidate.role !== "tool") {
4089
+ return false;
4090
+ }
4091
+ return "content" in candidate;
4092
+ }
4016
4093
  function applyOutdentToOptionalPrompt(value, enabled) {
4017
4094
  if (!enabled || typeof value !== "string") {
4018
4095
  return value;
@@ -4028,6 +4105,60 @@ function mergeSystemPrompts(primary, secondary) {
4028
4105
 
4029
4106
  `);
4030
4107
  }
4108
+ function prepareStructuredPromptPayload(payload, systemPrompt, schema, schemaInstruction) {
4109
+ if (Array.isArray(payload.messages) && payload.messages.length > 0) {
4110
+ const messages = payload.messages.map((message) => ({ ...message }));
4111
+ const mergedSystemPrompt = mergeSystemPrompts(payload.systemPrompt, systemPrompt);
4112
+ const systemMessages = mergedSystemPrompt ? [{ role: "system", content: mergedSystemPrompt }] : [];
4113
+ return {
4114
+ messages: injectStructuredFormatIntoMessages([...systemMessages, ...messages], schema, schemaInstruction)
4115
+ };
4116
+ }
4117
+ const resolvedPrompt = payload.prompt?.trim();
4118
+ if (!resolvedPrompt) {
4119
+ throw new Error("Structured prompt payload must include a non-empty prompt or messages.");
4120
+ }
4121
+ return {
4122
+ prompt: shouldInjectFormat(resolvedPrompt, schemaInstruction) ? formatPrompt(schema, resolvedPrompt, {
4123
+ schemaInstruction
4124
+ }) : resolvedPrompt,
4125
+ systemPrompt: mergeSystemPrompts(payload.systemPrompt, systemPrompt)
4126
+ };
4127
+ }
4128
+ function injectStructuredFormatIntoMessages(messages, schema, schemaInstruction) {
4129
+ const lastUserIndex = findLastUserMessageIndex(messages);
4130
+ if (lastUserIndex === -1) {
4131
+ throw new Error("Structured prompts with messages must include at least one user message.");
4132
+ }
4133
+ const target = messages[lastUserIndex];
4134
+ const content = typeof target?.content === "string" ? target.content.trim() : stringifyPromptContent(target?.content);
4135
+ const formatted = shouldInjectFormat(content, schemaInstruction) ? formatPrompt(schema, content, { schemaInstruction }) : content.trim();
4136
+ return messages.map((message, index) => index === lastUserIndex ? {
4137
+ ...message,
4138
+ content: formatted
4139
+ } : message);
4140
+ }
4141
+ function findLastUserMessageIndex(messages) {
4142
+ for (let index = messages.length - 1;index >= 0; index -= 1) {
4143
+ if (messages[index]?.role === "user") {
4144
+ return index;
4145
+ }
4146
+ }
4147
+ return -1;
4148
+ }
4149
+ function stringifyPromptContent(content) {
4150
+ if (typeof content === "string") {
4151
+ return content;
4152
+ }
4153
+ if (content === null || content === undefined) {
4154
+ return "";
4155
+ }
4156
+ try {
4157
+ return JSON.stringify(content, null, 2) ?? "";
4158
+ } catch {
4159
+ return String(content);
4160
+ }
4161
+ }
4031
4162
  function shouldInjectFormat(prompt, schemaInstruction) {
4032
4163
  const instruction = resolveSchemaInstruction(schemaInstruction);
4033
4164
  return !prompt.trimStart().startsWith(instruction);
@@ -4206,6 +4337,7 @@ function normalizeDebugConfig(option) {
4206
4337
  async function executeAttempt(adapter, input) {
4207
4338
  const response = await callModel(adapter, {
4208
4339
  prompt: input.prompt,
4340
+ messages: input.messages,
4209
4341
  systemPrompt: input.systemPrompt,
4210
4342
  request: input.request,
4211
4343
  stream: input.stream,
@@ -4243,6 +4375,7 @@ async function executeAttempt(adapter, input) {
4243
4375
  async function callModel(adapter, options) {
4244
4376
  const requestPayload = {
4245
4377
  prompt: options.prompt,
4378
+ messages: options.messages,
4246
4379
  systemPrompt: options.systemPrompt,
4247
4380
  temperature: options.request?.temperature,
4248
4381
  maxTokens: options.request?.maxTokens,
@@ -4252,7 +4385,8 @@ async function callModel(adapter, options) {
4252
4385
  maxToolRounds: options.request?.maxToolRounds,
4253
4386
  onToolExecution: options.request?.onToolExecution,
4254
4387
  toolDebug: options.request?.toolDebug,
4255
- body: options.request?.body
4388
+ body: options.request?.body,
4389
+ signal: options.request?.signal
4256
4390
  };
4257
4391
  emitDebugRequest(options.debug, {
4258
4392
  provider: adapter.provider,
@@ -4552,6 +4686,7 @@ function emitObserve(observe, event) {
4552
4686
  }
4553
4687
  function emitDebugRequest(config, input) {
4554
4688
  const requestBody = input.requestPayload.body !== undefined ? JSON.stringify(input.requestPayload.body, null, 2) : "(none)";
4689
+ const requestMessages = input.requestPayload.messages !== undefined ? JSON.stringify(input.requestPayload.messages, null, 2) : "(none)";
4555
4690
  const lines = [
4556
4691
  color(config, title(config, [
4557
4692
  "[structured][request]",
@@ -4565,7 +4700,9 @@ function emitDebugRequest(config, input) {
4565
4700
  `stream=${input.stream}`
4566
4701
  ].join(" ")),
4567
4702
  color(config, "prompt:", "yellow"),
4568
- input.requestPayload.prompt,
4703
+ input.requestPayload.prompt ?? "(none)",
4704
+ color(config, "messages:", "yellow"),
4705
+ requestMessages,
4569
4706
  color(config, "systemPrompt:", "yellow"),
4570
4707
  input.requestPayload.systemPrompt ?? "(none)",
4571
4708
  color(config, "request.body:", "yellow"),
@@ -4782,35 +4919,28 @@ function toPromptMessage(input, values) {
4782
4919
  }
4783
4920
  return renderPromptTemplate(input, values);
4784
4921
  }
4785
- function joinMessages(messages) {
4786
- return messages.join(`
4787
-
4788
- `);
4789
- }
4790
4922
 
4791
4923
  class PromptMessageBuilderImpl {
4792
- systemMessages = [];
4793
- userMessages = [];
4924
+ messages = [];
4794
4925
  system(input, ...values) {
4795
- const message = toPromptMessage(input, values);
4796
- if (message.length > 0) {
4797
- this.systemMessages.push(message);
4798
- }
4799
- return this;
4926
+ return this.pushMessage("system", input, values);
4800
4927
  }
4801
4928
  user(input, ...values) {
4929
+ return this.pushMessage("user", input, values);
4930
+ }
4931
+ assistant(input, ...values) {
4932
+ return this.pushMessage("assistant", input, values);
4933
+ }
4934
+ pushMessage(role, input, values) {
4802
4935
  const message = toPromptMessage(input, values);
4803
4936
  if (message.length > 0) {
4804
- this.userMessages.push(message);
4937
+ this.messages.push({ role, content: message });
4805
4938
  }
4806
4939
  return this;
4807
4940
  }
4808
4941
  build() {
4809
- const prompt = joinMessages(this.userMessages);
4810
- const systemPrompt = joinMessages(this.systemMessages);
4811
4942
  return {
4812
- prompt,
4813
- systemPrompt: systemPrompt.length > 0 ? systemPrompt : undefined
4943
+ messages: this.messages.map((message) => ({ ...message }))
4814
4944
  };
4815
4945
  }
4816
4946
  resolvePrompt(_context) {
@@ -4920,8 +5050,8 @@ function inferSchemaExample(schema) {
4920
5050
  }
4921
5051
  function getObjectShape(schema) {
4922
5052
  const unwrapped = unwrap2(schema).schema;
4923
- const typeName = unwrapped._def?.typeName;
4924
- if (typeName !== "ZodObject") {
5053
+ const typeName = unwrapped._def?.type;
5054
+ if (typeName !== "object") {
4925
5055
  return null;
4926
5056
  }
4927
5057
  const rawShape = unwrapped._def?.shape;
@@ -4932,33 +5062,25 @@ function getObjectShape(schema) {
4932
5062
  }
4933
5063
  function readDefaultValue(schema) {
4934
5064
  let current = schema;
4935
- while (current?._def?.typeName) {
4936
- const typeName = current._def.typeName;
4937
- if (typeName === "ZodDefault") {
4938
- const raw = current._def.defaultValue;
4939
- if (typeof raw === "function") {
4940
- try {
5065
+ while (current?._def?.type) {
5066
+ const typeName = current._def.type;
5067
+ if (typeName === "default") {
5068
+ try {
5069
+ const raw = current._def.defaultValue;
5070
+ if (typeof raw === "function") {
4941
5071
  return raw();
4942
- } catch {
4943
- return;
4944
5072
  }
5073
+ return raw;
5074
+ } catch {
5075
+ return;
4945
5076
  }
4946
- return raw;
4947
5077
  }
4948
- if (typeName === "ZodOptional" || typeName === "ZodNullable" || typeName === "ZodCatch" || typeName === "ZodReadonly") {
5078
+ if (typeName === "optional" || typeName === "nullable" || typeName === "catch" || typeName === "readonly") {
4949
5079
  current = current._def.innerType ?? current;
4950
5080
  continue;
4951
5081
  }
4952
- if (typeName === "ZodEffects") {
4953
- current = current._def.schema ?? current;
4954
- continue;
4955
- }
4956
- if (typeName === "ZodBranded") {
4957
- current = current._def.type ?? current;
4958
- continue;
4959
- }
4960
- if (typeName === "ZodPipeline") {
4961
- current = current._def.out ?? current;
5082
+ if (typeName === "pipe") {
5083
+ current = current._def.in ?? current;
4962
5084
  continue;
4963
5085
  }
4964
5086
  return;
@@ -4967,34 +5089,22 @@ function readDefaultValue(schema) {
4967
5089
  }
4968
5090
  function readSchemaDescription2(schema) {
4969
5091
  let current = schema;
4970
- while (current?._def?.typeName) {
4971
- const raw = current._def.description;
4972
- if (typeof raw === "string" && raw.trim().length > 0) {
4973
- return raw.trim();
5092
+ while (current?._def?.type) {
5093
+ const desc = current.description;
5094
+ if (typeof desc === "string" && desc.trim().length > 0) {
5095
+ return desc.trim();
4974
5096
  }
4975
- const fallback = current.description;
4976
- if (typeof fallback === "string" && fallback.trim().length > 0) {
4977
- return fallback.trim();
4978
- }
4979
- const typeName = current._def.typeName;
4980
- if (typeName === "ZodOptional" || typeName === "ZodDefault" || typeName === "ZodNullable") {
5097
+ const typeName = current._def.type;
5098
+ if (typeName === "optional" || typeName === "default" || typeName === "nullable") {
4981
5099
  current = current._def.innerType ?? current;
4982
5100
  continue;
4983
5101
  }
4984
- if (typeName === "ZodCatch" || typeName === "ZodReadonly") {
5102
+ if (typeName === "catch" || typeName === "readonly") {
4985
5103
  current = current._def.innerType ?? current;
4986
5104
  continue;
4987
5105
  }
4988
- if (typeName === "ZodEffects") {
4989
- current = current._def.schema ?? current;
4990
- continue;
4991
- }
4992
- if (typeName === "ZodBranded") {
4993
- current = current._def.type ?? current;
4994
- continue;
4995
- }
4996
- if (typeName === "ZodPipeline") {
4997
- current = current._def.out ?? current;
5106
+ if (typeName === "pipe") {
5107
+ current = current._def.in ?? current;
4998
5108
  continue;
4999
5109
  }
5000
5110
  break;
@@ -5004,27 +5114,19 @@ function readSchemaDescription2(schema) {
5004
5114
  function unwrap2(schema) {
5005
5115
  let current = schema;
5006
5116
  let optional = false;
5007
- while (current?._def?.typeName) {
5008
- const typeName = current._def.typeName;
5009
- if (typeName === "ZodOptional" || typeName === "ZodDefault") {
5117
+ while (current?._def?.type) {
5118
+ const typeName = current._def.type;
5119
+ if (typeName === "optional" || typeName === "default") {
5010
5120
  optional = true;
5011
5121
  current = current._def.innerType ?? current;
5012
5122
  continue;
5013
5123
  }
5014
- if (typeName === "ZodNullable" || typeName === "ZodCatch" || typeName === "ZodReadonly") {
5124
+ if (typeName === "nullable" || typeName === "catch" || typeName === "readonly") {
5015
5125
  current = current._def.innerType ?? current;
5016
5126
  continue;
5017
5127
  }
5018
- if (typeName === "ZodEffects") {
5019
- current = current._def.schema ?? current;
5020
- continue;
5021
- }
5022
- if (typeName === "ZodBranded") {
5023
- current = current._def.type ?? current;
5024
- continue;
5025
- }
5026
- if (typeName === "ZodPipeline") {
5027
- current = current._def.out ?? current;
5128
+ if (typeName === "pipe") {
5129
+ current = current._def.in ?? current;
5028
5130
  continue;
5029
5131
  }
5030
5132
  break;