@jeffusion/bungee-llms 5.18.0 → 5.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -8499,10 +8499,922 @@ function createTokenAccountingSession(input, options = {}) {
8499
8499
  }
8500
8500
  };
8501
8501
  }
8502
+ // src/responses-codec/common.ts
8503
+ var DEFAULT_RESPONSES_CODEC_LIMITS = Object.freeze({
8504
+ maxRequestBytes: 8 * 1024 * 1024,
8505
+ maxOutputBytes: 8 * 1024 * 1024,
8506
+ maxArgumentBytes: 1024 * 1024,
8507
+ maxItems: 1024
8508
+ });
8509
+
8510
+ class ResponsesCodecError extends Error {
8511
+ code;
8512
+ constructor(code, message) {
8513
+ super(message);
8514
+ this.code = code;
8515
+ this.name = "ResponsesCodecError";
8516
+ }
8517
+ }
8518
+ function fail(code, message) {
8519
+ throw new ResponsesCodecError(code, message);
8520
+ }
8521
+ function record(value, where) {
8522
+ if (!value || typeof value !== "object" || Array.isArray(value))
8523
+ fail("invalid_payload", `${where} must be an object`);
8524
+ return value;
8525
+ }
8526
+ function string(value, where, nonempty = false) {
8527
+ if (typeof value !== "string" || nonempty && !value)
8528
+ fail("invalid_payload", `${where} must be a${nonempty ? " non-empty" : ""} string`);
8529
+ return value;
8530
+ }
8531
+ function list(value, where) {
8532
+ if (!Array.isArray(value))
8533
+ fail("invalid_payload", `${where} must be an array`);
8534
+ return value;
8535
+ }
8536
+ function limits(overrides) {
8537
+ const result = { ...DEFAULT_RESPONSES_CODEC_LIMITS, ...overrides };
8538
+ for (const [key, value] of Object.entries(result)) {
8539
+ if (!Number.isSafeInteger(value) || value <= 0)
8540
+ fail("invalid_limit", `${key} must be a positive integer`);
8541
+ }
8542
+ return result;
8543
+ }
8544
+ function bytes(value) {
8545
+ return new TextEncoder().encode(value).byteLength;
8546
+ }
8547
+ function bounded(value, max, where) {
8548
+ if (bytes(value) > max)
8549
+ fail("resource_limit", `${where} exceeds ${max} bytes`);
8550
+ return value;
8551
+ }
8552
+ function serialized(value, max, where) {
8553
+ let result;
8554
+ try {
8555
+ result = JSON.stringify(value);
8556
+ } catch {
8557
+ fail("invalid_payload", `${where} must be serializable JSON`);
8558
+ }
8559
+ if (result === undefined)
8560
+ fail("invalid_payload", `${where} must be serializable JSON`);
8561
+ return bounded(result, max, where);
8562
+ }
8563
+ function argumentObject(text) {
8564
+ let value;
8565
+ try {
8566
+ value = JSON.parse(text);
8567
+ } catch {
8568
+ fail("invalid_tool_arguments", "Tool arguments must be complete JSON");
8569
+ }
8570
+ return record(value, "tool arguments");
8571
+ }
8572
+ function restoreTool(name, names) {
8573
+ const result = names.get(name);
8574
+ if (result)
8575
+ return result;
8576
+ if (names.size)
8577
+ fail("unknown_tool", `Provider returned undeclared tool ${name}`);
8578
+ return { name, custom: false };
8579
+ }
8580
+ function customInput(text) {
8581
+ const value = argumentObject(text);
8582
+ if (Object.keys(value).length !== 1 || typeof value.input !== "string") {
8583
+ fail("invalid_tool_arguments", "Custom tools require exactly one string input property");
8584
+ }
8585
+ return value.input;
8586
+ }
8587
+ function customInputPrefix(text) {
8588
+ const prefix = /^\s*\{\s*"input"\s*:\s*"/.exec(text);
8589
+ if (!prefix)
8590
+ return "";
8591
+ let result = "";
8592
+ for (let i = prefix[0].length;i < text.length; ) {
8593
+ const char = text[i];
8594
+ if (char === '"')
8595
+ break;
8596
+ if (char !== "\\") {
8597
+ if (char.charCodeAt(0) < 32)
8598
+ fail("invalid_tool_arguments", "Invalid JSON string character");
8599
+ result += char;
8600
+ i++;
8601
+ continue;
8602
+ }
8603
+ const escape = text[i + 1];
8604
+ if (escape === undefined)
8605
+ break;
8606
+ const size = escape === "u" ? 6 : 2;
8607
+ if (i + size > text.length)
8608
+ break;
8609
+ try {
8610
+ result += JSON.parse(`"${text.slice(i, i + size)}"`);
8611
+ } catch {
8612
+ fail("invalid_tool_arguments", "Invalid JSON string escape");
8613
+ }
8614
+ i += size;
8615
+ }
8616
+ return result;
8617
+ }
8618
+ function terminal(reason, protocol) {
8619
+ if (typeof reason !== "string" || !reason)
8620
+ fail("missing_terminal", "Upstream has no explicit completion reason");
8621
+ const completed = protocol === "chat_completions" ? ["stop", "tool_calls", "function_call"] : ["end_turn", "tool_use", "stop_sequence"];
8622
+ if (completed.includes(reason))
8623
+ return { status: "completed", reason };
8624
+ if (reason === "length" || reason === "max_tokens" || reason === "model_context_window_exceeded")
8625
+ return { status: "incomplete", reason: "max_output_tokens" };
8626
+ if (reason === "content_filter" || reason === "refusal")
8627
+ return { status: "incomplete", reason: "content_filter" };
8628
+ if (reason === "error")
8629
+ return { status: "failed", reason: "upstream_error" };
8630
+ fail("unknown_terminal", `Unsupported upstream completion reason: ${reason}`);
8631
+ }
8632
+ function tokens(value, where) {
8633
+ if (value === undefined)
8634
+ return 0;
8635
+ if (!Number.isSafeInteger(value) || value < 0)
8636
+ fail("invalid_usage", `${where} must be a non-negative integer`);
8637
+ return value;
8638
+ }
8639
+ function normalizeUsage(raw, protocol, prior = {}) {
8640
+ if (raw === undefined || raw === null)
8641
+ return prior;
8642
+ const usage = record(raw, "usage");
8643
+ const chat = protocol === "chat_completions";
8644
+ const input = tokens(usage[chat ? "prompt_tokens" : "input_tokens"] ?? prior.input_tokens, "input_tokens");
8645
+ const output = tokens(usage[chat ? "completion_tokens" : "output_tokens"] ?? prior.output_tokens, "output_tokens");
8646
+ const details = chat ? usage.prompt_tokens_details : undefined;
8647
+ const cached = chat ? details ? record(details, "prompt_tokens_details").cached_tokens : undefined : usage.cache_read_input_tokens;
8648
+ const cacheRead = tokens(cached ?? prior.input_tokens_details?.cached_tokens, "cached_tokens");
8649
+ const cacheWrite = chat ? 0 : tokens(usage.cache_creation_input_tokens, "cache_creation_input_tokens");
8650
+ const totalInput = chat ? input : usage.input_tokens === undefined ? input : input + cacheRead + cacheWrite;
8651
+ const reasoning = chat && usage.completion_tokens_details ? record(usage.completion_tokens_details, "completion_tokens_details").reasoning_tokens : undefined;
8652
+ return {
8653
+ input_tokens: totalInput,
8654
+ output_tokens: output,
8655
+ total_tokens: totalInput + output,
8656
+ input_tokens_details: { cached_tokens: cacheRead },
8657
+ output_tokens_details: { reasoning_tokens: tokens(reasoning ?? prior.output_tokens_details?.reasoning_tokens, "reasoning_tokens") }
8658
+ };
8659
+ }
8660
+ function toolItem(id, name, args, names, status = "completed") {
8661
+ const original = restoreTool(name, names);
8662
+ const item = { id: `fc_${id}`, type: original.custom ? "custom_tool_call" : "function_call", call_id: id, name: original.name, status };
8663
+ if (original.namespace)
8664
+ item.namespace = original.namespace;
8665
+ if (original.custom)
8666
+ item.input = customInput(args);
8667
+ else {
8668
+ argumentObject(args);
8669
+ item.arguments = args;
8670
+ }
8671
+ return item;
8672
+ }
8673
+ function responsePayload(id, model, output, end, usage, error, createdAt = Math.floor(Date.now() / 1000)) {
8674
+ const result = { id, object: "response", created_at: createdAt, model, status: end.status, output, usage: Object.keys(usage).length ? usage : null };
8675
+ if (end.status === "incomplete")
8676
+ result.incomplete_details = { reason: end.reason };
8677
+ if (end.status === "failed")
8678
+ result.error = error ?? { code: end.reason, message: end.reason };
8679
+ return result;
8680
+ }
8681
+
8682
+ // src/responses-codec/request.ts
8683
+ var contentNormalizer = new OpenAIProtocolConversion({ trimWhitespace: false });
8684
+ function decodeResponsesRequest(raw, protocol, capabilities = {}) {
8685
+ const body = record(raw, "Responses request");
8686
+ const budget = limits(capabilities.limits);
8687
+ serialized(body, budget.maxRequestBytes, "request");
8688
+ const supported = new Set([
8689
+ "model",
8690
+ "input",
8691
+ "instructions",
8692
+ "tools",
8693
+ "tool_choice",
8694
+ "reasoning",
8695
+ "text",
8696
+ "stream",
8697
+ "temperature",
8698
+ "top_p",
8699
+ "parallel_tool_calls",
8700
+ "metadata",
8701
+ "max_output_tokens",
8702
+ "previous_response_id",
8703
+ "conversation",
8704
+ "response_id",
8705
+ "background",
8706
+ "n",
8707
+ "truncation",
8708
+ "include",
8709
+ "store"
8710
+ ]);
8711
+ for (const key of Object.keys(body))
8712
+ if (!supported.has(key))
8713
+ fail("unsupported_request", `Unsupported Responses request field ${key}`);
8714
+ if (body.store === true)
8715
+ fail("unsupported_request", "Stored Responses require caller-owned persistence");
8716
+ for (const key of ["previous_response_id", "conversation", "response_id"]) {
8717
+ if (body[key] != null)
8718
+ fail("unresolved_reference", `${key} must be resolved before protocol conversion`);
8719
+ }
8720
+ if (body.background === true)
8721
+ fail("unsupported_request", "Background Responses cannot be represented by this codec");
8722
+ if (body.n !== undefined && body.n !== 1)
8723
+ fail("unsupported_request", "Only one response candidate is supported");
8724
+ if (body.truncation !== undefined && body.truncation !== "disabled")
8725
+ fail("unsupported_request", "Automatic input truncation cannot be represented");
8726
+ if (body.include !== undefined && list(body.include, "include").length)
8727
+ fail("unsupported_request", "Requested extra Responses output fields cannot be represented");
8728
+ const model = string(body.model, "model", true);
8729
+ const toolNames = new Map;
8730
+ const byOriginal = new Map;
8731
+ const tools = [];
8732
+ const identity = (name, namespace) => JSON.stringify([namespace ?? null, name]);
8733
+ const register = (name, namespace, custom) => {
8734
+ const key = identity(name, namespace);
8735
+ if (byOriginal.has(key))
8736
+ fail("tool_name_collision", `Duplicate tool ${namespace ? namespace + "." : ""}${name}`);
8737
+ if (toolNames.size >= budget.maxItems)
8738
+ fail("resource_limit", "Too many tools");
8739
+ const wire = `bungee_tool_${toolNames.size}`;
8740
+ toolNames.set(wire, { name, namespace, custom });
8741
+ byOriginal.set(key, wire);
8742
+ return wire;
8743
+ };
8744
+ const expandTool = (rawTool, namespace) => {
8745
+ const tool = record(rawTool, "tool");
8746
+ if (tool.type === "namespace") {
8747
+ if (namespace !== undefined)
8748
+ fail("unsupported_tool", "Nested tool namespaces are not supported");
8749
+ const name = string(tool.name, "namespace name", true);
8750
+ for (const child of list(tool.tools, "namespace tools"))
8751
+ expandTool(child, name);
8752
+ return;
8753
+ }
8754
+ if (tool.type !== "function" && tool.type !== "custom")
8755
+ fail("unsupported_tool", `Hosted tool ${String(tool.type)} cannot be executed by Codex through this protocol`);
8756
+ const name = string(tool.name, "tool name", true);
8757
+ const custom = tool.type === "custom";
8758
+ if (tool.strict !== undefined && typeof tool.strict !== "boolean")
8759
+ fail("invalid_payload", "Tool strict must be boolean");
8760
+ if (protocol === "anthropic_messages" && tool.strict === true)
8761
+ fail("unsupported_tool", "Anthropic strict tool enforcement requires an explicit provider capability");
8762
+ if (custom && tool.format !== undefined) {
8763
+ const format = record(tool.format, "custom format");
8764
+ if (format.type !== "text" && format.type !== "grammar")
8765
+ fail("unsupported_tool", "Unknown custom tool format");
8766
+ }
8767
+ const wire = register(name, namespace, custom);
8768
+ const parameters = custom ? { type: "object", properties: { input: { type: "string" } }, required: ["input"], additionalProperties: false } : record(tool.parameters ?? { type: "object", properties: {} }, "tool parameters");
8769
+ const description = tool.description === undefined ? undefined : string(tool.description, "tool description");
8770
+ const customHint = custom ? `Pass the complete original custom tool input verbatim in the input string.${tool.format ? ` Original input format: ${JSON.stringify(tool.format)}` : ""}` : undefined;
8771
+ if (protocol === "chat_completions") {
8772
+ tools.push({ type: "function", function: { name: wire, parameters, ...description || customHint ? { description: [description, customHint].filter(Boolean).join(`
8773
+ `) } : {}, ...tool.strict !== undefined ? { strict: tool.strict } : {} } });
8774
+ } else {
8775
+ tools.push({ name: wire, input_schema: parameters, ...description || customHint ? { description: [description, customHint].filter(Boolean).join(`
8776
+ `) } : {} });
8777
+ }
8778
+ };
8779
+ if (body.tools !== undefined)
8780
+ for (const tool of list(body.tools, "tools"))
8781
+ expandTool(tool);
8782
+ const resolve = (item, custom) => {
8783
+ const name = string(item.name, "call name", true);
8784
+ const namespace = item.namespace === undefined ? undefined : string(item.namespace, "call namespace", true);
8785
+ let wire = byOriginal.get(identity(name, namespace));
8786
+ if (wire === undefined)
8787
+ wire = register(name, namespace, custom);
8788
+ if (toolNames.get(wire).custom !== custom)
8789
+ fail("tool_name_collision", `Tool kind changed for ${name}`);
8790
+ return wire;
8791
+ };
8792
+ const normalizeContent = (rawContent, role) => {
8793
+ if (typeof rawContent === "string")
8794
+ return rawContent;
8795
+ const parts = list(rawContent, "message content");
8796
+ for (const rawPart of parts) {
8797
+ const part = record(rawPart, "content part");
8798
+ if (part.type === "input_text" || part.type === "output_text" || part.type === "text")
8799
+ string(part.text, "content text");
8800
+ else if (part.type === "input_image" && role === "user") {
8801
+ if (protocol !== "chat_completions")
8802
+ fail("unsupported_content", "Anthropic image conversion requires provider-specific URL/data support");
8803
+ string(part.image_url, "image_url", true);
8804
+ if (part.detail !== undefined && !["auto", "low", "high"].includes(String(part.detail)))
8805
+ fail("unsupported_content", "Unknown image detail");
8806
+ } else
8807
+ fail("unsupported_content", `Unsupported message content: ${String(part.type)}`);
8808
+ if (part.annotations !== undefined && list(part.annotations, "annotations").length)
8809
+ fail("unsupported_content", "Output annotations cannot be represented in input history");
8810
+ }
8811
+ const normalized = contentNormalizer.normalizeResponsesMessageContent(parts);
8812
+ for (let i = 0;i < parts.length; i++) {
8813
+ const part = parts[i];
8814
+ if (part.type === "input_image" && part.detail !== undefined)
8815
+ normalized[i].image_url.detail = part.detail;
8816
+ }
8817
+ return normalized;
8818
+ };
8819
+ const chat = [];
8820
+ const callIds = new Set;
8821
+ const answered = new Set;
8822
+ let pendingReasoning = "";
8823
+ const addMessage = (message) => {
8824
+ if (chat.length >= budget.maxItems)
8825
+ fail("resource_limit", "Too many input messages");
8826
+ chat.push(message);
8827
+ };
8828
+ if (body.instructions !== undefined)
8829
+ addMessage({ role: "system", content: string(body.instructions, "instructions") });
8830
+ const input = typeof body.input === "string" ? [{ role: "user", content: body.input }] : list(body.input, "input");
8831
+ if (input.length > budget.maxItems)
8832
+ fail("resource_limit", "Too many input items");
8833
+ for (const rawItem of input) {
8834
+ const item = record(rawItem, "input item");
8835
+ if (item.encrypted_content !== undefined || item.type === "compaction")
8836
+ fail("unsupported_content", "Encrypted reasoning and compaction cannot be restored");
8837
+ if (item.type === "item_reference")
8838
+ fail("unresolved_reference", "Input item references must be resolved before conversion");
8839
+ if (item.type === "reasoning") {
8840
+ if (protocol !== "chat_completions" || !capabilities.reasoningEffort)
8841
+ fail("unsupported_reasoning", "Reasoning history requires an explicit compatible reasoning capability");
8842
+ const summary = list(item.summary, "reasoning summary");
8843
+ pendingReasoning += summary.map((part) => {
8844
+ const p = record(part, "reasoning summary");
8845
+ if (p.type !== "summary_text")
8846
+ fail("unsupported_reasoning", "Unknown reasoning summary");
8847
+ return string(p.text, "summary text");
8848
+ }).join("");
8849
+ continue;
8850
+ }
8851
+ if (item.type === "function_call" || item.type === "custom_tool_call") {
8852
+ const custom = item.type === "custom_tool_call";
8853
+ const id = string(item.call_id, "call_id", true);
8854
+ if (callIds.has(id))
8855
+ fail("invalid_tool_history", `Duplicate call_id ${id}`);
8856
+ callIds.add(id);
8857
+ const args = custom ? JSON.stringify({ input: string(item.input, "custom input") }) : string(item.arguments, "arguments");
8858
+ bounded(args, budget.maxArgumentBytes, "arguments");
8859
+ argumentObject(args);
8860
+ const call = { id, type: "function", function: { name: resolve(item, custom), arguments: args } };
8861
+ const previous = chat.at(-1);
8862
+ if (previous?.role === "assistant") {
8863
+ previous.tool_calls = [...previous.tool_calls ?? [], call];
8864
+ if (pendingReasoning)
8865
+ previous.reasoning_content = pendingReasoning;
8866
+ } else
8867
+ addMessage({ role: "assistant", content: null, tool_calls: [call], ...pendingReasoning ? { reasoning_content: pendingReasoning } : {} });
8868
+ pendingReasoning = "";
8869
+ continue;
8870
+ }
8871
+ if (item.type === "function_call_output" || item.type === "custom_tool_call_output") {
8872
+ const id = string(item.call_id, "call_id", true);
8873
+ if (!callIds.has(id) || answered.has(id))
8874
+ fail("invalid_tool_history", `Unmatched or duplicate output ${id}`);
8875
+ answered.add(id);
8876
+ const output = typeof item.output === "string" ? item.output : normalizeContent(item.output, "tool");
8877
+ addMessage({ role: "tool", tool_call_id: id, content: output, ...item.is_error === true ? { is_error: true } : {} });
8878
+ continue;
8879
+ }
8880
+ if (item.type !== undefined && item.type !== "message")
8881
+ fail("unsupported_content", `Unsupported input item ${String(item.type)}`);
8882
+ const role = string(item.role, "message role", true);
8883
+ if (!["user", "assistant", "system", "developer"].includes(role))
8884
+ fail("unsupported_content", `Unknown message role ${role}`);
8885
+ const message = { role, content: normalizeContent(item.content, role) };
8886
+ if (pendingReasoning) {
8887
+ if (role !== "assistant")
8888
+ fail("unsupported_reasoning", "Reasoning must precede an assistant item");
8889
+ message.reasoning_content = pendingReasoning;
8890
+ pendingReasoning = "";
8891
+ }
8892
+ addMessage(message);
8893
+ }
8894
+ if (pendingReasoning)
8895
+ fail("unsupported_reasoning", "Orphan reasoning history cannot be represented");
8896
+ const result = { model, messages: chat };
8897
+ for (const key of ["stream", "temperature", "top_p", "parallel_tool_calls", "metadata"])
8898
+ if (body[key] !== undefined)
8899
+ result[key] = body[key];
8900
+ if (protocol === "chat_completions" && body.stream === true)
8901
+ result.stream_options = { include_usage: true };
8902
+ const maxTokens = body.max_output_tokens ?? capabilities.maxOutputTokens;
8903
+ if (maxTokens !== undefined) {
8904
+ if (!Number.isSafeInteger(maxTokens) || maxTokens <= 0)
8905
+ fail("invalid_payload", "max_output_tokens must be a positive integer");
8906
+ result[protocol === "chat_completions" ? "max_completion_tokens" : "max_tokens"] = maxTokens;
8907
+ }
8908
+ if (tools.length)
8909
+ result.tools = tools;
8910
+ if (body.tool_choice !== undefined) {
8911
+ const choice = body.tool_choice;
8912
+ if (typeof choice === "string") {
8913
+ if (!["auto", "none", "required"].includes(choice))
8914
+ fail("unsupported_tool_choice", `Unsupported tool choice ${choice}`);
8915
+ result.tool_choice = protocol === "chat_completions" ? choice : { type: choice === "required" ? "any" : choice };
8916
+ } else {
8917
+ const c = record(choice, "tool_choice");
8918
+ if (c.type !== "function" && c.type !== "custom")
8919
+ fail("unsupported_tool_choice", "Forced hosted tools are unsupported");
8920
+ const wire = byOriginal.get(identity(string(c.name, "tool choice name", true), c.namespace === undefined ? undefined : string(c.namespace, "tool choice namespace")));
8921
+ if (!wire || !tools.some((t) => t.name === wire || t.function?.name === wire))
8922
+ fail("unsupported_tool_choice", "Forced tool is not declared");
8923
+ result.tool_choice = protocol === "chat_completions" ? { type: "function", function: { name: wire } } : { type: "tool", name: wire };
8924
+ }
8925
+ }
8926
+ if (body.reasoning !== undefined) {
8927
+ const reasoning = record(body.reasoning, "reasoning");
8928
+ if (reasoning.summary !== undefined && reasoning.summary !== "none")
8929
+ fail("unsupported_reasoning", "Requested reasoning summaries are not guaranteed by this upstream protocol");
8930
+ if (reasoning.effort !== undefined && reasoning.effort !== "none") {
8931
+ const effort = string(reasoning.effort, "reasoning effort", true);
8932
+ if (protocol === "chat_completions") {
8933
+ if (!capabilities.reasoningEffort)
8934
+ fail("unsupported_reasoning", "Upstream does not advertise reasoning effort");
8935
+ result.reasoning_effort = effort;
8936
+ } else {
8937
+ const thinking = capabilities.anthropicThinkingBudget;
8938
+ if (!Number.isSafeInteger(thinking) || thinking < 1024 || typeof maxTokens !== "number" || thinking >= maxTokens)
8939
+ fail("unsupported_reasoning", "Anthropic thinking requires an explicit budget below max_output_tokens");
8940
+ result.thinking = { type: "enabled", budget_tokens: thinking };
8941
+ }
8942
+ }
8943
+ }
8944
+ if (body.text !== undefined) {
8945
+ const text = record(body.text, "text");
8946
+ if (text.verbosity !== undefined)
8947
+ fail("unsupported_request", "Text verbosity cannot be represented");
8948
+ if (text.format !== undefined) {
8949
+ const format = record(text.format, "text format");
8950
+ if (protocol !== "chat_completions" && format.type !== "text")
8951
+ fail("unsupported_request", "Anthropic structured output requires a separate provider capability");
8952
+ if (format.type === "json_schema")
8953
+ result.response_format = { type: "json_schema", json_schema: { name: format.name, schema: format.schema, ...format.strict !== undefined ? { strict: format.strict } : {}, ...format.description !== undefined ? { description: format.description } : {} } };
8954
+ else if (format.type === "json_object" || format.type === "text") {
8955
+ if (protocol === "chat_completions")
8956
+ result.response_format = format;
8957
+ } else
8958
+ fail("unsupported_request", "Unknown text format");
8959
+ }
8960
+ }
8961
+ if (protocol === "anthropic_messages") {
8962
+ const system = [];
8963
+ const messages = [];
8964
+ const append = (role, content) => {
8965
+ const previous = messages.at(-1);
8966
+ if (previous?.role === role)
8967
+ previous.content.push(...content);
8968
+ else
8969
+ messages.push({ role, content });
8970
+ };
8971
+ for (const msg of chat) {
8972
+ if (msg.role === "system" || msg.role === "developer") {
8973
+ if (messages.length)
8974
+ fail("unsupported_content", "Mid-conversation system instructions cannot be relocated safely");
8975
+ system.push(typeof msg.content === "string" ? msg.content : msg.content.map((p) => string(p.text, "system text")).join(""));
8976
+ continue;
8977
+ }
8978
+ if (msg.role === "tool") {
8979
+ append("user", [{ type: "tool_result", tool_use_id: msg.tool_call_id, content: msg.content, ...msg.is_error ? { is_error: true } : {} }]);
8980
+ } else {
8981
+ const content = msg.content == null ? [] : typeof msg.content === "string" ? [{ type: "text", text: msg.content }] : msg.content;
8982
+ for (const call of msg.tool_calls ?? []) {
8983
+ const fn = call.function;
8984
+ content.push({ type: "tool_use", id: call.id, name: fn.name, input: argumentObject(fn.arguments) });
8985
+ }
8986
+ append(msg.role, content);
8987
+ }
8988
+ }
8989
+ result.messages = messages;
8990
+ if (system.length)
8991
+ result.system = system.join(`
8992
+ `);
8993
+ if (maxTokens === undefined)
8994
+ fail("missing_capability", "Anthropic requires max_output_tokens or capabilities.maxOutputTokens");
8995
+ if (body.parallel_tool_calls !== undefined) {
8996
+ result.tool_choice = { ...record(result.tool_choice ?? { type: "auto" }, "tool_choice"), disable_parallel_tool_use: body.parallel_tool_calls === false };
8997
+ delete result.parallel_tool_calls;
8998
+ }
8999
+ }
9000
+ return { body: result, toolNames };
9001
+ }
9002
+ // src/responses-codec/events.ts
9003
+ class ResponsesEventEncoder {
9004
+ protocol;
9005
+ model;
9006
+ toolNames;
9007
+ budget;
9008
+ id = `resp_${crypto.randomUUID().replaceAll("-", "")}`;
9009
+ createdAt = Math.floor(Date.now() / 1000);
9010
+ output = [];
9011
+ states = new Map;
9012
+ anthropicBlocks = new Map;
9013
+ usage = {};
9014
+ end;
9015
+ error;
9016
+ started = false;
9017
+ anthropicStarted = false;
9018
+ anthropicStopped = false;
9019
+ finalized = false;
9020
+ poisoned = false;
9021
+ sequence = 0;
9022
+ retained = 0;
9023
+ constructor(protocol, model, toolNames = new Map, configuredLimits) {
9024
+ this.protocol = protocol;
9025
+ this.model = model;
9026
+ this.toolNames = toolNames;
9027
+ this.budget = limits(configuredLimits);
9028
+ }
9029
+ event(type, fields = {}) {
9030
+ return { type, sequence_number: this.sequence++, ...fields };
9031
+ }
9032
+ start(events) {
9033
+ if (this.started)
9034
+ return;
9035
+ this.started = true;
9036
+ const payload = { id: this.id, object: "response", created_at: this.createdAt, model: this.model, status: "in_progress", output: [], usage: null };
9037
+ events.push(this.event("response.created", { response: payload }), this.event("response.in_progress", { response: { ...payload } }));
9038
+ }
9039
+ retain(text) {
9040
+ this.retained += bytes(text);
9041
+ if (this.retained > this.budget.maxOutputBytes)
9042
+ fail("resource_limit", "Accumulated response output exceeds maxOutputBytes");
9043
+ }
9044
+ state(key, kind) {
9045
+ const existing = this.states.get(key);
9046
+ if (existing) {
9047
+ if (existing.kind !== kind)
9048
+ fail("invalid_stream", "Output item changed kind");
9049
+ return existing;
9050
+ }
9051
+ if (this.output.length >= this.budget.maxItems)
9052
+ fail("resource_limit", "Too many output items");
9053
+ const state = { key, index: this.output.length, kind, id: `${this.id}_item_${this.output.length}`, text: "", name: "", callId: "", args: "", emittedInput: "", added: false, closed: false };
9054
+ this.states.set(key, state);
9055
+ this.output.push(state);
9056
+ return state;
9057
+ }
9058
+ fields(state) {
9059
+ return { response_id: this.id, item_id: state.id, output_index: state.index };
9060
+ }
9061
+ item(state, status, strict = false) {
9062
+ if (state.kind === "tool") {
9063
+ if (strict)
9064
+ return { ...toolItem(state.callId, state.name, state.args || "{}", this.toolNames, status), id: state.id };
9065
+ const original = state.original ?? restoreTool(state.name, this.toolNames);
9066
+ return {
9067
+ id: state.id,
9068
+ type: original.custom ? "custom_tool_call" : "function_call",
9069
+ call_id: state.callId,
9070
+ name: original.name,
9071
+ ...original.namespace ? { namespace: original.namespace } : {},
9072
+ status,
9073
+ ...original.custom ? { input: state.emittedInput } : { arguments: state.args }
9074
+ };
9075
+ }
9076
+ if (state.kind === "reasoning")
9077
+ return { id: state.id, type: "reasoning", summary: status === "in_progress" ? [] : [{ type: "summary_text", text: state.text }] };
9078
+ return {
9079
+ id: state.id,
9080
+ type: "message",
9081
+ role: "assistant",
9082
+ status,
9083
+ content: status === "in_progress" ? [] : [this.part(state)]
9084
+ };
9085
+ }
9086
+ part(state) {
9087
+ return state.kind === "refusal" ? { type: "refusal", refusal: state.text } : state.kind === "reasoning" ? { type: "summary_text", text: state.text } : { type: "output_text", text: state.text, annotations: [] };
9088
+ }
9089
+ add(state, events, final = false) {
9090
+ if (state.added)
9091
+ return;
9092
+ if (state.kind === "tool") {
9093
+ if (!state.callId || !state.name || this.toolNames.size && !this.toolNames.has(state.name))
9094
+ return;
9095
+ if (!final && !state.args && [...this.toolNames.keys()].some((name) => name !== state.name && name.startsWith(state.name)))
9096
+ return;
9097
+ state.original = restoreTool(state.name, this.toolNames);
9098
+ }
9099
+ state.added = true;
9100
+ const initial = this.item(state, "in_progress");
9101
+ if (state.kind === "tool") {
9102
+ if (state.original?.custom)
9103
+ initial.input = "";
9104
+ else
9105
+ initial.arguments = "";
9106
+ }
9107
+ events.push(this.event("response.output_item.added", { response_id: this.id, output_index: state.index, item: initial }));
9108
+ if (state.kind !== "tool") {
9109
+ const part = state.kind === "reasoning" ? { type: "summary_text", text: "" } : state.kind === "refusal" ? { type: "refusal", refusal: "" } : { type: "output_text", text: "", annotations: [] };
9110
+ events.push(this.event(state.kind === "reasoning" ? "response.reasoning_summary_part.added" : "response.content_part.added", { ...this.fields(state), [state.kind === "reasoning" ? "summary_index" : "content_index"]: 0, part }));
9111
+ }
9112
+ }
9113
+ appendText(state, delta, events) {
9114
+ if (state.closed)
9115
+ fail("invalid_stream", "Delta arrived after content block stop");
9116
+ this.retain(delta);
9117
+ state.text += delta;
9118
+ this.add(state, events);
9119
+ const type = state.kind === "reasoning" ? "response.reasoning_summary_text.delta" : state.kind === "refusal" ? "response.refusal.delta" : "response.output_text.delta";
9120
+ if (delta)
9121
+ events.push(this.event(type, { ...this.fields(state), [state.kind === "reasoning" ? "summary_index" : "content_index"]: 0, delta }));
9122
+ }
9123
+ emitArgs(state, events, fragment = "", first = false) {
9124
+ if (!state.added)
9125
+ return;
9126
+ if (state.original?.custom) {
9127
+ const prefix = customInputPrefix(state.args);
9128
+ if (!prefix.startsWith(state.emittedInput))
9129
+ fail("invalid_tool_arguments", "Custom input prefix changed");
9130
+ const delta = prefix.slice(state.emittedInput.length);
9131
+ state.emittedInput = prefix;
9132
+ if (delta)
9133
+ events.push(this.event("response.custom_tool_call_input.delta", { ...this.fields(state), delta }));
9134
+ } else {
9135
+ const delta = first ? state.args : fragment;
9136
+ if (delta)
9137
+ events.push(this.event("response.function_call_arguments.delta", { ...this.fields(state), delta }));
9138
+ }
9139
+ }
9140
+ toolDelta(state, raw, events) {
9141
+ if (state.closed)
9142
+ fail("invalid_stream", "Tool delta arrived after content block stop");
9143
+ if (raw.id !== undefined) {
9144
+ const id = string(raw.id, "tool call id", true);
9145
+ if (state.callId && state.callId !== id)
9146
+ fail("invalid_stream", "Tool call id changed");
9147
+ if (!state.callId)
9148
+ this.retain(id);
9149
+ state.callId = id;
9150
+ }
9151
+ const fn = raw.function === undefined ? {} : record(raw.function, "tool function");
9152
+ if (fn.name !== undefined) {
9153
+ const name = string(fn.name, "tool name");
9154
+ if (state.added && name)
9155
+ fail("invalid_stream", "Tool name changed after output_item.added");
9156
+ this.retain(name);
9157
+ state.name += name;
9158
+ }
9159
+ const args = fn.arguments === undefined ? "" : string(fn.arguments, "tool arguments delta");
9160
+ this.retain(args);
9161
+ state.args = bounded(state.args + args, this.budget.maxArgumentBytes, "tool arguments");
9162
+ const wasAdded = state.added;
9163
+ this.add(state, events);
9164
+ this.emitArgs(state, events, args, !wasAdded);
9165
+ }
9166
+ push(raw) {
9167
+ if (this.poisoned)
9168
+ fail("invalid_stream", "Encoder cannot continue after a codec error");
9169
+ if (this.finalized)
9170
+ fail("invalid_stream", "Event arrived after response terminal");
9171
+ try {
9172
+ const chunk = record(raw, "stream event");
9173
+ serialized(chunk, this.budget.maxOutputBytes, "stream event");
9174
+ const events = [];
9175
+ this.start(events);
9176
+ if (chunk.error !== undefined || chunk.type === "error") {
9177
+ this.error = record(chunk.error, "upstream error");
9178
+ this.end = { status: "failed", reason: "upstream_error" };
9179
+ this.anthropicStopped = true;
9180
+ return [...events, ...this.complete()];
9181
+ }
9182
+ if (this.protocol === "chat_completions")
9183
+ this.chat(chunk, events);
9184
+ else
9185
+ this.anthropic(chunk, events);
9186
+ return events;
9187
+ } catch (error) {
9188
+ this.poisoned = true;
9189
+ throw error;
9190
+ }
9191
+ }
9192
+ chat(chunk, events) {
9193
+ const choices = list(chunk.choices, "choices");
9194
+ if (choices.length > 1)
9195
+ fail("unsupported_response", "Multiple response candidates are not supported");
9196
+ if (choices.length) {
9197
+ const choice = record(choices[0], "choice");
9198
+ if (choice.index !== undefined && choice.index !== 0)
9199
+ fail("unsupported_response", "Only choice index 0 is supported");
9200
+ const delta = record(choice.delta ?? {}, "choice delta");
9201
+ for (const key of Object.keys(delta))
9202
+ if (!["role", "content", "refusal", "reasoning_content", "reasoning", "tool_calls", "function_call", "annotations"].includes(key))
9203
+ fail("unsupported_content", `Unsupported Chat output field ${key}`);
9204
+ if (delta.annotations !== undefined && list(delta.annotations, "annotations").length)
9205
+ fail("unsupported_content", "Chat output annotations cannot be faithfully converted");
9206
+ if (delta.role !== undefined && delta.role !== "assistant")
9207
+ fail("unsupported_response", "Response role must be assistant");
9208
+ if (this.end && Object.values(delta).some((v) => v !== undefined && v !== null && v !== "" && (!Array.isArray(v) || v.length)))
9209
+ fail("invalid_stream", "Output arrived after finish_reason");
9210
+ const reasoning = delta.reasoning_content ?? delta.reasoning;
9211
+ if (reasoning !== undefined && reasoning !== null)
9212
+ this.appendText(this.state("reasoning", "reasoning"), string(reasoning, "reasoning delta"), events);
9213
+ if (delta.content !== undefined && delta.content !== null)
9214
+ this.appendText(this.state("text", "text"), string(delta.content, "text delta"), events);
9215
+ if (delta.refusal !== undefined && delta.refusal !== null)
9216
+ this.appendText(this.state("refusal", "refusal"), string(delta.refusal, "refusal delta"), events);
9217
+ if (delta.tool_calls !== undefined) {
9218
+ for (const rawTool of list(delta.tool_calls, "tool_calls")) {
9219
+ const tool = record(rawTool, "tool call");
9220
+ if (!Number.isSafeInteger(tool.index) || tool.index < 0)
9221
+ fail("invalid_stream", "Streamed tool requires a non-negative integer index");
9222
+ if (tool.type !== undefined && tool.type !== "function")
9223
+ fail("unsupported_tool", "Unknown upstream tool call type");
9224
+ this.toolDelta(this.state(`tool:${tool.index}`, "tool"), tool, events);
9225
+ }
9226
+ }
9227
+ if (delta.function_call !== undefined)
9228
+ fail("unsupported_response", "Legacy function_call lacks a stable call_id");
9229
+ if (choice.finish_reason !== undefined && choice.finish_reason !== null) {
9230
+ const next = terminal(choice.finish_reason, this.protocol);
9231
+ if (this.end && (this.end.status !== next.status || this.end.reason !== next.reason))
9232
+ fail("invalid_stream", "Conflicting finish reasons");
9233
+ this.end = next;
9234
+ }
9235
+ }
9236
+ this.usage = normalizeUsage(chunk.usage, this.protocol, this.usage);
9237
+ }
9238
+ anthropic(chunk, events) {
9239
+ if (chunk.type === "ping")
9240
+ return;
9241
+ if (this.anthropicStopped)
9242
+ fail("invalid_stream", "Event arrived after message_stop");
9243
+ if (chunk.type === "message_start") {
9244
+ if (this.anthropicStarted)
9245
+ fail("invalid_stream", "Duplicate message_start");
9246
+ const message = record(chunk.message, "message");
9247
+ this.anthropicStarted = true;
9248
+ this.usage = normalizeUsage(message.usage, this.protocol, this.usage);
9249
+ return;
9250
+ }
9251
+ if (!this.anthropicStarted)
9252
+ fail("invalid_stream", "Anthropic event arrived before message_start");
9253
+ if (chunk.type === "message_delta") {
9254
+ const delta = record(chunk.delta, "message delta");
9255
+ if (delta.stop_reason != null) {
9256
+ const next = terminal(delta.stop_reason, this.protocol);
9257
+ if (this.end && (this.end.status !== next.status || this.end.reason !== next.reason))
9258
+ fail("invalid_stream", "Conflicting stop reasons");
9259
+ this.end = next;
9260
+ }
9261
+ this.usage = normalizeUsage(chunk.usage, this.protocol, this.usage);
9262
+ return;
9263
+ }
9264
+ if (chunk.type === "message_stop") {
9265
+ if (!this.end)
9266
+ fail("missing_terminal", "message_stop has no preceding stop_reason");
9267
+ if ([...this.anthropicBlocks.values()].some((s) => !s.closed))
9268
+ fail("invalid_stream", "message_stop arrived before content_block_stop");
9269
+ this.anthropicStopped = true;
9270
+ return;
9271
+ }
9272
+ if (!Number.isSafeInteger(chunk.index) || chunk.index < 0)
9273
+ fail("invalid_stream", "Anthropic content requires a non-negative integer index");
9274
+ const index = chunk.index;
9275
+ if (this.end)
9276
+ fail("invalid_stream", "Content arrived after stop_reason");
9277
+ if (chunk.type === "content_block_start") {
9278
+ if (this.anthropicBlocks.has(index))
9279
+ fail("invalid_stream", "Duplicate content_block_start");
9280
+ const block = record(chunk.content_block, "content block");
9281
+ const kind = block.type === "tool_use" ? "tool" : block.type === "text" ? "text" : block.type === "thinking" ? "reasoning" : undefined;
9282
+ if (!kind)
9283
+ fail("unsupported_content", `Unsupported Anthropic block ${String(block.type)}`);
9284
+ const state = this.state(`block:${index}`, kind);
9285
+ this.anthropicBlocks.set(index, state);
9286
+ if (kind === "tool") {
9287
+ const input = record(block.input ?? {}, "tool input");
9288
+ this.toolDelta(state, { id: block.id, function: { name: block.name, ...Object.keys(input).length ? { arguments: serialized(input, this.budget.maxArgumentBytes, "tool input") } : {} } }, events);
9289
+ } else
9290
+ this.appendText(state, string(block[kind === "text" ? "text" : "thinking"] ?? "", "block text"), events);
9291
+ return;
9292
+ }
9293
+ const state = this.anthropicBlocks.get(index);
9294
+ if (!state || state.closed)
9295
+ fail("invalid_stream", "Content event has no open block");
9296
+ if (chunk.type === "content_block_stop") {
9297
+ state.closed = true;
9298
+ return;
9299
+ }
9300
+ if (chunk.type !== "content_block_delta")
9301
+ fail("unsupported_response", `Unknown Anthropic event ${String(chunk.type)}`);
9302
+ const delta = record(chunk.delta, "content delta");
9303
+ if (delta.type === "input_json_delta" && state.kind === "tool")
9304
+ this.toolDelta(state, { function: { arguments: delta.partial_json } }, events);
9305
+ else if (delta.type === "text_delta" && state.kind === "text")
9306
+ this.appendText(state, string(delta.text, "text delta"), events);
9307
+ else if (delta.type === "thinking_delta" && state.kind === "reasoning")
9308
+ this.appendText(state, string(delta.thinking, "thinking delta"), events);
9309
+ else if (delta.type === "signature_delta" && state.kind === "reasoning") {
9310
+ bounded(string(delta.signature, "signature"), this.budget.maxArgumentBytes, "signature");
9311
+ } else
9312
+ fail("unsupported_content", `Unsupported content delta ${String(delta.type)}`);
9313
+ }
9314
+ complete() {
9315
+ if (!this.end)
9316
+ fail("missing_terminal", "Stream ended without an explicit upstream terminal");
9317
+ const events = [];
9318
+ const items = [];
9319
+ const callIds = new Set;
9320
+ for (const state of this.output) {
9321
+ const strict = this.end.status === "completed";
9322
+ if (state.kind === "tool") {
9323
+ if (!state.callId || !state.name)
9324
+ fail("invalid_tool_arguments", "Tool call is missing id or name");
9325
+ if (callIds.has(state.callId))
9326
+ fail("invalid_tool_arguments", "Duplicate provider call_id");
9327
+ callIds.add(state.callId);
9328
+ state.original ??= restoreTool(state.name, this.toolNames);
9329
+ this.add(state, events, true);
9330
+ if (!state.added)
9331
+ fail("unknown_tool", `Unknown tool ${state.name}`);
9332
+ if (strict) {
9333
+ argumentObject(state.args || "{}");
9334
+ if (state.original.custom) {
9335
+ const text = customInput(state.args);
9336
+ if (!text.startsWith(state.emittedInput))
9337
+ fail("invalid_tool_arguments", "Custom tool input changed");
9338
+ if (text.length > state.emittedInput.length)
9339
+ events.push(this.event("response.custom_tool_call_input.delta", { ...this.fields(state), delta: text.slice(state.emittedInput.length) }));
9340
+ state.emittedInput = text;
9341
+ }
9342
+ }
9343
+ }
9344
+ const item = this.item(state, this.end.status === "completed" ? "completed" : "incomplete", strict);
9345
+ const fields = this.fields(state);
9346
+ if (state.kind === "tool") {
9347
+ const custom = state.original.custom;
9348
+ events.push(this.event(custom ? "response.custom_tool_call_input.done" : "response.function_call_arguments.done", { ...fields, [custom ? "input" : "arguments"]: custom ? item.input : item.arguments }));
9349
+ } else {
9350
+ const reasoning = state.kind === "reasoning";
9351
+ const textField = state.kind === "refusal" ? "refusal" : "text";
9352
+ events.push(this.event(reasoning ? "response.reasoning_summary_text.done" : state.kind === "refusal" ? "response.refusal.done" : "response.output_text.done", { ...fields, [reasoning ? "summary_index" : "content_index"]: 0, [textField]: state.text }));
9353
+ events.push(this.event(reasoning ? "response.reasoning_summary_part.done" : "response.content_part.done", { ...fields, [reasoning ? "summary_index" : "content_index"]: 0, part: this.part(state) }));
9354
+ }
9355
+ events.push(this.event("response.output_item.done", { response_id: this.id, output_index: state.index, item }));
9356
+ items.push(item);
9357
+ }
9358
+ const response = responsePayload(this.id, this.model, items, this.end, this.usage, this.error, this.createdAt);
9359
+ serialized(response, this.budget.maxOutputBytes, "final response");
9360
+ events.push(this.event(`response.${this.end.status}`, { response }));
9361
+ this.finalized = true;
9362
+ return events;
9363
+ }
9364
+ finish() {
9365
+ if (this.poisoned)
9366
+ fail("invalid_stream", "Encoder cannot finish after a codec error");
9367
+ if (this.finalized)
9368
+ return [];
9369
+ try {
9370
+ if (this.protocol === "anthropic_messages" && !this.anthropicStopped)
9371
+ fail("missing_terminal", "Anthropic stream ended before message_stop");
9372
+ return this.complete();
9373
+ } catch (error) {
9374
+ this.poisoned = true;
9375
+ throw error;
9376
+ }
9377
+ }
9378
+ }
9379
+
9380
+ // src/responses-codec/result.ts
9381
+ function encodeResponsesResult(raw, protocol, model, toolNames = new Map, configuredLimits) {
9382
+ const body = record(raw, "upstream response");
9383
+ const budget = limits(configuredLimits);
9384
+ serialized(body, budget.maxOutputBytes, "upstream response");
9385
+ if (body.error !== undefined || body.type === "error")
9386
+ return responsePayload(`resp_${crypto.randomUUID().replaceAll("-", "")}`, model, [], { status: "failed", reason: "upstream_error" }, {}, record(body.error, "upstream error"));
9387
+ const encoder = new ResponsesEventEncoder(protocol, model, toolNames, configuredLimits);
9388
+ if (protocol === "chat_completions") {
9389
+ const choices = list(body.choices, "choices");
9390
+ if (choices.length !== 1)
9391
+ fail("unsupported_response", "Exactly one response choice is required");
9392
+ const choice = record(choices[0], "choice");
9393
+ const message = record(choice.message, "message");
9394
+ const delta = { ...message };
9395
+ if (message.tool_calls !== undefined)
9396
+ delta.tool_calls = list(message.tool_calls, "tool_calls").map((tool, index) => ({ ...record(tool, "tool call"), index }));
9397
+ encoder.push({ choices: [{ index: choice.index ?? 0, delta, finish_reason: choice.finish_reason }], usage: body.usage });
9398
+ } else {
9399
+ encoder.push({ type: "message_start", message: { usage: body.usage } });
9400
+ for (const [index, rawBlock] of list(body.content, "content").entries()) {
9401
+ const block = record(rawBlock, "content block");
9402
+ encoder.push({ type: "content_block_start", index, content_block: block });
9403
+ encoder.push({ type: "content_block_stop", index });
9404
+ }
9405
+ encoder.push({ type: "message_delta", delta: { stop_reason: body.stop_reason } });
9406
+ encoder.push({ type: "message_stop" });
9407
+ }
9408
+ const end = encoder.finish().at(-1);
9409
+ if (!end)
9410
+ fail("missing_terminal", "JSON response has no terminal result");
9411
+ return record(end.response, "Responses result");
9412
+ }
8502
9413
  export {
8503
9414
  AnthropicAdapter,
8504
9415
  AnthropicToGeminiConverter,
8505
9416
  AnthropicToOpenAIConverter,
9417
+ DEFAULT_RESPONSES_CODEC_LIMITS,
8506
9418
  GeminiToAnthropicConverter,
8507
9419
  GeminiToOpenAIConverter,
8508
9420
  LLMProtocolAdapterRegistry,
@@ -8517,6 +9429,8 @@ export {
8517
9429
  OpenAIToGeminiConverter,
8518
9430
  PROVIDER_TOKEN_ACCOUNTING_CAPABILITY_MATRIX,
8519
9431
  ProtocolTransformerRegistry,
9432
+ ResponsesCodecError,
9433
+ ResponsesEventEncoder,
8520
9434
  SUPPORTED_TOKEN_ACCOUNTING_PROVIDERS,
8521
9435
  TOKEN_ACCOUNTING_AUTHORITIES,
8522
9436
  TOKEN_ACCOUNTING_OUTCOMES,
@@ -8531,6 +9445,8 @@ export {
8531
9445
  countTextTokens,
8532
9446
  createPartialTokenAccountingEvent,
8533
9447
  createTokenAccountingSession,
9448
+ decodeResponsesRequest,
9449
+ encodeResponsesResult,
8534
9450
  finalizeTokenAccountingEvent,
8535
9451
  generateAnthropicMessageId,
8536
9452
  generateGeminiCandidateId,