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.js CHANGED
@@ -697,45 +697,38 @@ function unwrap(schema) {
697
697
  let optional = false;
698
698
  let nullable = false;
699
699
  while (true) {
700
- const typeName = current?._def?.typeName;
700
+ const typeName = current?._def?.type;
701
701
  if (!typeName) {
702
702
  break;
703
703
  }
704
- if (typeName === "ZodOptional") {
704
+ if (typeName === "optional") {
705
705
  optional = true;
706
706
  current = current._def?.innerType ?? current;
707
707
  continue;
708
708
  }
709
- if (typeName === "ZodDefault") {
709
+ if (typeName === "default") {
710
710
  optional = true;
711
711
  current = current._def?.innerType ?? current;
712
712
  continue;
713
713
  }
714
- if (typeName === "ZodNullable") {
714
+ if (typeName === "nullable") {
715
715
  nullable = true;
716
716
  current = current._def?.innerType ?? current;
717
717
  continue;
718
718
  }
719
- if (typeName === "ZodEffects") {
720
- current = current._def?.schema ?? current;
721
- continue;
722
- }
723
- if (typeName === "ZodBranded") {
724
- current = current._def?.type ?? current;
725
- continue;
726
- }
727
- if (typeName === "ZodCatch") {
728
- current = current._def?.innerType ?? current;
719
+ if (typeName === "pipe") {
720
+ const outType = current._def?.out?._def?.type;
721
+ if (outType === "transform") {
722
+ current = current._def?.in ?? current;
723
+ } else {
724
+ current = current._def?.out ?? current;
725
+ }
729
726
  continue;
730
727
  }
731
- if (typeName === "ZodReadonly") {
728
+ if (typeName === "catch" || typeName === "readonly") {
732
729
  current = current._def?.innerType ?? current;
733
730
  continue;
734
731
  }
735
- if (typeName === "ZodPipeline") {
736
- current = current._def?.out ?? current;
737
- continue;
738
- }
739
732
  break;
740
733
  }
741
734
  return {
@@ -749,81 +742,74 @@ function formatCore(schema, depth, seen) {
749
742
  return "unknown";
750
743
  }
751
744
  seen.add(schema);
752
- const typeName = schema?._def?.typeName;
745
+ const typeName = schema?._def?.type;
753
746
  switch (typeName) {
754
- case "ZodString":
747
+ case "string":
755
748
  return "string";
756
- case "ZodNumber":
749
+ case "number":
757
750
  return isIntegerNumber(schema) ? "int" : "number";
758
- case "ZodBoolean":
751
+ case "boolean":
759
752
  return "boolean";
760
- case "ZodBigInt":
753
+ case "bigint":
761
754
  return "bigint";
762
- case "ZodDate":
755
+ case "date":
763
756
  return "Date";
764
- case "ZodUndefined":
757
+ case "undefined":
765
758
  return "undefined";
766
- case "ZodNull":
759
+ case "null":
767
760
  return "null";
768
- case "ZodAny":
761
+ case "any":
769
762
  return "any";
770
- case "ZodUnknown":
763
+ case "unknown":
771
764
  return "unknown";
772
- case "ZodNever":
765
+ case "never":
773
766
  return "never";
774
- case "ZodVoid":
767
+ case "void":
775
768
  return "void";
776
- case "ZodLiteral": {
777
- const value = schema._def?.value;
769
+ case "literal": {
770
+ const value = schema._def?.values?.[0];
778
771
  return JSON.stringify(value);
779
772
  }
780
- case "ZodEnum": {
781
- const values = schema._def?.values ?? [];
782
- return values.map((value) => JSON.stringify(value)).join(" | ") || "string";
783
- }
784
- case "ZodNativeEnum": {
785
- const values = Object.values(schema._def?.values ?? {});
786
- const unique = [...new Set(values.filter((value) => typeof value !== "string" || Number.isNaN(Number(value))))];
787
- return unique.map((value) => JSON.stringify(value)).join(" | ") || "string";
773
+ case "enum": {
774
+ const entries = schema._def?.entries;
775
+ const values = Object.values(entries ?? {});
776
+ const unique = [...new Set(values.filter((v) => typeof v !== "string" || Number.isNaN(Number(v))))];
777
+ return unique.map((v) => JSON.stringify(v)).join(" | ") || "string";
788
778
  }
789
- case "ZodArray": {
790
- const inner = formatType(schema._def?.type ?? schema, depth, seen);
779
+ case "array": {
780
+ const inner = formatType(schema._def?.element ?? schema, depth, seen);
791
781
  return requiresParentheses(inner) ? `(${inner})[]` : `${inner}[]`;
792
782
  }
793
- case "ZodTuple": {
783
+ case "tuple": {
794
784
  const items = (schema._def?.items ?? []).map((item) => formatType(item, depth, seen));
795
785
  return `[${items.join(", ")}]`;
796
786
  }
797
- case "ZodUnion": {
787
+ case "union": {
798
788
  const options = (schema._def?.options ?? []).map((option) => formatType(option, depth, seen));
799
789
  return options.join(" | ") || "unknown";
800
790
  }
801
- case "ZodDiscriminatedUnion": {
802
- const options = Array.from((schema._def?.options ?? new Map).values()).map((option) => formatType(option, depth, seen));
803
- return options.join(" | ") || "unknown";
804
- }
805
- case "ZodIntersection": {
791
+ case "intersection": {
806
792
  const left = formatType(schema._def?.left ?? schema, depth, seen);
807
793
  const right = formatType(schema._def?.right ?? schema, depth, seen);
808
794
  return `${left} & ${right}`;
809
795
  }
810
- case "ZodRecord": {
796
+ case "record": {
811
797
  const keyType = formatType(schema._def?.keyType ?? schema, depth, seen);
812
798
  const valueType = formatType(schema._def?.valueType ?? schema, depth, seen);
813
799
  return `Record<${keyType}, ${valueType}>`;
814
800
  }
815
- case "ZodMap": {
801
+ case "map": {
816
802
  const keyType = formatType(schema._def?.keyType ?? schema, depth, seen);
817
803
  const valueType = formatType(schema._def?.valueType ?? schema, depth, seen);
818
804
  return `Map<${keyType}, ${valueType}>`;
819
805
  }
820
- case "ZodSet": {
806
+ case "set": {
821
807
  const valueType = formatType(schema._def?.valueType ?? schema, depth, seen);
822
808
  return `Set<${valueType}>`;
823
809
  }
824
- case "ZodObject":
810
+ case "object":
825
811
  return formatObject(schema, depth, seen);
826
- case "ZodLazy":
812
+ case "lazy":
827
813
  return "unknown";
828
814
  default:
829
815
  return "unknown";
@@ -859,40 +845,28 @@ function requiresParentheses(typeText) {
859
845
  }
860
846
  function isIntegerNumber(schema) {
861
847
  const checks = schema._def?.checks ?? [];
862
- return checks.some((check) => check.kind === "int");
848
+ return checks.some((check) => check.isInt === true);
863
849
  }
864
850
  function readSchemaDescription(schema) {
865
851
  let current = schema;
866
- while (current?._def?.typeName) {
867
- const direct = current._def.description;
868
- if (typeof direct === "string" && direct.trim().length > 0) {
869
- return sanitizeDescription(direct);
870
- }
871
- const fallback = current.description;
872
- if (typeof fallback === "string" && fallback.trim().length > 0) {
873
- return sanitizeDescription(fallback);
852
+ while (current?._def?.type) {
853
+ const desc = current.description;
854
+ if (typeof desc === "string" && desc.trim().length > 0) {
855
+ return sanitizeDescription(desc);
874
856
  }
875
- const typeName = current._def.typeName;
876
- if (typeName === "ZodOptional" || typeName === "ZodDefault" || typeName === "ZodNullable") {
857
+ const typeName = current._def.type;
858
+ if (typeName === "optional" || typeName === "default" || typeName === "nullable") {
877
859
  current = current._def.innerType ?? current;
878
860
  continue;
879
861
  }
880
- if (typeName === "ZodEffects") {
881
- current = current._def.schema ?? current;
862
+ if (typeName === "pipe") {
863
+ current = current._def.in ?? current;
882
864
  continue;
883
865
  }
884
- if (typeName === "ZodBranded") {
885
- current = current._def.type ?? current;
886
- continue;
887
- }
888
- if (typeName === "ZodCatch" || typeName === "ZodReadonly") {
866
+ if (typeName === "catch" || typeName === "readonly") {
889
867
  current = current._def.innerType ?? current;
890
868
  continue;
891
869
  }
892
- if (typeName === "ZodPipeline") {
893
- current = current._def.out ?? current;
894
- continue;
895
- }
896
870
  break;
897
871
  }
898
872
  return;
@@ -2177,6 +2151,12 @@ function buildHeaders(options) {
2177
2151
  };
2178
2152
  }
2179
2153
  function buildMessages(request) {
2154
+ if (Array.isArray(request.messages) && request.messages.length > 0) {
2155
+ return request.messages.map((message) => toOpenAIMessage(message));
2156
+ }
2157
+ if (typeof request.prompt !== "string" || request.prompt.trim().length === 0) {
2158
+ throw new Error("LLMRequest must include a prompt or messages.");
2159
+ }
2180
2160
  const messages = [];
2181
2161
  if (request.systemPrompt) {
2182
2162
  messages.push({ role: "system", content: request.systemPrompt });
@@ -2188,18 +2168,16 @@ function buildResponsesInput(request) {
2188
2168
  if (isRecord2(request.body) && "input" in request.body) {
2189
2169
  return request.body.input;
2190
2170
  }
2191
- const input = [];
2192
- if (request.systemPrompt) {
2193
- input.push({
2194
- role: "system",
2195
- content: request.systemPrompt
2196
- });
2171
+ if (Array.isArray(request.messages) && request.messages.length > 0) {
2172
+ return request.messages.map((message) => toOpenAIMessage(message));
2197
2173
  }
2198
- input.push({
2199
- role: "user",
2200
- content: request.prompt
2201
- });
2202
- return input;
2174
+ return buildMessages(request);
2175
+ }
2176
+ function toOpenAIMessage(message) {
2177
+ return {
2178
+ role: message.role,
2179
+ content: message.content
2180
+ };
2203
2181
  }
2204
2182
  function toResponsesTools(tools) {
2205
2183
  if (!Array.isArray(tools) || tools.length === 0) {
@@ -2611,6 +2589,7 @@ function createAnthropicCompatibleAdapter(options) {
2611
2589
  if (hasMCPClients(request.mcpClients)) {
2612
2590
  return streamWithMCPToolLoop(options, fetcher, path, request, callbacks);
2613
2591
  }
2592
+ const input = resolveAnthropicInput(request);
2614
2593
  const response = await fetcher(buildURL(options.baseURL, path), {
2615
2594
  method: "POST",
2616
2595
  headers: buildHeaders2(options),
@@ -2618,8 +2597,8 @@ function createAnthropicCompatibleAdapter(options) {
2618
2597
  ...options.defaultBody,
2619
2598
  ...request.body,
2620
2599
  model: options.model,
2621
- system: request.systemPrompt,
2622
- messages: [{ role: "user", content: request.prompt }],
2600
+ system: input.systemPrompt,
2601
+ messages: input.messages,
2623
2602
  temperature: request.temperature,
2624
2603
  max_tokens: resolveMaxTokens(request.maxTokens, options.defaultMaxTokens),
2625
2604
  stream: true
@@ -2670,6 +2649,7 @@ function createAnthropicCompatibleAdapter(options) {
2670
2649
  };
2671
2650
  }
2672
2651
  async function completePassThrough(options, fetcher, path, request) {
2652
+ const input = resolveAnthropicInput(request);
2673
2653
  const response = await fetcher(buildURL(options.baseURL, path), {
2674
2654
  method: "POST",
2675
2655
  headers: buildHeaders2(options),
@@ -2677,8 +2657,8 @@ async function completePassThrough(options, fetcher, path, request) {
2677
2657
  ...options.defaultBody,
2678
2658
  ...request.body,
2679
2659
  model: options.model,
2680
- system: request.systemPrompt,
2681
- messages: [{ role: "user", content: request.prompt }],
2660
+ system: input.systemPrompt,
2661
+ messages: input.messages,
2682
2662
  temperature: request.temperature,
2683
2663
  max_tokens: resolveMaxTokens(request.maxTokens, options.defaultMaxTokens),
2684
2664
  stream: false
@@ -2705,7 +2685,8 @@ async function completePassThrough(options, fetcher, path, request) {
2705
2685
  }
2706
2686
  async function completeWithMCPToolLoop(options, fetcher, path, request) {
2707
2687
  const maxToolRounds = normalizeMaxToolRounds(request.maxToolRounds ?? options.defaultMaxToolRounds);
2708
- let messages = [{ role: "user", content: request.prompt }];
2688
+ const input = resolveAnthropicInput(request);
2689
+ let messages = input.messages;
2709
2690
  let aggregatedUsage;
2710
2691
  let finishReason;
2711
2692
  let lastPayload;
@@ -2721,7 +2702,7 @@ async function completeWithMCPToolLoop(options, fetcher, path, request) {
2721
2702
  ...options.defaultBody,
2722
2703
  ...request.body,
2723
2704
  model: options.model,
2724
- system: request.systemPrompt,
2705
+ system: input.systemPrompt,
2725
2706
  messages,
2726
2707
  temperature: request.temperature,
2727
2708
  max_tokens: resolveMaxTokens(request.maxTokens, options.defaultMaxTokens),
@@ -2788,7 +2769,8 @@ async function completeWithMCPToolLoop(options, fetcher, path, request) {
2788
2769
  }
2789
2770
  async function streamWithMCPToolLoop(options, fetcher, path, request, callbacks) {
2790
2771
  const maxToolRounds = normalizeMaxToolRounds(request.maxToolRounds ?? options.defaultMaxToolRounds);
2791
- let messages = [{ role: "user", content: request.prompt }];
2772
+ const input = resolveAnthropicInput(request);
2773
+ let messages = input.messages;
2792
2774
  let aggregatedUsage;
2793
2775
  let finishReason;
2794
2776
  let lastPayload;
@@ -2805,7 +2787,7 @@ async function streamWithMCPToolLoop(options, fetcher, path, request, callbacks)
2805
2787
  ...options.defaultBody,
2806
2788
  ...request.body,
2807
2789
  model: options.model,
2808
- system: request.systemPrompt,
2790
+ system: input.systemPrompt,
2809
2791
  messages,
2810
2792
  temperature: request.temperature,
2811
2793
  max_tokens: resolveMaxTokens(request.maxTokens, options.defaultMaxTokens),
@@ -2916,6 +2898,59 @@ function buildHeaders2(options) {
2916
2898
  ...options.headers
2917
2899
  };
2918
2900
  }
2901
+ function resolveAnthropicInput(request) {
2902
+ if (Array.isArray(request.messages) && request.messages.length > 0) {
2903
+ return toAnthropicInput(request.messages);
2904
+ }
2905
+ if (typeof request.prompt !== "string" || request.prompt.trim().length === 0) {
2906
+ throw new Error("LLMRequest must include a prompt or messages.");
2907
+ }
2908
+ return {
2909
+ systemPrompt: request.systemPrompt,
2910
+ messages: [{ role: "user", content: request.prompt }]
2911
+ };
2912
+ }
2913
+ function toAnthropicInput(messages) {
2914
+ const systemParts = [];
2915
+ const normalizedMessages = [];
2916
+ let sawNonSystem = false;
2917
+ for (const message of messages) {
2918
+ if (message.role === "system") {
2919
+ if (sawNonSystem) {
2920
+ throw new Error('Anthropic-compatible messages only support "system" turns at the beginning.');
2921
+ }
2922
+ systemParts.push(stringifyAnthropicSystemContent(message.content));
2923
+ continue;
2924
+ }
2925
+ sawNonSystem = true;
2926
+ normalizedMessages.push({
2927
+ role: message.role,
2928
+ content: message.content
2929
+ });
2930
+ }
2931
+ if (normalizedMessages.length === 0) {
2932
+ throw new Error("Anthropic-compatible requests require at least one non-system message.");
2933
+ }
2934
+ return {
2935
+ systemPrompt: systemParts.length > 0 ? systemParts.join(`
2936
+
2937
+ `) : undefined,
2938
+ messages: normalizedMessages
2939
+ };
2940
+ }
2941
+ function stringifyAnthropicSystemContent(content) {
2942
+ if (typeof content === "string") {
2943
+ return content;
2944
+ }
2945
+ if (content === null || content === undefined) {
2946
+ return "";
2947
+ }
2948
+ try {
2949
+ return JSON.stringify(content, null, 2) ?? "";
2950
+ } catch {
2951
+ return String(content);
2952
+ }
2953
+ }
2919
2954
  function resolveMaxTokens(value, fallback) {
2920
2955
  const requested = toFiniteNumber(value);
2921
2956
  if (requested !== undefined && requested > 0) {
@@ -3802,17 +3837,15 @@ async function structured(adapter, schemaOrOptions, promptInput, callOptions) {
3802
3837
  const useOutdent = normalized.outdent ?? true;
3803
3838
  const resolvedPrompt = applyPromptOutdent(resolvePrompt(normalized.prompt, { mode }), useOutdent);
3804
3839
  const resolvedSystemPrompt = applyOutdentToOptionalPrompt(normalized.systemPrompt, useOutdent);
3805
- const prompt = shouldInjectFormat(resolvedPrompt.prompt, normalized.schemaInstruction) ? formatPrompt(normalized.schema, resolvedPrompt.prompt, {
3806
- schemaInstruction: normalized.schemaInstruction
3807
- }) : resolvedPrompt.prompt.trim();
3808
- const systemPrompt = mergeSystemPrompts(resolvedPrompt.systemPrompt, resolvedSystemPrompt);
3840
+ const preparedPrompt = prepareStructuredPromptPayload(resolvedPrompt, resolvedSystemPrompt, normalized.schema, normalized.schemaInstruction);
3809
3841
  const first = await executeAttempt(adapter, {
3810
- prompt,
3842
+ prompt: preparedPrompt.prompt,
3843
+ messages: preparedPrompt.messages,
3811
3844
  schema: normalized.schema,
3812
3845
  parseOptions,
3813
3846
  stream: streamConfig,
3814
3847
  request: normalized.request,
3815
- systemPrompt,
3848
+ systemPrompt: preparedPrompt.systemPrompt,
3816
3849
  observe: normalized.observe,
3817
3850
  debug: debugConfig,
3818
3851
  attemptNumber: 1,
@@ -3872,7 +3905,7 @@ async function structured(adapter, schemaOrOptions, promptInput, callOptions) {
3872
3905
  parseOptions,
3873
3906
  stream: streamConfig,
3874
3907
  request: normalized.request,
3875
- systemPrompt,
3908
+ systemPrompt: preparedPrompt.systemPrompt,
3876
3909
  observe: normalized.observe,
3877
3910
  debug: debugConfig,
3878
3911
  attemptNumber,
@@ -3934,12 +3967,15 @@ function isPromptResolver(value) {
3934
3967
  return typeof value === "object" && value !== null && "resolvePrompt" in value && typeof value.resolvePrompt === "function";
3935
3968
  }
3936
3969
  function normalizePromptPayload(value) {
3937
- if (typeof value.prompt !== "string") {
3938
- throw new Error("Structured prompt payload must include a string prompt.");
3970
+ const prompt = typeof value.prompt === "string" ? value.prompt : undefined;
3971
+ const messages = Array.isArray(value.messages) ? value.messages.filter(isLLMMessage) : undefined;
3972
+ if ((!prompt || prompt.trim().length === 0) && (!messages || messages.length === 0)) {
3973
+ throw new Error("Structured prompt payload must include a non-empty prompt or messages.");
3939
3974
  }
3940
3975
  return {
3941
- prompt: value.prompt,
3942
- systemPrompt: typeof value.systemPrompt === "string" ? value.systemPrompt : undefined
3976
+ prompt,
3977
+ systemPrompt: typeof value.systemPrompt === "string" ? value.systemPrompt : undefined,
3978
+ messages: messages && messages.length > 0 ? messages.map((message) => ({ ...message })) : undefined
3943
3979
  };
3944
3980
  }
3945
3981
  function applyPromptOutdent(payload, enabled) {
@@ -3947,10 +3983,24 @@ function applyPromptOutdent(payload, enabled) {
3947
3983
  return payload;
3948
3984
  }
3949
3985
  return {
3950
- prompt: structuredOutdent.string(payload.prompt),
3951
- systemPrompt: applyOutdentToOptionalPrompt(payload.systemPrompt, enabled)
3986
+ prompt: typeof payload.prompt === "string" ? structuredOutdent.string(payload.prompt) : undefined,
3987
+ systemPrompt: applyOutdentToOptionalPrompt(payload.systemPrompt, enabled),
3988
+ messages: payload.messages?.map((message) => ({
3989
+ ...message,
3990
+ content: typeof message.content === "string" ? structuredOutdent.string(message.content) : message.content
3991
+ }))
3952
3992
  };
3953
3993
  }
3994
+ function isLLMMessage(value) {
3995
+ if (typeof value !== "object" || value === null) {
3996
+ return false;
3997
+ }
3998
+ const candidate = value;
3999
+ if (candidate.role !== "system" && candidate.role !== "user" && candidate.role !== "assistant" && candidate.role !== "tool") {
4000
+ return false;
4001
+ }
4002
+ return "content" in candidate;
4003
+ }
3954
4004
  function applyOutdentToOptionalPrompt(value, enabled) {
3955
4005
  if (!enabled || typeof value !== "string") {
3956
4006
  return value;
@@ -3966,6 +4016,60 @@ function mergeSystemPrompts(primary, secondary) {
3966
4016
 
3967
4017
  `);
3968
4018
  }
4019
+ function prepareStructuredPromptPayload(payload, systemPrompt, schema, schemaInstruction) {
4020
+ if (Array.isArray(payload.messages) && payload.messages.length > 0) {
4021
+ const messages = payload.messages.map((message) => ({ ...message }));
4022
+ const mergedSystemPrompt = mergeSystemPrompts(payload.systemPrompt, systemPrompt);
4023
+ const systemMessages = mergedSystemPrompt ? [{ role: "system", content: mergedSystemPrompt }] : [];
4024
+ return {
4025
+ messages: injectStructuredFormatIntoMessages([...systemMessages, ...messages], schema, schemaInstruction)
4026
+ };
4027
+ }
4028
+ const resolvedPrompt = payload.prompt?.trim();
4029
+ if (!resolvedPrompt) {
4030
+ throw new Error("Structured prompt payload must include a non-empty prompt or messages.");
4031
+ }
4032
+ return {
4033
+ prompt: shouldInjectFormat(resolvedPrompt, schemaInstruction) ? formatPrompt(schema, resolvedPrompt, {
4034
+ schemaInstruction
4035
+ }) : resolvedPrompt,
4036
+ systemPrompt: mergeSystemPrompts(payload.systemPrompt, systemPrompt)
4037
+ };
4038
+ }
4039
+ function injectStructuredFormatIntoMessages(messages, schema, schemaInstruction) {
4040
+ const lastUserIndex = findLastUserMessageIndex(messages);
4041
+ if (lastUserIndex === -1) {
4042
+ throw new Error("Structured prompts with messages must include at least one user message.");
4043
+ }
4044
+ const target = messages[lastUserIndex];
4045
+ const content = typeof target?.content === "string" ? target.content.trim() : stringifyPromptContent(target?.content);
4046
+ const formatted = shouldInjectFormat(content, schemaInstruction) ? formatPrompt(schema, content, { schemaInstruction }) : content.trim();
4047
+ return messages.map((message, index) => index === lastUserIndex ? {
4048
+ ...message,
4049
+ content: formatted
4050
+ } : message);
4051
+ }
4052
+ function findLastUserMessageIndex(messages) {
4053
+ for (let index = messages.length - 1;index >= 0; index -= 1) {
4054
+ if (messages[index]?.role === "user") {
4055
+ return index;
4056
+ }
4057
+ }
4058
+ return -1;
4059
+ }
4060
+ function stringifyPromptContent(content) {
4061
+ if (typeof content === "string") {
4062
+ return content;
4063
+ }
4064
+ if (content === null || content === undefined) {
4065
+ return "";
4066
+ }
4067
+ try {
4068
+ return JSON.stringify(content, null, 2) ?? "";
4069
+ } catch {
4070
+ return String(content);
4071
+ }
4072
+ }
3969
4073
  function shouldInjectFormat(prompt, schemaInstruction) {
3970
4074
  const instruction = resolveSchemaInstruction(schemaInstruction);
3971
4075
  return !prompt.trimStart().startsWith(instruction);
@@ -4144,6 +4248,7 @@ function normalizeDebugConfig(option) {
4144
4248
  async function executeAttempt(adapter, input) {
4145
4249
  const response = await callModel(adapter, {
4146
4250
  prompt: input.prompt,
4251
+ messages: input.messages,
4147
4252
  systemPrompt: input.systemPrompt,
4148
4253
  request: input.request,
4149
4254
  stream: input.stream,
@@ -4181,6 +4286,7 @@ async function executeAttempt(adapter, input) {
4181
4286
  async function callModel(adapter, options) {
4182
4287
  const requestPayload = {
4183
4288
  prompt: options.prompt,
4289
+ messages: options.messages,
4184
4290
  systemPrompt: options.systemPrompt,
4185
4291
  temperature: options.request?.temperature,
4186
4292
  maxTokens: options.request?.maxTokens,
@@ -4491,6 +4597,7 @@ function emitObserve(observe, event) {
4491
4597
  }
4492
4598
  function emitDebugRequest(config, input) {
4493
4599
  const requestBody = input.requestPayload.body !== undefined ? JSON.stringify(input.requestPayload.body, null, 2) : "(none)";
4600
+ const requestMessages = input.requestPayload.messages !== undefined ? JSON.stringify(input.requestPayload.messages, null, 2) : "(none)";
4494
4601
  const lines = [
4495
4602
  color(config, title(config, [
4496
4603
  "[structured][request]",
@@ -4504,7 +4611,9 @@ function emitDebugRequest(config, input) {
4504
4611
  `stream=${input.stream}`
4505
4612
  ].join(" ")),
4506
4613
  color(config, "prompt:", "yellow"),
4507
- input.requestPayload.prompt,
4614
+ input.requestPayload.prompt ?? "(none)",
4615
+ color(config, "messages:", "yellow"),
4616
+ requestMessages,
4508
4617
  color(config, "systemPrompt:", "yellow"),
4509
4618
  input.requestPayload.systemPrompt ?? "(none)",
4510
4619
  color(config, "request.body:", "yellow"),
@@ -4725,35 +4834,28 @@ function toPromptMessage(input, values) {
4725
4834
  }
4726
4835
  return renderPromptTemplate(input, values);
4727
4836
  }
4728
- function joinMessages(messages) {
4729
- return messages.join(`
4730
-
4731
- `);
4732
- }
4733
4837
 
4734
4838
  class PromptMessageBuilderImpl {
4735
- systemMessages = [];
4736
- userMessages = [];
4839
+ messages = [];
4737
4840
  system(input, ...values) {
4738
- const message = toPromptMessage(input, values);
4739
- if (message.length > 0) {
4740
- this.systemMessages.push(message);
4741
- }
4742
- return this;
4841
+ return this.pushMessage("system", input, values);
4743
4842
  }
4744
4843
  user(input, ...values) {
4844
+ return this.pushMessage("user", input, values);
4845
+ }
4846
+ assistant(input, ...values) {
4847
+ return this.pushMessage("assistant", input, values);
4848
+ }
4849
+ pushMessage(role, input, values) {
4745
4850
  const message = toPromptMessage(input, values);
4746
4851
  if (message.length > 0) {
4747
- this.userMessages.push(message);
4852
+ this.messages.push({ role, content: message });
4748
4853
  }
4749
4854
  return this;
4750
4855
  }
4751
4856
  build() {
4752
- const prompt = joinMessages(this.userMessages);
4753
- const systemPrompt = joinMessages(this.systemMessages);
4754
4857
  return {
4755
- prompt,
4756
- systemPrompt: systemPrompt.length > 0 ? systemPrompt : undefined
4858
+ messages: this.messages.map((message) => ({ ...message }))
4757
4859
  };
4758
4860
  }
4759
4861
  resolvePrompt(_context) {
@@ -4863,8 +4965,8 @@ function inferSchemaExample(schema) {
4863
4965
  }
4864
4966
  function getObjectShape(schema) {
4865
4967
  const unwrapped = unwrap2(schema).schema;
4866
- const typeName = unwrapped._def?.typeName;
4867
- if (typeName !== "ZodObject") {
4968
+ const typeName = unwrapped._def?.type;
4969
+ if (typeName !== "object") {
4868
4970
  return null;
4869
4971
  }
4870
4972
  const rawShape = unwrapped._def?.shape;
@@ -4875,33 +4977,25 @@ function getObjectShape(schema) {
4875
4977
  }
4876
4978
  function readDefaultValue(schema) {
4877
4979
  let current = schema;
4878
- while (current?._def?.typeName) {
4879
- const typeName = current._def.typeName;
4880
- if (typeName === "ZodDefault") {
4881
- const raw = current._def.defaultValue;
4882
- if (typeof raw === "function") {
4883
- try {
4980
+ while (current?._def?.type) {
4981
+ const typeName = current._def.type;
4982
+ if (typeName === "default") {
4983
+ try {
4984
+ const raw = current._def.defaultValue;
4985
+ if (typeof raw === "function") {
4884
4986
  return raw();
4885
- } catch {
4886
- return;
4887
4987
  }
4988
+ return raw;
4989
+ } catch {
4990
+ return;
4888
4991
  }
4889
- return raw;
4890
4992
  }
4891
- if (typeName === "ZodOptional" || typeName === "ZodNullable" || typeName === "ZodCatch" || typeName === "ZodReadonly") {
4993
+ if (typeName === "optional" || typeName === "nullable" || typeName === "catch" || typeName === "readonly") {
4892
4994
  current = current._def.innerType ?? current;
4893
4995
  continue;
4894
4996
  }
4895
- if (typeName === "ZodEffects") {
4896
- current = current._def.schema ?? current;
4897
- continue;
4898
- }
4899
- if (typeName === "ZodBranded") {
4900
- current = current._def.type ?? current;
4901
- continue;
4902
- }
4903
- if (typeName === "ZodPipeline") {
4904
- current = current._def.out ?? current;
4997
+ if (typeName === "pipe") {
4998
+ current = current._def.in ?? current;
4905
4999
  continue;
4906
5000
  }
4907
5001
  return;
@@ -4910,34 +5004,22 @@ function readDefaultValue(schema) {
4910
5004
  }
4911
5005
  function readSchemaDescription2(schema) {
4912
5006
  let current = schema;
4913
- while (current?._def?.typeName) {
4914
- const raw = current._def.description;
4915
- if (typeof raw === "string" && raw.trim().length > 0) {
4916
- return raw.trim();
5007
+ while (current?._def?.type) {
5008
+ const desc = current.description;
5009
+ if (typeof desc === "string" && desc.trim().length > 0) {
5010
+ return desc.trim();
4917
5011
  }
4918
- const fallback = current.description;
4919
- if (typeof fallback === "string" && fallback.trim().length > 0) {
4920
- return fallback.trim();
4921
- }
4922
- const typeName = current._def.typeName;
4923
- if (typeName === "ZodOptional" || typeName === "ZodDefault" || typeName === "ZodNullable") {
5012
+ const typeName = current._def.type;
5013
+ if (typeName === "optional" || typeName === "default" || typeName === "nullable") {
4924
5014
  current = current._def.innerType ?? current;
4925
5015
  continue;
4926
5016
  }
4927
- if (typeName === "ZodCatch" || typeName === "ZodReadonly") {
5017
+ if (typeName === "catch" || typeName === "readonly") {
4928
5018
  current = current._def.innerType ?? current;
4929
5019
  continue;
4930
5020
  }
4931
- if (typeName === "ZodEffects") {
4932
- current = current._def.schema ?? current;
4933
- continue;
4934
- }
4935
- if (typeName === "ZodBranded") {
4936
- current = current._def.type ?? current;
4937
- continue;
4938
- }
4939
- if (typeName === "ZodPipeline") {
4940
- current = current._def.out ?? current;
5021
+ if (typeName === "pipe") {
5022
+ current = current._def.in ?? current;
4941
5023
  continue;
4942
5024
  }
4943
5025
  break;
@@ -4947,27 +5029,19 @@ function readSchemaDescription2(schema) {
4947
5029
  function unwrap2(schema) {
4948
5030
  let current = schema;
4949
5031
  let optional = false;
4950
- while (current?._def?.typeName) {
4951
- const typeName = current._def.typeName;
4952
- if (typeName === "ZodOptional" || typeName === "ZodDefault") {
5032
+ while (current?._def?.type) {
5033
+ const typeName = current._def.type;
5034
+ if (typeName === "optional" || typeName === "default") {
4953
5035
  optional = true;
4954
5036
  current = current._def.innerType ?? current;
4955
5037
  continue;
4956
5038
  }
4957
- if (typeName === "ZodNullable" || typeName === "ZodCatch" || typeName === "ZodReadonly") {
5039
+ if (typeName === "nullable" || typeName === "catch" || typeName === "readonly") {
4958
5040
  current = current._def.innerType ?? current;
4959
5041
  continue;
4960
5042
  }
4961
- if (typeName === "ZodEffects") {
4962
- current = current._def.schema ?? current;
4963
- continue;
4964
- }
4965
- if (typeName === "ZodBranded") {
4966
- current = current._def.type ?? current;
4967
- continue;
4968
- }
4969
- if (typeName === "ZodPipeline") {
4970
- current = current._def.out ?? current;
5043
+ if (typeName === "pipe") {
5044
+ current = current._def.in ?? current;
4971
5045
  continue;
4972
5046
  }
4973
5047
  break;