@cognipeer/agent-sdk 0.10.4 → 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.mjs CHANGED
@@ -18,6 +18,238 @@ var __export = (target, all) => {
18
18
  __defProp(target, name, { get: all[name], enumerable: true });
19
19
  };
20
20
 
21
+ // src/utils/content.ts
22
+ function isRecord(value) {
23
+ return value !== null && typeof value === "object" && !Array.isArray(value);
24
+ }
25
+ function nonEmpty(value) {
26
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
27
+ }
28
+ function kindFromMediaType(mediaType) {
29
+ const top = mediaType?.split("/")[0];
30
+ return top === "image" || top === "audio" || top === "video" ? top : "file";
31
+ }
32
+ function inlineDataOf(part) {
33
+ const inline = part.inlineData ?? part.inline_data ?? part.fileData ?? part.file_data;
34
+ return isRecord(inline) ? inline : void 0;
35
+ }
36
+ function mediaKindOf(part) {
37
+ if (!isRecord(part)) return void 0;
38
+ const type = nonEmpty(part.type);
39
+ if (type) return MEDIA_PART_KINDS[type];
40
+ const inline = inlineDataOf(part);
41
+ if (inline) return kindFromMediaType(nonEmpty(inline.mimeType) ?? nonEmpty(inline.mime_type));
42
+ return void 0;
43
+ }
44
+ function hasMediaPart(content) {
45
+ return Array.isArray(content) && content.some((part) => mediaKindOf(part) !== void 0);
46
+ }
47
+ function urlOfPart(part) {
48
+ const image = part.image_url;
49
+ const video = part.video_url;
50
+ 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);
51
+ }
52
+ function mediaTypeOfPart(part) {
53
+ const image = isRecord(part.image_url) ? part.image_url : void 0;
54
+ const source = isRecord(part.source) ? part.source : void 0;
55
+ const inline = inlineDataOf(part);
56
+ const audioFormat = nonEmpty(part.input_audio?.format);
57
+ const fromDataUrl = /^data:([^;,]+)/i.exec(urlOfPart(part) ?? "")?.[1];
58
+ 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);
59
+ }
60
+ function nameOfPart(part) {
61
+ const file = isRecord(part.file) ? part.file : void 0;
62
+ const image = isRecord(part.image_url) ? part.image_url : void 0;
63
+ const source = isRecord(part.source) ? part.source : void 0;
64
+ 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);
65
+ }
66
+ function labelFromUrl(url) {
67
+ if (!url || url.startsWith("data:")) return void 0;
68
+ try {
69
+ const parsed = new URL(url);
70
+ if (parsed.protocol === "session-file:") return nonEmpty(parsed.hostname) ?? nonEmpty(parsed.pathname.replace(/^\/+/, ""));
71
+ if (parsed.protocol === "http:" || parsed.protocol === "https:") {
72
+ return nonEmpty(decodeURIComponent(parsed.pathname.split("/").filter(Boolean).pop() ?? ""));
73
+ }
74
+ } catch {
75
+ }
76
+ return void 0;
77
+ }
78
+ function describeContentPart(part) {
79
+ const kind = mediaKindOf(part);
80
+ if (!kind || !isRecord(part)) return void 0;
81
+ const label = nameOfPart(part) ?? mediaTypeOfPart(part) ?? labelFromUrl(urlOfPart(part));
82
+ if (!label) return `[${kind}]`;
83
+ const clean = label.replace(/[\r\n\]]+/g, " ").slice(0, PLACEHOLDER_LABEL_MAX);
84
+ return `[${kind}: ${clean}]`;
85
+ }
86
+ function contentPartToText(part, fallback) {
87
+ if (typeof part === "string") return part;
88
+ if (!isRecord(part)) return part == null ? "" : String(part);
89
+ const media = describeContentPart(part);
90
+ if (media) return media;
91
+ if (typeof part.text === "string") return part.text;
92
+ if (typeof part.content === "string") return part.content;
93
+ if (fallback) return fallback(part);
94
+ try {
95
+ return JSON.stringify(part);
96
+ } catch {
97
+ return String(part);
98
+ }
99
+ }
100
+ function contentToString(content) {
101
+ try {
102
+ if (content == null) return "";
103
+ if (typeof content === "string") return content;
104
+ if (Array.isArray(content)) {
105
+ return content.map((p) => {
106
+ if (!p || typeof p !== "object") return String(p);
107
+ if (p.type === "text") return String(p.text ?? "");
108
+ if (p.type === "image_url") {
109
+ const img = p.image_url;
110
+ const url = typeof img === "string" ? img : img?.url;
111
+ if (typeof url === "string" && /^https?:\/\//i.test(url)) {
112
+ const detail = typeof img === "string" ? void 0 : img?.detail;
113
+ return `[image:${url}${detail ? ` detail=${detail}` : ""}]`;
114
+ }
115
+ return describeContentPart(p) ?? "[image]";
116
+ }
117
+ const media = describeContentPart(p);
118
+ if (media) return media;
119
+ return JSON.stringify(p);
120
+ }).join("\n");
121
+ }
122
+ return describeContentPart(content) ?? JSON.stringify(content);
123
+ } catch {
124
+ return String(content);
125
+ }
126
+ }
127
+ function mergeContentsToString(contents) {
128
+ return contents.map((c) => contentToString(c)).join("\n");
129
+ }
130
+ function safeStringify(value, pretty = false) {
131
+ if (value == null) return "";
132
+ if (typeof value === "string") return value;
133
+ try {
134
+ return JSON.stringify(value, null, pretty ? 2 : void 0) ?? String(value);
135
+ } catch {
136
+ return String(value);
137
+ }
138
+ }
139
+ function extractMessageText(message) {
140
+ if (!message) return "";
141
+ const content = message.content;
142
+ if (typeof content === "string") return content;
143
+ if (Array.isArray(content)) {
144
+ return content.map((part) => typeof part === "string" ? part : part?.text ?? part?.content ?? "").join("");
145
+ }
146
+ return "";
147
+ }
148
+ function textFromContent(content) {
149
+ if (typeof content === "string") return content;
150
+ if (!Array.isArray(content)) return "";
151
+ return content.filter((part) => isTextPart(part)).map((part) => part.text ?? "").join("\n");
152
+ }
153
+ function isTextPart(part) {
154
+ return !!part && typeof part === "object" && part.type === "text";
155
+ }
156
+ function mapTextParts(content, fn) {
157
+ if (typeof content === "string") return fn(content);
158
+ if (!Array.isArray(content)) return content;
159
+ return content.map((part) => isTextPart(part) ? { ...part, text: fn(part.text) } : part);
160
+ }
161
+ function replaceTextContent(content, text) {
162
+ if (typeof content === "string" || content == null) return text;
163
+ if (!Array.isArray(content)) return text;
164
+ const textIndexes = content.reduce((acc, part, index) => {
165
+ if (isTextPart(part)) acc.push(index);
166
+ return acc;
167
+ }, []);
168
+ if (textIndexes.length === 0) {
169
+ return text.length > 0 ? [{ type: "text", text }, ...content] : content;
170
+ }
171
+ const [first, ...rest] = textIndexes;
172
+ const dropped = new Set(rest);
173
+ return content.map((part, index) => index === first ? { ...part, text } : part).filter((_part, index) => !dropped.has(index));
174
+ }
175
+ function normalizeSource(source) {
176
+ if (!source || typeof source !== "object") return {};
177
+ const src = source;
178
+ if (src.type === "base64" && typeof src.data === "string") {
179
+ return {
180
+ sourceType: "base64",
181
+ mediaType: typeof src.mediaType === "string" ? src.mediaType : void 0,
182
+ // base64 encodes 3 bytes per 4 characters; padding makes this an upper bound.
183
+ approxBytes: Math.floor(src.data.length * 3 / 4)
184
+ };
185
+ }
186
+ if (src.type === "url" && typeof src.url === "string") {
187
+ return {
188
+ sourceType: "url",
189
+ url: src.url,
190
+ mediaType: typeof src.mediaType === "string" ? src.mediaType : void 0
191
+ };
192
+ }
193
+ return {};
194
+ }
195
+ function collectAttachments(content) {
196
+ if (!Array.isArray(content)) return [];
197
+ const attachments = [];
198
+ content.forEach((part, index) => {
199
+ if (!part || typeof part !== "object") return;
200
+ const type = part.type;
201
+ if (!type || type === "text") return;
202
+ if (type === "image" || type === "audio" || type === "video" || type === "file") {
203
+ attachments.push({
204
+ index,
205
+ kind: type,
206
+ fileName: typeof part.fileName === "string" ? part.fileName : void 0,
207
+ ...normalizeSource(part.source)
208
+ });
209
+ return;
210
+ }
211
+ if (type === "image_url") {
212
+ const image = part.image_url;
213
+ const url = typeof image === "string" ? image : image?.url;
214
+ if (typeof url === "string" && url.startsWith("data:")) {
215
+ const comma = url.indexOf(",");
216
+ const header = url.slice(5, comma);
217
+ attachments.push({
218
+ index,
219
+ kind: "image",
220
+ sourceType: "base64",
221
+ mediaType: header.split(";")[0] || void 0,
222
+ approxBytes: Math.floor((url.length - comma - 1) * 3 / 4)
223
+ });
224
+ } else {
225
+ attachments.push({ index, kind: "image", sourceType: "url", url });
226
+ }
227
+ return;
228
+ }
229
+ attachments.push({ index, kind: "unknown" });
230
+ });
231
+ return attachments;
232
+ }
233
+ var MEDIA_PART_KINDS, PLACEHOLDER_LABEL_MAX;
234
+ var init_content = __esm({
235
+ "src/utils/content.ts"() {
236
+ MEDIA_PART_KINDS = {
237
+ image: "image",
238
+ image_url: "image",
239
+ input_image: "image",
240
+ image_file: "image",
241
+ audio: "audio",
242
+ input_audio: "audio",
243
+ video: "video",
244
+ video_url: "video",
245
+ file: "file",
246
+ input_file: "file",
247
+ document: "file"
248
+ };
249
+ PLACEHOLDER_LABEL_MAX = 80;
250
+ }
251
+ });
252
+
21
253
  // src/utils/utilTokens.ts
22
254
  var utilTokens_exports = {};
