extrait 0.4.0 → 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;
951
+ if (typeName === "pipe") {
952
+ current = current._def.in ?? current;
961
953
  continue;
962
954
  }
963
- if (typeName === "ZodBranded") {
964
- current = current._def.type ?? current;
965
- continue;
966
- }
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;
@@ -2256,6 +2240,12 @@ function buildHeaders(options) {
2256
2240
  };
2257
2241
  }
2258
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
+ }
2259
2249
  const messages = [];
2260
2250
  if (request.systemPrompt) {
2261
2251
  messages.push({ role: "system", content: request.systemPrompt });
@@ -2267,18 +2257,16 @@ function buildResponsesInput(request) {
2267
2257
  if (isRecord2(request.body) && "input" in request.body) {
2268
2258
  return request.body.input;
2269
2259
  }
2270
- const input = [];
2271
- if (request.systemPrompt) {
2272
- input.push({
2273
- role: "system",
2274
- content: request.systemPrompt
2275
- });
2260
+ if (Array.isArray(request.messages) && request.messages.length > 0) {
2261
+ return request.messages.map((message) => toOpenAIMessage(message));
2276
2262
  }
2277
- input.push({
2278
- role: "user",
2279
- content: request.prompt
2280
- });
2281
- return input;
2263
+ return buildMessages(request);
2264
+ }
2265
+ function toOpenAIMessage(message) {
2266
+ return {
2267
+ role: message.role,
2268
+ content: message.content
2269
+ };
2282
2270
  }
2283
2271
  function toResponsesTools(tools) {
2284
2272
  if (!Array.isArray(tools) || tools.length === 0) {
@@ -2690,6 +2678,7 @@ function createAnthropicCompatibleAdapter(options) {
2690
2678
  if (hasMCPClients(request.mcpClients)) {
2691
2679
  return streamWithMCPToolLoop(options, fetcher, path, request, callbacks);
2692
2680
  }
2681
+ const input = resolveAnthropicInput(request);
2693
2682
  const response = await fetcher(buildURL(options.baseURL, path), {
2694
2683
  method: "POST",
2695
2684
  headers: buildHeaders2(options),
@@ -2697,8 +2686,8 @@ function createAnthropicCompatibleAdapter(options) {
2697
2686
  ...options.defaultBody,
2698
2687
  ...request.body,
2699
2688
  model: options.model,
2700
- system: request.systemPrompt,
2701
- messages: [{ role: "user", content: request.prompt }],
2689
+ system: input.systemPrompt,
2690
+ messages: input.messages,
2702
2691
  temperature: request.temperature,
2703
2692
  max_tokens: resolveMaxTokens(request.maxTokens, options.defaultMaxTokens),
2704
2693
  stream: true
@@ -2749,6 +2738,7 @@ function createAnthropicCompatibleAdapter(options) {
2749
2738
  };
2750
2739
  }
2751
2740
  async function completePassThrough(options, fetcher, path, request) {
2741
+ const input = resolveAnthropicInput(request);
2752
2742
  const response = await fetcher(buildURL(options.baseURL, path), {
2753
2743
  method: "POST",
2754
2744
  headers: buildHeaders2(options),
@@ -2756,8 +2746,8 @@ async function completePassThrough(options, fetcher, path, request) {
2756
2746
  ...options.defaultBody,
2757
2747
  ...request.body,
2758
2748
  model: options.model,
2759
- system: request.systemPrompt,
2760
- messages: [{ role: "user", content: request.prompt }],
2749
+ system: input.systemPrompt,
2750
+ messages: input.messages,
2761
2751
  temperature: request.temperature,
2762
2752
  max_tokens: resolveMaxTokens(request.maxTokens, options.defaultMaxTokens),
2763
2753
  stream: false
@@ -2784,7 +2774,8 @@ async function completePassThrough(options, fetcher, path, request) {
2784
2774
  }
2785
2775
  async function completeWithMCPToolLoop(options, fetcher, path, request) {
2786
2776
  const maxToolRounds = normalizeMaxToolRounds(request.maxToolRounds ?? options.defaultMaxToolRounds);
2787
- let messages = [{ role: "user", content: request.prompt }];
2777
+ const input = resolveAnthropicInput(request);
2778
+ let messages = input.messages;
2788
2779
  let aggregatedUsage;
2789
2780
  let finishReason;
2790
2781
  let lastPayload;
@@ -2800,7 +2791,7 @@ async function completeWithMCPToolLoop(options, fetcher, path, request) {
2800
2791
  ...options.defaultBody,
2801
2792
  ...request.body,
2802
2793
  model: options.model,
2803
- system: request.systemPrompt,
2794
+ system: input.systemPrompt,
2804
2795
  messages,
2805
2796
  temperature: request.temperature,
2806
2797
  max_tokens: resolveMaxTokens(request.maxTokens, options.defaultMaxTokens),
@@ -2867,7 +2858,8 @@ async function completeWithMCPToolLoop(options, fetcher, path, request) {
2867
2858
  }
2868
2859
  async function streamWithMCPToolLoop(options, fetcher, path, request, callbacks) {
2869
2860
  const maxToolRounds = normalizeMaxToolRounds(request.maxToolRounds ?? options.defaultMaxToolRounds);
2870
- let messages = [{ role: "user", content: request.prompt }];
2861
+ const input = resolveAnthropicInput(request);
2862
+ let messages = input.messages;
2871
2863
  let aggregatedUsage;
2872
2864
  let finishReason;
2873
2865
  let lastPayload;
@@ -2884,7 +2876,7 @@ async function streamWithMCPToolLoop(options, fetcher, path, request, callbacks)
2884
2876
  ...options.defaultBody,
2885
2877
  ...request.body,
2886
2878
  model: options.model,
2887
- system: request.systemPrompt,
2879
+ system: input.systemPrompt,
2888
2880
  messages,
2889
2881
  temperature: request.temperature,
2890
2882
  max_tokens: resolveMaxTokens(request.maxTokens, options.defaultMaxTokens),
@@ -2995,6 +2987,59 @@ function buildHeaders2(options) {
2995
2987
  ...options.headers
2996
2988
  };
2997
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
+ }
2998
3043
  function resolveMaxTokens(value, fallback) {
2999
3044
  const requested = toFiniteNumber(value);
3000
3045
  if (requested !== undefined && requested > 0) {
@@ -3881,17 +3926,15 @@ async function structured(adapter, schemaOrOptions, promptInput, callOptions) {
3881
3926
  const useOutdent = normalized.outdent ?? true;
3882
3927
  const resolvedPrompt = applyPromptOutdent(resolvePrompt(normalized.prompt, { mode }), useOutdent);
3883
3928
  const resolvedSystemPrompt = applyOutdentToOptionalPrompt(normalized.systemPrompt, useOutdent);
3884
- const prompt = shouldInjectFormat(resolvedPrompt.prompt, normalized.schemaInstruction) ? formatPrompt(normalized.schema, resolvedPrompt.prompt, {
3885
- schemaInstruction: normalized.schemaInstruction
3886
- }) : resolvedPrompt.prompt.trim();
3887
- const systemPrompt = mergeSystemPrompts(resolvedPrompt.systemPrompt, resolvedSystemPrompt);
3929
+ const preparedPrompt = prepareStructuredPromptPayload(resolvedPrompt, resolvedSystemPrompt, normalized.schema, normalized.schemaInstruction);
3888
3930
  const first = await executeAttempt(adapter, {
3889
- prompt,
3931
+ prompt: preparedPrompt.prompt,
3932
+ messages: preparedPrompt.messages,
3890
3933
  schema: normalized.schema,
3891
3934
  parseOptions,
3892
3935
  stream: streamConfig,
3893
3936
  request: normalized.request,
3894
- systemPrompt,
3937
+ systemPrompt: preparedPrompt.systemPrompt,
3895
3938
  observe: normalized.observe,
3896
3939
  debug: debugConfig,
3897
3940
  attemptNumber: 1,
@@ -3951,7 +3994,7 @@ async function structured(adapter, schemaOrOptions, promptInput, callOptions) {
3951
3994
  parseOptions,
3952
3995
  stream: streamConfig,
3953
3996
  request: normalized.request,
3954
- systemPrompt,
3997
+ systemPrompt: preparedPrompt.systemPrompt,
3955
3998
  observe: normalized.observe,
3956
3999
  debug: debugConfig,
3957
4000
  attemptNumber,
@@ -4013,12 +4056,15 @@ function isPromptResolver(value) {
4013
4056
  return typeof value === "object" && value !== null && "resolvePrompt" in value && typeof value.resolvePrompt === "function";
4014
4057
  }
4015
4058
  function normalizePromptPayload(value) {
4016
- if (typeof value.prompt !== "string") {
4017
- 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.");
4018
4063
  }
4019
4064
  return {
4020
- prompt: value.prompt,
4021
- 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
4022
4068
  };
4023
4069
  }
4024
4070
  function applyPromptOutdent(payload, enabled) {
@@ -4026,10 +4072,24 @@ function applyPromptOutdent(payload, enabled) {
4026
4072
  return payload;
4027
4073
  }
4028
4074
  return {
4029
- prompt: structuredOutdent.string(payload.prompt),
4030
- 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
+ }))
4031
4081
  };
4032
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
+ }
4033
4093
  function applyOutdentToOptionalPrompt(value, enabled) {
4034
4094
  if (!enabled || typeof value !== "string") {
4035
4095
  return value;
@@ -4045,6 +4105,60 @@ function mergeSystemPrompts(primary, secondary) {
4045
4105
 
4046
4106
  `);
4047
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
+ }
4048
4162
  function shouldInjectFormat(prompt, schemaInstruction) {
4049
4163
  const instruction = resolveSchemaInstruction(schemaInstruction);
4050
4164
  return !prompt.trimStart().startsWith(instruction);
@@ -4223,6 +4337,7 @@ function normalizeDebugConfig(option) {
4223
4337
  async function executeAttempt(adapter, input) {
4224
4338
  const response = await callModel(adapter, {
4225
4339
  prompt: input.prompt,
4340
+ messages: input.messages,
4226
4341
  systemPrompt: input.systemPrompt,
4227
4342
  request: input.request,
4228
4343
  stream: input.stream,
@@ -4260,6 +4375,7 @@ async function executeAttempt(adapter, input) {
4260
4375
  async function callModel(adapter, options) {
4261
4376
  const requestPayload = {
4262
4377
  prompt: options.prompt,
4378
+ messages: options.messages,
4263
4379
  systemPrompt: options.systemPrompt,
4264
4380
  temperature: options.request?.temperature,
4265
4381
  maxTokens: options.request?.maxTokens,
@@ -4570,6 +4686,7 @@ function emitObserve(observe, event) {
4570
4686
  }
4571
4687
  function emitDebugRequest(config, input) {
4572
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)";
4573
4690
  const lines = [
4574
4691
  color(config, title(config, [
4575
4692
  "[structured][request]",
@@ -4583,7 +4700,9 @@ function emitDebugRequest(config, input) {
4583
4700
  `stream=${input.stream}`
4584
4701
  ].join(" ")),
4585
4702
  color(config, "prompt:", "yellow"),
4586
- input.requestPayload.prompt,
4703
+ input.requestPayload.prompt ?? "(none)",
4704
+ color(config, "messages:", "yellow"),
4705
+ requestMessages,
4587
4706
  color(config, "systemPrompt:", "yellow"),
4588
4707
  input.requestPayload.systemPrompt ?? "(none)",
4589
4708
  color(config, "request.body:", "yellow"),
@@ -4800,35 +4919,28 @@ function toPromptMessage(input, values) {
4800
4919
  }
4801
4920
  return renderPromptTemplate(input, values);
4802
4921
  }
4803
- function joinMessages(messages) {
4804
- return messages.join(`
4805
-
4806
- `);
4807
- }
4808
4922
 
4809
4923
  class PromptMessageBuilderImpl {
4810
- systemMessages = [];
4811
- userMessages = [];
4924
+ messages = [];
4812
4925
  system(input, ...values) {
4813
- const message = toPromptMessage(input, values);
4814
- if (message.length > 0) {
4815
- this.systemMessages.push(message);
4816
- }
4817
- return this;
4926
+ return this.pushMessage("system", input, values);
4818
4927
  }
4819
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) {
4820
4935
  const message = toPromptMessage(input, values);
4821
4936
  if (message.length > 0) {
4822
- this.userMessages.push(message);
4937
+ this.messages.push({ role, content: message });
4823
4938
  }
4824
4939
  return this;
4825
4940
  }
4826
4941
  build() {
4827
- const prompt = joinMessages(this.userMessages);
4828
- const systemPrompt = joinMessages(this.systemMessages);
4829
4942
  return {
4830
- prompt,
4831
- systemPrompt: systemPrompt.length > 0 ? systemPrompt : undefined
4943
+ messages: this.messages.map((message) => ({ ...message }))
4832
4944
  };
4833
4945
  }
4834
4946
  resolvePrompt(_context) {
@@ -4938,8 +5050,8 @@ function inferSchemaExample(schema) {
4938
5050
  }
4939
5051
  function getObjectShape(schema) {
4940
5052
  const unwrapped = unwrap2(schema).schema;
4941
- const typeName = unwrapped._def?.typeName;
4942
- if (typeName !== "ZodObject") {
5053
+ const typeName = unwrapped._def?.type;
5054
+ if (typeName !== "object") {
4943
5055
  return null;
4944
5056
  }
4945
5057
  const rawShape = unwrapped._def?.shape;
@@ -4950,33 +5062,25 @@ function getObjectShape(schema) {
4950
5062
  }
4951
5063
  function readDefaultValue(schema) {
4952
5064
  let current = schema;
4953
- while (current?._def?.typeName) {
4954
- const typeName = current._def.typeName;
4955
- if (typeName === "ZodDefault") {
4956
- const raw = current._def.defaultValue;
4957
- if (typeof raw === "function") {
4958
- 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") {
4959
5071
  return raw();
4960
- } catch {
4961
- return;
4962
5072
  }
5073
+ return raw;
5074
+ } catch {
5075
+ return;
4963
5076
  }
4964
- return raw;
4965
5077
  }
4966
- if (typeName === "ZodOptional" || typeName === "ZodNullable" || typeName === "ZodCatch" || typeName === "ZodReadonly") {
5078
+ if (typeName === "optional" || typeName === "nullable" || typeName === "catch" || typeName === "readonly") {
4967
5079
  current = current._def.innerType ?? current;
4968
5080
  continue;
4969
5081
  }
4970
- if (typeName === "ZodEffects") {
4971
- current = current._def.schema ?? current;
4972
- continue;
4973
- }
4974
- if (typeName === "ZodBranded") {
4975
- current = current._def.type ?? current;
4976
- continue;
4977
- }
4978
- if (typeName === "ZodPipeline") {
4979
- current = current._def.out ?? current;
5082
+ if (typeName === "pipe") {
5083
+ current = current._def.in ?? current;
4980
5084
  continue;
4981
5085
  }
4982
5086
  return;
@@ -4985,34 +5089,22 @@ function readDefaultValue(schema) {
4985
5089
  }
4986
5090
  function readSchemaDescription2(schema) {
4987
5091
  let current = schema;
4988
- while (current?._def?.typeName) {
4989
- const raw = current._def.description;
4990
- if (typeof raw === "string" && raw.trim().length > 0) {
4991
- 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();
4992
5096
  }
4993
- const fallback = current.description;
4994
- if (typeof fallback === "string" && fallback.trim().length > 0) {
4995
- return fallback.trim();
4996
- }
4997
- const typeName = current._def.typeName;
4998
- if (typeName === "ZodOptional" || typeName === "ZodDefault" || typeName === "ZodNullable") {
5097
+ const typeName = current._def.type;
5098
+ if (typeName === "optional" || typeName === "default" || typeName === "nullable") {
4999
5099
  current = current._def.innerType ?? current;
5000
5100
  continue;
5001
5101
  }
5002
- if (typeName === "ZodCatch" || typeName === "ZodReadonly") {
5102
+ if (typeName === "catch" || typeName === "readonly") {
5003
5103
  current = current._def.innerType ?? current;
5004
5104
  continue;
5005
5105
  }
5006
- if (typeName === "ZodEffects") {
5007
- current = current._def.schema ?? current;
5008
- continue;
5009
- }
5010
- if (typeName === "ZodBranded") {
5011
- current = current._def.type ?? current;
5012
- continue;
5013
- }
5014
- if (typeName === "ZodPipeline") {
5015
- current = current._def.out ?? current;
5106
+ if (typeName === "pipe") {
5107
+ current = current._def.in ?? current;
5016
5108
  continue;
5017
5109
  }
5018
5110
  break;
@@ -5022,27 +5114,19 @@ function readSchemaDescription2(schema) {
5022
5114
  function unwrap2(schema) {
5023
5115
  let current = schema;
5024
5116
  let optional = false;
5025
- while (current?._def?.typeName) {
5026
- const typeName = current._def.typeName;
5027
- if (typeName === "ZodOptional" || typeName === "ZodDefault") {
5117
+ while (current?._def?.type) {
5118
+ const typeName = current._def.type;
5119
+ if (typeName === "optional" || typeName === "default") {
5028
5120
  optional = true;
5029
5121
  current = current._def.innerType ?? current;
5030
5122
  continue;
5031
5123
  }
5032
- if (typeName === "ZodNullable" || typeName === "ZodCatch" || typeName === "ZodReadonly") {
5124
+ if (typeName === "nullable" || typeName === "catch" || typeName === "readonly") {
5033
5125
  current = current._def.innerType ?? current;
5034
5126
  continue;
5035
5127
  }
5036
- if (typeName === "ZodEffects") {
5037
- current = current._def.schema ?? current;
5038
- continue;
5039
- }
5040
- if (typeName === "ZodBranded") {
5041
- current = current._def.type ?? current;
5042
- continue;
5043
- }
5044
- if (typeName === "ZodPipeline") {
5045
- current = current._def.out ?? current;
5128
+ if (typeName === "pipe") {
5129
+ current = current._def.in ?? current;
5046
5130
  continue;
5047
5131
  }
5048
5132
  break;