@cognipeer/agent-sdk 0.10.5 → 0.10.6
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 +761 -311
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +831 -690
- package/dist/index.d.ts +831 -690
- package/dist/index.mjs +756 -311
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -28,6 +28,238 @@ var __export = (target, all) => {
|
|
|
28
28
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
29
29
|
};
|
|
30
30
|
|
|
31
|
+
// src/utils/content.ts
|
|
32
|
+
function isRecord(value) {
|
|
33
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
34
|
+
}
|
|
35
|
+
function nonEmpty(value) {
|
|
36
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
|
|
37
|
+
}
|
|
38
|
+
function kindFromMediaType(mediaType) {
|
|
39
|
+
const top = mediaType?.split("/")[0];
|
|
40
|
+
return top === "image" || top === "audio" || top === "video" ? top : "file";
|
|
41
|
+
}
|
|
42
|
+
function inlineDataOf(part) {
|
|
43
|
+
const inline = part.inlineData ?? part.inline_data ?? part.fileData ?? part.file_data;
|
|
44
|
+
return isRecord(inline) ? inline : void 0;
|
|
45
|
+
}
|
|
46
|
+
function mediaKindOf(part) {
|
|
47
|
+
if (!isRecord(part)) return void 0;
|
|
48
|
+
const type = nonEmpty(part.type);
|
|
49
|
+
if (type) return MEDIA_PART_KINDS[type];
|
|
50
|
+
const inline = inlineDataOf(part);
|
|
51
|
+
if (inline) return kindFromMediaType(nonEmpty(inline.mimeType) ?? nonEmpty(inline.mime_type));
|
|
52
|
+
return void 0;
|
|
53
|
+
}
|
|
54
|
+
function hasMediaPart(content) {
|
|
55
|
+
return Array.isArray(content) && content.some((part) => mediaKindOf(part) !== void 0);
|
|
56
|
+
}
|
|
57
|
+
function urlOfPart(part) {
|
|
58
|
+
const image = part.image_url;
|
|
59
|
+
const video = part.video_url;
|
|
60
|
+
return nonEmpty(typeof image === "string" ? image : image?.url) ?? nonEmpty(typeof video === "string" ? video : video?.url) ?? nonEmpty(part.url) ?? nonEmpty(part.source?.url) ?? nonEmpty(inlineDataOf(part)?.fileUri) ?? nonEmpty(inlineDataOf(part)?.file_uri);
|
|
61
|
+
}
|
|
62
|
+
function mediaTypeOfPart(part) {
|
|
63
|
+
const image = isRecord(part.image_url) ? part.image_url : void 0;
|
|
64
|
+
const source = isRecord(part.source) ? part.source : void 0;
|
|
65
|
+
const inline = inlineDataOf(part);
|
|
66
|
+
const audioFormat = nonEmpty(part.input_audio?.format);
|
|
67
|
+
const fromDataUrl = /^data:([^;,]+)/i.exec(urlOfPart(part) ?? "")?.[1];
|
|
68
|
+
return nonEmpty(part.mediaType) ?? nonEmpty(part.media_type) ?? nonEmpty(part.mimeType) ?? nonEmpty(part.mime_type) ?? nonEmpty(source?.mediaType) ?? nonEmpty(source?.media_type) ?? nonEmpty(image?.mediaType) ?? nonEmpty(image?.media_type) ?? nonEmpty(inline?.mimeType) ?? nonEmpty(inline?.mime_type) ?? nonEmpty(fromDataUrl) ?? (audioFormat ? `audio/${audioFormat}` : void 0);
|
|
69
|
+
}
|
|
70
|
+
function nameOfPart(part) {
|
|
71
|
+
const file = isRecord(part.file) ? part.file : void 0;
|
|
72
|
+
const image = isRecord(part.image_url) ? part.image_url : void 0;
|
|
73
|
+
const source = isRecord(part.source) ? part.source : void 0;
|
|
74
|
+
return nonEmpty(part.name) ?? nonEmpty(part.fileName) ?? nonEmpty(part.filename) ?? nonEmpty(part.file_name) ?? nonEmpty(file?.filename) ?? nonEmpty(file?.fileName) ?? nonEmpty(image?.name) ?? nonEmpty(source?.fileName) ?? nonEmpty(source?.filename) ?? nonEmpty(part.fileId) ?? nonEmpty(part.file_id) ?? nonEmpty(file?.file_id) ?? nonEmpty(file?.fileId) ?? nonEmpty(image?.fileId) ?? nonEmpty(image?.file_id) ?? nonEmpty(part.image_file?.file_id);
|
|
75
|
+
}
|
|
76
|
+
function labelFromUrl(url) {
|
|
77
|
+
if (!url || url.startsWith("data:")) return void 0;
|
|
78
|
+
try {
|
|
79
|
+
const parsed = new URL(url);
|
|
80
|
+
if (parsed.protocol === "session-file:") return nonEmpty(parsed.hostname) ?? nonEmpty(parsed.pathname.replace(/^\/+/, ""));
|
|
81
|
+
if (parsed.protocol === "http:" || parsed.protocol === "https:") {
|
|
82
|
+
return nonEmpty(decodeURIComponent(parsed.pathname.split("/").filter(Boolean).pop() ?? ""));
|
|
83
|
+
}
|
|
84
|
+
} catch {
|
|
85
|
+
}
|
|
86
|
+
return void 0;
|
|
87
|
+
}
|
|
88
|
+
function describeContentPart(part) {
|
|
89
|
+
const kind = mediaKindOf(part);
|
|
90
|
+
if (!kind || !isRecord(part)) return void 0;
|
|
91
|
+
const label = nameOfPart(part) ?? mediaTypeOfPart(part) ?? labelFromUrl(urlOfPart(part));
|
|
92
|
+
if (!label) return `[${kind}]`;
|
|
93
|
+
const clean = label.replace(/[\r\n\]]+/g, " ").slice(0, PLACEHOLDER_LABEL_MAX);
|
|
94
|
+
return `[${kind}: ${clean}]`;
|
|
95
|
+
}
|
|
96
|
+
function contentPartToText(part, fallback) {
|
|
97
|
+
if (typeof part === "string") return part;
|
|
98
|
+
if (!isRecord(part)) return part == null ? "" : String(part);
|
|
99
|
+
const media = describeContentPart(part);
|
|
100
|
+
if (media) return media;
|
|
101
|
+
if (typeof part.text === "string") return part.text;
|
|
102
|
+
if (typeof part.content === "string") return part.content;
|
|
103
|
+
if (fallback) return fallback(part);
|
|
104
|
+
try {
|
|
105
|
+
return JSON.stringify(part);
|
|
106
|
+
} catch {
|
|
107
|
+
return String(part);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
function contentToString(content) {
|
|
111
|
+
try {
|
|
112
|
+
if (content == null) return "";
|
|
113
|
+
if (typeof content === "string") return content;
|
|
114
|
+
if (Array.isArray(content)) {
|
|
115
|
+
return content.map((p) => {
|
|
116
|
+
if (!p || typeof p !== "object") return String(p);
|
|
117
|
+
if (p.type === "text") return String(p.text ?? "");
|
|
118
|
+
if (p.type === "image_url") {
|
|
119
|
+
const img = p.image_url;
|
|
120
|
+
const url = typeof img === "string" ? img : img?.url;
|
|
121
|
+
if (typeof url === "string" && /^https?:\/\//i.test(url)) {
|
|
122
|
+
const detail = typeof img === "string" ? void 0 : img?.detail;
|
|
123
|
+
return `[image:${url}${detail ? ` detail=${detail}` : ""}]`;
|
|
124
|
+
}
|
|
125
|
+
return describeContentPart(p) ?? "[image]";
|
|
126
|
+
}
|
|
127
|
+
const media = describeContentPart(p);
|
|
128
|
+
if (media) return media;
|
|
129
|
+
return JSON.stringify(p);
|
|
130
|
+
}).join("\n");
|
|
131
|
+
}
|
|
132
|
+
return describeContentPart(content) ?? JSON.stringify(content);
|
|
133
|
+
} catch {
|
|
134
|
+
return String(content);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function mergeContentsToString(contents) {
|
|
138
|
+
return contents.map((c) => contentToString(c)).join("\n");
|
|
139
|
+
}
|
|
140
|
+
function safeStringify(value, pretty = false) {
|
|
141
|
+
if (value == null) return "";
|
|
142
|
+
if (typeof value === "string") return value;
|
|
143
|
+
try {
|
|
144
|
+
return JSON.stringify(value, null, pretty ? 2 : void 0) ?? String(value);
|
|
145
|
+
} catch {
|
|
146
|
+
return String(value);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function extractMessageText(message) {
|
|
150
|
+
if (!message) return "";
|
|
151
|
+
const content = message.content;
|
|
152
|
+
if (typeof content === "string") return content;
|
|
153
|
+
if (Array.isArray(content)) {
|
|
154
|
+
return content.map((part) => typeof part === "string" ? part : part?.text ?? part?.content ?? "").join("");
|
|
155
|
+
}
|
|
156
|
+
return "";
|
|
157
|
+
}
|
|
158
|
+
function textFromContent(content) {
|
|
159
|
+
if (typeof content === "string") return content;
|
|
160
|
+
if (!Array.isArray(content)) return "";
|
|
161
|
+
return content.filter((part) => isTextPart(part)).map((part) => part.text ?? "").join("\n");
|
|
162
|
+
}
|
|
163
|
+
function isTextPart(part) {
|
|
164
|
+
return !!part && typeof part === "object" && part.type === "text";
|
|
165
|
+
}
|
|
166
|
+
function mapTextParts(content, fn) {
|
|
167
|
+
if (typeof content === "string") return fn(content);
|
|
168
|
+
if (!Array.isArray(content)) return content;
|
|
169
|
+
return content.map((part) => isTextPart(part) ? { ...part, text: fn(part.text) } : part);
|
|
170
|
+
}
|
|
171
|
+
function replaceTextContent(content, text) {
|
|
172
|
+
if (typeof content === "string" || content == null) return text;
|
|
173
|
+
if (!Array.isArray(content)) return text;
|
|
174
|
+
const textIndexes = content.reduce((acc, part, index) => {
|
|
175
|
+
if (isTextPart(part)) acc.push(index);
|
|
176
|
+
return acc;
|
|
177
|
+
}, []);
|
|
178
|
+
if (textIndexes.length === 0) {
|
|
179
|
+
return text.length > 0 ? [{ type: "text", text }, ...content] : content;
|
|
180
|
+
}
|
|
181
|
+
const [first, ...rest] = textIndexes;
|
|
182
|
+
const dropped = new Set(rest);
|
|
183
|
+
return content.map((part, index) => index === first ? { ...part, text } : part).filter((_part, index) => !dropped.has(index));
|
|
184
|
+
}
|
|
185
|
+
function normalizeSource(source) {
|
|
186
|
+
if (!source || typeof source !== "object") return {};
|
|
187
|
+
const src = source;
|
|
188
|
+
if (src.type === "base64" && typeof src.data === "string") {
|
|
189
|
+
return {
|
|
190
|
+
sourceType: "base64",
|
|
191
|
+
mediaType: typeof src.mediaType === "string" ? src.mediaType : void 0,
|
|
192
|
+
// base64 encodes 3 bytes per 4 characters; padding makes this an upper bound.
|
|
193
|
+
approxBytes: Math.floor(src.data.length * 3 / 4)
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
if (src.type === "url" && typeof src.url === "string") {
|
|
197
|
+
return {
|
|
198
|
+
sourceType: "url",
|
|
199
|
+
url: src.url,
|
|
200
|
+
mediaType: typeof src.mediaType === "string" ? src.mediaType : void 0
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
return {};
|
|
204
|
+
}
|
|
205
|
+
function collectAttachments(content) {
|
|
206
|
+
if (!Array.isArray(content)) return [];
|
|
207
|
+
const attachments = [];
|
|
208
|
+
content.forEach((part, index) => {
|
|
209
|
+
if (!part || typeof part !== "object") return;
|
|
210
|
+
const type = part.type;
|
|
211
|
+
if (!type || type === "text") return;
|
|
212
|
+
if (type === "image" || type === "audio" || type === "video" || type === "file") {
|
|
213
|
+
attachments.push({
|
|
214
|
+
index,
|
|
215
|
+
kind: type,
|
|
216
|
+
fileName: typeof part.fileName === "string" ? part.fileName : void 0,
|
|
217
|
+
...normalizeSource(part.source)
|
|
218
|
+
});
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
if (type === "image_url") {
|
|
222
|
+
const image = part.image_url;
|
|
223
|
+
const url = typeof image === "string" ? image : image?.url;
|
|
224
|
+
if (typeof url === "string" && url.startsWith("data:")) {
|
|
225
|
+
const comma = url.indexOf(",");
|
|
226
|
+
const header = url.slice(5, comma);
|
|
227
|
+
attachments.push({
|
|
228
|
+
index,
|
|
229
|
+
kind: "image",
|
|
230
|
+
sourceType: "base64",
|
|
231
|
+
mediaType: header.split(";")[0] || void 0,
|
|
232
|
+
approxBytes: Math.floor((url.length - comma - 1) * 3 / 4)
|
|
233
|
+
});
|
|
234
|
+
} else {
|
|
235
|
+
attachments.push({ index, kind: "image", sourceType: "url", url });
|
|
236
|
+
}
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
attachments.push({ index, kind: "unknown" });
|
|
240
|
+
});
|
|
241
|
+
return attachments;
|
|
242
|
+
}
|
|
243
|
+
var MEDIA_PART_KINDS, PLACEHOLDER_LABEL_MAX;
|
|
244
|
+
var init_content = __esm({
|
|
245
|
+
"src/utils/content.ts"() {
|
|
246
|
+
MEDIA_PART_KINDS = {
|
|
247
|
+
image: "image",
|
|
248
|
+
image_url: "image",
|
|
249
|
+
input_image: "image",
|
|
250
|
+
image_file: "image",
|
|
251
|
+
audio: "audio",
|
|
252
|
+
input_audio: "audio",
|
|
253
|
+
video: "video",
|
|
254
|
+
video_url: "video",
|
|
255
|
+
file: "file",
|
|
256
|
+
input_file: "file",
|
|
257
|
+
document: "file"
|
|
258
|
+
};
|
|
259
|
+
PLACEHOLDER_LABEL_MAX = 80;
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
|
|
31
263
|
// src/utils/utilTokens.ts
|
|
32
264
|
var utilTokens_exports = {};
|
|
33
265
|
__export(utilTokens_exports, {
|
|
@@ -52,7 +284,7 @@ function getTokenCounter() {
|
|
|
52
284
|
function countApproxTokens(text) {
|
|
53
285
|
return activeTokenCounter(text || "");
|
|
54
286
|
}
|
|
55
|
-
function
|
|
287
|
+
function extractMessageText2(m) {
|
|
56
288
|
if (!m) return "";
|
|
57
289
|
const parts = [];
|
|
58
290
|
parts.push(m.role || "");
|
|
@@ -62,6 +294,7 @@ function extractMessageText(m) {
|
|
|
62
294
|
} else if (Array.isArray(m.content)) {
|
|
63
295
|
for (const c of m.content) {
|
|
64
296
|
if (typeof c === "string") parts.push(c);
|
|
297
|
+
else if (describeContentPart(c)) parts.push(describeContentPart(c));
|
|
65
298
|
else if (c?.text) parts.push(c.text);
|
|
66
299
|
else if (c?.content) parts.push(c.content);
|
|
67
300
|
else if (c?.type === "tool_use" && c?.input) {
|
|
@@ -72,7 +305,7 @@ function extractMessageText(m) {
|
|
|
72
305
|
}
|
|
73
306
|
}
|
|
74
307
|
} else if (m.content != null && typeof m.content === "object") {
|
|
75
|
-
parts.push(JSON.stringify(m.content));
|
|
308
|
+
parts.push(describeContentPart(m.content) ?? JSON.stringify(m.content));
|
|
76
309
|
}
|
|
77
310
|
if (Array.isArray(m.tool_calls)) {
|
|
78
311
|
for (const tc of m.tool_calls) {
|
|
@@ -102,12 +335,13 @@ function extractMessageText(m) {
|
|
|
102
335
|
}
|
|
103
336
|
function countMessagesTokens(messages) {
|
|
104
337
|
if (!Array.isArray(messages) || messages.length === 0) return 0;
|
|
105
|
-
const allText = messages.map(
|
|
338
|
+
const allText = messages.map(extractMessageText2).join("\n");
|
|
106
339
|
return countApproxTokens(allText) + messages.length * 4;
|
|
107
340
|
}
|
|
108
341
|
var activeTokenCounter;
|
|
109
342
|
var init_utilTokens = __esm({
|
|
110
343
|
"src/utils/utilTokens.ts"() {
|
|
344
|
+
init_content();
|
|
111
345
|
activeTokenCounter = defaultTokenCounter;
|
|
112
346
|
}
|
|
113
347
|
});
|
|
@@ -568,6 +802,125 @@ function isOpenAIHostedEndpoint(lcModel) {
|
|
|
568
802
|
}
|
|
569
803
|
}
|
|
570
804
|
|
|
805
|
+
// src/utils/abort.ts
|
|
806
|
+
var POLL_INTERVAL_MS = 100;
|
|
807
|
+
var NOOP = () => void 0;
|
|
808
|
+
function isObject(value) {
|
|
809
|
+
return value !== null && typeof value === "object";
|
|
810
|
+
}
|
|
811
|
+
function isRealSignal(value) {
|
|
812
|
+
return typeof AbortSignal !== "undefined" && value instanceof AbortSignal;
|
|
813
|
+
}
|
|
814
|
+
function isCancellationRequested(source) {
|
|
815
|
+
if (!source) return false;
|
|
816
|
+
for (const candidate of [source.signal, source.cancellationToken]) {
|
|
817
|
+
if (!isObject(candidate)) continue;
|
|
818
|
+
if (candidate.aborted === true || candidate.isCancellationRequested === true) return true;
|
|
819
|
+
}
|
|
820
|
+
return false;
|
|
821
|
+
}
|
|
822
|
+
function linkAbortSignal(source) {
|
|
823
|
+
if (!source) return { signal: void 0, dispose: NOOP };
|
|
824
|
+
const candidates = [];
|
|
825
|
+
for (const candidate of [source.signal, source.cancellationToken]) {
|
|
826
|
+
if (isObject(candidate) && !candidates.includes(candidate)) candidates.push(candidate);
|
|
827
|
+
}
|
|
828
|
+
if (candidates.length === 0) return { signal: void 0, dispose: NOOP };
|
|
829
|
+
const real = candidates.filter(isRealSignal);
|
|
830
|
+
if (candidates.length === 1 && real.length === 1) {
|
|
831
|
+
return { signal: real[0], dispose: NOOP };
|
|
832
|
+
}
|
|
833
|
+
const controller = new AbortController();
|
|
834
|
+
const cleanups = [];
|
|
835
|
+
let polled = [];
|
|
836
|
+
let timer;
|
|
837
|
+
const fire = (reason) => {
|
|
838
|
+
if (controller.signal.aborted) return;
|
|
839
|
+
try {
|
|
840
|
+
controller.abort(reason);
|
|
841
|
+
} catch {
|
|
842
|
+
controller.abort();
|
|
843
|
+
}
|
|
844
|
+
};
|
|
845
|
+
const dispose = () => {
|
|
846
|
+
if (timer !== void 0) {
|
|
847
|
+
clearInterval(timer);
|
|
848
|
+
timer = void 0;
|
|
849
|
+
}
|
|
850
|
+
polled = [];
|
|
851
|
+
for (const cleanup of cleanups.splice(0)) {
|
|
852
|
+
try {
|
|
853
|
+
cleanup();
|
|
854
|
+
} catch {
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
};
|
|
858
|
+
for (const candidate of candidates) {
|
|
859
|
+
if (candidate.aborted === true || candidate.isCancellationRequested === true) {
|
|
860
|
+
fire(isRealSignal(candidate) ? candidate.reason : void 0);
|
|
861
|
+
return { signal: controller.signal, dispose };
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
for (const candidate of candidates) {
|
|
865
|
+
if (typeof candidate.addEventListener === "function") {
|
|
866
|
+
const onAbort = () => fire(isRealSignal(candidate) ? candidate.reason : void 0);
|
|
867
|
+
candidate.addEventListener("abort", onAbort, { once: true });
|
|
868
|
+
cleanups.push(() => candidate.removeEventListener?.("abort", onAbort));
|
|
869
|
+
continue;
|
|
870
|
+
}
|
|
871
|
+
if (typeof candidate.onCancellationRequested === "function") {
|
|
872
|
+
let handle;
|
|
873
|
+
try {
|
|
874
|
+
handle = candidate.onCancellationRequested(() => fire());
|
|
875
|
+
} catch {
|
|
876
|
+
handle = void 0;
|
|
877
|
+
}
|
|
878
|
+
if (isObject(handle) && typeof handle.dispose === "function") {
|
|
879
|
+
cleanups.push(() => handle.dispose());
|
|
880
|
+
}
|
|
881
|
+
polled.push(candidate);
|
|
882
|
+
continue;
|
|
883
|
+
}
|
|
884
|
+
if ("isCancellationRequested" in candidate || "aborted" in candidate) {
|
|
885
|
+
polled.push(candidate);
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
if (polled.length > 0) {
|
|
889
|
+
timer = setInterval(() => {
|
|
890
|
+
for (const candidate of polled) {
|
|
891
|
+
if (candidate.aborted === true || candidate.isCancellationRequested === true) {
|
|
892
|
+
fire();
|
|
893
|
+
dispose();
|
|
894
|
+
return;
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
}, POLL_INTERVAL_MS);
|
|
898
|
+
timer.unref?.();
|
|
899
|
+
}
|
|
900
|
+
return { signal: controller.signal, dispose };
|
|
901
|
+
}
|
|
902
|
+
function abortableSleep(ms, signal) {
|
|
903
|
+
if (!signal) return new Promise((resolve) => setTimeout(resolve, ms));
|
|
904
|
+
if (signal.aborted) return Promise.reject(abortReason(signal));
|
|
905
|
+
return new Promise((resolve, reject) => {
|
|
906
|
+
const onAbort = () => {
|
|
907
|
+
clearTimeout(timer);
|
|
908
|
+
reject(abortReason(signal));
|
|
909
|
+
};
|
|
910
|
+
const timer = setTimeout(() => {
|
|
911
|
+
signal.removeEventListener("abort", onAbort);
|
|
912
|
+
resolve();
|
|
913
|
+
}, ms);
|
|
914
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
915
|
+
});
|
|
916
|
+
}
|
|
917
|
+
function abortReason(signal) {
|
|
918
|
+
if (signal.reason !== void 0) return signal.reason;
|
|
919
|
+
const error = new Error("This operation was aborted");
|
|
920
|
+
error.name = "AbortError";
|
|
921
|
+
return error;
|
|
922
|
+
}
|
|
923
|
+
|
|
571
924
|
// src/model.ts
|
|
572
925
|
function isSmartModel(m) {
|
|
573
926
|
return !!m && typeof m === "object" && typeof m.invoke === "function";
|
|
@@ -576,6 +929,10 @@ function withTools(model, tools, options) {
|
|
|
576
929
|
if (model?.bindTools) return model.bindTools(tools, options);
|
|
577
930
|
return model;
|
|
578
931
|
}
|
|
932
|
+
function withLinkedSignal(options, signal) {
|
|
933
|
+
if (!signal || options?.signal === signal) return options;
|
|
934
|
+
return { ...options || {}, signal };
|
|
935
|
+
}
|
|
579
936
|
function fromLangchainModel(lcModel) {
|
|
580
937
|
if (!lcModel) throw new Error("fromLangchainModel: model is undefined/null");
|
|
581
938
|
const normalizeContent = (content) => {
|
|
@@ -611,7 +968,13 @@ function fromLangchainModel(lcModel) {
|
|
|
611
968
|
const adapted = {
|
|
612
969
|
invoke: async (messages, options) => {
|
|
613
970
|
const lcMessages = messages.map(toLC);
|
|
614
|
-
const
|
|
971
|
+
const link = linkAbortSignal(options);
|
|
972
|
+
let response;
|
|
973
|
+
try {
|
|
974
|
+
response = await lcModel.invoke(lcMessages, withLinkedSignal(options, link.signal));
|
|
975
|
+
} finally {
|
|
976
|
+
link.dispose();
|
|
977
|
+
}
|
|
615
978
|
if (response && typeof response === "object") {
|
|
616
979
|
const content = response.content ?? response.text ?? "";
|
|
617
980
|
return {
|
|
@@ -629,10 +992,15 @@ function fromLangchainModel(lcModel) {
|
|
|
629
992
|
stream: async function* (messages, options) {
|
|
630
993
|
if (typeof lcModel.stream !== "function") return;
|
|
631
994
|
const lcMessages = messages.map(toLC);
|
|
632
|
-
const
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
995
|
+
const link = linkAbortSignal(options);
|
|
996
|
+
try {
|
|
997
|
+
const streamResult = lcModel.stream(lcMessages, withLinkedSignal(options, link.signal));
|
|
998
|
+
const stream = typeof streamResult?.then === "function" ? await streamResult : streamResult;
|
|
999
|
+
for await (const chunk of stream) {
|
|
1000
|
+
yield chunk;
|
|
1001
|
+
}
|
|
1002
|
+
} finally {
|
|
1003
|
+
link.dispose();
|
|
636
1004
|
}
|
|
637
1005
|
},
|
|
638
1006
|
bindTools: (tools, options) => {
|
|
@@ -811,6 +1179,9 @@ function safe(v) {
|
|
|
811
1179
|
const n = Number(v);
|
|
812
1180
|
return Number.isFinite(n) && n >= 0 ? n : 0;
|
|
813
1181
|
}
|
|
1182
|
+
|
|
1183
|
+
// src/utils/tracing.ts
|
|
1184
|
+
init_content();
|
|
814
1185
|
var DEFAULT_COGNIPEER_URL = "https://console.cognipeer.com/api/client/v1/tracing/sessions";
|
|
815
1186
|
function fileSink(path2) {
|
|
816
1187
|
return { type: "file", path: path2 };
|
|
@@ -1555,6 +1926,12 @@ function buildMessageLabel(role, index) {
|
|
|
1555
1926
|
const base = `${normalized.charAt(0).toUpperCase()}${normalized.slice(1)} Message`;
|
|
1556
1927
|
return index > 1 ? `${base} #${index}` : base;
|
|
1557
1928
|
}
|
|
1929
|
+
function structuredMessageParts(content) {
|
|
1930
|
+
if (!hasMediaPart(content)) return void 0;
|
|
1931
|
+
const cloned = sanitizeTracePayload(content);
|
|
1932
|
+
if (!Array.isArray(cloned)) return void 0;
|
|
1933
|
+
return cloned.map((part) => typeof part === "string" ? { type: "text", text: part } : part);
|
|
1934
|
+
}
|
|
1558
1935
|
function toDisplayString(value) {
|
|
1559
1936
|
const sanitized = sanitizeTracePayload(value);
|
|
1560
1937
|
if (sanitized == null) return "";
|
|
@@ -1563,7 +1940,9 @@ function toDisplayString(value) {
|
|
|
1563
1940
|
return sanitized.map((item) => toDisplayString(item)).filter((part) => part && part.trim().length > 0).join("\n");
|
|
1564
1941
|
}
|
|
1565
1942
|
if (typeof sanitized === "object") {
|
|
1566
|
-
|
|
1943
|
+
const media = describeContentPart(sanitized);
|
|
1944
|
+
if (media) return media;
|
|
1945
|
+
if (typeof sanitized.text === "string" && (Object.keys(sanitized).length === 1 || sanitized.type === "text")) {
|
|
1567
1946
|
return sanitized.text;
|
|
1568
1947
|
}
|
|
1569
1948
|
if (typeof sanitized.content === "string") {
|
|
@@ -1635,11 +2014,13 @@ function convertMessageListToSections(messageList) {
|
|
|
1635
2014
|
if (!content || !content.trim().length) continue;
|
|
1636
2015
|
}
|
|
1637
2016
|
}
|
|
2017
|
+
const parts = structuredMessageParts(message?.content);
|
|
1638
2018
|
sections.push({
|
|
1639
2019
|
kind: "message",
|
|
1640
2020
|
label: buildMessageLabel(role, next),
|
|
1641
2021
|
role,
|
|
1642
2022
|
content,
|
|
2023
|
+
...parts ? { parts } : {},
|
|
1643
2024
|
metadata: typeof message?.name === "string" ? { name: message.name } : void 0
|
|
1644
2025
|
});
|
|
1645
2026
|
}
|
|
@@ -2067,50 +2448,63 @@ function fromNativeProvider(provider, options) {
|
|
|
2067
2448
|
modelName,
|
|
2068
2449
|
capabilities: resolveCapabilities(provider.providerName),
|
|
2069
2450
|
invoke: async (messages, _invokeOptions) => {
|
|
2070
|
-
const
|
|
2071
|
-
|
|
2072
|
-
|
|
2451
|
+
const link = linkAbortSignal(_invokeOptions);
|
|
2452
|
+
try {
|
|
2453
|
+
const request = buildRequest(messages, boundTools, options, _invokeOptions);
|
|
2454
|
+
if (link.signal) request.signal = link.signal;
|
|
2455
|
+
const response = await provider.complete(request);
|
|
2456
|
+
return toBaseChatMessage(response);
|
|
2457
|
+
} finally {
|
|
2458
|
+
link.dispose();
|
|
2459
|
+
}
|
|
2073
2460
|
},
|
|
2074
2461
|
stream: async function* (messages, _invokeOptions) {
|
|
2075
|
-
const
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2462
|
+
const link = linkAbortSignal(_invokeOptions);
|
|
2463
|
+
try {
|
|
2464
|
+
const request = buildRequest(messages, boundTools, options, _invokeOptions);
|
|
2465
|
+
request.stream = true;
|
|
2466
|
+
if (link.signal) request.signal = link.signal;
|
|
2467
|
+
let fullContent = "";
|
|
2468
|
+
let allToolCalls = [];
|
|
2469
|
+
let lastUsage;
|
|
2470
|
+
let reasoningBlocks;
|
|
2471
|
+
const toolCallBuffers = /* @__PURE__ */ new Map();
|
|
2472
|
+
for await (const chunk of provider.completeStream(request)) {
|
|
2473
|
+
if (chunk.delta.content) {
|
|
2474
|
+
fullContent += chunk.delta.content;
|
|
2475
|
+
yield chunk.delta.content;
|
|
2476
|
+
}
|
|
2477
|
+
if (chunk.delta.reasoning?.blocks?.length) {
|
|
2478
|
+
reasoningBlocks = chunk.delta.reasoning.blocks;
|
|
2479
|
+
}
|
|
2480
|
+
if (chunk.delta.toolCalls) {
|
|
2481
|
+
for (const tc of chunk.delta.toolCalls) {
|
|
2482
|
+
if (tc.id) {
|
|
2483
|
+
const existing = toolCallBuffers.get(tc.id);
|
|
2484
|
+
if (existing) {
|
|
2485
|
+
if (tc.arguments) existing.arguments += tc.arguments;
|
|
2486
|
+
} else {
|
|
2487
|
+
toolCallBuffers.set(tc.id, {
|
|
2488
|
+
id: tc.id,
|
|
2489
|
+
name: tc.name ?? "",
|
|
2490
|
+
arguments: tc.arguments ?? ""
|
|
2491
|
+
});
|
|
2492
|
+
}
|
|
2102
2493
|
}
|
|
2103
2494
|
}
|
|
2104
2495
|
}
|
|
2496
|
+
if (chunk.usage) lastUsage = chunk.usage;
|
|
2105
2497
|
}
|
|
2106
|
-
if (
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2498
|
+
if (link.signal?.aborted) return;
|
|
2499
|
+
allToolCalls = [...toolCallBuffers.values()];
|
|
2500
|
+
const finalMessage = assembleMessage(fullContent, allToolCalls, lastUsage);
|
|
2501
|
+
if (reasoningBlocks?.length) {
|
|
2502
|
+
finalMessage.reasoning = { blocks: reasoningBlocks };
|
|
2503
|
+
}
|
|
2504
|
+
yield finalMessage;
|
|
2505
|
+
} finally {
|
|
2506
|
+
link.dispose();
|
|
2112
2507
|
}
|
|
2113
|
-
yield finalMessage;
|
|
2114
2508
|
},
|
|
2115
2509
|
bindTools: (tools, _bindOptions) => {
|
|
2116
2510
|
const strict = _bindOptions?.strict ?? false;
|
|
@@ -2553,157 +2947,28 @@ function resolveCapabilities(provider) {
|
|
|
2553
2947
|
};
|
|
2554
2948
|
case "bedrock":
|
|
2555
2949
|
return {
|
|
2556
|
-
structuredOutput: "tool_based",
|
|
2557
|
-
strictToolCalling: false,
|
|
2558
|
-
streaming: false,
|
|
2559
|
-
// streaming uses binary protocol
|
|
2560
|
-
provider: "bedrock"
|
|
2561
|
-
};
|
|
2562
|
-
case "vertex":
|
|
2563
|
-
return {
|
|
2564
|
-
structuredOutput: "native",
|
|
2565
|
-
strictToolCalling: false,
|
|
2566
|
-
streaming: true,
|
|
2567
|
-
provider: "google"
|
|
2568
|
-
};
|
|
2569
|
-
default:
|
|
2570
|
-
return { provider };
|
|
2571
|
-
}
|
|
2572
|
-
}
|
|
2573
|
-
|
|
2574
|
-
// src/smart/toolResponses.ts
|
|
2575
|
-
init_utilTokens();
|
|
2576
|
-
|
|
2577
|
-
// src/utils/content.ts
|
|
2578
|
-
function contentToString(content) {
|
|
2579
|
-
try {
|
|
2580
|
-
if (content == null) return "";
|
|
2581
|
-
if (typeof content === "string") return content;
|
|
2582
|
-
if (Array.isArray(content)) {
|
|
2583
|
-
return content.map((p) => {
|
|
2584
|
-
if (!p || typeof p !== "object") return String(p);
|
|
2585
|
-
if (p.type === "text") return String(p.text ?? "");
|
|
2586
|
-
if (p.type === "image_url") {
|
|
2587
|
-
const img = p.image_url;
|
|
2588
|
-
const url = typeof img === "string" ? img : img?.url;
|
|
2589
|
-
const detail = typeof img === "string" ? void 0 : img?.detail;
|
|
2590
|
-
return `[image:${url || "unknown"}${detail ? ` detail=${detail}` : ""}]`;
|
|
2591
|
-
}
|
|
2592
|
-
return JSON.stringify(p);
|
|
2593
|
-
}).join("\n");
|
|
2594
|
-
}
|
|
2595
|
-
return JSON.stringify(content);
|
|
2596
|
-
} catch {
|
|
2597
|
-
return String(content);
|
|
2598
|
-
}
|
|
2599
|
-
}
|
|
2600
|
-
function mergeContentsToString(contents) {
|
|
2601
|
-
return contents.map((c) => contentToString(c)).join("\n");
|
|
2602
|
-
}
|
|
2603
|
-
function safeStringify(value, pretty = false) {
|
|
2604
|
-
if (value == null) return "";
|
|
2605
|
-
if (typeof value === "string") return value;
|
|
2606
|
-
try {
|
|
2607
|
-
return JSON.stringify(value, null, pretty ? 2 : void 0) ?? String(value);
|
|
2608
|
-
} catch {
|
|
2609
|
-
return String(value);
|
|
2610
|
-
}
|
|
2611
|
-
}
|
|
2612
|
-
function extractMessageText2(message) {
|
|
2613
|
-
if (!message) return "";
|
|
2614
|
-
const content = message.content;
|
|
2615
|
-
if (typeof content === "string") return content;
|
|
2616
|
-
if (Array.isArray(content)) {
|
|
2617
|
-
return content.map((part) => typeof part === "string" ? part : part?.text ?? part?.content ?? "").join("");
|
|
2618
|
-
}
|
|
2619
|
-
return "";
|
|
2620
|
-
}
|
|
2621
|
-
function textFromContent(content) {
|
|
2622
|
-
if (typeof content === "string") return content;
|
|
2623
|
-
if (!Array.isArray(content)) return "";
|
|
2624
|
-
return content.filter((part) => isTextPart(part)).map((part) => part.text ?? "").join("\n");
|
|
2625
|
-
}
|
|
2626
|
-
function isTextPart(part) {
|
|
2627
|
-
return !!part && typeof part === "object" && part.type === "text";
|
|
2628
|
-
}
|
|
2629
|
-
function mapTextParts(content, fn) {
|
|
2630
|
-
if (typeof content === "string") return fn(content);
|
|
2631
|
-
if (!Array.isArray(content)) return content;
|
|
2632
|
-
return content.map((part) => isTextPart(part) ? { ...part, text: fn(part.text) } : part);
|
|
2633
|
-
}
|
|
2634
|
-
function replaceTextContent(content, text) {
|
|
2635
|
-
if (typeof content === "string" || content == null) return text;
|
|
2636
|
-
if (!Array.isArray(content)) return text;
|
|
2637
|
-
const textIndexes = content.reduce((acc, part, index) => {
|
|
2638
|
-
if (isTextPart(part)) acc.push(index);
|
|
2639
|
-
return acc;
|
|
2640
|
-
}, []);
|
|
2641
|
-
if (textIndexes.length === 0) {
|
|
2642
|
-
return text.length > 0 ? [{ type: "text", text }, ...content] : content;
|
|
2643
|
-
}
|
|
2644
|
-
const [first, ...rest] = textIndexes;
|
|
2645
|
-
const dropped = new Set(rest);
|
|
2646
|
-
return content.map((part, index) => index === first ? { ...part, text } : part).filter((_part, index) => !dropped.has(index));
|
|
2647
|
-
}
|
|
2648
|
-
function normalizeSource(source) {
|
|
2649
|
-
if (!source || typeof source !== "object") return {};
|
|
2650
|
-
const src = source;
|
|
2651
|
-
if (src.type === "base64" && typeof src.data === "string") {
|
|
2652
|
-
return {
|
|
2653
|
-
sourceType: "base64",
|
|
2654
|
-
mediaType: typeof src.mediaType === "string" ? src.mediaType : void 0,
|
|
2655
|
-
// base64 encodes 3 bytes per 4 characters; padding makes this an upper bound.
|
|
2656
|
-
approxBytes: Math.floor(src.data.length * 3 / 4)
|
|
2657
|
-
};
|
|
2658
|
-
}
|
|
2659
|
-
if (src.type === "url" && typeof src.url === "string") {
|
|
2660
|
-
return {
|
|
2661
|
-
sourceType: "url",
|
|
2662
|
-
url: src.url,
|
|
2663
|
-
mediaType: typeof src.mediaType === "string" ? src.mediaType : void 0
|
|
2664
|
-
};
|
|
2950
|
+
structuredOutput: "tool_based",
|
|
2951
|
+
strictToolCalling: false,
|
|
2952
|
+
streaming: false,
|
|
2953
|
+
// streaming uses binary protocol
|
|
2954
|
+
provider: "bedrock"
|
|
2955
|
+
};
|
|
2956
|
+
case "vertex":
|
|
2957
|
+
return {
|
|
2958
|
+
structuredOutput: "native",
|
|
2959
|
+
strictToolCalling: false,
|
|
2960
|
+
streaming: true,
|
|
2961
|
+
provider: "google"
|
|
2962
|
+
};
|
|
2963
|
+
default:
|
|
2964
|
+
return { provider };
|
|
2665
2965
|
}
|
|
2666
|
-
return {};
|
|
2667
|
-
}
|
|
2668
|
-
function collectAttachments(content) {
|
|
2669
|
-
if (!Array.isArray(content)) return [];
|
|
2670
|
-
const attachments = [];
|
|
2671
|
-
content.forEach((part, index) => {
|
|
2672
|
-
if (!part || typeof part !== "object") return;
|
|
2673
|
-
const type = part.type;
|
|
2674
|
-
if (!type || type === "text") return;
|
|
2675
|
-
if (type === "image" || type === "audio" || type === "video" || type === "file") {
|
|
2676
|
-
attachments.push({
|
|
2677
|
-
index,
|
|
2678
|
-
kind: type,
|
|
2679
|
-
fileName: typeof part.fileName === "string" ? part.fileName : void 0,
|
|
2680
|
-
...normalizeSource(part.source)
|
|
2681
|
-
});
|
|
2682
|
-
return;
|
|
2683
|
-
}
|
|
2684
|
-
if (type === "image_url") {
|
|
2685
|
-
const image = part.image_url;
|
|
2686
|
-
const url = typeof image === "string" ? image : image?.url;
|
|
2687
|
-
if (typeof url === "string" && url.startsWith("data:")) {
|
|
2688
|
-
const comma = url.indexOf(",");
|
|
2689
|
-
const header = url.slice(5, comma);
|
|
2690
|
-
attachments.push({
|
|
2691
|
-
index,
|
|
2692
|
-
kind: "image",
|
|
2693
|
-
sourceType: "base64",
|
|
2694
|
-
mediaType: header.split(";")[0] || void 0,
|
|
2695
|
-
approxBytes: Math.floor((url.length - comma - 1) * 3 / 4)
|
|
2696
|
-
});
|
|
2697
|
-
} else {
|
|
2698
|
-
attachments.push({ index, kind: "image", sourceType: "url", url });
|
|
2699
|
-
}
|
|
2700
|
-
return;
|
|
2701
|
-
}
|
|
2702
|
-
attachments.push({ index, kind: "unknown" });
|
|
2703
|
-
});
|
|
2704
|
-
return attachments;
|
|
2705
2966
|
}
|
|
2706
2967
|
|
|
2968
|
+
// src/smart/toolResponses.ts
|
|
2969
|
+
init_utilTokens();
|
|
2970
|
+
init_content();
|
|
2971
|
+
|
|
2707
2972
|
// src/smart/toolArgCoercion.ts
|
|
2708
2973
|
var PLACEHOLDER_TEXT = /* @__PURE__ */ new Set(["", "null", "undefined", "none", "nil", "n/a", "na"]);
|
|
2709
2974
|
var ENVELOPE_KEYS = ["input", "args", "arguments", "params", "parameters", "payload"];
|
|
@@ -3591,6 +3856,7 @@ function detectVolatileContent(text, limit = 20) {
|
|
|
3591
3856
|
|
|
3592
3857
|
// src/smart/contextPilot/jsonCrusher.ts
|
|
3593
3858
|
init_utilTokens();
|
|
3859
|
+
init_content();
|
|
3594
3860
|
var CONTEXT_PILOT_JSON_MARKER_KEY = "__contextPilotDropped";
|
|
3595
3861
|
function findCompressibleArray(output, minItems) {
|
|
3596
3862
|
if (Array.isArray(output)) {
|
|
@@ -3803,6 +4069,7 @@ function compressSearchOutput(text, config, ccrStore) {
|
|
|
3803
4069
|
|
|
3804
4070
|
// src/smart/contextPilot/pipeline.ts
|
|
3805
4071
|
init_utilTokens();
|
|
4072
|
+
init_content();
|
|
3806
4073
|
function createContextPilotRuntime(config) {
|
|
3807
4074
|
return {
|
|
3808
4075
|
ccrStore: new CCRStore({ ttlMs: config.ccr.ttlMs, maxEntries: config.ccr.maxEntries }),
|
|
@@ -4176,6 +4443,8 @@ function createAgentCoreNode(opts) {
|
|
|
4176
4443
|
const streamingEnabled = Boolean(state.ctx?.__streaming);
|
|
4177
4444
|
const cancellationToken = state.ctx?.__cancellationToken;
|
|
4178
4445
|
const abortSignal = state.ctx?.__abortSignal;
|
|
4446
|
+
const onProgress = state.ctx?.__onProgress;
|
|
4447
|
+
const cancelRequested = () => isCancellationRequested({ signal: abortSignal, cancellationToken });
|
|
4179
4448
|
const resolvedForCachePilot = getResolvedSmartConfig(opts, runtime);
|
|
4180
4449
|
if (resolvedForCachePilot.contextPilot.enabled && resolvedForCachePilot.contextPilot.cacheAlignment.enabled) {
|
|
4181
4450
|
const ctxForCacheWarning = state.ctx = state.ctx || {};
|
|
@@ -4334,6 +4603,29 @@ ${append}`;
|
|
|
4334
4603
|
let response;
|
|
4335
4604
|
let modelAttempt = 0;
|
|
4336
4605
|
const maxModelRetries = host?.maxModelRetries ?? 0;
|
|
4606
|
+
const finishCancelledTurn = (partialText) => {
|
|
4607
|
+
const reason = abortSignal?.aborted ? "aborted" : "cancelled";
|
|
4608
|
+
const ctx = state.ctx = state.ctx || {};
|
|
4609
|
+
ctx.__cancelled = { stage: "agent", reason, timestamp: (/* @__PURE__ */ new Date()).toISOString() };
|
|
4610
|
+
recordTraceEvent(traceSession, {
|
|
4611
|
+
type: "ai_call",
|
|
4612
|
+
label: "Assistant Cancelled",
|
|
4613
|
+
actor: { scope: "agent", name: actorName, role: "assistant", version: actorVersion },
|
|
4614
|
+
// "skipped", not "error": the call did not fail, the caller ended it —
|
|
4615
|
+
// and an "error" would flip the whole session to error.
|
|
4616
|
+
status: "skipped",
|
|
4617
|
+
durationMs: Date.now() - start,
|
|
4618
|
+
requestBytes: promptBytes,
|
|
4619
|
+
model: getModelName(runtime.model || opts.model),
|
|
4620
|
+
provider: getProviderName(runtime.model || opts.model),
|
|
4621
|
+
messageList: state.messages,
|
|
4622
|
+
toolDefinitions: traceToolDefinitions
|
|
4623
|
+
});
|
|
4624
|
+
onEvent?.({ type: "cancelled", stage: "agent", reason });
|
|
4625
|
+
onProgress?.({ stage: "agent", message: "Cancelled", detail: { reason } });
|
|
4626
|
+
const partial = partialText.trim().length > 0 ? [{ role: "assistant", content: partialText }] : [];
|
|
4627
|
+
return { messages: [...state.messages, ...partial], usage: state.usage };
|
|
4628
|
+
};
|
|
4337
4629
|
while (true) {
|
|
4338
4630
|
start = Date.now();
|
|
4339
4631
|
if (shortCircuited !== void 0) {
|
|
@@ -4349,14 +4641,16 @@ ${append}`;
|
|
|
4349
4641
|
toolDefinitions: traceToolDefinitions
|
|
4350
4642
|
});
|
|
4351
4643
|
} else {
|
|
4644
|
+
let streamedText = "";
|
|
4352
4645
|
try {
|
|
4353
4646
|
const normalizedMessages = normalizeBedrockToolPairing([...wireMessages]);
|
|
4354
4647
|
debugToolPairing(normalizedMessages);
|
|
4355
4648
|
if (streamingEnabled && typeof modelWithTools.stream === "function") {
|
|
4356
|
-
let streamedText = "";
|
|
4357
4649
|
let streamedMessage;
|
|
4650
|
+
let cutByCancel = false;
|
|
4358
4651
|
for await (const chunk of modelWithTools.stream(normalizedMessages, invokeParams)) {
|
|
4359
|
-
if (
|
|
4652
|
+
if (cancelRequested()) {
|
|
4653
|
+
cutByCancel = true;
|
|
4360
4654
|
break;
|
|
4361
4655
|
}
|
|
4362
4656
|
if (chunk && typeof chunk === "object" && chunk.role) {
|
|
@@ -4370,6 +4664,7 @@ ${append}`;
|
|
|
4370
4664
|
onEvent?.({ type: "stream", text });
|
|
4371
4665
|
}
|
|
4372
4666
|
}
|
|
4667
|
+
if (cutByCancel) return finishCancelledTurn(streamedText);
|
|
4373
4668
|
if (streamedMessage) {
|
|
4374
4669
|
response = { ...streamedMessage };
|
|
4375
4670
|
if (response.content == null || response.content === "") {
|
|
@@ -4382,6 +4677,7 @@ ${append}`;
|
|
|
4382
4677
|
response = await modelWithTools.invoke(normalizedMessages, invokeParams);
|
|
4383
4678
|
}
|
|
4384
4679
|
} catch (err) {
|
|
4680
|
+
if (cancelRequested()) return finishCancelledTurn(streamedText);
|
|
4385
4681
|
const durationMs2 = Date.now() - start;
|
|
4386
4682
|
recordTraceEvent(traceSession, {
|
|
4387
4683
|
type: "ai_call",
|
|
@@ -4479,6 +4775,7 @@ ${append}`;
|
|
|
4479
4775
|
}
|
|
4480
4776
|
|
|
4481
4777
|
// src/utils/traceSections.ts
|
|
4778
|
+
init_content();
|
|
4482
4779
|
function truncate(text, max = 500) {
|
|
4483
4780
|
if (!text) return "";
|
|
4484
4781
|
return text.length > max ? `${text.slice(0, max)}\u2026` : text;
|
|
@@ -6369,6 +6666,9 @@ function isCompactedToolContent(content) {
|
|
|
6369
6666
|
return typeof content === "string" && (content === "SUMMARIZED" || content.startsWith("SUMMARIZED_TOOL_RESPONSE") || content.startsWith("ARCHIVED_TOOL_RESPONSE") || content.startsWith("STRUCTURED_TOOL_RESPONSE") || content.startsWith("DROPPED_TOOL_RESPONSE"));
|
|
6370
6667
|
}
|
|
6371
6668
|
|
|
6669
|
+
// src/agent.ts
|
|
6670
|
+
init_content();
|
|
6671
|
+
|
|
6372
6672
|
// src/structuredOutput/manager.ts
|
|
6373
6673
|
var StructuredOutputManager = class {
|
|
6374
6674
|
constructor(schema, strategy, config) {
|
|
@@ -6601,6 +6901,7 @@ function buildSubagentCatalogBlock(subagents, policy, toolNames) {
|
|
|
6601
6901
|
}
|
|
6602
6902
|
|
|
6603
6903
|
// src/plugins/host.ts
|
|
6904
|
+
init_content();
|
|
6604
6905
|
var DEFAULT_PRIORITY = 100;
|
|
6605
6906
|
var DEFAULT_TIMEOUT_MS = 1e4;
|
|
6606
6907
|
var HOOK_SPECS = {
|
|
@@ -7137,6 +7438,7 @@ function performanceNow() {
|
|
|
7137
7438
|
}
|
|
7138
7439
|
|
|
7139
7440
|
// src/plugins/session.ts
|
|
7441
|
+
init_content();
|
|
7140
7442
|
async function openPluginSession(runHost, params) {
|
|
7141
7443
|
let messages = params.messages;
|
|
7142
7444
|
const startGate = await runHost.runGate("sessionStart", {
|
|
@@ -7606,6 +7908,7 @@ function createAgent(opts) {
|
|
|
7606
7908
|
onProgress?.({ stage: "agent", message: "Invoking model" });
|
|
7607
7909
|
if (cancelIfRequested("before_agent")) break;
|
|
7608
7910
|
state = publish({ ...state, ...await agentCore(state) });
|
|
7911
|
+
if (state.ctx?.__cancelled) break;
|
|
7609
7912
|
onProgress?.({ stage: "agent", message: "Model response received" });
|
|
7610
7913
|
if (checkpointIfRequested("after_agent")) break;
|
|
7611
7914
|
const postGuardrails = getGuardrailConfig(state);
|
|
@@ -7676,7 +7979,7 @@ function createAgent(opts) {
|
|
|
7676
7979
|
if (toolCalls.length === 0) {
|
|
7677
7980
|
if (soManager && !state.ctx?.__finalizedDueToStructuredOutput && !state.ctx?.__structuredOutputForceFinalize && !state.ctx?.__guardrailBlocked) {
|
|
7678
7981
|
if (soManager.strategy.kind === "native") {
|
|
7679
|
-
const assistantText =
|
|
7982
|
+
const assistantText = extractMessageText(lastMsg);
|
|
7680
7983
|
if (assistantText) {
|
|
7681
7984
|
const parsed = soManager.parseFromContent(assistantText);
|
|
7682
7985
|
if (parsed.success) {
|
|
@@ -7732,7 +8035,7 @@ function createAgent(opts) {
|
|
|
7732
8035
|
if (soManager && !state.ctx?.__finalizedDueToStructuredOutput && !structuredFinalizeBlocked) {
|
|
7733
8036
|
const lastForParse = state.messages[state.messages.length - 1];
|
|
7734
8037
|
if (lastForParse?.role === "assistant") {
|
|
7735
|
-
const assistantText =
|
|
8038
|
+
const assistantText = extractMessageText(lastForParse);
|
|
7736
8039
|
if (assistantText) {
|
|
7737
8040
|
const parsed = soManager.parseFromContent(assistantText);
|
|
7738
8041
|
if (parsed.success) {
|
|
@@ -7994,7 +8297,7 @@ function createAgent(opts) {
|
|
|
7994
8297
|
const isTransientSummarizationExit = !!res.ctx?.__needsSummarization;
|
|
7995
8298
|
const finalAssistantMsg = isTransientSummarizationExit ? void 0 : getLastAssistantMessage(res.messages);
|
|
7996
8299
|
const finalIsSyntheticSummary = !isTransientSummarizationExit && finalAssistantMsg && isSyntheticSummaryMessage(finalAssistantMsg);
|
|
7997
|
-
let content = isTransientSummarizationExit || finalIsSyntheticSummary ? "" :
|
|
8300
|
+
let content = isTransientSummarizationExit || finalIsSyntheticSummary ? "" : extractMessageText(finalAssistantMsg);
|
|
7998
8301
|
const finalAnswerBlocked = Boolean(
|
|
7999
8302
|
isTransientSummarizationExit || res.ctx?.__awaitingApproval || res.ctx?.__awaitingUserQuestion || res.ctx?.__cancelled || res.ctx?.__paused || res.ctx?.__limitBreached
|
|
8000
8303
|
);
|
|
@@ -8253,9 +8556,11 @@ function createAgentNode(opts) {
|
|
|
8253
8556
|
|
|
8254
8557
|
// src/nodes/contextSummarize.ts
|
|
8255
8558
|
init_utilTokens();
|
|
8559
|
+
init_content();
|
|
8256
8560
|
|
|
8257
8561
|
// src/smart/contextPolicy.ts
|
|
8258
8562
|
init_utilTokens();
|
|
8563
|
+
init_content();
|
|
8259
8564
|
function collectRecentTurns(messages, lastTurnsToKeep) {
|
|
8260
8565
|
if (lastTurnsToKeep <= 0) return [];
|
|
8261
8566
|
const systemPrefix = messages.filter((message, index) => index === 0 && message.role === "system");
|
|
@@ -8317,7 +8622,7 @@ function isClampProtected(message, index, firstUserIndex) {
|
|
|
8317
8622
|
function clampToBudget(messages, maxContextTokens) {
|
|
8318
8623
|
let working = [...messages];
|
|
8319
8624
|
while (working.length > 2) {
|
|
8320
|
-
const tokenCount = countApproxTokens(working.map(
|
|
8625
|
+
const tokenCount = countApproxTokens(working.map(extractMessageText).join("\n"));
|
|
8321
8626
|
if (tokenCount <= maxContextTokens) return working;
|
|
8322
8627
|
const firstUserIndex = working.findIndex((message) => message.role === "user");
|
|
8323
8628
|
const firstNonSystem = working.findIndex((message, index) => !isClampProtected(message, index, firstUserIndex));
|
|
@@ -8657,7 +8962,7 @@ function createContextSummarizeNode(opts) {
|
|
|
8657
8962
|
let content = "";
|
|
8658
8963
|
if (typeof m.content === "string") content = m.content;
|
|
8659
8964
|
else if (Array.isArray(m.content)) {
|
|
8660
|
-
content = m.content.map((c) => c
|
|
8965
|
+
content = m.content.map((c) => contentPartToText(c, (part) => JSON.stringify(part))).join(" ");
|
|
8661
8966
|
}
|
|
8662
8967
|
if (m.role === "tool" && isSummarizedToolPlaceholder(content)) {
|
|
8663
8968
|
const historyEntry = findToolHistoryEntry(state, m.tool_call_id, m.name);
|
|
@@ -9502,6 +9807,9 @@ async function writeSummaryFactsToMemory(store, config, summary, sourceTurn) {
|
|
|
9502
9807
|
return store.get(config.memory.scope, { limit: config.context.lastTurnsToKeep + summary.stable_facts.length });
|
|
9503
9808
|
}
|
|
9504
9809
|
|
|
9810
|
+
// src/smart/index.ts
|
|
9811
|
+
init_content();
|
|
9812
|
+
|
|
9505
9813
|
// src/smart/skills/types.ts
|
|
9506
9814
|
var DEFAULT_SKILL_POLICY = {
|
|
9507
9815
|
maxOpenSkills: 4,
|
|
@@ -10516,7 +10824,7 @@ function createSmartAgent(opts) {
|
|
|
10516
10824
|
].join("\n");
|
|
10517
10825
|
function latestUserPrompt(messages) {
|
|
10518
10826
|
const latest = [...messages].reverse().find((message) => message.role === "user");
|
|
10519
|
-
return latest ?
|
|
10827
|
+
return latest ? extractMessageText(latest) : "";
|
|
10520
10828
|
}
|
|
10521
10829
|
async function syncMemory(state) {
|
|
10522
10830
|
const query = latestUserPrompt(state.messages || []);
|
|
@@ -11227,6 +11535,132 @@ async function runSmartAgentEvalHarness(params) {
|
|
|
11227
11535
|
}
|
|
11228
11536
|
return results;
|
|
11229
11537
|
}
|
|
11538
|
+
|
|
11539
|
+
// src/providers/base.ts
|
|
11540
|
+
var DEFAULT_RETRY = {
|
|
11541
|
+
maxRetries: 3,
|
|
11542
|
+
baseDelayMs: 500,
|
|
11543
|
+
maxDelayMs: 8e3
|
|
11544
|
+
};
|
|
11545
|
+
var BaseProvider = class {
|
|
11546
|
+
constructor() {
|
|
11547
|
+
this.retryPolicy = DEFAULT_RETRY;
|
|
11548
|
+
}
|
|
11549
|
+
/**
|
|
11550
|
+
* Helper concrete providers can wrap their fetch with. Retries 429/5xx
|
|
11551
|
+
* with exponential backoff and respects Retry-After if the response
|
|
11552
|
+
* carries one.
|
|
11553
|
+
*
|
|
11554
|
+
* `signal` is the call's cancellation: a run that is cancelled while the
|
|
11555
|
+
* provider is backing off must not sit out the delay, nor start another attempt.
|
|
11556
|
+
*/
|
|
11557
|
+
async doFetchWithRetry(execute, signal) {
|
|
11558
|
+
const policy = this.retryPolicy;
|
|
11559
|
+
const maxRetries = Math.max(0, policy.maxRetries ?? DEFAULT_RETRY.maxRetries);
|
|
11560
|
+
const baseDelay = Math.max(0, policy.baseDelayMs ?? DEFAULT_RETRY.baseDelayMs);
|
|
11561
|
+
const maxDelay = Math.max(baseDelay, policy.maxDelayMs ?? DEFAULT_RETRY.maxDelayMs);
|
|
11562
|
+
let lastResp;
|
|
11563
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
11564
|
+
if (signal?.aborted) throw abortReason(signal);
|
|
11565
|
+
const res = await execute();
|
|
11566
|
+
const isRetryable = res.status === 429 || res.status >= 500 && res.status < 600;
|
|
11567
|
+
if (!isRetryable) return res;
|
|
11568
|
+
const predicate = policy.shouldRetry;
|
|
11569
|
+
if (predicate && !predicate({ status: res.status }, attempt)) return res;
|
|
11570
|
+
if (attempt === maxRetries) {
|
|
11571
|
+
lastResp = res;
|
|
11572
|
+
break;
|
|
11573
|
+
}
|
|
11574
|
+
const retryAfter = res.headers.get("retry-after");
|
|
11575
|
+
let delay2 = Math.min(maxDelay, baseDelay * Math.pow(2, attempt));
|
|
11576
|
+
if (retryAfter) {
|
|
11577
|
+
const asNumber = Number(retryAfter);
|
|
11578
|
+
if (!Number.isNaN(asNumber)) delay2 = Math.min(maxDelay, Math.max(delay2, asNumber * 1e3));
|
|
11579
|
+
}
|
|
11580
|
+
try {
|
|
11581
|
+
await res.text();
|
|
11582
|
+
} catch {
|
|
11583
|
+
}
|
|
11584
|
+
await abortableSleep(delay2, signal);
|
|
11585
|
+
}
|
|
11586
|
+
return lastResp;
|
|
11587
|
+
}
|
|
11588
|
+
};
|
|
11589
|
+
|
|
11590
|
+
// src/providers/types.ts
|
|
11591
|
+
function emptyUsage() {
|
|
11592
|
+
return {
|
|
11593
|
+
inputTokens: 0,
|
|
11594
|
+
outputTokens: 0,
|
|
11595
|
+
totalTokens: 0,
|
|
11596
|
+
cachedInputTokens: 0,
|
|
11597
|
+
cachedWriteTokens: 0,
|
|
11598
|
+
cachedOutputTokens: 0,
|
|
11599
|
+
reasoningTokens: 0
|
|
11600
|
+
};
|
|
11601
|
+
}
|
|
11602
|
+
var ProviderError = class extends Error {
|
|
11603
|
+
constructor(message, provider, statusCode, responseBody) {
|
|
11604
|
+
super(message);
|
|
11605
|
+
this.provider = provider;
|
|
11606
|
+
this.statusCode = statusCode;
|
|
11607
|
+
this.responseBody = responseBody;
|
|
11608
|
+
this.name = "ProviderError";
|
|
11609
|
+
}
|
|
11610
|
+
};
|
|
11611
|
+
|
|
11612
|
+
// src/providers/jev.ts
|
|
11613
|
+
var JEV_DEFAULT_BASE_URL = "https://api.typesafe.ai";
|
|
11614
|
+
var JevProvider = class extends BaseProvider {
|
|
11615
|
+
constructor(config) {
|
|
11616
|
+
super();
|
|
11617
|
+
this.providerName = "jev";
|
|
11618
|
+
this.apiKey = config.apiKey;
|
|
11619
|
+
this.baseURL = (config.baseURL ?? JEV_DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
11620
|
+
this.defaultModel = config.defaultModel;
|
|
11621
|
+
this.defaultHeaders = config.defaultHeaders ?? {};
|
|
11622
|
+
if (config.retry) this.retryPolicy = { ...this.retryPolicy, ...config.retry };
|
|
11623
|
+
}
|
|
11624
|
+
/** Ask System One questions about `state`. */
|
|
11625
|
+
async systemOne(request, options) {
|
|
11626
|
+
const model = request.model ?? this.defaultModel;
|
|
11627
|
+
const body = {
|
|
11628
|
+
...model ? { model } : {},
|
|
11629
|
+
state: request.state,
|
|
11630
|
+
questions: request.questions
|
|
11631
|
+
};
|
|
11632
|
+
const res = await this.doFetchWithRetry(
|
|
11633
|
+
() => fetch(`${this.baseURL}/v1/systemone`, {
|
|
11634
|
+
method: "POST",
|
|
11635
|
+
headers: {
|
|
11636
|
+
"Content-Type": "application/json",
|
|
11637
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
11638
|
+
...this.defaultHeaders
|
|
11639
|
+
},
|
|
11640
|
+
body: JSON.stringify(body),
|
|
11641
|
+
signal: options?.signal
|
|
11642
|
+
})
|
|
11643
|
+
);
|
|
11644
|
+
if (!res.ok) {
|
|
11645
|
+
const text = await res.text().catch(() => "");
|
|
11646
|
+
throw new ProviderError(`Jev API error ${res.status}: ${text}`, this.providerName, res.status, text);
|
|
11647
|
+
}
|
|
11648
|
+
return await res.json();
|
|
11649
|
+
}
|
|
11650
|
+
async complete(_request) {
|
|
11651
|
+
throw new ProviderError(
|
|
11652
|
+
'Jev is a decision model and has no chat completion; use systemOne() or agentVerdictRule({ engine: "jev" })',
|
|
11653
|
+
this.providerName
|
|
11654
|
+
);
|
|
11655
|
+
}
|
|
11656
|
+
// eslint-disable-next-line require-yield
|
|
11657
|
+
async *completeStream(_request) {
|
|
11658
|
+
throw new ProviderError("Jev does not stream; use systemOne()", this.providerName);
|
|
11659
|
+
}
|
|
11660
|
+
};
|
|
11661
|
+
|
|
11662
|
+
// src/guardrails/checks.ts
|
|
11663
|
+
init_content();
|
|
11230
11664
|
var Ajv = AjvModule__default.default?.default ?? AjvModule__default.default;
|
|
11231
11665
|
var defaultAjv = new Ajv({ allErrors: true });
|
|
11232
11666
|
defaultAjv.opts.strict = false;
|
|
@@ -11376,14 +11810,82 @@ function defaultPayload(context) {
|
|
|
11376
11810
|
2
|
|
11377
11811
|
);
|
|
11378
11812
|
}
|
|
11813
|
+
var DEFAULT_JEV_THRESHOLD = 0.5;
|
|
11814
|
+
var JEV_QUESTION_KEY = "shouldBlock";
|
|
11815
|
+
var DEFAULT_JEV_QUESTION = "Does this conversation payload pose a safety, security, or policy risk that should stop the agent from continuing? Answer yes when the latest message or action should be blocked, and no when it is safe to allow.";
|
|
11816
|
+
var DEFAULT_JEV_CRITERIA = {
|
|
11817
|
+
true: "The payload is unsafe, non-compliant, or otherwise warrants blocking.",
|
|
11818
|
+
false: "The payload is benign and the agent should be allowed to continue."
|
|
11819
|
+
};
|
|
11820
|
+
function resolveJevClient(config) {
|
|
11821
|
+
if (config.client) return config.client;
|
|
11822
|
+
const apiKey = config.apiKey ?? process.env.TYPESAFE_API_KEY;
|
|
11823
|
+
if (!apiKey) {
|
|
11824
|
+
throw new Error(
|
|
11825
|
+
"Jev engine requires an API key: pass `jev.apiKey`, set TYPESAFE_API_KEY, or pass a `jev.client`."
|
|
11826
|
+
);
|
|
11827
|
+
}
|
|
11828
|
+
return new JevProvider({
|
|
11829
|
+
provider: "jev",
|
|
11830
|
+
apiKey,
|
|
11831
|
+
baseURL: config.baseURL ?? process.env.TYPESAFE_BASE_URL
|
|
11832
|
+
});
|
|
11833
|
+
}
|
|
11379
11834
|
function agentVerdictRule(options) {
|
|
11380
11835
|
const payloadBuilder = options.payloadBuilder || defaultPayload;
|
|
11381
11836
|
const fallbackDisposition = options.dispositionFallback || "block";
|
|
11837
|
+
const engine = options.engine || "llm";
|
|
11838
|
+
const jevOptions = options.jev || {};
|
|
11839
|
+
const jevThreshold = typeof jevOptions.threshold === "number" ? jevOptions.threshold : DEFAULT_JEV_THRESHOLD;
|
|
11840
|
+
let jevClient;
|
|
11841
|
+
async function evaluateWithJev(context) {
|
|
11842
|
+
const client = jevClient ?? (jevClient = resolveJevClient(jevOptions));
|
|
11843
|
+
const instructions = jevOptions.question ? jevOptions.question(context) : DEFAULT_JEV_QUESTION;
|
|
11844
|
+
const result = await client.systemOne({
|
|
11845
|
+
state: payloadBuilder(context),
|
|
11846
|
+
questions: {
|
|
11847
|
+
[JEV_QUESTION_KEY]: {
|
|
11848
|
+
type: "noul",
|
|
11849
|
+
instructions,
|
|
11850
|
+
criteria: jevOptions.criteria ?? DEFAULT_JEV_CRITERIA
|
|
11851
|
+
}
|
|
11852
|
+
},
|
|
11853
|
+
...jevOptions.model ? { model: jevOptions.model } : {}
|
|
11854
|
+
});
|
|
11855
|
+
const answer = result?.answers?.[JEV_QUESTION_KEY];
|
|
11856
|
+
const probability = typeof answer?.noul === "number" ? answer.noul : void 0;
|
|
11857
|
+
if (probability === void 0) {
|
|
11858
|
+
return {
|
|
11859
|
+
passed: false,
|
|
11860
|
+
disposition: fallbackDisposition,
|
|
11861
|
+
reason: "Jev engine did not return a noul probability.",
|
|
11862
|
+
details: { jevModel: result?.model, jevUsage: result?.usage }
|
|
11863
|
+
};
|
|
11864
|
+
}
|
|
11865
|
+
const passed = probability < jevThreshold;
|
|
11866
|
+
return {
|
|
11867
|
+
passed,
|
|
11868
|
+
disposition: passed ? "allow" : fallbackDisposition,
|
|
11869
|
+
reason: passed ? void 0 : `Jev risk probability ${probability.toFixed(3)} met or exceeded threshold ${jevThreshold}.`,
|
|
11870
|
+
details: {
|
|
11871
|
+
jevProbability: probability,
|
|
11872
|
+
jevThreshold,
|
|
11873
|
+
jevModel: result?.model,
|
|
11874
|
+
jevUsage: result?.usage
|
|
11875
|
+
}
|
|
11876
|
+
};
|
|
11877
|
+
}
|
|
11382
11878
|
return {
|
|
11383
11879
|
id: options.id,
|
|
11384
11880
|
title: options.title || "Agent-based guardrail",
|
|
11385
11881
|
description: options.description,
|
|
11386
11882
|
async evaluate(context) {
|
|
11883
|
+
if (engine === "jev") {
|
|
11884
|
+
return evaluateWithJev(context);
|
|
11885
|
+
}
|
|
11886
|
+
if (!options.agent) {
|
|
11887
|
+
throw new Error("agentVerdictRule requires an `agent` when using the default 'llm' engine.");
|
|
11888
|
+
}
|
|
11387
11889
|
const payload = payloadBuilder(context);
|
|
11388
11890
|
const systemPrompt = options.systemPrompt || "You are a safety auditor. Review the provided conversation payload and decide whether it should continue. Return JSON with keys allow (boolean), optional disposition ('allow' | 'warn' | 'block'), optional reason (string), and optional details (object).";
|
|
11389
11891
|
const review = await options.agent.invoke({
|
|
@@ -11599,6 +12101,7 @@ function isHookImplemented(hook) {
|
|
|
11599
12101
|
}
|
|
11600
12102
|
|
|
11601
12103
|
// src/plugins/builtin/guardrail.ts
|
|
12104
|
+
init_content();
|
|
11602
12105
|
var ALLOW = { action: "allow" };
|
|
11603
12106
|
var RETRYABLE_STATUS = /* @__PURE__ */ new Set([408, 425, 429, 500, 502, 503, 504]);
|
|
11604
12107
|
var RetryableGuardrailError = class extends Error {
|
|
@@ -11885,7 +12388,7 @@ function createGuardrailPlugin(options) {
|
|
|
11885
12388
|
return { decision: "deny", reason: verdict.message ?? "Request blocked by guardrail policy." };
|
|
11886
12389
|
},
|
|
11887
12390
|
postModelCall: async ({ message }, ctx) => {
|
|
11888
|
-
const text =
|
|
12391
|
+
const text = extractMessageText(message);
|
|
11889
12392
|
if (!text) return void 0;
|
|
11890
12393
|
const verdict = await check({ phase: "output", content: text, hook: "postModelCall" }, ctx);
|
|
11891
12394
|
if (!raiseIfFailed(verdict, ctx) || verdict.action === "allow") return void 0;
|
|
@@ -12155,6 +12658,7 @@ function portkeyGuardrail(config = {}) {
|
|
|
12155
12658
|
}
|
|
12156
12659
|
|
|
12157
12660
|
// src/plugins/builtin/piiRedaction.ts
|
|
12661
|
+
init_content();
|
|
12158
12662
|
function isValidTckn(value) {
|
|
12159
12663
|
const digits = value.replace(/\D/g, "");
|
|
12160
12664
|
if (digits.length !== 11 || digits[0] === "0") return false;
|
|
@@ -12274,7 +12778,7 @@ function piiRedaction(config = {}) {
|
|
|
12274
12778
|
},
|
|
12275
12779
|
postModelCall: ({ message }, ctx) => {
|
|
12276
12780
|
if (!applied.has("modelOutput")) return void 0;
|
|
12277
|
-
const text =
|
|
12781
|
+
const text = extractMessageText(message);
|
|
12278
12782
|
if (!text) return void 0;
|
|
12279
12783
|
const result = redactText(text, detectors, mask);
|
|
12280
12784
|
if (result.findings.length === 0) return void 0;
|
|
@@ -14681,74 +15185,8 @@ function languageGuard(config) {
|
|
|
14681
15185
|
};
|
|
14682
15186
|
}
|
|
14683
15187
|
|
|
14684
|
-
// src/
|
|
14685
|
-
|
|
14686
|
-
return {
|
|
14687
|
-
inputTokens: 0,
|
|
14688
|
-
outputTokens: 0,
|
|
14689
|
-
totalTokens: 0,
|
|
14690
|
-
cachedInputTokens: 0,
|
|
14691
|
-
cachedWriteTokens: 0,
|
|
14692
|
-
cachedOutputTokens: 0,
|
|
14693
|
-
reasoningTokens: 0
|
|
14694
|
-
};
|
|
14695
|
-
}
|
|
14696
|
-
var ProviderError = class extends Error {
|
|
14697
|
-
constructor(message, provider, statusCode, responseBody) {
|
|
14698
|
-
super(message);
|
|
14699
|
-
this.provider = provider;
|
|
14700
|
-
this.statusCode = statusCode;
|
|
14701
|
-
this.responseBody = responseBody;
|
|
14702
|
-
this.name = "ProviderError";
|
|
14703
|
-
}
|
|
14704
|
-
};
|
|
14705
|
-
|
|
14706
|
-
// src/providers/base.ts
|
|
14707
|
-
var DEFAULT_RETRY = {
|
|
14708
|
-
maxRetries: 3,
|
|
14709
|
-
baseDelayMs: 500,
|
|
14710
|
-
maxDelayMs: 8e3
|
|
14711
|
-
};
|
|
14712
|
-
var BaseProvider = class {
|
|
14713
|
-
constructor() {
|
|
14714
|
-
this.retryPolicy = DEFAULT_RETRY;
|
|
14715
|
-
}
|
|
14716
|
-
/**
|
|
14717
|
-
* Helper concrete providers can wrap their fetch with. Retries 429/5xx
|
|
14718
|
-
* with exponential backoff and respects Retry-After if the response
|
|
14719
|
-
* carries one.
|
|
14720
|
-
*/
|
|
14721
|
-
async doFetchWithRetry(execute) {
|
|
14722
|
-
const policy = this.retryPolicy;
|
|
14723
|
-
const maxRetries = Math.max(0, policy.maxRetries ?? DEFAULT_RETRY.maxRetries);
|
|
14724
|
-
const baseDelay = Math.max(0, policy.baseDelayMs ?? DEFAULT_RETRY.baseDelayMs);
|
|
14725
|
-
const maxDelay = Math.max(baseDelay, policy.maxDelayMs ?? DEFAULT_RETRY.maxDelayMs);
|
|
14726
|
-
let lastResp;
|
|
14727
|
-
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
14728
|
-
const res = await execute();
|
|
14729
|
-
const isRetryable = res.status === 429 || res.status >= 500 && res.status < 600;
|
|
14730
|
-
if (!isRetryable) return res;
|
|
14731
|
-
const predicate = policy.shouldRetry;
|
|
14732
|
-
if (predicate && !predicate({ status: res.status }, attempt)) return res;
|
|
14733
|
-
if (attempt === maxRetries) {
|
|
14734
|
-
lastResp = res;
|
|
14735
|
-
break;
|
|
14736
|
-
}
|
|
14737
|
-
const retryAfter = res.headers.get("retry-after");
|
|
14738
|
-
let delay2 = Math.min(maxDelay, baseDelay * Math.pow(2, attempt));
|
|
14739
|
-
if (retryAfter) {
|
|
14740
|
-
const asNumber = Number(retryAfter);
|
|
14741
|
-
if (!Number.isNaN(asNumber)) delay2 = Math.min(maxDelay, Math.max(delay2, asNumber * 1e3));
|
|
14742
|
-
}
|
|
14743
|
-
try {
|
|
14744
|
-
await res.text();
|
|
14745
|
-
} catch {
|
|
14746
|
-
}
|
|
14747
|
-
await new Promise((r) => setTimeout(r, delay2));
|
|
14748
|
-
}
|
|
14749
|
-
return lastResp;
|
|
14750
|
-
}
|
|
14751
|
-
};
|
|
15188
|
+
// src/index.ts
|
|
15189
|
+
init_content();
|
|
14752
15190
|
|
|
14753
15191
|
// src/providers/utils/sse.ts
|
|
14754
15192
|
async function* parseSSEStream(body, signal) {
|
|
@@ -14757,7 +15195,7 @@ async function* parseSSEStream(body, signal) {
|
|
|
14757
15195
|
let buffer = "";
|
|
14758
15196
|
try {
|
|
14759
15197
|
while (true) {
|
|
14760
|
-
if (signal?.aborted) ;
|
|
15198
|
+
if (signal?.aborted) throw abortReason(signal);
|
|
14761
15199
|
const { done, value } = await reader.read();
|
|
14762
15200
|
if (done) break;
|
|
14763
15201
|
buffer += decoder.decode(value, { stream: true });
|
|
@@ -14774,6 +15212,7 @@ async function* parseSSEStream(body, signal) {
|
|
|
14774
15212
|
if (event) yield event;
|
|
14775
15213
|
}
|
|
14776
15214
|
} finally {
|
|
15215
|
+
reader.cancel().catch(() => void 0);
|
|
14777
15216
|
reader.releaseLock();
|
|
14778
15217
|
}
|
|
14779
15218
|
}
|
|
@@ -14994,12 +15433,12 @@ function sanitizeBedrockDocName(name, fallback = "document") {
|
|
|
14994
15433
|
// src/providers/utils/jsonSchemaRefs.ts
|
|
14995
15434
|
var DEFINITION_KEYS = ["definitions", "$defs"];
|
|
14996
15435
|
function inlineJsonSchemaRefs(schema) {
|
|
14997
|
-
if (!
|
|
15436
|
+
if (!isObject2(schema) || !containsRef(schema)) return schema;
|
|
14998
15437
|
const root = structuredClone(schema);
|
|
14999
15438
|
const selfReaching = /* @__PURE__ */ new Map();
|
|
15000
15439
|
const targetOf = (ref) => {
|
|
15001
15440
|
const target = resolvePointer(root, ref);
|
|
15002
|
-
return
|
|
15441
|
+
return isObject2(target) ? target : void 0;
|
|
15003
15442
|
};
|
|
15004
15443
|
const reachesItself = (target) => {
|
|
15005
15444
|
const known = selfReaching.get(target);
|
|
@@ -15007,7 +15446,7 @@ function inlineJsonSchemaRefs(schema) {
|
|
|
15007
15446
|
const seen = /* @__PURE__ */ new Set();
|
|
15008
15447
|
const walk = (node) => {
|
|
15009
15448
|
if (Array.isArray(node)) return node.some(walk);
|
|
15010
|
-
if (!
|
|
15449
|
+
if (!isObject2(node)) return false;
|
|
15011
15450
|
if (typeof node.$ref === "string") {
|
|
15012
15451
|
const next = targetOf(node.$ref);
|
|
15013
15452
|
if (next === target) return true;
|
|
@@ -15025,7 +15464,7 @@ function inlineJsonSchemaRefs(schema) {
|
|
|
15025
15464
|
const keptRefs = /* @__PURE__ */ new Set();
|
|
15026
15465
|
const expand = (node) => {
|
|
15027
15466
|
if (Array.isArray(node)) return node.map(expand);
|
|
15028
|
-
if (!
|
|
15467
|
+
if (!isObject2(node)) return node;
|
|
15029
15468
|
if (typeof node.$ref === "string") {
|
|
15030
15469
|
const target = targetOf(node.$ref);
|
|
15031
15470
|
if (target && !reachesItself(target)) {
|
|
@@ -15047,7 +15486,7 @@ function inlineJsonSchemaRefs(schema) {
|
|
|
15047
15486
|
for (const key of DEFINITION_KEYS) delete result[key];
|
|
15048
15487
|
for (const key of DEFINITION_KEYS) {
|
|
15049
15488
|
const block = root[key];
|
|
15050
|
-
if (!
|
|
15489
|
+
if (!isObject2(block)) continue;
|
|
15051
15490
|
const needed = neededEntries(key, block, keptRefs);
|
|
15052
15491
|
if (needed.length === 0) continue;
|
|
15053
15492
|
const kept = {};
|
|
@@ -15075,13 +15514,13 @@ function collectRefs(node, into) {
|
|
|
15075
15514
|
node.forEach((child) => collectRefs(child, into));
|
|
15076
15515
|
return;
|
|
15077
15516
|
}
|
|
15078
|
-
if (!
|
|
15517
|
+
if (!isObject2(node)) return;
|
|
15079
15518
|
if (typeof node.$ref === "string") into.push(node.$ref);
|
|
15080
15519
|
for (const [k, value] of Object.entries(node)) if (k !== "$ref") collectRefs(value, into);
|
|
15081
15520
|
}
|
|
15082
15521
|
function containsRef(node) {
|
|
15083
15522
|
if (Array.isArray(node)) return node.some(containsRef);
|
|
15084
|
-
if (!
|
|
15523
|
+
if (!isObject2(node)) return false;
|
|
15085
15524
|
if (typeof node.$ref === "string") return true;
|
|
15086
15525
|
return Object.values(node).some(containsRef);
|
|
15087
15526
|
}
|
|
@@ -15098,7 +15537,7 @@ function resolvePointer(document, ref) {
|
|
|
15098
15537
|
if (Array.isArray(current)) {
|
|
15099
15538
|
if (!/^\d+$/.test(segment)) return void 0;
|
|
15100
15539
|
current = current[Number(segment)];
|
|
15101
|
-
} else if (
|
|
15540
|
+
} else if (isObject2(current) && Object.prototype.hasOwnProperty.call(current, segment)) {
|
|
15102
15541
|
current = current[segment];
|
|
15103
15542
|
} else {
|
|
15104
15543
|
return void 0;
|
|
@@ -15106,7 +15545,7 @@ function resolvePointer(document, ref) {
|
|
|
15106
15545
|
}
|
|
15107
15546
|
return current;
|
|
15108
15547
|
}
|
|
15109
|
-
function
|
|
15548
|
+
function isObject2(value) {
|
|
15110
15549
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
15111
15550
|
}
|
|
15112
15551
|
|
|
@@ -15162,7 +15601,7 @@ var OpenAIProvider = class _OpenAIProvider extends BaseProvider {
|
|
|
15162
15601
|
return this.completeResponses(request);
|
|
15163
15602
|
}
|
|
15164
15603
|
const body = this.buildRequestBody(request, false);
|
|
15165
|
-
const res = await this.doFetch(body);
|
|
15604
|
+
const res = await this.doFetch(body, request.signal);
|
|
15166
15605
|
const json = await res.json();
|
|
15167
15606
|
return this.parseResponse(json);
|
|
15168
15607
|
}
|
|
@@ -15187,13 +15626,13 @@ var OpenAIProvider = class _OpenAIProvider extends BaseProvider {
|
|
|
15187
15626
|
return;
|
|
15188
15627
|
}
|
|
15189
15628
|
const body = this.buildRequestBody(request, true);
|
|
15190
|
-
const res = await this.doFetch(body);
|
|
15629
|
+
const res = await this.doFetch(body, request.signal);
|
|
15191
15630
|
if (!res.body) throw new ProviderError("No response body for stream", this.providerName);
|
|
15192
15631
|
let id = "";
|
|
15193
15632
|
let model = "";
|
|
15194
15633
|
const toolCallBuffers = /* @__PURE__ */ new Map();
|
|
15195
15634
|
let usage;
|
|
15196
|
-
for await (const event of parseSSEStream(res.body)) {
|
|
15635
|
+
for await (const event of parseSSEStream(res.body, request.signal)) {
|
|
15197
15636
|
if (event.data === "[DONE]") break;
|
|
15198
15637
|
let chunk;
|
|
15199
15638
|
try {
|
|
@@ -15288,7 +15727,7 @@ var OpenAIProvider = class _OpenAIProvider extends BaseProvider {
|
|
|
15288
15727
|
async completeResponses(request) {
|
|
15289
15728
|
const body = this.buildResponsesBody(request);
|
|
15290
15729
|
if (this.isResponsesApiModel(request)) adaptChatExtrasForResponses(body, request.extra);
|
|
15291
|
-
const res = await this.responsesFetch(body);
|
|
15730
|
+
const res = await this.responsesFetch(body, request.signal);
|
|
15292
15731
|
const json = await res.json();
|
|
15293
15732
|
return this.parseResponsesResponse(json, request.model || this.defaultModel);
|
|
15294
15733
|
}
|
|
@@ -15304,13 +15743,13 @@ var OpenAIProvider = class _OpenAIProvider extends BaseProvider {
|
|
|
15304
15743
|
const body = this.buildResponsesBody(request);
|
|
15305
15744
|
adaptChatExtrasForResponses(body, request.extra);
|
|
15306
15745
|
body.stream = true;
|
|
15307
|
-
const res = await this.responsesFetch(body);
|
|
15746
|
+
const res = await this.responsesFetch(body, request.signal);
|
|
15308
15747
|
if (!res.body) throw new ProviderError("No response body for stream", this.providerName);
|
|
15309
15748
|
let id = "";
|
|
15310
15749
|
let model = modelId;
|
|
15311
15750
|
const calls = /* @__PURE__ */ new Map();
|
|
15312
15751
|
let final;
|
|
15313
|
-
for await (const event of parseSSEStream(res.body)) {
|
|
15752
|
+
for await (const event of parseSSEStream(res.body, request.signal)) {
|
|
15314
15753
|
if (event.data === "[DONE]") break;
|
|
15315
15754
|
let data;
|
|
15316
15755
|
try {
|
|
@@ -15478,7 +15917,7 @@ var OpenAIProvider = class _OpenAIProvider extends BaseProvider {
|
|
|
15478
15917
|
});
|
|
15479
15918
|
return { role, content };
|
|
15480
15919
|
}
|
|
15481
|
-
async responsesFetch(body) {
|
|
15920
|
+
async responsesFetch(body, signal) {
|
|
15482
15921
|
body.input = expandResponsesInput(body.input);
|
|
15483
15922
|
const url = `${this.baseURL}/responses`;
|
|
15484
15923
|
const headers = {
|
|
@@ -15487,7 +15926,7 @@ var OpenAIProvider = class _OpenAIProvider extends BaseProvider {
|
|
|
15487
15926
|
...this.defaultHeaders
|
|
15488
15927
|
};
|
|
15489
15928
|
const payload = JSON.stringify(body);
|
|
15490
|
-
const res = await this.doFetchWithRetry(() => fetch(url, { method: "POST", headers, body: payload }));
|
|
15929
|
+
const res = await this.doFetchWithRetry(() => fetch(url, { method: "POST", headers, body: payload, signal }), signal);
|
|
15491
15930
|
if (!res.ok) {
|
|
15492
15931
|
const text = await res.text().catch(() => "");
|
|
15493
15932
|
throw new ProviderError(
|
|
@@ -15608,7 +16047,7 @@ var OpenAIProvider = class _OpenAIProvider extends BaseProvider {
|
|
|
15608
16047
|
}
|
|
15609
16048
|
return { type: "function", function: fn };
|
|
15610
16049
|
}
|
|
15611
|
-
async doFetch(body) {
|
|
16050
|
+
async doFetch(body, signal) {
|
|
15612
16051
|
const url = `${this.baseURL}/chat/completions`;
|
|
15613
16052
|
const headers = {
|
|
15614
16053
|
"Content-Type": "application/json",
|
|
@@ -15616,7 +16055,7 @@ var OpenAIProvider = class _OpenAIProvider extends BaseProvider {
|
|
|
15616
16055
|
...this.defaultHeaders
|
|
15617
16056
|
};
|
|
15618
16057
|
const payload = JSON.stringify(body);
|
|
15619
|
-
const res = await this.doFetchWithRetry(() => fetch(url, { method: "POST", headers, body: payload }));
|
|
16058
|
+
const res = await this.doFetchWithRetry(() => fetch(url, { method: "POST", headers, body: payload, signal }), signal);
|
|
15620
16059
|
if (!res.ok) {
|
|
15621
16060
|
const text = await res.text().catch(() => "");
|
|
15622
16061
|
throw new ProviderError(
|
|
@@ -15752,13 +16191,13 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
15752
16191
|
}
|
|
15753
16192
|
async complete(request) {
|
|
15754
16193
|
const body = this.buildRequestBody(request, false);
|
|
15755
|
-
const res = await this.doFetch(body);
|
|
16194
|
+
const res = await this.doFetch(body, request.signal);
|
|
15756
16195
|
const json = await res.json();
|
|
15757
16196
|
return this.parseResponse(json);
|
|
15758
16197
|
}
|
|
15759
16198
|
async *completeStream(request) {
|
|
15760
16199
|
const body = this.buildRequestBody(request, true);
|
|
15761
|
-
const res = await this.doFetch(body);
|
|
16200
|
+
const res = await this.doFetch(body, request.signal);
|
|
15762
16201
|
if (!res.body) throw new ProviderError("No response body for stream", this.providerName);
|
|
15763
16202
|
let id = "";
|
|
15764
16203
|
let model = "";
|
|
@@ -15768,7 +16207,7 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
15768
16207
|
let cacheCreationInputTokens = 0;
|
|
15769
16208
|
const currentToolCalls = /* @__PURE__ */ new Map();
|
|
15770
16209
|
const reasoningBlocks = /* @__PURE__ */ new Map();
|
|
15771
|
-
for await (const event of parseSSEStream(res.body)) {
|
|
16210
|
+
for await (const event of parseSSEStream(res.body, request.signal)) {
|
|
15772
16211
|
let data;
|
|
15773
16212
|
try {
|
|
15774
16213
|
data = JSON.parse(event.data);
|
|
@@ -16048,7 +16487,7 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
16048
16487
|
input_schema: t.parameters
|
|
16049
16488
|
};
|
|
16050
16489
|
}
|
|
16051
|
-
async doFetch(body) {
|
|
16490
|
+
async doFetch(body, signal) {
|
|
16052
16491
|
const url = `${this.baseURL}/v1/messages`;
|
|
16053
16492
|
const headers = {
|
|
16054
16493
|
"Content-Type": "application/json",
|
|
@@ -16057,7 +16496,7 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
16057
16496
|
...this.defaultHeaders
|
|
16058
16497
|
};
|
|
16059
16498
|
const payload = JSON.stringify(body);
|
|
16060
|
-
const res = await this.doFetchWithRetry(() => fetch(url, { method: "POST", headers, body: payload }));
|
|
16499
|
+
const res = await this.doFetchWithRetry(() => fetch(url, { method: "POST", headers, body: payload, signal }), signal);
|
|
16061
16500
|
if (!res.ok) {
|
|
16062
16501
|
const text = await res.text().catch(() => "");
|
|
16063
16502
|
throw new ProviderError(
|
|
@@ -16167,7 +16606,7 @@ var AzureProvider = class extends OpenAIProvider {
|
|
|
16167
16606
|
this.deploymentName = config.deploymentName;
|
|
16168
16607
|
this.azureApiKey = config.apiKey;
|
|
16169
16608
|
}
|
|
16170
|
-
async doFetch(body) {
|
|
16609
|
+
async doFetch(body, signal) {
|
|
16171
16610
|
const deployment = this.deploymentName ?? body.model;
|
|
16172
16611
|
if (!deployment) {
|
|
16173
16612
|
throw new ProviderError("Azure requires a deploymentName or model", this.providerName);
|
|
@@ -16181,7 +16620,8 @@ var AzureProvider = class extends OpenAIProvider {
|
|
|
16181
16620
|
"api-key": this.azureApiKey,
|
|
16182
16621
|
...this.defaultHeaders
|
|
16183
16622
|
},
|
|
16184
|
-
body: JSON.stringify(bodyWithoutModel)
|
|
16623
|
+
body: JSON.stringify(bodyWithoutModel),
|
|
16624
|
+
signal
|
|
16185
16625
|
});
|
|
16186
16626
|
if (!res.ok) {
|
|
16187
16627
|
const text = await res.text().catch(() => "");
|
|
@@ -16197,7 +16637,7 @@ var AzureProvider = class extends OpenAIProvider {
|
|
|
16197
16637
|
/** Azure exposes the Responses API at /openai/responses with api-key auth.
|
|
16198
16638
|
* Reasoning summaries require a preview api-version; callers can override via
|
|
16199
16639
|
* the `apiVersion` config. */
|
|
16200
|
-
async responsesFetch(body) {
|
|
16640
|
+
async responsesFetch(body, signal) {
|
|
16201
16641
|
body.input = expandAzureResponsesInput(body.input);
|
|
16202
16642
|
const deployment = this.deploymentName ?? body.model;
|
|
16203
16643
|
if (!deployment) {
|
|
@@ -16212,7 +16652,8 @@ var AzureProvider = class extends OpenAIProvider {
|
|
|
16212
16652
|
"api-key": this.azureApiKey,
|
|
16213
16653
|
...this.defaultHeaders
|
|
16214
16654
|
},
|
|
16215
|
-
body: payload
|
|
16655
|
+
body: payload,
|
|
16656
|
+
signal
|
|
16216
16657
|
});
|
|
16217
16658
|
if (!res.ok) {
|
|
16218
16659
|
const text = await res.text().catch(() => "");
|
|
@@ -16280,7 +16721,7 @@ var BedrockProvider = class extends BaseProvider {
|
|
|
16280
16721
|
async complete(request) {
|
|
16281
16722
|
const modelId = request.model || this.defaultModel;
|
|
16282
16723
|
const body = this.buildConverseBody(request);
|
|
16283
|
-
const json = await this.doFetch(modelId, body);
|
|
16724
|
+
const json = await this.doFetch(modelId, body, request.signal);
|
|
16284
16725
|
return this.parseResponse(json, modelId);
|
|
16285
16726
|
}
|
|
16286
16727
|
async *completeStream(request) {
|
|
@@ -16457,7 +16898,7 @@ var BedrockProvider = class extends BaseProvider {
|
|
|
16457
16898
|
}
|
|
16458
16899
|
};
|
|
16459
16900
|
}
|
|
16460
|
-
async doFetch(modelId, body) {
|
|
16901
|
+
async doFetch(modelId, body, signal) {
|
|
16461
16902
|
const host = `bedrock-runtime.${this.region}.amazonaws.com`;
|
|
16462
16903
|
const url = `https://${host}/model/${encodeURIComponent(modelId)}/converse`;
|
|
16463
16904
|
const bodyStr = JSON.stringify(body);
|
|
@@ -16475,8 +16916,8 @@ var BedrockProvider = class extends BaseProvider {
|
|
|
16475
16916
|
service: "bedrock",
|
|
16476
16917
|
credentials: this.credentials
|
|
16477
16918
|
});
|
|
16478
|
-
return fetch(url, { method: "POST", headers, body: bodyStr });
|
|
16479
|
-
});
|
|
16919
|
+
return fetch(url, { method: "POST", headers, body: bodyStr, signal });
|
|
16920
|
+
}, signal);
|
|
16480
16921
|
if (!res.ok) {
|
|
16481
16922
|
const text = await res.text().catch(() => "");
|
|
16482
16923
|
throw new ProviderError(
|
|
@@ -16609,7 +17050,7 @@ var VertexProvider = class extends BaseProvider {
|
|
|
16609
17050
|
const modelId = request.model || this.defaultModel;
|
|
16610
17051
|
const body = this.buildGeminiBody(request);
|
|
16611
17052
|
const url = this.buildUrl(modelId, false);
|
|
16612
|
-
const res = await this.doFetch(url, body);
|
|
17053
|
+
const res = await this.doFetch(url, body, request.signal);
|
|
16613
17054
|
const json = await res.json();
|
|
16614
17055
|
return this.parseResponse(json, modelId);
|
|
16615
17056
|
}
|
|
@@ -16617,11 +17058,11 @@ var VertexProvider = class extends BaseProvider {
|
|
|
16617
17058
|
const modelId = request.model || this.defaultModel;
|
|
16618
17059
|
const body = this.buildGeminiBody(request);
|
|
16619
17060
|
const url = this.buildUrl(modelId, true);
|
|
16620
|
-
const res = await this.doFetch(url, body);
|
|
17061
|
+
const res = await this.doFetch(url, body, request.signal);
|
|
16621
17062
|
if (!res.body) throw new ProviderError("No response body for stream", this.providerName);
|
|
16622
17063
|
const contentType = res.headers.get("content-type") ?? "";
|
|
16623
17064
|
if (contentType.includes("text/event-stream")) {
|
|
16624
|
-
for await (const event of parseSSEStream(res.body)) {
|
|
17065
|
+
for await (const event of parseSSEStream(res.body, request.signal)) {
|
|
16625
17066
|
if (event.data === "[DONE]") break;
|
|
16626
17067
|
let chunk;
|
|
16627
17068
|
try {
|
|
@@ -16663,6 +17104,7 @@ var VertexProvider = class extends BaseProvider {
|
|
|
16663
17104
|
}
|
|
16664
17105
|
}
|
|
16665
17106
|
} finally {
|
|
17107
|
+
reader.cancel().catch(() => void 0);
|
|
16666
17108
|
reader.releaseLock();
|
|
16667
17109
|
}
|
|
16668
17110
|
}
|
|
@@ -16874,7 +17316,7 @@ var VertexProvider = class extends BaseProvider {
|
|
|
16874
17316
|
const tokenJson = await tokenRes.json();
|
|
16875
17317
|
return tokenJson.access_token;
|
|
16876
17318
|
}
|
|
16877
|
-
async doFetch(url, body) {
|
|
17319
|
+
async doFetch(url, body, signal) {
|
|
16878
17320
|
const token = await this.getAccessToken();
|
|
16879
17321
|
const res = await fetch(url, {
|
|
16880
17322
|
method: "POST",
|
|
@@ -16883,7 +17325,8 @@ var VertexProvider = class extends BaseProvider {
|
|
|
16883
17325
|
Authorization: `Bearer ${token}`,
|
|
16884
17326
|
...this.defaultHeaders
|
|
16885
17327
|
},
|
|
16886
|
-
body: JSON.stringify(body)
|
|
17328
|
+
body: JSON.stringify(body),
|
|
17329
|
+
signal
|
|
16887
17330
|
});
|
|
16888
17331
|
if (!res.ok) {
|
|
16889
17332
|
const text = await res.text().catch(() => "");
|
|
@@ -17022,6 +17465,8 @@ function createProvider(config) {
|
|
|
17022
17465
|
return new BedrockProvider(config);
|
|
17023
17466
|
case "vertex":
|
|
17024
17467
|
return new VertexProvider(config);
|
|
17468
|
+
case "jev":
|
|
17469
|
+
return new JevProvider(config);
|
|
17025
17470
|
default:
|
|
17026
17471
|
throw new Error(`Unknown provider: ${config.provider}`);
|
|
17027
17472
|
}
|
|
@@ -17049,6 +17494,7 @@ exports.HOOK_CONTRACT_VERSION = HOOK_CONTRACT_VERSION;
|
|
|
17049
17494
|
exports.HOOK_NAMES = HOOK_NAMES;
|
|
17050
17495
|
exports.HookTimeoutError = HookTimeoutError;
|
|
17051
17496
|
exports.InMemoryMemoryStore = InMemoryMemoryStore;
|
|
17497
|
+
exports.JevProvider = JevProvider;
|
|
17052
17498
|
exports.NativeJsonSchemaStrategy = NativeJsonSchemaStrategy;
|
|
17053
17499
|
exports.OpenAICompatibleProvider = OpenAICompatibleProvider;
|
|
17054
17500
|
exports.OpenAIProvider = OpenAIProvider;
|
|
@@ -17088,6 +17534,7 @@ exports.compressLogOutput = compressLogOutput;
|
|
|
17088
17534
|
exports.compressSearchOutput = compressSearchOutput;
|
|
17089
17535
|
exports.compressTextOutput = compressTextOutput;
|
|
17090
17536
|
exports.compressToolOutput = compressToolOutput;
|
|
17537
|
+
exports.contentPartToText = contentPartToText;
|
|
17091
17538
|
exports.contentToString = contentToString;
|
|
17092
17539
|
exports.conversationHistory = conversationHistory;
|
|
17093
17540
|
exports.countApproxTokens = countApproxTokens;
|
|
@@ -17130,6 +17577,7 @@ exports.dedupeToolsByName = dedupeToolsByName;
|
|
|
17130
17577
|
exports.defaultTokenCounter = defaultTokenCounter;
|
|
17131
17578
|
exports.defineHook = defineHook;
|
|
17132
17579
|
exports.definePlugin = definePlugin;
|
|
17580
|
+
exports.describeContentPart = describeContentPart;
|
|
17133
17581
|
exports.detectLanguage = detectLanguage;
|
|
17134
17582
|
exports.detectTextFormat = detectTextFormat;
|
|
17135
17583
|
exports.detectVolatileContent = detectVolatileContent;
|
|
@@ -17138,7 +17586,7 @@ exports.digestToolInputValue = digestToolInputValue;
|
|
|
17138
17586
|
exports.emptyUsage = emptyUsage;
|
|
17139
17587
|
exports.evaluateGuardrails = evaluateGuardrails;
|
|
17140
17588
|
exports.extractLatestUserQuery = extractLatestUserQuery;
|
|
17141
|
-
exports.extractMessageText =
|
|
17589
|
+
exports.extractMessageText = extractMessageText;
|
|
17142
17590
|
exports.fileCheckpointStore = fileCheckpointStore;
|
|
17143
17591
|
exports.fileSink = fileSink;
|
|
17144
17592
|
exports.findSubagent = findSubagent;
|
|
@@ -17152,6 +17600,7 @@ exports.getModelCapabilities = getModelCapabilities;
|
|
|
17152
17600
|
exports.getNestedValue = getNestedValue;
|
|
17153
17601
|
exports.getResolvedSmartConfig = getResolvedSmartConfig;
|
|
17154
17602
|
exports.getTokenCounter = getTokenCounter;
|
|
17603
|
+
exports.hasMediaPart = hasMediaPart;
|
|
17155
17604
|
exports.hasToolResponseRecoveryReference = hasToolResponseRecoveryReference;
|
|
17156
17605
|
exports.httpGuardrail = httpGuardrail;
|
|
17157
17606
|
exports.httpSink = httpSink;
|
|
@@ -17171,6 +17620,7 @@ exports.loadSkillsFromDisk = loadSkillsFromDisk;
|
|
|
17171
17620
|
exports.mapConsoleHookVerdict = mapConsoleHookVerdict;
|
|
17172
17621
|
exports.mapTextParts = mapTextParts;
|
|
17173
17622
|
exports.mcp = mcp;
|
|
17623
|
+
exports.mediaKindOf = mediaKindOf;
|
|
17174
17624
|
exports.mediaPolicy = mediaPolicy;
|
|
17175
17625
|
exports.normalizeSmartAgentOptions = normalizeSmartAgentOptions;
|
|
17176
17626
|
exports.normalizeVerdicts = normalizeVerdicts;
|