@cognipeer/agent-sdk 0.10.3 → 0.10.5

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
@@ -503,7 +503,7 @@ function getModelCapabilities(model) {
503
503
  return {
504
504
  provider,
505
505
  structuredOutput: supportsNativeStructuredOutput(provider) ? "native" : "tool_based",
506
- strictToolCalling: requiresStrictToolCalling(provider),
506
+ strictToolCalling: requiresStrictToolCalling(provider) && isOpenAIHostedEndpoint(model._lc),
507
507
  streaming: true
508
508
  };
509
509
  }
@@ -546,6 +546,17 @@ function supportsNativeStructuredOutput(provider) {
546
546
  function requiresStrictToolCalling(provider) {
547
547
  return ["openai"].includes(provider);
548
548
  }
549
+ function isOpenAIHostedEndpoint(lcModel) {
550
+ if (!lcModel) return true;
551
+ const baseURL = lcModel.clientConfig?.baseURL ?? lcModel.configuration?.baseURL ?? lcModel.baseURL;
552
+ if (typeof baseURL !== "string" || baseURL.trim() === "") return true;
553
+ try {
554
+ const host = new URL(baseURL).hostname.toLowerCase();
555
+ return host === "api.openai.com" || host.endsWith(".openai.azure.com") || host.endsWith(".cognitiveservices.azure.com");
556
+ } catch {
557
+ return false;
558
+ }
559
+ }
549
560
 
550
561
  // src/model.ts
551
562
  function isSmartModel(m) {
@@ -2510,13 +2521,19 @@ function resolveCapabilities(provider) {
2510
2521
  switch (provider) {
2511
2522
  case "openai":
2512
2523
  case "azure":
2513
- case "openai-compatible":
2514
2524
  return {
2515
2525
  structuredOutput: "native",
2516
2526
  strictToolCalling: true,
2517
2527
  streaming: true,
2518
2528
  provider
2519
2529
  };
2530
+ case "openai-compatible":
2531
+ return {
2532
+ structuredOutput: "native",
2533
+ strictToolCalling: false,
2534
+ streaming: true,
2535
+ provider
2536
+ };
2520
2537
  case "anthropic":
2521
2538
  return {
2522
2539
  structuredOutput: "tool_based",
@@ -3845,6 +3862,187 @@ Identical to an earlier ${duplicate.toolName} result. Use get_tool_response with
3845
3862
  }
3846
3863
  return notApplied4(output);
3847
3864
  }
3865
+ var identity = (value) => value;
3866
+ function describeLike(schema, source, suffix) {
3867
+ const description = [source.description, suffix].filter(Boolean).join(" ");
3868
+ return description ? schema.describe(description) : schema;
3869
+ }
3870
+ function jsonString(source) {
3871
+ return {
3872
+ schema: describeLike(z.string(), source, "(a JSON value, encoded as a string)"),
3873
+ restore: (value) => {
3874
+ if (typeof value !== "string") return value;
3875
+ try {
3876
+ return JSON.parse(value);
3877
+ } catch {
3878
+ return value;
3879
+ }
3880
+ }
3881
+ };
3882
+ }
3883
+ function unwrapOptional(schema) {
3884
+ const def = schema._def;
3885
+ if (def?.typeName === "ZodOptional") return { inner: def.innerType, optional: true };
3886
+ if (def?.typeName === "ZodDefault") return { inner: def.innerType, optional: true };
3887
+ return { inner: schema, optional: false };
3888
+ }
3889
+ function isZodSchema2(schema) {
3890
+ return Boolean(schema) && typeof schema.safeParse === "function" && Boolean(schema._def);
3891
+ }
3892
+ function toStrictCompatible(schema) {
3893
+ const def = schema?._def;
3894
+ switch (def?.typeName) {
3895
+ case "ZodObject": {
3896
+ const shape = typeof def.shape === "function" ? def.shape() : def.shape;
3897
+ const keys = Object.keys(shape ?? {});
3898
+ const open = def.unknownKeys === "passthrough" || def.catchall && def.catchall._def?.typeName !== "ZodNever";
3899
+ if (keys.length === 0 && open) return jsonString(schema);
3900
+ const nextShape = {};
3901
+ const restores = {};
3902
+ for (const key of keys) {
3903
+ const field = shape[key];
3904
+ const { inner, optional } = unwrapOptional(field);
3905
+ const child = toStrictCompatible(inner);
3906
+ const childSchema = describeLike(child.schema, field.description ? field : inner);
3907
+ nextShape[key] = optional ? childSchema.nullable() : childSchema;
3908
+ restores[key] = { restore: child.restore, optional };
3909
+ }
3910
+ return {
3911
+ schema: describeLike(z.object(nextShape), schema),
3912
+ restore: (value) => {
3913
+ if (!value || typeof value !== "object" || Array.isArray(value)) return value;
3914
+ const out = {};
3915
+ for (const [key, raw] of Object.entries(value)) {
3916
+ const entry = restores[key];
3917
+ if (raw === null && entry?.optional) continue;
3918
+ out[key] = entry ? entry.restore(raw) : raw;
3919
+ }
3920
+ return out;
3921
+ }
3922
+ };
3923
+ }
3924
+ case "ZodOptional":
3925
+ case "ZodDefault": {
3926
+ const child = toStrictCompatible(def.innerType);
3927
+ return {
3928
+ schema: describeLike(child.schema.nullable(), schema),
3929
+ restore: (value) => value === null ? void 0 : child.restore(value)
3930
+ };
3931
+ }
3932
+ case "ZodNullable": {
3933
+ const child = toStrictCompatible(def.innerType);
3934
+ return {
3935
+ schema: describeLike(child.schema.nullable(), schema),
3936
+ restore: (value) => value === null ? null : child.restore(value)
3937
+ };
3938
+ }
3939
+ case "ZodArray": {
3940
+ const child = toStrictCompatible(def.type);
3941
+ return {
3942
+ schema: describeLike(z.array(child.schema), schema),
3943
+ restore: (value) => Array.isArray(value) ? value.map(child.restore) : value
3944
+ };
3945
+ }
3946
+ case "ZodUnion":
3947
+ case "ZodDiscriminatedUnion": {
3948
+ const rawOptions = def.options instanceof Map ? [...def.options.values()] : def.options;
3949
+ const options = rawOptions.map(toStrictCompatible);
3950
+ if (options.length === 1) return options[0];
3951
+ if (options.every((option, index) => option.schema === rawOptions[index])) {
3952
+ return { schema, restore: identity };
3953
+ }
3954
+ return {
3955
+ schema: describeLike(z.union(options.map((option) => option.schema)), schema),
3956
+ restore: (value) => {
3957
+ const candidates = options.map((option) => option.restore(value));
3958
+ const index = candidates.findIndex((candidate, i) => rawOptions[i].safeParse(candidate).success);
3959
+ return candidates[index >= 0 ? index : 0];
3960
+ }
3961
+ };
3962
+ }
3963
+ case "ZodEffects":
3964
+ return toStrictCompatible(def.schema);
3965
+ case "ZodRecord":
3966
+ case "ZodAny":
3967
+ case "ZodUnknown":
3968
+ return jsonString(schema);
3969
+ default:
3970
+ return { schema, restore: identity };
3971
+ }
3972
+ }
3973
+ function topLevelObject(transform) {
3974
+ if (transform.schema._def?.typeName === "ZodObject") return transform;
3975
+ return {
3976
+ schema: z.object({
3977
+ input: transform.schema.describe(
3978
+ transform.schema.description ?? "The tool arguments as a JSON object, encoded as a string"
3979
+ )
3980
+ }),
3981
+ restore: (value) => {
3982
+ const input = value && typeof value === "object" ? value.input : void 0;
3983
+ const restored = transform.restore(input);
3984
+ return restored && typeof restored === "object" ? restored : {};
3985
+ }
3986
+ };
3987
+ }
3988
+ function toStrictToolSchema(schema) {
3989
+ return topLevelObject(toStrictCompatible(schema));
3990
+ }
3991
+ function restoreToolCalls(message, restorers) {
3992
+ if (!message || typeof message !== "object" || restorers.size === 0) return message;
3993
+ const restoreList = (calls) => {
3994
+ if (!Array.isArray(calls) || calls.length === 0) return calls;
3995
+ return calls.map((call) => {
3996
+ const fn = call?.function;
3997
+ const name = call?.name ?? fn?.name;
3998
+ const restore = name ? restorers.get(name) : void 0;
3999
+ if (!restore) return call;
4000
+ let next = call;
4001
+ if (call.args && typeof call.args === "object") next = { ...next, args: restore(call.args) };
4002
+ if (fn && typeof fn.arguments === "string") {
4003
+ try {
4004
+ next = { ...next, function: { ...fn, arguments: JSON.stringify(restore(JSON.parse(fn.arguments))) } };
4005
+ } catch {
4006
+ }
4007
+ }
4008
+ return next;
4009
+ });
4010
+ };
4011
+ const m = message;
4012
+ const hasDirect = Array.isArray(m.tool_calls) && m.tool_calls.length > 0;
4013
+ const hasKwargs = Array.isArray(m.additional_kwargs?.tool_calls) && m.additional_kwargs.tool_calls.length > 0;
4014
+ if (!hasDirect && !hasKwargs) return message;
4015
+ return {
4016
+ ...message,
4017
+ ...hasDirect ? { tool_calls: restoreList(m.tool_calls) } : {},
4018
+ ...hasKwargs ? { additional_kwargs: { ...m.additional_kwargs, tool_calls: restoreList(m.additional_kwargs.tool_calls) } } : {}
4019
+ };
4020
+ }
4021
+ var strictViews = /* @__PURE__ */ new WeakMap();
4022
+ function prepareStrictToolMenu(tools) {
4023
+ const restorers = /* @__PURE__ */ new Map();
4024
+ const menu = tools.map((tool) => {
4025
+ const t = tool;
4026
+ if (!t || typeof t.name !== "string" || !isZodSchema2(t.schema)) return tool;
4027
+ const cached = strictViews.get(tool);
4028
+ if (cached && cached.schema === t.schema) {
4029
+ restorers.set(t.name, cached.restore);
4030
+ return cached.view;
4031
+ }
4032
+ try {
4033
+ const transform = toStrictToolSchema(t.schema);
4034
+ const view = Object.create(tool);
4035
+ view.schema = transform.schema;
4036
+ view.__lcTool = void 0;
4037
+ strictViews.set(tool, { schema: t.schema, view, restore: transform.restore });
4038
+ restorers.set(t.name, transform.restore);
4039
+ return view;
4040
+ } catch {
4041
+ return tool;
4042
+ }
4043
+ });
4044
+ return { menu, restorers };
4045
+ }
3848
4046
 
3849
4047
  // src/nodes/agentCore.ts
3850
4048
  function createAgentCoreNode(opts) {
@@ -3865,10 +4063,17 @@ function createAgentCoreNode(opts) {
3865
4063
  };
3866
4064
  let tools = runtime.tools ?? [];
3867
4065
  const shouldUseStrictToolCalling = Boolean(
3868
- runtime.responseFormat && runtime.model?.capabilities?.strictToolCalling
4066
+ runtime.model?.capabilities?.strictToolCalling
3869
4067
  );
4068
+ let strictRestorers = /* @__PURE__ */ new Map();
4069
+ const wireMenu = (menu) => {
4070
+ if (!shouldUseStrictToolCalling) return menu;
4071
+ const prepared = prepareStrictToolMenu(menu);
4072
+ strictRestorers = prepared.restorers;
4073
+ return prepared.menu;
4074
+ };
3870
4075
  const bindToolMenu = (menu) => runtime.model?.bindTools ? runtime.model.bindTools(
3871
- menu,
4076
+ wireMenu(menu),
3872
4077
  shouldUseStrictToolCalling ? { strict: true } : void 0
3873
4078
  ) : runtime.model;
3874
4079
  const menuMutationReachesProvider = typeof runtime.model?.bindTools === "function";
@@ -3879,7 +4084,8 @@ function createAgentCoreNode(opts) {
3879
4084
  const computeTraceToolDefinitions = (menu) => {
3880
4085
  if (!traceSession || !traceSession.resolvedConfig.logData || menu.length === 0) return void 0;
3881
4086
  try {
3882
- return menu.map((tool) => {
4087
+ const wire = shouldUseStrictToolCalling ? prepareStrictToolMenu(menu).menu : menu;
4088
+ return wire.map((tool) => {
3883
4089
  const def = toToolDefinition(tool, shouldUseStrictToolCalling ? true : void 0);
3884
4090
  return { name: def.name, description: def.description || void 0, parameters: def.parameters };
3885
4091
  });
@@ -4185,6 +4391,9 @@ ${append}`;
4185
4391
  throw err;
4186
4392
  }
4187
4393
  }
4394
+ if (shortCircuited === void 0 && strictRestorers.size > 0) {
4395
+ response = restoreToolCalls(response, strictRestorers);
4396
+ }
4188
4397
  if (!host?.has("postModelCall")) break;
4189
4398
  const postGate = await host.runGate("postModelCall", {
4190
4399
  message: response,
@@ -8783,6 +8992,21 @@ var todoUpdateItemSchema = z.object({
8783
8992
  status: todoStatusSchema.optional(),
8784
8993
  evidence: z.string().max(300).optional()
8785
8994
  });
8995
+ var todoItemWireSchema = z.object({
8996
+ id: z.number().int().min(1).describe("Sequential id starting from 1 (write) or an existing id (update)"),
8997
+ step: z.string().min(1).optional(),
8998
+ title: z.string().min(1).optional(),
8999
+ description: z.string().min(1).optional(),
9000
+ owner: z.string().min(1).optional(),
9001
+ exitCriteria: z.string().min(1).optional(),
9002
+ status: todoStatusSchema.optional().describe("Required for every item on write"),
9003
+ evidence: z.string().max(300).optional()
9004
+ });
9005
+ function describeTodoIssue(issue) {
9006
+ if (!issue) return void 0;
9007
+ const path2 = issue.path.length > 0 ? `todoList[${issue.path[0]}]${issue.path.slice(1).map((p) => `.${String(p)}`).join("")}` : "todoList";
9008
+ return `${path2}: ${issue.message}`;
9009
+ }
8786
9010
  function normalizeTodoItem(item, existing) {
8787
9011
  const id = item.id ?? existing?.id;
8788
9012
  const step = item.step || item.title || item.description || existing?.step || existing?.title || existing?.description || `Step ${id}`;
@@ -8899,7 +9123,7 @@ function createPlanTool(stateRef, toolName, description) {
8899
9123
  schema: z.object({
8900
9124
  operation: z.enum(["write", "read", "update"]),
8901
9125
  expectedVersion: z.number().int().min(0).optional(),
8902
- todoList: z.array(z.union([todoWriteItemSchema, todoUpdateItemSchema])).optional()
9126
+ todoList: z.array(todoItemWireSchema).optional()
8903
9127
  }),
8904
9128
  func: async ({ operation, expectedVersion, todoList }) => {
8905
9129
  const toolStateRef = manageTodo._stateRef;
@@ -8965,7 +9189,10 @@ function createPlanTool(stateRef, toolName, description) {
8965
9189
  return {
8966
9190
  status: "error",
8967
9191
  operation,
8968
- error: parsed.error.issues[0]?.message || "Invalid todoList for write.",
9192
+ // The wire schema has `status` optional (one shape for write and
9193
+ // update), so a missing one is caught here — named, so the model
9194
+ // can fix the call.
9195
+ error: describeTodoIssue(parsed.error.issues[0]) || "Invalid todoList for write.",
8969
9196
  version: currentVersion,
8970
9197
  adherenceScore: stateRef.adherenceScore || 0
8971
9198
  };
@@ -8988,7 +9215,7 @@ function createPlanTool(stateRef, toolName, description) {
8988
9215
  return {
8989
9216
  status: "error",
8990
9217
  operation,
8991
- error: parsed.error.issues[0]?.message || "Invalid todoList for update.",
9218
+ error: describeTodoIssue(parsed.error.issues[0]) || "Invalid todoList for update.",
8992
9219
  version: currentVersion,
8993
9220
  adherenceScore: stateRef.adherenceScore || 0
8994
9221
  };
@@ -14754,8 +14981,127 @@ function sanitizeBedrockDocName(name, fallback = "document") {
14754
14981
  return cleaned || fallback;
14755
14982
  }
14756
14983
 
14984
+ // src/providers/utils/jsonSchemaRefs.ts
14985
+ var DEFINITION_KEYS = ["definitions", "$defs"];
14986
+ function inlineJsonSchemaRefs(schema) {
14987
+ if (!isObject(schema) || !containsRef(schema)) return schema;
14988
+ const root = structuredClone(schema);
14989
+ const selfReaching = /* @__PURE__ */ new Map();
14990
+ const targetOf = (ref) => {
14991
+ const target = resolvePointer(root, ref);
14992
+ return isObject(target) ? target : void 0;
14993
+ };
14994
+ const reachesItself = (target) => {
14995
+ const known = selfReaching.get(target);
14996
+ if (known !== void 0) return known;
14997
+ const seen = /* @__PURE__ */ new Set();
14998
+ const walk = (node) => {
14999
+ if (Array.isArray(node)) return node.some(walk);
15000
+ if (!isObject(node)) return false;
15001
+ if (typeof node.$ref === "string") {
15002
+ const next = targetOf(node.$ref);
15003
+ if (next === target) return true;
15004
+ if (next && !seen.has(next)) {
15005
+ seen.add(next);
15006
+ if (walk(next)) return true;
15007
+ }
15008
+ }
15009
+ return Object.entries(node).some(([key, value]) => key !== "$ref" && walk(value));
15010
+ };
15011
+ const result2 = walk(target);
15012
+ selfReaching.set(target, result2);
15013
+ return result2;
15014
+ };
15015
+ const keptRefs = /* @__PURE__ */ new Set();
15016
+ const expand = (node) => {
15017
+ if (Array.isArray(node)) return node.map(expand);
15018
+ if (!isObject(node)) return node;
15019
+ if (typeof node.$ref === "string") {
15020
+ const target = targetOf(node.$ref);
15021
+ if (target && !reachesItself(target)) {
15022
+ const { $ref: _inlined, ...siblings } = node;
15023
+ return { ...expand(target), ...expandEntries(siblings) };
15024
+ }
15025
+ keptRefs.add(node.$ref);
15026
+ return expandEntries(node);
15027
+ }
15028
+ return expandEntries(node);
15029
+ };
15030
+ const expandEntries = (node) => {
15031
+ const out = {};
15032
+ for (const [key, value] of Object.entries(node)) out[key] = key === "$ref" ? value : expand(value);
15033
+ return out;
15034
+ };
15035
+ const { definitions: _definitions, $defs: _defs, ...rootBody } = root;
15036
+ const result = typeof root.$ref === "string" ? expand(rootBody) : expandEntries(rootBody);
15037
+ for (const key of DEFINITION_KEYS) delete result[key];
15038
+ for (const key of DEFINITION_KEYS) {
15039
+ const block = root[key];
15040
+ if (!isObject(block)) continue;
15041
+ const needed = neededEntries(key, block, keptRefs);
15042
+ if (needed.length === 0) continue;
15043
+ const kept = {};
15044
+ for (const name of Object.keys(block)) if (needed.includes(name)) kept[name] = block[name];
15045
+ result[key] = kept;
15046
+ }
15047
+ return result;
15048
+ }
15049
+ function neededEntries(key, block, keptRefs) {
15050
+ const needed = [];
15051
+ const queue = [...keptRefs];
15052
+ while (queue.length > 0) {
15053
+ const ref = queue.shift();
15054
+ const segments = pointerSegments(ref);
15055
+ if (!segments || segments[0] !== key || segments.length < 2) continue;
15056
+ const name = segments[1];
15057
+ if (needed.includes(name) || !(name in block)) continue;
15058
+ needed.push(name);
15059
+ collectRefs(block[name], queue);
15060
+ }
15061
+ return needed;
15062
+ }
15063
+ function collectRefs(node, into) {
15064
+ if (Array.isArray(node)) {
15065
+ node.forEach((child) => collectRefs(child, into));
15066
+ return;
15067
+ }
15068
+ if (!isObject(node)) return;
15069
+ if (typeof node.$ref === "string") into.push(node.$ref);
15070
+ for (const [k, value] of Object.entries(node)) if (k !== "$ref") collectRefs(value, into);
15071
+ }
15072
+ function containsRef(node) {
15073
+ if (Array.isArray(node)) return node.some(containsRef);
15074
+ if (!isObject(node)) return false;
15075
+ if (typeof node.$ref === "string") return true;
15076
+ return Object.values(node).some(containsRef);
15077
+ }
15078
+ function pointerSegments(ref) {
15079
+ if (ref === "#") return [];
15080
+ if (!ref.startsWith("#/")) return null;
15081
+ return ref.slice(2).split("/").map((segment) => segment.replace(/~1/g, "/").replace(/~0/g, "~"));
15082
+ }
15083
+ function resolvePointer(document, ref) {
15084
+ const segments = pointerSegments(ref);
15085
+ if (!segments) return void 0;
15086
+ let current = document;
15087
+ for (const segment of segments) {
15088
+ if (Array.isArray(current)) {
15089
+ if (!/^\d+$/.test(segment)) return void 0;
15090
+ current = current[Number(segment)];
15091
+ } else if (isObject(current) && Object.prototype.hasOwnProperty.call(current, segment)) {
15092
+ current = current[segment];
15093
+ } else {
15094
+ return void 0;
15095
+ }
15096
+ }
15097
+ return current;
15098
+ }
15099
+ function isObject(value) {
15100
+ return typeof value === "object" && value !== null && !Array.isArray(value);
15101
+ }
15102
+
14757
15103
  // src/providers/openai.ts
14758
- var OpenAIProvider = class extends BaseProvider {
15104
+ var OpenAIProvider = class _OpenAIProvider extends BaseProvider {
14759
15105
  constructor(config) {
14760
15106
  super();
14761
15107
  this.providerName = "openai";
@@ -14767,8 +15113,21 @@ var OpenAIProvider = class extends BaseProvider {
14767
15113
  ...config.organization ? { "OpenAI-Organization": config.organization } : {}
14768
15114
  };
14769
15115
  this.responsesApi = config.responsesApi ?? "auto";
15116
+ const ownInstance = new.target === _OpenAIProvider;
15117
+ this.responsesApiModels = ownInstance ? [...config.responsesApiModels ?? []] : [];
15118
+ this.responsesStreaming = ownInstance && config.responsesStreaming === true;
14770
15119
  if (config.retry) this.retryPolicy = { ...this.retryPolicy, ...config.retry };
14771
15120
  }
15121
+ /** True when the caller listed this request's model in `responsesApiModels`. */
15122
+ isResponsesApiModel(request) {
15123
+ if (this.responsesApiModels.length === 0) return false;
15124
+ const model = request.model || this.defaultModel;
15125
+ return this.responsesApiModels.some((entry) => {
15126
+ if (typeof entry === "string") return entry === model;
15127
+ entry.lastIndex = 0;
15128
+ return entry.test(model);
15129
+ });
15130
+ }
14772
15131
  /** True when this request should go to the Responses API rather than Chat
14773
15132
  * Completions — which exposes `reasoning.effort` and reasoning summaries that
14774
15133
  * Chat Completions silently drops.
@@ -14777,10 +15136,14 @@ var OpenAIProvider = class extends BaseProvider {
14777
15136
  * carries a reasoning config AND the model name looks like an o-series/gpt-5
14778
15137
  * model. `never`/`always` let a caller state the answer instead, because the
14779
15138
  * name check is a guess and the two APIs differ in far more than reasoning —
14780
- * see `responsesApi` in OpenAIProviderConfig. */
15139
+ * see `responsesApi` in OpenAIProviderConfig.
15140
+ *
15141
+ * A model listed in `responsesApiModels` is the caller stating the answer
15142
+ * for that model alone; `never` still overrides it. */
14781
15143
  useResponsesApi(request) {
14782
15144
  if (this.responsesApi === "never") return false;
14783
15145
  if (this.responsesApi === "always") return true;
15146
+ if (this.isResponsesApiModel(request)) return true;
14784
15147
  if (!request.reasoning) return false;
14785
15148
  return isReasoningModel(request.model || this.defaultModel);
14786
15149
  }
@@ -14795,6 +15158,10 @@ var OpenAIProvider = class extends BaseProvider {
14795
15158
  }
14796
15159
  async *completeStream(request) {
14797
15160
  if (this.useResponsesApi(request)) {
15161
+ if (this.responsesStreaming && this.isResponsesApiModel(request)) {
15162
+ yield* this.streamResponses(request);
15163
+ return;
15164
+ }
14798
15165
  const response = await this.completeResponses(request);
14799
15166
  yield {
14800
15167
  id: response.id,
@@ -14910,10 +15277,101 @@ var OpenAIProvider = class extends BaseProvider {
14910
15277
  // ─── Responses API (reasoning models) ──────────────────────────────────────
14911
15278
  async completeResponses(request) {
14912
15279
  const body = this.buildResponsesBody(request);
15280
+ if (this.isResponsesApiModel(request)) adaptChatExtrasForResponses(body, request.extra);
14913
15281
  const res = await this.responsesFetch(body);
14914
15282
  const json = await res.json();
14915
15283
  return this.parseResponsesResponse(json, request.model || this.defaultModel);
14916
15284
  }
15285
+ /** Real Responses SSE streaming, for models opted in through
15286
+ * `responsesApiModels` with `responsesStreaming` on. Emits the same chunk
15287
+ * shapes as the Chat Completions stream: text deltas as they arrive, a tool
15288
+ * call's id + name when it opens and its argument fragments under that id,
15289
+ * then one final chunk with usage, finish reason and any reasoning summary
15290
+ * (taken from the completed response, exactly as the non-streaming parse
15291
+ * reads it). */
15292
+ async *streamResponses(request) {
15293
+ const modelId = request.model || this.defaultModel;
15294
+ const body = this.buildResponsesBody(request);
15295
+ adaptChatExtrasForResponses(body, request.extra);
15296
+ body.stream = true;
15297
+ const res = await this.responsesFetch(body);
15298
+ if (!res.body) throw new ProviderError("No response body for stream", this.providerName);
15299
+ let id = "";
15300
+ let model = modelId;
15301
+ const calls = /* @__PURE__ */ new Map();
15302
+ let final;
15303
+ for await (const event of parseSSEStream(res.body)) {
15304
+ if (event.data === "[DONE]") break;
15305
+ let data;
15306
+ try {
15307
+ data = JSON.parse(event.data);
15308
+ } catch {
15309
+ continue;
15310
+ }
15311
+ switch (data.type ?? event.event) {
15312
+ case "response.created":
15313
+ case "response.in_progress":
15314
+ id = data.response?.id ?? id;
15315
+ model = data.response?.model ?? model;
15316
+ break;
15317
+ case "response.output_text.delta":
15318
+ if (data.delta) yield { id, model, delta: { content: data.delta } };
15319
+ break;
15320
+ case "response.output_item.added": {
15321
+ const item = data.item;
15322
+ if (item?.type !== "function_call") break;
15323
+ const call = { callId: item.call_id ?? item.id ?? "", name: item.name ?? "", arguments: item.arguments ?? "" };
15324
+ calls.set(item.id ?? call.callId, call);
15325
+ yield { id, model, delta: { toolCalls: [{ id: call.callId, name: call.name, arguments: call.arguments }] } };
15326
+ break;
15327
+ }
15328
+ case "response.function_call_arguments.delta": {
15329
+ const call = calls.get(data.item_id);
15330
+ if (!call || !data.delta) break;
15331
+ call.arguments += data.delta;
15332
+ yield { id, model, delta: { toolCalls: [{ id: call.callId, arguments: data.delta }] } };
15333
+ break;
15334
+ }
15335
+ case "response.output_item.done": {
15336
+ const item = data.item;
15337
+ if (item?.type !== "function_call") break;
15338
+ const full = typeof item.arguments === "string" ? item.arguments : "";
15339
+ const call = calls.get(item.id ?? item.call_id);
15340
+ if (!call) {
15341
+ const added = { callId: item.call_id ?? item.id ?? "", name: item.name ?? "", arguments: full };
15342
+ calls.set(item.id ?? added.callId, added);
15343
+ yield { id, model, delta: { toolCalls: [{ id: added.callId, name: added.name, arguments: full }] } };
15344
+ } else if (full.length > call.arguments.length && full.startsWith(call.arguments)) {
15345
+ const rest = full.slice(call.arguments.length);
15346
+ call.arguments = full;
15347
+ yield { id, model, delta: { toolCalls: [{ id: call.callId, arguments: rest }] } };
15348
+ }
15349
+ break;
15350
+ }
15351
+ case "response.completed":
15352
+ case "response.incomplete":
15353
+ final = this.parseResponsesResponse(data.response ?? {}, modelId);
15354
+ break;
15355
+ case "response.failed":
15356
+ case "error": {
15357
+ const err = data.response?.error ?? data.error ?? data;
15358
+ throw new ProviderError(
15359
+ `OpenAI Responses API stream error: ${err?.message ?? "unknown error"}`,
15360
+ this.providerName,
15361
+ void 0,
15362
+ data
15363
+ );
15364
+ }
15365
+ }
15366
+ }
15367
+ yield {
15368
+ id: final?.id || id,
15369
+ model: final?.model || model,
15370
+ delta: final?.reasoning ? { reasoning: final.reasoning } : {},
15371
+ usage: final?.usage,
15372
+ finishReason: final?.finishReason ?? (calls.size > 0 ? "tool_calls" : "stop")
15373
+ };
15374
+ }
14917
15375
  buildResponsesBody(request) {
14918
15376
  const body = {
14919
15377
  model: request.model || this.defaultModel,
@@ -14943,7 +15401,7 @@ var OpenAIProvider = class extends BaseProvider {
14943
15401
  format: {
14944
15402
  type: "json_schema",
14945
15403
  name: request.responseFormat.name ?? "response",
14946
- schema: request.responseFormat.schema,
15404
+ schema: inlineJsonSchemaRefs(request.responseFormat.schema),
14947
15405
  strict: true
14948
15406
  }
14949
15407
  };
@@ -15198,6 +15656,48 @@ function isReasoningModel(model) {
15198
15656
  const m = model.toLowerCase();
15199
15657
  return /(^|[/_-])o[0-9]/.test(m) || m.startsWith("o1") || m.startsWith("o3") || m.startsWith("o4") || m.includes("gpt-5") || m.includes("gpt5");
15200
15658
  }
15659
+ function adaptChatExtrasForResponses(body, extra) {
15660
+ const native = extra ?? {};
15661
+ if ("reasoning_effort" in body) {
15662
+ const effort = body.reasoning_effort;
15663
+ delete body.reasoning_effort;
15664
+ if (effort != null) {
15665
+ const reasoning = body.reasoning && typeof body.reasoning === "object" ? body.reasoning : {};
15666
+ if (reasoning.effort == null) body.reasoning = { ...reasoning, effort };
15667
+ }
15668
+ }
15669
+ for (const key of ["max_tokens", "max_completion_tokens"]) {
15670
+ if (!(key in body)) continue;
15671
+ const value = body[key];
15672
+ delete body[key];
15673
+ if (value != null && !("max_output_tokens" in native)) body.max_output_tokens = value;
15674
+ }
15675
+ if ("response_format" in body) {
15676
+ const format = toResponsesTextFormat(body.response_format);
15677
+ delete body.response_format;
15678
+ if (format && !("text" in native)) body.text = { ...body.text, format };
15679
+ }
15680
+ if (body.stream_options && typeof body.stream_options === "object" && "include_usage" in body.stream_options) {
15681
+ const { include_usage: _dropped, ...rest } = body.stream_options;
15682
+ if (Object.keys(rest).length > 0) body.stream_options = rest;
15683
+ else delete body.stream_options;
15684
+ }
15685
+ }
15686
+ function toResponsesTextFormat(rf) {
15687
+ if (!rf || typeof rf !== "object") return void 0;
15688
+ if (rf.type === "json_schema") {
15689
+ const js = rf.json_schema ?? {};
15690
+ return {
15691
+ type: "json_schema",
15692
+ name: js.name ?? "response",
15693
+ schema: inlineJsonSchemaRefs(js.schema),
15694
+ ...js.description != null ? { description: js.description } : {},
15695
+ ...js.strict != null ? { strict: js.strict } : {}
15696
+ };
15697
+ }
15698
+ if (rf.type === "json_object" || rf.type === "text") return { type: rf.type };
15699
+ return void 0;
15700
+ }
15201
15701
  function expandResponsesInput(input) {
15202
15702
  const out = [];
15203
15703
  for (const item of input) {
@@ -16517,6 +17017,6 @@ function createProvider(config) {
16517
17017
  }
16518
17018
  }
16519
17019
 
16520
- 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, 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, promptInjectionGuard, rateLimit, readMemoryFacts, redactText, regexGuardrail, regexRule, replaceTextContent, resolveAvailableSkills, resolveAvailableSubagents, resolveInputRetention, resolveMemoryStore, resolveReasoning, resolveStrategy, resolveSubagentTools, resolveSummarizationRetention, resolveToolApprovalState, resolveUserQuestionState, responseCache, restoreSnapshot, runSmartAgentEvalHarness, scoreItemsByRelevance, searchSkills, seedChildMessages, selectTopIndicesInOrder, sessionMetrics, setTokenCounter, startStreamingSession, summarizeObject, textFromContent, tokenize, toolPolicy, traceSessionToOtlp, validateReasoningConfig, validateToolArgs, webhookApproval, withTools, withinDepth, writeSummaryFactsToMemory };
17020
+ 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 };
16521
17021
  //# sourceMappingURL=index.mjs.map
16522
17022
  //# sourceMappingURL=index.mjs.map