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/README.md +20 -0
- package/dist/index.cjs +276 -192
- package/dist/index.d.ts +2 -2
- package/dist/index.js +258 -184
- package/dist/prompt.d.ts +2 -0
- package/dist/types.d.ts +9 -3
- package/package.json +9 -3
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
|
-
|
|
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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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: (
|
|
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?.
|
|
789
|
+
const typeName = current?._def?.type;
|
|
780
790
|
if (!typeName) {
|
|
781
791
|
break;
|
|
782
792
|
}
|
|
783
|
-
if (typeName === "
|
|
793
|
+
if (typeName === "optional") {
|
|
784
794
|
optional = true;
|
|
785
795
|
current = current._def?.innerType ?? current;
|
|
786
796
|
continue;
|
|
787
797
|
}
|
|
788
|
-
if (typeName === "
|
|
798
|
+
if (typeName === "default") {
|
|
789
799
|
optional = true;
|
|
790
800
|
current = current._def?.innerType ?? current;
|
|
791
801
|
continue;
|
|
792
802
|
}
|
|
793
|
-
if (typeName === "
|
|
803
|
+
if (typeName === "nullable") {
|
|
794
804
|
nullable = true;
|
|
795
805
|
current = current._def?.innerType ?? current;
|
|
796
806
|
continue;
|
|
797
807
|
}
|
|
798
|
-
if (typeName === "
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
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 === "
|
|
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?.
|
|
834
|
+
const typeName = schema?._def?.type;
|
|
832
835
|
switch (typeName) {
|
|
833
|
-
case "
|
|
836
|
+
case "string":
|
|
834
837
|
return "string";
|
|
835
|
-
case "
|
|
838
|
+
case "number":
|
|
836
839
|
return isIntegerNumber(schema) ? "int" : "number";
|
|
837
|
-
case "
|
|
840
|
+
case "boolean":
|
|
838
841
|
return "boolean";
|
|
839
|
-
case "
|
|
842
|
+
case "bigint":
|
|
840
843
|
return "bigint";
|
|
841
|
-
case "
|
|
844
|
+
case "date":
|
|
842
845
|
return "Date";
|
|
843
|
-
case "
|
|
846
|
+
case "undefined":
|
|
844
847
|
return "undefined";
|
|
845
|
-
case "
|
|
848
|
+
case "null":
|
|
846
849
|
return "null";
|
|
847
|
-
case "
|
|
850
|
+
case "any":
|
|
848
851
|
return "any";
|
|
849
|
-
case "
|
|
852
|
+
case "unknown":
|
|
850
853
|
return "unknown";
|
|
851
|
-
case "
|
|
854
|
+
case "never":
|
|
852
855
|
return "never";
|
|
853
|
-
case "
|
|
856
|
+
case "void":
|
|
854
857
|
return "void";
|
|
855
|
-
case "
|
|
856
|
-
const value = schema._def?.
|
|
858
|
+
case "literal": {
|
|
859
|
+
const value = schema._def?.values?.[0];
|
|
857
860
|
return JSON.stringify(value);
|
|
858
861
|
}
|
|
859
|
-
case "
|
|
860
|
-
const
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
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 "
|
|
869
|
-
const inner = formatType(schema._def?.
|
|
868
|
+
case "array": {
|
|
869
|
+
const inner = formatType(schema._def?.element ?? schema, depth, seen);
|
|
870
870
|
return requiresParentheses(inner) ? `(${inner})[]` : `${inner}[]`;
|
|
871
871
|
}
|
|
872
|
-
case "
|
|
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 "
|
|
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 "
|
|
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 "
|
|
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 "
|
|
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 "
|
|
895
|
+
case "set": {
|
|
900
896
|
const valueType = formatType(schema._def?.valueType ?? schema, depth, seen);
|
|
901
897
|
return `Set<${valueType}>`;
|
|
902
898
|
}
|
|
903
|
-
case "
|
|
899
|
+
case "object":
|
|
904
900
|
return formatObject(schema, depth, seen);
|
|
905
|
-
case "
|
|
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.
|
|
937
|
+
return checks.some((check) => check.isInt === true);
|
|
942
938
|
}
|
|
943
939
|
function readSchemaDescription(schema) {
|
|
944
940
|
let current = schema;
|
|
945
|
-
while (current?._def?.
|
|
946
|
-
const
|
|
947
|
-
if (typeof
|
|
948
|
-
return sanitizeDescription(
|
|
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
|
|
951
|
-
if (
|
|
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 === "
|
|
960
|
-
current = current._def.
|
|
951
|
+
if (typeName === "pipe") {
|
|
952
|
+
current = current._def.in ?? current;
|
|
961
953
|
continue;
|
|
962
954
|
}
|
|
963
|
-
if (typeName === "
|
|
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
|
-
|
|
2271
|
-
|
|
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
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
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:
|
|
2701
|
-
messages:
|
|
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:
|
|
2760
|
-
messages:
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
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:
|
|
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
|
|
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
|
-
|
|
4017
|
-
|
|
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
|
|
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
|
-
|
|
4811
|
-
userMessages = [];
|
|
4924
|
+
messages = [];
|
|
4812
4925
|
system(input, ...values) {
|
|
4813
|
-
|
|
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.
|
|
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
|
-
|
|
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?.
|
|
4942
|
-
if (typeName !== "
|
|
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?.
|
|
4954
|
-
const typeName = current._def.
|
|
4955
|
-
if (typeName === "
|
|
4956
|
-
|
|
4957
|
-
|
|
4958
|
-
|
|
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 === "
|
|
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 === "
|
|
4971
|
-
current = current._def.
|
|
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?.
|
|
4989
|
-
const
|
|
4990
|
-
if (typeof
|
|
4991
|
-
return
|
|
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
|
|
4994
|
-
if (
|
|
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 === "
|
|
5102
|
+
if (typeName === "catch" || typeName === "readonly") {
|
|
5003
5103
|
current = current._def.innerType ?? current;
|
|
5004
5104
|
continue;
|
|
5005
5105
|
}
|
|
5006
|
-
if (typeName === "
|
|
5007
|
-
current = current._def.
|
|
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?.
|
|
5026
|
-
const typeName = current._def.
|
|
5027
|
-
if (typeName === "
|
|
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 === "
|
|
5124
|
+
if (typeName === "nullable" || typeName === "catch" || typeName === "readonly") {
|
|
5033
5125
|
current = current._def.innerType ?? current;
|
|
5034
5126
|
continue;
|
|
5035
5127
|
}
|
|
5036
|
-
if (typeName === "
|
|
5037
|
-
current = current._def.
|
|
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;
|