23
255
  __export(utilTokens_exports, {
@@ -42,7 +274,7 @@ function getTokenCounter() {
42
274
  function countApproxTokens(text) {
43
275
  return activeTokenCounter(text || "");
44
276
  }
45
- function extractMessageText(m) {
277
+ function extractMessageText2(m) {
46
278
  if (!m) return "";
47
279
  const parts = [];
48
280
  parts.push(m.role || "");
@@ -52,6 +284,7 @@ function extractMessageText(m) {
52
284
  } else if (Array.isArray(m.content)) {
53
285
  for (const c of m.content) {
54
286
  if (typeof c === "string") parts.push(c);
287
+ else if (describeContentPart(c)) parts.push(describeContentPart(c));
55
288
  else if (c?.text) parts.push(c.text);
56
289
  else if (c?.content) parts.push(c.content);
57
290
  else if (c?.type === "tool_use" && c?.input) {
@@ -62,7 +295,7 @@ function extractMessageText(m) {
62
295
  }
63
296
  }
64
297
  } else if (m.content != null && typeof m.content === "object") {
65
- parts.push(JSON.stringify(m.content));
298
+ parts.push(describeContentPart(m.content) ?? JSON.stringify(m.content));
66
299
  }
67
300
  if (Array.isArray(m.tool_calls)) {
68
301
  for (const tc of m.tool_calls) {
@@ -92,12 +325,13 @@ function extractMessageText(m) {
92
325
  }
93
326
  function countMessagesTokens(messages) {
94
327
  if (!Array.isArray(messages) || messages.length === 0) return 0;
95
- const allText = messages.map(extractMessageText).join("\n");
328
+ const allText = messages.map(extractMessageText2).join("\n");
96
329
  return countApproxTokens(allText) + messages.length * 4;
97
330
  }
98
331
  var activeTokenCounter;
99
332
  var init_utilTokens = __esm({
100
333
  "src/utils/utilTokens.ts"() {
334
+ init_content();
101
335
  activeTokenCounter = defaultTokenCounter;
102
336
  }
103
337
  });
@@ -558,6 +792,125 @@ function isOpenAIHostedEndpoint(lcModel) {
558
792
  }
559
793
  }
560
794
 
795
+ // src/utils/abort.ts
796
+ var POLL_INTERVAL_MS = 100;
797
+ var NOOP = () => void 0;
798
+ function isObject(value) {
799
+ return value !== null && typeof value === "object";
800
+ }
801
+ function isRealSignal(value) {
802
+ return typeof AbortSignal !== "undefined" && value instanceof AbortSignal;
803
+ }
804
+ function isCancellationRequested(source) {
805
+ if (!source) return false;
806
+ for (const candidate of [source.signal, source.cancellationToken]) {
807
+ if (!isObject(candidate)) continue;
808
+ if (candidate.aborted === true || candidate.isCancellationRequested === true) return true;
809
+ }
810
+ return false;
811
+ }
812
+ function linkAbortSignal(source) {
813
+ if (!source) return { signal: void 0, dispose: NOOP };
814
+ const candidates = [];
815
+ for (const candidate of [source.signal, source.cancellationToken]) {
816
+ if (isObject(candidate) && !candidates.includes(candidate)) candidates.push(candidate);
817
+ }
818
+ if (candidates.length === 0) return { signal: void 0, dispose: NOOP };
819
+ const real = candidates.filter(isRealSignal);
820
+ if (candidates.length === 1 && real.length === 1) {
821
+ return { signal: real[0], dispose: NOOP };
822
+ }
823
+ const controller = new AbortController();
824
+ const cleanups = [];
825
+ let polled = [];
826
+ let timer;
827
+ const fire = (reason) => {
828
+ if (controller.signal.aborted) return;
829
+ try {
830
+ controller.abort(reason);
831
+ } catch {
832
+ controller.abort();
833
+ }
834
+ };
835
+ const dispose = () => {
836
+ if (timer !== void 0) {
837
+ clearInterval(timer);
838
+ timer = void 0;
839
+ }
840
+ polled = [];
841
+ for (const cleanup of cleanups.splice(0)) {
842
+ try {
843
+ cleanup();
844
+ } catch {
845
+ }
846
+ }
847
+ };
848
+ for (const candidate of candidates) {
849
+ if (candidate.aborted === true || candidate.isCancellationRequested === true) {
850
+ fire(isRealSignal(candidate) ? candidate.reason : void 0);
851
+ return { signal: controller.signal, dispose };
852
+ }
853
+ }
854
+ for (const candidate of candidates) {
855
+ if (typeof candidate.addEventListener === "function") {
856
+ const onAbort = () => fire(isRealSignal(candidate) ? candidate.reason : void 0);
857
+ candidate.addEventListener("abort", onAbort, { once: true });
858
+ cleanups.push(() => candidate.removeEventListener?.("abort", onAbort));
859
+ continue;
860
+ }
861
+ if (typeof candidate.onCancellationRequested === "function") {
862
+ let handle;
863
+ try {
864
+ handle = candidate.onCancellationRequested(() => fire());
865
+ } catch {
866
+ handle = void 0;
867
+ }
868
+ if (isObject(handle) && typeof handle.dispose === "function") {
869
+ cleanups.push(() => handle.dispose());
870
+ }
871
+ polled.push(candidate);
872
+ continue;
873
+ }
874
+ if ("isCancellationRequested" in candidate || "aborted" in candidate) {
875
+ polled.push(candidate);
876
+ }
877
+ }
878
+ if (polled.length > 0) {
879
+ timer = setInterval(() => {
880
+ for (const candidate of polled) {
881
+ if (candidate.aborted === true || candidate.isCancellationRequested === true) {
882
+ fire();
883
+ dispose();
884
+ return;
885
+ }
886
+ }
887
+ }, POLL_INTERVAL_MS);
888
+ timer.unref?.();
889
+ }
890
+ return { signal: controller.signal, dispose };
891
+ }
892
+ function abortableSleep(ms, signal) {
893
+ if (!signal) return new Promise((resolve) => setTimeout(resolve, ms));
894
+ if (signal.aborted) return Promise.reject(abortReason(signal));
895
+ return new Promise((resolve, reject) => {
896
+ const onAbort = () => {
897
+ clearTimeout(timer);
898
+ reject(abortReason(signal));
899
+ };
900
+ const timer = setTimeout(() => {
901
+ signal.removeEventListener("abort", onAbort);
902
+ resolve();
903
+ }, ms);
904
+ signal.addEventListener("abort", onAbort, { once: true });
905
+ });
906
+ }
907
+ function abortReason(signal) {
908
+ if (signal.reason !== void 0) return signal.reason;
909
+ const error = new Error("This operation was aborted");
910
+ error.name = "AbortError";
911
+ return error;
912
+ }
913
+
561
914
  // src/model.ts
562
915
  function isSmartModel(m) {
563
916
  return !!m && typeof m === "object" && typeof m.invoke === "function";
@@ -566,6 +919,10 @@ function withTools(model, tools, options) {
566
919
  if (model?.bindTools) return model.bindTools(tools, options);
567
920
  return model;
568
921
  }
922
+ function withLinkedSignal(options, signal) {
923
+ if (!signal || options?.signal === signal) return options;
924
+ return { ...options || {}, signal };
925
+ }
569
926
  function fromLangchainModel(lcModel) {
570
927
  if (!lcModel) throw new Error("fromLangchainModel: model is undefined/null");
571
928
  const normalizeContent = (content) => {
@@ -601,7 +958,13 @@ function fromLangchainModel(lcModel) {
601
958
  const adapted = {
602
959
  invoke: async (messages, options) => {
603
960
  const lcMessages = messages.map(toLC);
604
- const response = await lcModel.invoke(lcMessages, options);
961
+ const link = linkAbortSignal(options);
962
+ let response;
963
+ try {
964
+ response = await lcModel.invoke(lcMessages, withLinkedSignal(options, link.signal));
965
+ } finally {
966
+ link.dispose();
967
+ }
605
968
  if (response && typeof response === "object") {
606
969
  const content = response.content ?? response.text ?? "";
607
970
  return {
@@ -619,10 +982,15 @@ function fromLangchainModel(lcModel) {
619
982
  stream: async function* (messages, options) {
620
983
  if (typeof lcModel.stream !== "function") return;
621
984
  const lcMessages = messages.map(toLC);
622
- const streamResult = lcModel.stream(lcMessages, options);
623
- const stream = typeof streamResult?.then === "function" ? await streamResult : streamResult;
624
- for await (const chunk of stream) {
625
- yield chunk;
985
+ const link = linkAbortSignal(options);
986
+ try {
987
+ const streamResult = lcModel.stream(lcMessages, withLinkedSignal(options, link.signal));
988
+ const stream = typeof streamResult?.then === "function" ? await streamResult : streamResult;
989
+ for await (const chunk of stream) {
990
+ yield chunk;
991
+ }
992
+ } finally {
993
+ link.dispose();
626
994
  }
627
995
  },
628
996
  bindTools: (tools, options) => {
@@ -801,6 +1169,9 @@ function safe(v) {
801
1169
  const n = Number(v);
802
1170
  return Number.isFinite(n) && n >= 0 ? n : 0;
803
1171
  }
1172
+
1173
+ // src/utils/tracing.ts
1174
+ init_content();
804
1175
  var DEFAULT_COGNIPEER_URL = "https://console.cognipeer.com/api/client/v1/tracing/sessions";
805
1176
  function fileSink(path2) {
806
1177
  return { type: "file", path: path2 };
@@ -1545,6 +1916,12 @@ function buildMessageLabel(role, index) {
1545
1916
  const base = `${normalized.charAt(0).toUpperCase()}${normalized.slice(1)} Message`;
1546
1917
  return index > 1 ? `${base} #${index}` : base;
1547
1918
  }
1919
+ function structuredMessageParts(content) {
1920
+ if (!hasMediaPart(content)) return void 0;
1921
+ const cloned = sanitizeTracePayload(content);
1922
+ if (!Array.isArray(cloned)) return void 0;
1923
+ return cloned.map((part) => typeof part === "string" ? { type: "text", text: part } : part);
1924
+ }
1548
1925
  function toDisplayString(value) {
1549
1926
  const sanitized = sanitizeTracePayload(value);
1550
1927
  if (sanitized == null) return "";
@@ -1553,7 +1930,9 @@ function toDisplayString(value) {
1553
1930
  return sanitized.map((item) => toDisplayString(item)).filter((part) => part && part.trim().length > 0).join("\n");
1554
1931
  }
1555
1932
  if (typeof sanitized === "object") {
1556
- if (typeof sanitized.text === "string" && Object.keys(sanitized).length === 1) {
1933
+ const media = describeContentPart(sanitized);
1934
+ if (media) return media;
1935
+ if (typeof sanitized.text === "string" && (Object.keys(sanitized).length === 1 || sanitized.type === "text")) {
1557
1936
  return sanitized.text;
1558
1937
  }
1559
1938
  if (typeof sanitized.content === "string") {
@@ -1625,11 +2004,13 @@ function convertMessageListToSections(messageList) {
1625
2004
  if (!content || !content.trim().length) continue;
1626
2005
  }
1627
2006
  }
2007
+ const parts = structuredMessageParts(message?.content);
1628
2008
  sections.push({
1629
2009
  kind: "message",
1630
2010
  label: buildMessageLabel(role, next),
1631
2011
  role,
1632
2012
  content,
2013
+ ...parts ? { parts } : {},
1633
2014
  metadata: typeof message?.name === "string" ? { name: message.name } : void 0
1634
2015
  });
1635
2016
  }
@@ -2057,50 +2438,63 @@ function fromNativeProvider(provider, options) {
2057
2438
  modelName,
2058
2439
  capabilities: resolveCapabilities(provider.providerName),
2059
2440
  invoke: async (messages, _invokeOptions) => {
2060
- const request = buildRequest(messages, boundTools, options, _invokeOptions);
2061
- const response = await provider.complete(request);
2062
- return toBaseChatMessage(response);
2441
+ const link = linkAbortSignal(_invokeOptions);
2442
+ try {
2443
+ const request = buildRequest(messages, boundTools, options, _invokeOptions);
2444
+ if (link.signal) request.signal = link.signal;
2445
+ const response = await provider.complete(request);
2446
+ return toBaseChatMessage(response);
2447
+ } finally {
2448
+ link.dispose();
2449
+ }
2063
2450
  },
2064
2451
  stream: async function* (messages, _invokeOptions) {
2065
- const request = buildRequest(messages, boundTools, options, _invokeOptions);
2066
- request.stream = true;
2067
- let fullContent = "";
2068
- let allToolCalls = [];
2069
- let lastUsage;
2070
- let reasoningBlocks;
2071
- const toolCallBuffers = /* @__PURE__ */ new Map();
2072
- for await (const chunk of provider.completeStream(request)) {
2073
- if (chunk.delta.content) {
2074
- fullContent += chunk.delta.content;
2075
- yield chunk.delta.content;
2076
- }
2077
- if (chunk.delta.reasoning?.blocks?.length) {
2078
- reasoningBlocks = chunk.delta.reasoning.blocks;
2079
- }
2080
- if (chunk.delta.toolCalls) {
2081
- for (const tc of chunk.delta.toolCalls) {
2082
- if (tc.id) {
2083
- const existing = toolCallBuffers.get(tc.id);
2084
- if (existing) {
2085
- if (tc.arguments) existing.arguments += tc.arguments;
2086
- } else {
2087
- toolCallBuffers.set(tc.id, {
2088
- id: tc.id,
2089
- name: tc.name ?? "",
2090
- arguments: tc.arguments ?? ""
2091
- });
2452
+ const link = linkAbortSignal(_invokeOptions);
2453
+ try {
2454
+ const request = buildRequest(messages, boundTools, options, _invokeOptions);
2455
+ request.stream = true;
2456
+ if (link.signal) request.signal = link.signal;
2457
+ let fullContent = "";
2458
+ let allToolCalls = [];
2459
+ let lastUsage;
2460
+ let reasoningBlocks;
2461
+ const toolCallBuffers = /* @__PURE__ */ new Map();
2462
+ for await (const chunk of provider.completeStream(request)) {
2463
+ if (chunk.delta.content) {
2464
+ fullContent += chunk.delta.content;
2465
+ yield chunk.delta.content;
2466
+ }
2467
+ if (chunk.delta.reasoning?.blocks?.length) {
2468
+ reasoningBlocks = chunk.delta.reasoning.blocks;
2469
+ }
2470
+ if (chunk.delta.toolCalls) {
2471
+ for (const tc of chunk.delta.toolCalls) {
2472
+ if (tc.id) {
2473
+ const existing = toolCallBuffers.get(tc.id);
2474
+ if (existing) {
2475
+ if (tc.arguments) existing.arguments += tc.arguments;
2476
+ } else {
2477
+ toolCallBuffers.set(tc.id, {
2478
+ id: tc.id,
2479
+ name: tc.name ?? "",
2480
+ arguments: tc.arguments ?? ""
2481
+ });
2482
+ }
2092
2483
  }
2093
2484
  }
2094
2485
  }
2486
+ if (chunk.usage) lastUsage = chunk.usage;
2095
2487
  }
2096
- if (chunk.usage) lastUsage = chunk.usage;
2097
- }
2098
- allToolCalls = [...toolCallBuffers.values()];
2099
- const finalMessage = assembleMessage(fullContent, allToolCalls, lastUsage);
2100
- if (reasoningBlocks?.length) {
2101
- finalMessage.reasoning = { blocks: reasoningBlocks };
2488
+ if (link.signal?.aborted) return;
2489
+ allToolCalls = [...toolCallBuffers.values()];
2490
+ const finalMessage = assembleMessage(fullContent, allToolCalls, lastUsage);
2491
+ if (reasoningBlocks?.length) {
2492
+ finalMessage.reasoning = { blocks: reasoningBlocks };
2493
+ }
2494
+ yield finalMessage;
2495
+ } finally {
2496
+ link.dispose();
2102
2497
  }
2103
- yield finalMessage;
2104
2498
  },
2105
2499
  bindTools: (tools, _bindOptions) => {
2106
2500
  const strict = _bindOptions?.strict ?? false;
@@ -2563,136 +2957,7 @@ function resolveCapabilities(provider) {
2563
2957
 
2564
2958
  // src/smart/toolResponses.ts
2565
2959
  init_utilTokens();
2566
-
2567
- // src/utils/content.ts
2568
- function contentToString(content) {
2569
- try {
2570
- if (content == null) return "";
2571
- if (typeof content === "string") return content;
2572
- if (Array.isArray(content)) {
2573
- return content.map((p) => {
2574
- if (!p || typeof p !== "object") return String(p);
2575
- if (p.type === "text") return String(p.text ?? "");
2576
- if (p.type === "image_url") {
2577
- const img = p.image_url;
2578
- const url = typeof img === "string" ? img : img?.url;
2579
- const detail = typeof img === "string" ? void 0 : img?.detail;
2580
- return `[image:${url || "unknown"}${detail ? ` detail=${detail}` : ""}]`;
2581
- }
2582
- return JSON.stringify(p);
2583
- }).join("\n");
2584
- }
2585
- return JSON.stringify(content);
2586
- } catch {
2587
- return String(content);
2588
- }
2589
- }
2590
- function mergeContentsToString(contents) {
2591
- return contents.map((c) => contentToString(c)).join("\n");
2592
- }
2593
- function safeStringify(value, pretty = false) {
2594
- if (value == null) return "";
2595
- if (typeof value === "string") return value;
2596
- try {
2597
- return JSON.stringify(value, null, pretty ? 2 : void 0) ?? String(value);
2598
- } catch {
2599
- return String(value);
2600
- }
2601
- }
2602
- function extractMessageText2(message) {
2603
- if (!message) return "";
2604
- const content = message.content;
2605
- if (typeof content === "string") return content;
2606
- if (Array.isArray(content)) {
2607
- return content.map((part) => typeof part === "string" ? part : part?.text ?? part?.content ?? "").join("");
2608
- }
2609
- return "";
2610
- }
2611
- function textFromContent(content) {
2612
- if (typeof content === "string") return content;
2613
- if (!Array.isArray(content)) return "";
2614
- return content.filter((part) => isTextPart(part)).map((part) => part.text ?? "").join("\n");
2615
- }
2616
- function isTextPart(part) {
2617
- return !!part && typeof part === "object" && part.type === "text";
2618
- }
2619
- function mapTextParts(content, fn) {
2620
- if (typeof content === "string") return fn(content);
2621
- if (!Array.isArray(content)) return content;
2622
- return content.map((part) => isTextPart(part) ? { ...part, text: fn(part.text) } : part);
2623
- }
2624
- function replaceTextContent(content, text) {
2625
- if (typeof content === "string" || content == null) return text;
2626
- if (!Array.isArray(content)) return text;
2627
- const textIndexes = content.reduce((acc, part, index) => {
2628
- if (isTextPart(part)) acc.push(index);
2629
- return acc;
2630
- }, []);
2631
- if (textIndexes.length === 0) {
2632
- return text.length > 0 ? [{ type: "text", text }, ...content] : content;
2633
- }
2634
- const [first, ...rest] = textIndexes;
2635
- const dropped = new Set(rest);
2636
- return content.map((part, index) => index === first ? { ...part, text } : part).filter((_part, index) => !dropped.has(index));
2637
- }
2638
- function normalizeSource(source) {
2639
- if (!source || typeof source !== "object") return {};
2640
- const src = source;
2641
- if (src.type === "base64" && typeof src.data === "string") {
2642
- return {
2643
- sourceType: "base64",
2644
- mediaType: typeof src.mediaType === "string" ? src.mediaType : void 0,
2645
- // base64 encodes 3 bytes per 4 characters; padding makes this an upper bound.
2646
- approxBytes: Math.floor(src.data.length * 3 / 4)
2647
- };
2648
- }
2649
- if (src.type === "url" && typeof src.url === "string") {
2650
- return {
2651
- sourceType: "url",
2652
- url: src.url,
2653
- mediaType: typeof src.mediaType === "string" ? src.mediaType : void 0
2654
- };
2655
- }
2656
- return {};
2657
- }
2658
- function collectAttachments(content) {
2659
- if (!Array.isArray(content)) return [];
2660
- const attachments = [];
2661
- content.forEach((part, index) => {
2662
- if (!part || typeof part !== "object") return;
2663
- const type = part.type;
2664
- if (!type || type === "text") return;
2665
- if (type === "image" || type === "audio" || type === "video" || type === "file") {
2666
- attachments.push({
2667
- index,
2668
- kind: type,
2669
- fileName: typeof part.fileName === "string" ? part.fileName : void 0,
2670
- ...normalizeSource(part.source)
2671
- });
2672
- return;
2673
- }
2674
- if (type === "image_url") {
2675
- const image = part.image_url;
2676
- const url = typeof image === "string" ? image : image?.url;
2677
- if (typeof url === "string" && url.startsWith("data:")) {
2678
- const comma = url.indexOf(",");
2679
- const header = url.slice(5, comma);
2680
- attachments.push({
2681
- index,
2682
- kind: "image",
2683
- sourceType: "base64",
2684
- mediaType: header.split(";")[0] || void 0,
2685
- approxBytes: Math.floor((url.length - comma - 1) * 3 / 4)
2686
- });
2687
- } else {
2688
- attachments.push({ index, kind: "image", sourceType: "url", url });
2689
- }
2690
- return;
2691
- }
2692
- attachments.push({ index, kind: "unknown" });
2693
- });
2694
- return attachments;
2695
- }
2960
+ init_content();
2696
2961
 
2697
2962
  // src/smart/toolArgCoercion.ts
2698
2963
  var PLACEHOLDER_TEXT = /* @__PURE__ */ new Set(["", "null", "undefined", "none", "nil", "n/a", "na"]);
@@ -3581,6 +3846,7 @@ function detectVolatileContent(text, limit = 20) {
3581
3846
 
3582
3847
  // src/smart/contextPilot/jsonCrusher.ts
3583
3848
  init_utilTokens();
3849
+ init_content();
3584
3850
  var CONTEXT_PILOT_JSON_MARKER_KEY = "__contextPilotDropped";
3585
3851
  function findCompressibleArray(output, minItems) {
3586
3852
  if (Array.isArray(output)) {
@@ -3793,6 +4059,7 @@ function compressSearchOutput(text, config, ccrStore) {
3793
4059
 
3794
4060
  // src/smart/contextPilot/pipeline.ts
3795
4061
  init_utilTokens();
4062
+ init_content();
3796
4063
  function createContextPilotRuntime(config) {
3797
4064
  return {
3798
4065
  ccrStore: new CCRStore({ ttlMs: config.ccr.ttlMs, maxEntries: config.ccr.maxEntries }),
@@ -4166,6 +4433,8 @@ function createAgentCoreNode(opts) {
4166
4433
  const streamingEnabled = Boolean(state.ctx?.__streaming);
4167
4434
  const cancellationToken = state.ctx?.__cancellationToken;
4168
4435
  const abortSignal = state.ctx?.__abortSignal;
4436
+ const onProgress = state.ctx?.__onProgress;
4437
+ const cancelRequested = () => isCancellationRequested({ signal: abortSignal, cancellationToken });
4169
4438
  const resolvedForCachePilot = getResolvedSmartConfig(opts, runtime);
4170
4439
  if (resolvedForCachePilot.contextPilot.enabled && resolvedForCachePilot.contextPilot.cacheAlignment.enabled) {
4171
4440
  const ctxForCacheWarning = state.ctx = state.ctx || {};
@@ -4321,9 +4590,32 @@ ${append}`;
4321
4590
  }
4322
4591
  return merged;
4323
4592
  };
4324
- let response;
4325
- let modelAttempt = 0;
4326
- const maxModelRetries = host?.maxModelRetries ?? 0;
4593
+ let response;
4594
+ let modelAttempt = 0;
4595
+ const maxModelRetries = host?.maxModelRetries ?? 0;
4596
+ const finishCancelledTurn = (partialText) => {
4597
+ const reason = abortSignal?.aborted ? "aborted" : "cancelled";
4598
+ const ctx = state.ctx = state.ctx || {};
4599
+ ctx.__cancelled = { stage: "agent", reason, timestamp: (/* @__PURE__ */ new Date()).toISOString() };
4600
+ recordTraceEvent(traceSession, {
4601
+ type: "ai_call",
4602
+ label: "Assistant Cancelled",
4603
+ actor: { scope: "agent", name: actorName, role: "assistant", version: actorVersion },
4604
+ // "skipped", not "error": the call did not fail, the caller ended it —
4605
+ // and an "error" would flip the whole session to error.
4606
+ status: "skipped",
4607
+ durationMs: Date.now() - start,
4608
+ requestBytes: promptBytes,
4609
+ model: getModelName(runtime.model || opts.model),
4610
+ provider: getProviderName(runtime.model || opts.model),
4611
+ messageList: state.messages,
4612
+ toolDefinitions: traceToolDefinitions
4613
+ });
4614
+ onEvent?.({ type: "cancelled", stage: "agent", reason });
4615
+ onProgress?.({ stage: "agent", message: "Cancelled", detail: { reason } });
4616
+ const partial = partialText.trim().length > 0 ? [{ role: "assistant", content: partialText }] : [];
4617
+ return { messages: [...state.messages, ...partial], usage: state.usage };
4618
+ };
4327
4619
  while (true) {
4328
4620
  start = Date.now();
4329
4621
  if (shortCircuited !== void 0) {
@@ -4339,14 +4631,16 @@ ${append}`;
4339
4631
  toolDefinitions: traceToolDefinitions
4340
4632
  });
4341
4633
  } else {
4634
+ let streamedText = "";
4342
4635
  try {
4343
4636
  const normalizedMessages = normalizeBedrockToolPairing([...wireMessages]);
4344
4637
  debugToolPairing(normalizedMessages);
4345
4638
  if (streamingEnabled && typeof modelWithTools.stream === "function") {
4346
- let streamedText = "";
4347
4639
  let streamedMessage;
4640
+ let cutByCancel = false;
4348
4641
  for await (const chunk of modelWithTools.stream(normalizedMessages, invokeParams)) {
4349
- if (cancellationToken && cancellationToken.isCancellationRequested || abortSignal?.aborted) {
4642
+ if (cancelRequested()) {
4643
+ cutByCancel = true;
4350
4644
  break;
4351
4645
  }
4352
4646
  if (chunk && typeof chunk === "object" && chunk.role) {
@@ -4360,6 +4654,7 @@ ${append}`;
4360
4654
  onEvent?.({ type: "stream", text });
4361
4655
  }
4362
4656
  }
4657
+ if (cutByCancel) return finishCancelledTurn(streamedText);
4363
4658
  if (streamedMessage) {
4364
4659
  response = { ...streamedMessage };
4365
4660
  if (response.content == null || response.content === "") {
@@ -4372,6 +4667,7 @@ ${append}`;
4372
4667
  response = await modelWithTools.invoke(normalizedMessages, invokeParams);
4373
4668
  }
4374
4669
  } catch (err) {
4670
+ if (cancelRequested()) return finishCancelledTurn(streamedText);
4375
4671
  const durationMs2 = Date.now() - start;
4376
4672
  recordTraceEvent(traceSession, {
4377
4673
  type: "ai_call",
@@ -4469,6 +4765,7 @@ ${append}`;
4469
4765
  }
4470
4766
 
4471
4767
  // src/utils/traceSections.ts
4768
+ init_content();
4472
4769
  function truncate(text, max = 500) {
4473
4770
  if (!text) return "";
4474
4771
  return text.length > max ? `${text.slice(0, max)}\u2026` : text;
@@ -6359,6 +6656,9 @@ function isCompactedToolContent(content) {
6359
6656
  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"));
6360
6657
  }
6361
6658
 
6659
+ // src/agent.ts
6660
+ init_content();
6661
+
6362
6662
  // src/structuredOutput/manager.ts
6363
6663
  var StructuredOutputManager = class {
6364
6664
  constructor(schema, strategy, config) {
@@ -6591,6 +6891,7 @@ function buildSubagentCatalogBlock(subagents, policy, toolNames) {
6591
6891
  }
6592
6892
 
6593
6893
  // src/plugins/host.ts
6894
+ init_content();
6594
6895
  var DEFAULT_PRIORITY = 100;
6595
6896
  var DEFAULT_TIMEOUT_MS = 1e4;
6596
6897
  var HOOK_SPECS = {
@@ -7127,6 +7428,7 @@ function performanceNow() {
7127
7428
  }
7128
7429
 
7129
7430
  // src/plugins/session.ts
7431
+ init_content();
7130
7432
  async function openPluginSession(runHost, params) {
7131
7433
  let messages = params.messages;
7132
7434
  const startGate = await runHost.runGate("sessionStart", {
@@ -7596,6 +7898,7 @@ function createAgent(opts) {
7596
7898
  onProgress?.({ stage: "agent", message: "Invoking model" });
7597
7899
  if (cancelIfRequested("before_agent")) break;
7598
7900
  state = publish({ ...state, ...await agentCore(state) });
7901
+ if (state.ctx?.__cancelled) break;
7599
7902
  onProgress?.({ stage: "agent", message: "Model response received" });
7600
7903
  if (checkpointIfRequested("after_agent")) break;
7601
7904
  const postGuardrails = getGuardrailConfig(state);
@@ -7666,7 +7969,7 @@ function createAgent(opts) {
7666
7969
  if (toolCalls.length === 0) {
7667
7970
  if (soManager && !state.ctx?.__finalizedDueToStructuredOutput && !state.ctx?.__structuredOutputForceFinalize && !state.ctx?.__guardrailBlocked) {
7668
7971
  if (soManager.strategy.kind === "native") {
7669
- const assistantText = extractMessageText2(lastMsg);
7972
+ const assistantText = extractMessageText(lastMsg);
7670
7973
  if (assistantText) {
7671
7974
  const parsed = soManager.parseFromContent(assistantText);
7672
7975
  if (parsed.success) {
@@ -7722,7 +8025,7 @@ function createAgent(opts) {
7722
8025
  if (soManager && !state.ctx?.__finalizedDueToStructuredOutput && !structuredFinalizeBlocked) {
7723
8026
  const lastForParse = state.messages[state.messages.length - 1];
7724
8027
  if (lastForParse?.role === "assistant") {
7725
- const assistantText = extractMessageText2(lastForParse);
8028
+ const assistantText = extractMessageText(lastForParse);
7726
8029
  if (assistantText) {
7727
8030
  const parsed = soManager.parseFromContent(assistantText);
7728
8031
  if (parsed.success) {
@@ -7984,7 +8287,7 @@ function createAgent(opts) {
7984
8287
  const isTransientSummarizationExit = !!res.ctx?.__needsSummarization;
7985
8288
  const finalAssistantMsg = isTransientSummarizationExit ? void 0 : getLastAssistantMessage(res.messages);
7986
8289
  const finalIsSyntheticSummary = !isTransientSummarizationExit && finalAssistantMsg && isSyntheticSummaryMessage(finalAssistantMsg);
7987
- let content = isTransientSummarizationExit || finalIsSyntheticSummary ? "" : extractMessageText2(finalAssistantMsg);
8290
+ let content = isTransientSummarizationExit || finalIsSyntheticSummary ? "" : extractMessageText(finalAssistantMsg);
7988
8291
  const finalAnswerBlocked = Boolean(
7989
8292
  isTransientSummarizationExit || res.ctx?.__awaitingApproval || res.ctx?.__awaitingUserQuestion || res.ctx?.__cancelled || res.ctx?.__paused || res.ctx?.__limitBreached
7990
8293
  );
@@ -8243,9 +8546,11 @@ function createAgentNode(opts) {
8243
8546
 
8244
8547
  // src/nodes/contextSummarize.ts
8245
8548
  init_utilTokens();
8549
+ init_content();
8246
8550
 
8247
8551
  // src/smart/contextPolicy.ts
8248
8552
  init_utilTokens();
8553
+ init_content();
8249
8554
  function collectRecentTurns(messages, lastTurnsToKeep) {
8250
8555
  if (lastTurnsToKeep <= 0) return [];
8251
8556
  const systemPrefix = messages.filter((message, index) => index === 0 && message.role === "system");
@@ -8307,7 +8612,7 @@ function isClampProtected(message, index, firstUserIndex) {
8307
8612
  function clampToBudget(messages, maxContextTokens) {
8308
8613
  let working = [...messages];
8309
8614
  while (working.length > 2) {
8310
- const tokenCount = countApproxTokens(working.map(extractMessageText2).join("\n"));
8615
+ const tokenCount = countApproxTokens(working.map(extractMessageText).join("\n"));
8311
8616
  if (tokenCount <= maxContextTokens) return working;
8312
8617
  const firstUserIndex = working.findIndex((message) => message.role === "user");
8313
8618
  const firstNonSystem = working.findIndex((message, index) => !isClampProtected(message, index, firstUserIndex));
@@ -8647,7 +8952,7 @@ function createContextSummarizeNode(opts) {
8647
8952
  let content = "";
8648
8953
  if (typeof m.content === "string") content = m.content;
8649
8954
  else if (Array.isArray(m.content)) {
8650
- content = m.content.map((c) => c.text || JSON.stringify(c)).join(" ");
8955
+ content = m.content.map((c) => contentPartToText(c, (part) => JSON.stringify(part))).join(" ");
8651
8956
  }
8652
8957
  if (m.role === "tool" && isSummarizedToolPlaceholder(content)) {
8653
8958
  const historyEntry = findToolHistoryEntry(state, m.tool_call_id, m.name);
@@ -9492,6 +9797,9 @@ async function writeSummaryFactsToMemory(store, config, summary, sourceTurn) {
9492
9797
  return store.get(config.memory.scope, { limit: config.context.lastTurnsToKeep + summary.stable_facts.length });
9493
9798
  }
9494
9799
 
9800
+ // src/smart/index.ts
9801
+ init_content();
9802
+
9495
9803
  // src/smart/skills/types.ts
9496
9804
  var DEFAULT_SKILL_POLICY = {
9497
9805
  maxOpenSkills: 4,
@@ -10506,7 +10814,7 @@ function createSmartAgent(opts) {
10506
10814
  ].join("\n");
10507
10815
  function latestUserPrompt(messages) {
10508
10816
  const latest = [...messages].reverse().find((message) => message.role === "user");
10509
- return latest ? extractMessageText2(latest) : "";
10817
+ return latest ? extractMessageText(latest) : "";
10510
10818
  }
10511
10819
  async function syncMemory(state) {
10512
10820
  const query = latestUserPrompt(state.messages || []);
@@ -11217,6 +11525,132 @@ async function runSmartAgentEvalHarness(params) {
11217
11525
  }
11218
11526
  return results;
11219
11527
  }
11528
+
11529
+ // src/providers/base.ts
11530
+ var DEFAULT_RETRY = {
11531
+ maxRetries: 3,
11532
+ baseDelayMs: 500,
11533
+ maxDelayMs: 8e3
11534
+ };
11535
+ var BaseProvider = class {
11536
+ constructor() {
11537
+ this.retryPolicy = DEFAULT_RETRY;
11538
+ }
11539
+ /**
11540
+ * Helper concrete providers can wrap their fetch with. Retries 429/5xx
11541
+ * with exponential backoff and respects Retry-After if the response
11542
+ * carries one.
11543
+ *
11544
+ * `signal` is the call's cancellation: a run that is cancelled while the
11545
+ * provider is backing off must not sit out the delay, nor start another attempt.
11546
+ */
11547
+ async doFetchWithRetry(execute, signal) {
11548
+ const policy = this.retryPolicy;
11549
+ const maxRetries = Math.max(0, policy.maxRetries ?? DEFAULT_RETRY.maxRetries);
11550
+ const baseDelay = Math.max(0, policy.baseDelayMs ?? DEFAULT_RETRY.baseDelayMs);
11551
+ const maxDelay = Math.max(baseDelay, policy.maxDelayMs ?? DEFAULT_RETRY.maxDelayMs);
11552
+ let lastResp;
11553
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
11554
+ if (signal?.aborted) throw abortReason(signal);
11555
+ const res = await execute();
11556
+ const isRetryable = res.status === 429 || res.status >= 500 && res.status < 600;
11557
+ if (!isRetryable) return res;
11558
+ const predicate = policy.shouldRetry;
11559
+ if (predicate && !predicate({ status: res.status }, attempt)) return res;
11560
+ if (attempt === maxRetries) {
11561
+ lastResp = res;
11562
+ break;
11563
+ }
11564
+ const retryAfter = res.headers.get("retry-after");
11565
+ let delay2 = Math.min(maxDelay, baseDelay * Math.pow(2, attempt));
11566
+ if (retryAfter) {
11567
+ const asNumber = Number(retryAfter);
11568
+ if (!Number.isNaN(asNumber)) delay2 = Math.min(maxDelay, Math.max(delay2, asNumber * 1e3));
11569
+ }
11570
+ try {
11571
+ await res.text();
11572
+ } catch {
11573
+ }
11574
+ await abortableSleep(delay2, signal);
11575
+ }
11576
+ return lastResp;
11577
+ }
11578
+ };
11579
+
11580
+ // src/providers/types.ts
11581
+ function emptyUsage() {
11582
+ return {
11583
+ inputTokens: 0,
11584
+ outputTokens: 0,
11585
+ totalTokens: 0,
11586
+ cachedInputTokens: 0,
11587
+ cachedWriteTokens: 0,
11588
+ cachedOutputTokens: 0,
11589
+ reasoningTokens: 0
11590
+ };
11591
+ }
11592
+ var ProviderError = class extends Error {
11593
+ constructor(message, provider, statusCode, responseBody) {
11594
+ super(message);
11595
+ this.provider = provider;
11596
+ this.statusCode = statusCode;
11597
+ this.responseBody = responseBody;
11598
+ this.name = "ProviderError";
11599
+ }
11600
+ };
11601
+
11602
+ // src/providers/jev.ts
11603
+ var JEV_DEFAULT_BASE_URL = "https://api.typesafe.ai";
11604
+ var JevProvider = class extends BaseProvider {
11605
+ constructor(config) {
11606
+ super();
11607
+ this.providerName = "jev";
11608
+ this.apiKey = config.apiKey;
11609
+ this.baseURL = (config.baseURL ?? JEV_DEFAULT_BASE_URL).replace(/\/$/, "");
11610
+ this.defaultModel = config.defaultModel;
11611
+ this.defaultHeaders = config.defaultHeaders ?? {};
11612
+ if (config.retry) this.retryPolicy = { ...this.retryPolicy, ...config.retry };
11613
+ }
11614
+ /** Ask System One questions about `state`. */
11615
+ async systemOne(request, options) {
11616
+ const model = request.model ?? this.defaultModel;
11617
+ const body = {
11618
+ ...model ? { model } : {},
11619
+ state: request.state,
11620
+ questions: request.questions
11621
+ };
11622
+ const res = await this.doFetchWithRetry(
11623
+ () => fetch(`${this.baseURL}/v1/systemone`, {
11624
+ method: "POST",
11625
+ headers: {
11626
+ "Content-Type": "application/json",
11627
+ Authorization: `Bearer ${this.apiKey}`,
11628
+ ...this.defaultHeaders
11629
+ },
11630
+ body: JSON.stringify(body),
11631
+ signal: options?.signal
11632
+ })
11633
+ );
11634
+ if (!res.ok) {
11635
+ const text = await res.text().catch(() => "");
11636
+ throw new ProviderError(`Jev API error ${res.status}: ${text}`, this.providerName, res.status, text);
11637
+ }
11638
+ return await res.json();
11639
+ }
11640
+ async complete(_request) {
11641
+ throw new ProviderError(
11642
+ 'Jev is a decision model and has no chat completion; use systemOne() or agentVerdictRule({ engine: "jev" })',
11643
+ this.providerName
11644
+ );
11645
+ }
11646
+ // eslint-disable-next-line require-yield
11647
+ async *completeStream(_request) {
11648
+ throw new ProviderError("Jev does not stream; use systemOne()", this.providerName);
11649
+ }
11650
+ };
11651
+
11652
+ // src/guardrails/checks.ts
11653
+ init_content();
11220
11654
  var Ajv = AjvModule?.default ?? AjvModule;
11221
11655
  var defaultAjv = new Ajv({ allErrors: true });
11222
11656
  defaultAjv.opts.strict = false;
@@ -11366,14 +11800,82 @@ function defaultPayload(context) {
11366
11800
  2
11367
11801
  );
11368
11802
  }
11803
+ var DEFAULT_JEV_THRESHOLD = 0.5;
11804
+ var JEV_QUESTION_KEY = "shouldBlock";
11805
+ 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.";
11806
+ var DEFAULT_JEV_CRITERIA = {
11807
+ true: "The payload is unsafe, non-compliant, or otherwise warrants blocking.",
11808
+ false: "The payload is benign and the agent should be allowed to continue."
11809
+ };
11810
+ function resolveJevClient(config) {
11811
+ if (config.client) return config.client;
11812
+ const apiKey = config.apiKey ?? process.env.TYPESAFE_API_KEY;
11813
+ if (!apiKey) {
11814
+ throw new Error(
11815
+ "Jev engine requires an API key: pass `jev.apiKey`, set TYPESAFE_API_KEY, or pass a `jev.client`."
11816
+ );
11817
+ }
11818
+ return new JevProvider({
11819
+ provider: "jev",
11820
+ apiKey,
11821
+ baseURL: config.baseURL ?? process.env.TYPESAFE_BASE_URL
11822
+ });
11823
+ }
11369
11824
  function agentVerdictRule(options) {
11370
11825
  const payloadBuilder = options.payloadBuilder || defaultPayload;
11371
11826
  const fallbackDisposition = options.dispositionFallback || "block";
11827
+ const engine = options.engine || "llm";
11828
+ const jevOptions = options.jev || {};
11829
+ const jevThreshold = typeof jevOptions.threshold === "number" ? jevOptions.threshold : DEFAULT_JEV_THRESHOLD;
11830
+ let jevClient;
11831
+ async function evaluateWithJev(context) {
11832
+ const client = jevClient ?? (jevClient = resolveJevClient(jevOptions));
11833
+ const instructions = jevOptions.question ? jevOptions.question(context) : DEFAULT_JEV_QUESTION;
11834
+ const result = await client.systemOne({
11835
+ state: payloadBuilder(context),
11836
+ questions: {
11837
+ [JEV_QUESTION_KEY]: {
11838
+ type: "noul",
11839
+ instructions,
11840
+ criteria: jevOptions.criteria ?? DEFAULT_JEV_CRITERIA
11841
+ }
11842
+ },
11843
+ ...jevOptions.model ? { model: jevOptions.model } : {}
11844
+ });
11845
+ const answer = result?.answers?.[JEV_QUESTION_KEY];
11846
+ const probability = typeof answer?.noul === "number" ? answer.noul : void 0;
11847
+ if (probability === void 0) {
11848
+ return {
11849
+ passed: false,
11850
+ disposition: fallbackDisposition,
11851
+ reason: "Jev engine did not return a noul probability.",
11852
+ details: { jevModel: result?.model, jevUsage: result?.usage }
11853
+ };
11854
+ }
11855
+ const passed = probability < jevThreshold;
11856
+ return {
11857
+ passed,
11858
+ disposition: passed ? "allow" : fallbackDisposition,
11859
+ reason: passed ? void 0 : `Jev risk probability ${probability.toFixed(3)} met or exceeded threshold ${jevThreshold}.`,
11860
+ details: {
11861
+ jevProbability: probability,
11862
+ jevThreshold,
11863
+ jevModel: result?.model,
11864
+ jevUsage: result?.usage
11865
+ }
11866
+ };
11867
+ }
11372
11868
  return {
11373
11869
  id: options.id,
11374
11870
  title: options.title || "Agent-based guardrail",
11375
11871
  description: options.description,
11376
11872
  async evaluate(context) {
11873
+ if (engine === "jev") {
11874
+ return evaluateWithJev(context);
11875
+ }
11876
+ if (!options.agent) {
11877
+ throw new Error("agentVerdictRule requires an `agent` when using the default 'llm' engine.");
11878
+ }
11377
11879
  const payload = payloadBuilder(context);
11378
11880
  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).";
11379
11881
  const review = await options.agent.invoke({
@@ -11589,6 +12091,7 @@ function isHookImplemented(hook) {
11589
12091
  }
11590
12092
 
11591
12093
  // src/plugins/builtin/guardrail.ts
12094
+ init_content();
11592
12095
  var ALLOW = { action: "allow" };
11593
12096
  var RETRYABLE_STATUS = /* @__PURE__ */ new Set([408, 425, 429, 500, 502, 503, 504]);
11594
12097
  var RetryableGuardrailError = class extends Error {
@@ -11875,7 +12378,7 @@ function createGuardrailPlugin(options) {
11875
12378
  return { decision: "deny", reason: verdict.message ?? "Request blocked by guardrail policy." };
11876
12379
  },
11877
12380
  postModelCall: async ({ message }, ctx) => {
11878
- const text = extractMessageText2(message);
12381
+ const text = extractMessageText(message);
11879
12382
  if (!text) return void 0;
11880
12383
  const verdict = await check({ phase: "output", content: text, hook: "postModelCall" }, ctx);
11881
12384
  if (!raiseIfFailed(verdict, ctx) || verdict.action === "allow") return void 0;
@@ -12145,6 +12648,7 @@ function portkeyGuardrail(config = {}) {
12145
12648
  }
12146
12649
 
12147
12650
  // src/plugins/builtin/piiRedaction.ts
12651
+ init_content();
12148
12652
  function isValidTckn(value) {
12149
12653
  const digits = value.replace(/\D/g, "");
12150
12654
  if (digits.length !== 11 || digits[0] === "0") return false;
@@ -12264,7 +12768,7 @@ function piiRedaction(config = {}) {
12264
12768
  },
12265
12769
  postModelCall: ({ message }, ctx) => {
12266
12770
  if (!applied.has("modelOutput")) return void 0;
12267
- const text = extractMessageText2(message);
12771
+ const text = extractMessageText(message);
12268
12772
  if (!text) return void 0;
12269
12773
  const result = redactText(text, detectors, mask);
12270
12774
  if (result.findings.length === 0) return void 0;
@@ -14671,74 +15175,8 @@ function languageGuard(config) {
14671
15175
  };
14672
15176
  }
14673
15177
 
14674
- // src/providers/types.ts
14675
- function emptyUsage() {
14676
- return {
14677
- inputTokens: 0,
14678
- outputTokens: 0,
14679
- totalTokens: 0,
14680
- cachedInputTokens: 0,
14681
- cachedWriteTokens: 0,
14682
- cachedOutputTokens: 0,
14683
- reasoningTokens: 0
14684
- };
14685
- }
14686
- var ProviderError = class extends Error {
14687
- constructor(message, provider, statusCode, responseBody) {
14688
- super(message);
14689
- this.provider = provider;
14690
- this.statusCode = statusCode;
14691
- this.responseBody = responseBody;
14692
- this.name = "ProviderError";
14693
- }
14694
- };
14695
-
14696
- // src/providers/base.ts
14697
- var DEFAULT_RETRY = {
14698
- maxRetries: 3,
14699
- baseDelayMs: 500,
14700
- maxDelayMs: 8e3
14701
- };
14702
- var BaseProvider = class {
14703
- constructor() {
14704
- this.retryPolicy = DEFAULT_RETRY;
14705
- }
14706
- /**
14707
- * Helper concrete providers can wrap their fetch with. Retries 429/5xx
14708
- * with exponential backoff and respects Retry-After if the response
14709
- * carries one.
14710
- */
14711
- async doFetchWithRetry(execute) {
14712
- const policy = this.retryPolicy;
14713
- const maxRetries = Math.max(0, policy.maxRetries ?? DEFAULT_RETRY.maxRetries);
14714
- const baseDelay = Math.max(0, policy.baseDelayMs ?? DEFAULT_RETRY.baseDelayMs);
14715
- const maxDelay = Math.max(baseDelay, policy.maxDelayMs ?? DEFAULT_RETRY.maxDelayMs);
14716
- let lastResp;
14717
- for (let attempt = 0; attempt <= maxRetries; attempt++) {
14718
- const res = await execute();
14719
- const isRetryable = res.status === 429 || res.status >= 500 && res.status < 600;
14720
- if (!isRetryable) return res;
14721
- const predicate = policy.shouldRetry;
14722
- if (predicate && !predicate({ status: res.status }, attempt)) return res;
14723
- if (attempt === maxRetries) {
14724
- lastResp = res;
14725
- break;
14726
- }
14727
- const retryAfter = res.headers.get("retry-after");
14728
- let delay2 = Math.min(maxDelay, baseDelay * Math.pow(2, attempt));
14729
- if (retryAfter) {
14730
- const asNumber = Number(retryAfter);
14731
- if (!Number.isNaN(asNumber)) delay2 = Math.min(maxDelay, Math.max(delay2, asNumber * 1e3));
14732
- }
14733
- try {
14734
- await res.text();
14735
- } catch {
14736
- }
14737
- await new Promise((r) => setTimeout(r, delay2));
14738
- }
14739
- return lastResp;
14740
- }
14741
- };
15178
+ // src/index.ts
15179
+ init_content();
14742
15180
 
14743
15181
  // src/providers/utils/sse.ts
14744
15182
  async function* parseSSEStream(body, signal) {
@@ -14747,7 +15185,7 @@ async function* parseSSEStream(body, signal) {
14747
15185
  let buffer = "";
14748
15186
  try {
14749
15187
  while (true) {
14750
- if (signal?.aborted) ;
15188
+ if (signal?.aborted) throw abortReason(signal);
14751
15189
  const { done, value } = await reader.read();
14752
15190
  if (done) break;
14753
15191
  buffer += decoder.decode(value, { stream: true });
@@ -14764,6 +15202,7 @@ async function* parseSSEStream(body, signal) {
14764
15202
  if (event) yield event;
14765
15203
  }
14766
15204
  } finally {
15205
+ reader.cancel().catch(() => void 0);
14767
15206
  reader.releaseLock();
14768
15207
  }
14769
15208
  }
@@ -14981,8 +15420,127 @@ function sanitizeBedrockDocName(name, fallback = "document") {
14981
15420
  return cleaned || fallback;
14982
15421
  }
14983
15422
 
15423
+ // src/providers/utils/jsonSchemaRefs.ts
15424
+ var DEFINITION_KEYS = ["definitions", "$defs"];
15425
+ function inlineJsonSchemaRefs(schema) {
15426
+ if (!isObject2(schema) || !containsRef(schema)) return schema;
15427
+ const root = structuredClone(schema);
15428
+ const selfReaching = /* @__PURE__ */ new Map();
15429
+ const targetOf = (ref) => {
15430
+ const target = resolvePointer(root, ref);
15431
+ return isObject2(target) ? target : void 0;
15432
+ };
15433
+ const reachesItself = (target) => {
15434
+ const known = selfReaching.get(target);
15435
+ if (known !== void 0) return known;
15436
+ const seen = /* @__PURE__ */ new Set();
15437
+ const walk = (node) => {
15438
+ if (Array.isArray(node)) return node.some(walk);
15439
+ if (!isObject2(node)) return false;
15440
+ if (typeof node.$ref === "string") {
15441
+ const next = targetOf(node.$ref);
15442
+ if (next === target) return true;
15443
+ if (next && !seen.has(next)) {
15444
+ seen.add(next);
15445
+ if (walk(next)) return true;
15446
+ }
15447
+ }
15448
+ return Object.entries(node).some(([key, value]) => key !== "$ref" && walk(value));
15449
+ };
15450
+ const result2 = walk(target);
15451
+ selfReaching.set(target, result2);
15452
+ return result2;
15453
+ };
15454
+ const keptRefs = /* @__PURE__ */ new Set();
15455
+ const expand = (node) => {
15456
+ if (Array.isArray(node)) return node.map(expand);
15457
+ if (!isObject2(node)) return node;
15458
+ if (typeof node.$ref === "string") {
15459
+ const target = targetOf(node.$ref);
15460
+ if (target && !reachesItself(target)) {
15461
+ const { $ref: _inlined, ...siblings } = node;
15462
+ return { ...expand(target), ...expandEntries(siblings) };
15463
+ }
15464
+ keptRefs.add(node.$ref);
15465
+ return expandEntries(node);
15466
+ }
15467
+ return expandEntries(node);
15468
+ };
15469
+ const expandEntries = (node) => {
15470
+ const out = {};
15471
+ for (const [key, value] of Object.entries(node)) out[key] = key === "$ref" ? value : expand(value);
15472
+ return out;
15473
+ };
15474
+ const { definitions: _definitions, $defs: _defs, ...rootBody } = root;
15475
+ const result = typeof root.$ref === "string" ? expand(rootBody) : expandEntries(rootBody);
15476
+ for (const key of DEFINITION_KEYS) delete result[key];
15477
+ for (const key of DEFINITION_KEYS) {
15478
+ const block = root[key];
15479
+ if (!isObject2(block)) continue;
15480
+ const needed = neededEntries(key, block, keptRefs);
15481
+ if (needed.length === 0) continue;
15482
+ const kept = {};
15483
+ for (const name of Object.keys(block)) if (needed.includes(name)) kept[name] = block[name];
15484
+ result[key] = kept;
15485
+ }
15486
+ return result;
15487
+ }
15488
+ function neededEntries(key, block, keptRefs) {
15489
+ const needed = [];
15490
+ const queue = [...keptRefs];
15491
+ while (queue.length > 0) {
15492
+ const ref = queue.shift();
15493
+ const segments = pointerSegments(ref);
15494
+ if (!segments || segments[0] !== key || segments.length < 2) continue;
15495
+ const name = segments[1];
15496
+ if (needed.includes(name) || !(name in block)) continue;
15497
+ needed.push(name);
15498
+ collectRefs(block[name], queue);
15499
+ }
15500
+ return needed;
15501
+ }
15502
+ function collectRefs(node, into) {
15503
+ if (Array.isArray(node)) {
15504
+ node.forEach((child) => collectRefs(child, into));
15505
+ return;
15506
+ }
15507
+ if (!isObject2(node)) return;
15508
+ if (typeof node.$ref === "string") into.push(node.$ref);
15509
+ for (const [k, value] of Object.entries(node)) if (k !== "$ref") collectRefs(value, into);
15510
+ }
15511
+ function containsRef(node) {
15512
+ if (Array.isArray(node)) return node.some(containsRef);
15513
+ if (!isObject2(node)) return false;
15514
+ if (typeof node.$ref === "string") return true;
15515
+ return Object.values(node).some(containsRef);
15516
+ }
15517
+ function pointerSegments(ref) {
15518
+ if (ref === "#") return [];
15519
+ if (!ref.startsWith("#/")) return null;
15520
+ return ref.slice(2).split("/").map((segment) => segment.replace(/~1/g, "/").replace(/~0/g, "~"));
15521
+ }
15522
+ function resolvePointer(document, ref) {
15523
+ const segments = pointerSegments(ref);
15524
+ if (!segments) return void 0;
15525
+ let current = document;
15526
+ for (const segment of segments) {
15527
+ if (Array.isArray(current)) {
15528
+ if (!/^\d+$/.test(segment)) return void 0;
15529
+ current = current[Number(segment)];
15530
+ } else if (isObject2(current) && Object.prototype.hasOwnProperty.call(current, segment)) {
15531
+ current = current[segment];
15532
+ } else {
15533
+ return void 0;
15534
+ }
15535
+ }
15536
+ return current;
15537
+ }
15538
+ function isObject2(value) {
15539
+ return typeof value === "object" && value !== null && !Array.isArray(value);
15540
+ }
15541
+
14984
15542
  // src/providers/openai.ts
14985
- var OpenAIProvider = class extends BaseProvider {
15543
+ var OpenAIProvider = class _OpenAIProvider extends BaseProvider {
14986
15544
  constructor(config) {
14987
15545
  super();
14988
15546
  this.providerName = "openai";
@@ -14994,8 +15552,21 @@ var OpenAIProvider = class extends BaseProvider {
14994
15552
  ...config.organization ? { "OpenAI-Organization": config.organization } : {}
14995
15553
  };
14996
15554
  this.responsesApi = config.responsesApi ?? "auto";
15555
+ const ownInstance = new.target === _OpenAIProvider;
15556
+ this.responsesApiModels = ownInstance ? [...config.responsesApiModels ?? []] : [];
15557
+ this.responsesStreaming = ownInstance && config.responsesStreaming === true;
14997
15558
  if (config.retry) this.retryPolicy = { ...this.retryPolicy, ...config.retry };
14998
15559
  }
15560
+ /** True when the caller listed this request's model in `responsesApiModels`. */
15561
+ isResponsesApiModel(request) {
15562
+ if (this.responsesApiModels.length === 0) return false;
15563
+ const model = request.model || this.defaultModel;
15564
+ return this.responsesApiModels.some((entry) => {
15565
+ if (typeof entry === "string") return entry === model;
15566
+ entry.lastIndex = 0;
15567
+ return entry.test(model);
15568
+ });
15569
+ }
14999
15570
  /** True when this request should go to the Responses API rather than Chat
15000
15571
  * Completions — which exposes `reasoning.effort` and reasoning summaries that
15001
15572
  * Chat Completions silently drops.
@@ -15004,10 +15575,14 @@ var OpenAIProvider = class extends BaseProvider {
15004
15575
  * carries a reasoning config AND the model name looks like an o-series/gpt-5
15005
15576
  * model. `never`/`always` let a caller state the answer instead, because the
15006
15577
  * name check is a guess and the two APIs differ in far more than reasoning —
15007
- * see `responsesApi` in OpenAIProviderConfig. */
15578
+ * see `responsesApi` in OpenAIProviderConfig.
15579
+ *
15580
+ * A model listed in `responsesApiModels` is the caller stating the answer
15581
+ * for that model alone; `never` still overrides it. */
15008
15582
  useResponsesApi(request) {
15009
15583
  if (this.responsesApi === "never") return false;
15010
15584
  if (this.responsesApi === "always") return true;
15585
+ if (this.isResponsesApiModel(request)) return true;
15011
15586
  if (!request.reasoning) return false;
15012
15587
  return isReasoningModel(request.model || this.defaultModel);
15013
15588
  }
@@ -15016,12 +15591,16 @@ var OpenAIProvider = class extends BaseProvider {
15016
15591
  return this.completeResponses(request);
15017
15592
  }
15018
15593
  const body = this.buildRequestBody(request, false);
15019
- const res = await this.doFetch(body);
15594
+ const res = await this.doFetch(body, request.signal);
15020
15595
  const json = await res.json();
15021
15596
  return this.parseResponse(json);
15022
15597
  }
15023
15598
  async *completeStream(request) {
15024
15599
  if (this.useResponsesApi(request)) {
15600
+ if (this.responsesStreaming && this.isResponsesApiModel(request)) {
15601
+ yield* this.streamResponses(request);
15602
+ return;
15603
+ }
15025
15604
  const response = await this.completeResponses(request);
15026
15605
  yield {
15027
15606
  id: response.id,
@@ -15037,13 +15616,13 @@ var OpenAIProvider = class extends BaseProvider {
15037
15616
  return;
15038
15617
  }
15039
15618
  const body = this.buildRequestBody(request, true);
15040
- const res = await this.doFetch(body);
15619
+ const res = await this.doFetch(body, request.signal);
15041
15620
  if (!res.body) throw new ProviderError("No response body for stream", this.providerName);
15042
15621
  let id = "";
15043
15622
  let model = "";
15044
15623
  const toolCallBuffers = /* @__PURE__ */ new Map();
15045
15624
  let usage;
15046
- for await (const event of parseSSEStream(res.body)) {
15625
+ for await (const event of parseSSEStream(res.body, request.signal)) {
15047
15626
  if (event.data === "[DONE]") break;
15048
15627
  let chunk;
15049
15628
  try {
@@ -15137,10 +15716,101 @@ var OpenAIProvider = class extends BaseProvider {
15137
15716
  // ─── Responses API (reasoning models) ──────────────────────────────────────
15138
15717
  async completeResponses(request) {
15139
15718
  const body = this.buildResponsesBody(request);
15140
- const res = await this.responsesFetch(body);
15719
+ if (this.isResponsesApiModel(request)) adaptChatExtrasForResponses(body, request.extra);
15720
+ const res = await this.responsesFetch(body, request.signal);
15141
15721
  const json = await res.json();
15142
15722
  return this.parseResponsesResponse(json, request.model || this.defaultModel);
15143
15723
  }
15724
+ /** Real Responses SSE streaming, for models opted in through
15725
+ * `responsesApiModels` with `responsesStreaming` on. Emits the same chunk
15726
+ * shapes as the Chat Completions stream: text deltas as they arrive, a tool
15727
+ * call's id + name when it opens and its argument fragments under that id,
15728
+ * then one final chunk with usage, finish reason and any reasoning summary
15729
+ * (taken from the completed response, exactly as the non-streaming parse
15730
+ * reads it). */
15731
+ async *streamResponses(request) {
15732
+ const modelId = request.model || this.defaultModel;
15733
+ const body = this.buildResponsesBody(request);
15734
+ adaptChatExtrasForResponses(body, request.extra);
15735
+ body.stream = true;
15736
+ const res = await this.responsesFetch(body, request.signal);
15737
+ if (!res.body) throw new ProviderError("No response body for stream", this.providerName);
15738
+ let id = "";
15739
+ let model = modelId;
15740
+ const calls = /* @__PURE__ */ new Map();
15741
+ let final;
15742
+ for await (const event of parseSSEStream(res.body, request.signal)) {
15743
+ if (event.data === "[DONE]") break;
15744
+ let data;
15745
+ try {
15746
+ data = JSON.parse(event.data);
15747
+ } catch {
15748
+ continue;
15749
+ }
15750
+ switch (data.type ?? event.event) {
15751
+ case "response.created":
15752
+ case "response.in_progress":
15753
+ id = data.response?.id ?? id;
15754
+ model = data.response?.model ?? model;
15755
+ break;
15756
+ case "response.output_text.delta":
15757
+ if (data.delta) yield { id, model, delta: { content: data.delta } };
15758
+ break;
15759
+ case "response.output_item.added": {
15760
+ const item = data.item;
15761
+ if (item?.type !== "function_call") break;
15762
+ const call = { callId: item.call_id ?? item.id ?? "", name: item.name ?? "", arguments: item.arguments ?? "" };
15763
+ calls.set(item.id ?? call.callId, call);
15764
+ yield { id, model, delta: { toolCalls: [{ id: call.callId, name: call.name, arguments: call.arguments }] } };
15765
+ break;
15766
+ }
15767
+ case "response.function_call_arguments.delta": {
15768
+ const call = calls.get(data.item_id);
15769
+ if (!call || !data.delta) break;
15770
+ call.arguments += data.delta;
15771
+ yield { id, model, delta: { toolCalls: [{ id: call.callId, arguments: data.delta }] } };
15772
+ break;
15773
+ }
15774
+ case "response.output_item.done": {
15775
+ const item = data.item;
15776
+ if (item?.type !== "function_call") break;
15777
+ const full = typeof item.arguments === "string" ? item.arguments : "";
15778
+ const call = calls.get(item.id ?? item.call_id);
15779
+ if (!call) {
15780
+ const added = { callId: item.call_id ?? item.id ?? "", name: item.name ?? "", arguments: full };
15781
+ calls.set(item.id ?? added.callId, added);
15782
+ yield { id, model, delta: { toolCalls: [{ id: added.callId, name: added.name, arguments: full }] } };
15783
+ } else if (full.length > call.arguments.length && full.startsWith(call.arguments)) {
15784
+ const rest = full.slice(call.arguments.length);
15785
+ call.arguments = full;
15786
+ yield { id, model, delta: { toolCalls: [{ id: call.callId, arguments: rest }] } };
15787
+ }
15788
+ break;
15789
+ }
15790
+ case "response.completed":
15791
+ case "response.incomplete":
15792
+ final = this.parseResponsesResponse(data.response ?? {}, modelId);
15793
+ break;
15794
+ case "response.failed":
15795
+ case "error": {
15796
+ const err = data.response?.error ?? data.error ?? data;
15797
+ throw new ProviderError(
15798
+ `OpenAI Responses API stream error: ${err?.message ?? "unknown error"}`,
15799
+ this.providerName,
15800
+ void 0,
15801
+ data
15802
+ );
15803
+ }
15804
+ }
15805
+ }
15806
+ yield {
15807
+ id: final?.id || id,
15808
+ model: final?.model || model,
15809
+ delta: final?.reasoning ? { reasoning: final.reasoning } : {},
15810
+ usage: final?.usage,
15811
+ finishReason: final?.finishReason ?? (calls.size > 0 ? "tool_calls" : "stop")
15812
+ };
15813
+ }
15144
15814
  buildResponsesBody(request) {
15145
15815
  const body = {
15146
15816
  model: request.model || this.defaultModel,
@@ -15170,7 +15840,7 @@ var OpenAIProvider = class extends BaseProvider {
15170
15840
  format: {
15171
15841
  type: "json_schema",
15172
15842
  name: request.responseFormat.name ?? "response",
15173
- schema: request.responseFormat.schema,
15843
+ schema: inlineJsonSchemaRefs(request.responseFormat.schema),
15174
15844
  strict: true
15175
15845
  }
15176
15846
  };
@@ -15237,7 +15907,7 @@ var OpenAIProvider = class extends BaseProvider {
15237
15907
  });
15238
15908
  return { role, content };
15239
15909
  }
15240
- async responsesFetch(body) {
15910
+ async responsesFetch(body, signal) {
15241
15911
  body.input = expandResponsesInput(body.input);
15242
15912
  const url = `${this.baseURL}/responses`;
15243
15913
  const headers = {
@@ -15246,7 +15916,7 @@ var OpenAIProvider = class extends BaseProvider {
15246
15916
  ...this.defaultHeaders
15247
15917
  };
15248
15918
  const payload = JSON.stringify(body);
15249
- const res = await this.doFetchWithRetry(() => fetch(url, { method: "POST", headers, body: payload }));
15919
+ const res = await this.doFetchWithRetry(() => fetch(url, { method: "POST", headers, body: payload, signal }), signal);
15250
15920
  if (!res.ok) {
15251
15921
  const text = await res.text().catch(() => "");
15252
15922
  throw new ProviderError(
@@ -15367,7 +16037,7 @@ var OpenAIProvider = class extends BaseProvider {
15367
16037
  }
15368
16038
  return { type: "function", function: fn };
15369
16039
  }
15370
- async doFetch(body) {
16040
+ async doFetch(body, signal) {
15371
16041
  const url = `${this.baseURL}/chat/completions`;
15372
16042
  const headers = {
15373
16043
  "Content-Type": "application/json",
@@ -15375,7 +16045,7 @@ var OpenAIProvider = class extends BaseProvider {
15375
16045
  ...this.defaultHeaders
15376
16046
  };
15377
16047
  const payload = JSON.stringify(body);
15378
- const res = await this.doFetchWithRetry(() => fetch(url, { method: "POST", headers, body: payload }));
16048
+ const res = await this.doFetchWithRetry(() => fetch(url, { method: "POST", headers, body: payload, signal }), signal);
15379
16049
  if (!res.ok) {
15380
16050
  const text = await res.text().catch(() => "");
15381
16051
  throw new ProviderError(
@@ -15425,6 +16095,48 @@ function isReasoningModel(model) {
15425
16095
  const m = model.toLowerCase();
15426
16096
  return /(^|[/_-])o[0-9]/.test(m) || m.startsWith("o1") || m.startsWith("o3") || m.startsWith("o4") || m.includes("gpt-5") || m.includes("gpt5");
15427
16097
  }
16098
+ function adaptChatExtrasForResponses(body, extra) {
16099
+ const native = extra ?? {};
16100
+ if ("reasoning_effort" in body) {
16101
+ const effort = body.reasoning_effort;
16102
+ delete body.reasoning_effort;
16103
+ if (effort != null) {
16104
+ const reasoning = body.reasoning && typeof body.reasoning === "object" ? body.reasoning : {};
16105
+ if (reasoning.effort == null) body.reasoning = { ...reasoning, effort };
16106
+ }
16107
+ }
16108
+ for (const key of ["max_tokens", "max_completion_tokens"]) {
16109
+ if (!(key in body)) continue;
16110
+ const value = body[key];
16111
+ delete body[key];
16112
+ if (value != null && !("max_output_tokens" in native)) body.max_output_tokens = value;
16113
+ }
16114
+ if ("response_format" in body) {
16115
+ const format = toResponsesTextFormat(body.response_format);
16116
+ delete body.response_format;
16117
+ if (format && !("text" in native)) body.text = { ...body.text, format };
16118
+ }
16119
+ if (body.stream_options && typeof body.stream_options === "object" && "include_usage" in body.stream_options) {
16120
+ const { include_usage: _dropped, ...rest } = body.stream_options;
16121
+ if (Object.keys(rest).length > 0) body.stream_options = rest;
16122
+ else delete body.stream_options;
16123
+ }
16124
+ }
16125
+ function toResponsesTextFormat(rf) {
16126
+ if (!rf || typeof rf !== "object") return void 0;
16127
+ if (rf.type === "json_schema") {
16128
+ const js = rf.json_schema ?? {};
16129
+ return {
16130
+ type: "json_schema",
16131
+ name: js.name ?? "response",
16132
+ schema: inlineJsonSchemaRefs(js.schema),
16133
+ ...js.description != null ? { description: js.description } : {},
16134
+ ...js.strict != null ? { strict: js.strict } : {}
16135
+ };
16136
+ }
16137
+ if (rf.type === "json_object" || rf.type === "text") return { type: rf.type };
16138
+ return void 0;
16139
+ }
15428
16140
  function expandResponsesInput(input) {
15429
16141
  const out = [];
15430
16142
  for (const item of input) {
@@ -15469,13 +16181,13 @@ var AnthropicProvider = class extends BaseProvider {
15469
16181
  }
15470
16182
  async complete(request) {
15471
16183
  const body = this.buildRequestBody(request, false);
15472
- const res = await this.doFetch(body);
16184
+ const res = await this.doFetch(body, request.signal);
15473
16185
  const json = await res.json();
15474
16186
  return this.parseResponse(json);
15475
16187
  }
15476
16188
  async *completeStream(request) {
15477
16189
  const body = this.buildRequestBody(request, true);
15478
- const res = await this.doFetch(body);
16190
+ const res = await this.doFetch(body, request.signal);
15479
16191
  if (!res.body) throw new ProviderError("No response body for stream", this.providerName);
15480
16192
  let id = "";
15481
16193
  let model = "";
@@ -15485,7 +16197,7 @@ var AnthropicProvider = class extends BaseProvider {
15485
16197
  let cacheCreationInputTokens = 0;
15486
16198
  const currentToolCalls = /* @__PURE__ */ new Map();
15487
16199
  const reasoningBlocks = /* @__PURE__ */ new Map();
15488
- for await (const event of parseSSEStream(res.body)) {
16200
+ for await (const event of parseSSEStream(res.body, request.signal)) {
15489
16201
  let data;
15490
16202
  try {
15491
16203
  data = JSON.parse(event.data);
@@ -15765,7 +16477,7 @@ var AnthropicProvider = class extends BaseProvider {
15765
16477
  input_schema: t.parameters
15766
16478
  };
15767
16479
  }
15768
- async doFetch(body) {
16480
+ async doFetch(body, signal) {
15769
16481
  const url = `${this.baseURL}/v1/messages`;
15770
16482
  const headers = {
15771
16483
  "Content-Type": "application/json",
@@ -15774,7 +16486,7 @@ var AnthropicProvider = class extends BaseProvider {
15774
16486
  ...this.defaultHeaders
15775
16487
  };
15776
16488
  const payload = JSON.stringify(body);
15777
- const res = await this.doFetchWithRetry(() => fetch(url, { method: "POST", headers, body: payload }));
16489
+ const res = await this.doFetchWithRetry(() => fetch(url, { method: "POST", headers, body: payload, signal }), signal);
15778
16490
  if (!res.ok) {
15779
16491
  const text = await res.text().catch(() => "");
15780
16492
  throw new ProviderError(
@@ -15884,7 +16596,7 @@ var AzureProvider = class extends OpenAIProvider {
15884
16596
  this.deploymentName = config.deploymentName;
15885
16597
  this.azureApiKey = config.apiKey;
15886
16598
  }
15887
- async doFetch(body) {
16599
+ async doFetch(body, signal) {
15888
16600
  const deployment = this.deploymentName ?? body.model;
15889
16601
  if (!deployment) {
15890
16602
  throw new ProviderError("Azure requires a deploymentName or model", this.providerName);
@@ -15898,7 +16610,8 @@ var AzureProvider = class extends OpenAIProvider {
15898
16610
  "api-key": this.azureApiKey,
15899
16611
  ...this.defaultHeaders
15900
16612
  },
15901
- body: JSON.stringify(bodyWithoutModel)
16613
+ body: JSON.stringify(bodyWithoutModel),
16614
+ signal
15902
16615
  });
15903
16616
  if (!res.ok) {
15904
16617
  const text = await res.text().catch(() => "");
@@ -15914,7 +16627,7 @@ var AzureProvider = class extends OpenAIProvider {
15914
16627
  /** Azure exposes the Responses API at /openai/responses with api-key auth.
15915
16628
  * Reasoning summaries require a preview api-version; callers can override via
15916
16629
  * the `apiVersion` config. */
15917
- async responsesFetch(body) {
16630
+ async responsesFetch(body, signal) {
15918
16631
  body.input = expandAzureResponsesInput(body.input);
15919
16632
  const deployment = this.deploymentName ?? body.model;
15920
16633
  if (!deployment) {
@@ -15929,7 +16642,8 @@ var AzureProvider = class extends OpenAIProvider {
15929
16642
  "api-key": this.azureApiKey,
15930
16643
  ...this.defaultHeaders
15931
16644
  },
15932
- body: payload
16645
+ body: payload,
16646
+ signal
15933
16647
  });
15934
16648
  if (!res.ok) {
15935
16649
  const text = await res.text().catch(() => "");
@@ -15997,7 +16711,7 @@ var BedrockProvider = class extends BaseProvider {
15997
16711
  async complete(request) {
15998
16712
  const modelId = request.model || this.defaultModel;
15999
16713
  const body = this.buildConverseBody(request);
16000
- const json = await this.doFetch(modelId, body);
16714
+ const json = await this.doFetch(modelId, body, request.signal);
16001
16715
  return this.parseResponse(json, modelId);
16002
16716
  }
16003
16717
  async *completeStream(request) {
@@ -16174,7 +16888,7 @@ var BedrockProvider = class extends BaseProvider {
16174
16888
  }
16175
16889
  };
16176
16890
  }
16177
- async doFetch(modelId, body) {
16891
+ async doFetch(modelId, body, signal) {
16178
16892
  const host = `bedrock-runtime.${this.region}.amazonaws.com`;
16179
16893
  const url = `https://${host}/model/${encodeURIComponent(modelId)}/converse`;
16180
16894
  const bodyStr = JSON.stringify(body);
@@ -16192,8 +16906,8 @@ var BedrockProvider = class extends BaseProvider {
16192
16906
  service: "bedrock",
16193
16907
  credentials: this.credentials
16194
16908
  });
16195
- return fetch(url, { method: "POST", headers, body: bodyStr });
16196
- });
16909
+ return fetch(url, { method: "POST", headers, body: bodyStr, signal });
16910
+ }, signal);
16197
16911
  if (!res.ok) {
16198
16912
  const text = await res.text().catch(() => "");
16199
16913
  throw new ProviderError(
@@ -16326,7 +17040,7 @@ var VertexProvider = class extends BaseProvider {
16326
17040
  const modelId = request.model || this.defaultModel;
16327
17041
  const body = this.buildGeminiBody(request);
16328
17042
  const url = this.buildUrl(modelId, false);
16329
- const res = await this.doFetch(url, body);
17043
+ const res = await this.doFetch(url, body, request.signal);
16330
17044
  const json = await res.json();
16331
17045
  return this.parseResponse(json, modelId);
16332
17046
  }
@@ -16334,11 +17048,11 @@ var VertexProvider = class extends BaseProvider {
16334
17048
  const modelId = request.model || this.defaultModel;
16335
17049
  const body = this.buildGeminiBody(request);
16336
17050
  const url = this.buildUrl(modelId, true);
16337
- const res = await this.doFetch(url, body);
17051
+ const res = await this.doFetch(url, body, request.signal);
16338
17052
  if (!res.body) throw new ProviderError("No response body for stream", this.providerName);
16339
17053
  const contentType = res.headers.get("content-type") ?? "";
16340
17054
  if (contentType.includes("text/event-stream")) {
16341
- for await (const event of parseSSEStream(res.body)) {
17055
+ for await (const event of parseSSEStream(res.body, request.signal)) {
16342
17056
  if (event.data === "[DONE]") break;
16343
17057
  let chunk;
16344
17058
  try {
@@ -16380,6 +17094,7 @@ var VertexProvider = class extends BaseProvider {
16380
17094
  }
16381
17095
  }
16382
17096
  } finally {
17097
+ reader.cancel().catch(() => void 0);
16383
17098
  reader.releaseLock();
16384
17099
  }
16385
17100
  }
@@ -16591,7 +17306,7 @@ var VertexProvider = class extends BaseProvider {
16591
17306
  const tokenJson = await tokenRes.json();
16592
17307
  return tokenJson.access_token;
16593
17308
  }
16594
- async doFetch(url, body) {
17309
+ async doFetch(url, body, signal) {
16595
17310
  const token = await this.getAccessToken();
16596
17311
  const res = await fetch(url, {
16597
17312
  method: "POST",
@@ -16600,7 +17315,8 @@ var VertexProvider = class extends BaseProvider {
16600
17315
  Authorization: `Bearer ${token}`,
16601
17316
  ...this.defaultHeaders
16602
17317
  },
16603
- body: JSON.stringify(body)
17318
+ body: JSON.stringify(body),
17319
+ signal
16604
17320
  });
16605
17321
  if (!res.ok) {
16606
17322
  const text = await res.text().catch(() => "");
@@ -16739,11 +17455,13 @@ function createProvider(config) {
16739
17455
  return new BedrockProvider(config);
16740
17456
  case "vertex":
16741
17457
  return new VertexProvider(config);
17458
+ case "jev":
17459
+ return new JevProvider(config);
16742
17460
  default:
16743
17461
  throw new Error(`Unknown provider: ${config.provider}`);
16744
17462
  }
16745
17463
  }
16746
17464
 
16747
- export { ASK_USER_TOOL_NAME, AnthropicProvider, AzureProvider, BaseProvider, BedrockProvider, CCRStore, CONSOLE_HOOK_MAP, CONTEXT_PILOT_JSON_MARKER_KEY, CONTROL_PLANE_TOOL_NAMES, DEFAULT_MAX_TOOL_INPUT_FIELD_CHARS, DEFAULT_PROFILE_CONFIGS, DEFAULT_SKILL_POLICY, DEFAULT_SUBAGENT_POLICY, DEFAULT_SUBAGENT_TOOL_NAMES, DEFAULT_TOOL_INPUT_DIGEST_HEAD_CHARS, DELEGATION_TOOL_NAMES, DedupTracker, GuardrailPhase, HOOK_CONTRACT_VERSION, HOOK_NAMES, HookTimeoutError, InMemoryMemoryStore, NativeJsonSchemaStrategy, OpenAICompatibleProvider, OpenAIProvider, PREOPEN_TOOL_CALL_PREFIX, ProviderError, SMALL_TIER_SKILL_POLICY, StructuredOutputManager, TOOL_INPUT_DIGEST_KEY, ToolBasedStrategy, VertexProvider, agentVerdictRule, appendBoundTools, auditLog, azureContentSafety, bedrockGuardrail, budgetGuard, buildHandoffTools, buildResponseFormatSection, buildSkillHeaderBlock, buildSubagentCatalogBlock, buildSystemPrompt, buildToolDefinitionsSection, canOpenSkill, canSpawn, captureSnapshot, checkpointing, codePresenceRule, coerceToolArgs, cognipeerGuardrail, cognipeerSink, collectAttachments, collectToolRetentionDeclarations, composeToolSets, compressDiffOutput, compressJsonOutput, compressLogOutput, compressSearchOutput, compressTextOutput, compressToolOutput, contentToString, conversationHistory, countApproxTokens, countMessagesTokens, createAgent, createAgentNode, createAskUserQuestionTool, createBindSkillToolsTool, createCodeGuardrail, createContextPilotRuntime, createContextSummarizeNode, createContextTools, createDelegateTool, createGetToolResponseTool, createGuardrail, createGuardrailPlugin, createJsonGuardrail, createManageTodoListAliasTool, createManageTodoTool, createOpenSkillTool, createParallelTool, createPluginHost, createProvider, createRegexGuardrail, createResolverNode, createSearchSkillsTool, createSkillRegistryRef, createSkillTools, createSmartAgent, createSpawnTool, createSubagentRegistryRef, createSubagentTools, createTool, createToolLimitFinalizeNode, createToolsNode, customCallbackRule, customGuardrail, customSink, dedupeToolsByName, defaultTokenCounter, defineHook, definePlugin, detectLanguage, detectTextFormat, detectVolatileContent, digestToolInputArguments, digestToolInputValue, emptyUsage, evaluateGuardrails, extractLatestUserQuery, extractMessageText2 as extractMessageText, fileCheckpointStore, fileSink, findSubagent, formatZodError, fromLangchainModel, fromLangchainTools, fromNativeProvider, generateSpanId, generateTraceId, getModelCapabilities, getNestedValue, getResolvedSmartConfig, getTokenCounter, hasToolResponseRecoveryReference, httpGuardrail, httpSink, inMemoryCheckpointStore, inMemoryConversationStore, isHookImplemented, isOpenAIHostedEndpoint, isSmartModel, isValidIban, isValidLuhn, isValidTckn, jsonSchemaRule, defaultBuildPayload as langfuseDefaultPayload, langfuseTracing, languageGuard, loadSkillsFromDisk, mapConsoleHookVerdict, mapTextParts, mcp, mediaPolicy, normalizeSmartAgentOptions, normalizeVerdicts, openAIModeration, otelTracing, otlpSink, outputGuard, parseApprovalDecision, parseSkillFrontmatter, pathSandbox, piiRedaction, pluginCapabilities, portkeyGateway, portkeyGuardrail, preopenSkills, preopenToolCallId, prepareStrictToolMenu, promptInjectionGuard, rateLimit, readMemoryFacts, redactText, regexGuardrail, regexRule, replaceTextContent, resolveAvailableSkills, resolveAvailableSubagents, resolveInputRetention, resolveMemoryStore, resolveReasoning, resolveStrategy, resolveSubagentTools, resolveSummarizationRetention, resolveToolApprovalState, resolveUserQuestionState, responseCache, restoreSnapshot, restoreToolCalls, runSmartAgentEvalHarness, scoreItemsByRelevance, searchSkills, seedChildMessages, selectTopIndicesInOrder, sessionMetrics, setTokenCounter, startStreamingSession, summarizeObject, textFromContent, toStrictCompatible, toStrictToolSchema, tokenize, toolPolicy, traceSessionToOtlp, validateReasoningConfig, validateToolArgs, webhookApproval, withTools, withinDepth, writeSummaryFactsToMemory };
17465
+ export { ASK_USER_TOOL_NAME, AnthropicProvider, AzureProvider, BaseProvider, BedrockProvider, CCRStore, CONSOLE_HOOK_MAP, CONTEXT_PILOT_JSON_MARKER_KEY, CONTROL_PLANE_TOOL_NAMES, DEFAULT_MAX_TOOL_INPUT_FIELD_CHARS, DEFAULT_PROFILE_CONFIGS, DEFAULT_SKILL_POLICY, DEFAULT_SUBAGENT_POLICY, DEFAULT_SUBAGENT_TOOL_NAMES, DEFAULT_TOOL_INPUT_DIGEST_HEAD_CHARS, DELEGATION_TOOL_NAMES, DedupTracker, GuardrailPhase, HOOK_CONTRACT_VERSION, HOOK_NAMES, HookTimeoutError, InMemoryMemoryStore, JevProvider, NativeJsonSchemaStrategy, OpenAICompatibleProvider, OpenAIProvider, PREOPEN_TOOL_CALL_PREFIX, ProviderError, SMALL_TIER_SKILL_POLICY, StructuredOutputManager, TOOL_INPUT_DIGEST_KEY, ToolBasedStrategy, VertexProvider, agentVerdictRule, appendBoundTools, auditLog, azureContentSafety, bedrockGuardrail, budgetGuard, buildHandoffTools, buildResponseFormatSection, buildSkillHeaderBlock, buildSubagentCatalogBlock, buildSystemPrompt, buildToolDefinitionsSection, canOpenSkill, canSpawn, captureSnapshot, checkpointing, codePresenceRule, coerceToolArgs, cognipeerGuardrail, cognipeerSink, collectAttachments, collectToolRetentionDeclarations, composeToolSets, compressDiffOutput, compressJsonOutput, compressLogOutput, compressSearchOutput, compressTextOutput, compressToolOutput, contentPartToText, contentToString, conversationHistory, countApproxTokens, countMessagesTokens, createAgent, createAgentNode, createAskUserQuestionTool, createBindSkillToolsTool, createCodeGuardrail, createContextPilotRuntime, createContextSummarizeNode, createContextTools, createDelegateTool, createGetToolResponseTool, createGuardrail, createGuardrailPlugin, createJsonGuardrail, createManageTodoListAliasTool, createManageTodoTool, createOpenSkillTool, createParallelTool, createPluginHost, createProvider, createRegexGuardrail, createResolverNode, createSearchSkillsTool, createSkillRegistryRef, createSkillTools, createSmartAgent, createSpawnTool, createSubagentRegistryRef, createSubagentTools, createTool, createToolLimitFinalizeNode, createToolsNode, customCallbackRule, customGuardrail, customSink, dedupeToolsByName, defaultTokenCounter, defineHook, definePlugin, describeContentPart, detectLanguage, detectTextFormat, detectVolatileContent, digestToolInputArguments, digestToolInputValue, emptyUsage, evaluateGuardrails, extractLatestUserQuery, extractMessageText, fileCheckpointStore, fileSink, findSubagent, formatZodError, fromLangchainModel, fromLangchainTools, fromNativeProvider, generateSpanId, generateTraceId, getModelCapabilities, getNestedValue, getResolvedSmartConfig, getTokenCounter, hasMediaPart, hasToolResponseRecoveryReference, httpGuardrail, httpSink, inMemoryCheckpointStore, inMemoryConversationStore, isHookImplemented, isOpenAIHostedEndpoint, isSmartModel, isValidIban, isValidLuhn, isValidTckn, jsonSchemaRule, defaultBuildPayload as langfuseDefaultPayload, langfuseTracing, languageGuard, loadSkillsFromDisk, mapConsoleHookVerdict, mapTextParts, mcp, mediaKindOf, mediaPolicy, normalizeSmartAgentOptions, normalizeVerdicts, openAIModeration, otelTracing, otlpSink, outputGuard, parseApprovalDecision, parseSkillFrontmatter, pathSandbox, piiRedaction, pluginCapabilities, portkeyGateway, portkeyGuardrail, preopenSkills, preopenToolCallId, prepareStrictToolMenu, promptInjectionGuard, rateLimit, readMemoryFacts, redactText, regexGuardrail, regexRule, replaceTextContent, resolveAvailableSkills, resolveAvailableSubagents, resolveInputRetention, resolveMemoryStore, resolveReasoning, resolveStrategy, resolveSubagentTools, resolveSummarizationRetention, resolveToolApprovalState, resolveUserQuestionState, responseCache, restoreSnapshot, restoreToolCalls, runSmartAgentEvalHarness, scoreItemsByRelevance, searchSkills, seedChildMessages, selectTopIndicesInOrder, sessionMetrics, setTokenCounter, startStreamingSession, summarizeObject, textFromContent, toStrictCompatible, toStrictToolSchema, tokenize, toolPolicy, traceSessionToOtlp, validateReasoningConfig, validateToolArgs, webhookApproval, withTools, withinDepth, writeSummaryFactsToMemory };
16748
17466
  //# sourceMappingURL=index.mjs.map
16749
17467
  //# sourceMappingURL=index.mjs.map