@velum-labs/routekit-gateway 0.9.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/LICENSE +201 -0
- package/README.md +28 -0
- package/dist/acp-agent.d.ts +38 -0
- package/dist/acp-agent.js +142 -0
- package/dist/acp-registry.d.ts +36 -0
- package/dist/acp-registry.js +85 -0
- package/dist/adapters/anthropic.d.ts +131 -0
- package/dist/adapters/anthropic.js +1195 -0
- package/dist/adapters/chat.d.ts +14 -0
- package/dist/adapters/chat.js +34 -0
- package/dist/adapters/cursor.d.ts +34 -0
- package/dist/adapters/cursor.js +305 -0
- package/dist/adapters/dropped.d.ts +10 -0
- package/dist/adapters/dropped.js +24 -0
- package/dist/adapters/openai-chat-wire.d.ts +93 -0
- package/dist/adapters/openai-chat-wire.js +143 -0
- package/dist/adapters/responses-stream.d.ts +7 -0
- package/dist/adapters/responses-stream.js +597 -0
- package/dist/adapters/responses.d.ts +174 -0
- package/dist/adapters/responses.js +778 -0
- package/dist/adapters/server-tool-loop.d.ts +94 -0
- package/dist/adapters/server-tool-loop.js +477 -0
- package/dist/adapters/upstream-error.d.ts +14 -0
- package/dist/adapters/upstream-error.js +25 -0
- package/dist/adapters/validate.d.ts +27 -0
- package/dist/adapters/validate.js +180 -0
- package/dist/adapters/web-search.d.ts +46 -0
- package/dist/adapters/web-search.js +151 -0
- package/dist/auth.d.ts +10 -0
- package/dist/auth.js +28 -0
- package/dist/backend.d.ts +151 -0
- package/dist/backend.js +143 -0
- package/dist/capacity-pool.d.ts +31 -0
- package/dist/capacity-pool.js +99 -0
- package/dist/cost.d.ts +49 -0
- package/dist/cost.js +112 -0
- package/dist/endpoint-health.d.ts +54 -0
- package/dist/endpoint-health.js +123 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.js +23 -0
- package/dist/provenance.d.ts +31 -0
- package/dist/provenance.js +191 -0
- package/dist/provider-backends.d.ts +40 -0
- package/dist/provider-backends.js +1050 -0
- package/dist/provider-source.d.ts +40 -0
- package/dist/provider-source.js +293 -0
- package/dist/router.d.ts +168 -0
- package/dist/router.js +474 -0
- package/dist/server.d.ts +67 -0
- package/dist/server.js +930 -0
- package/dist/sse/chat-assembler.d.ts +45 -0
- package/dist/sse/chat-assembler.js +190 -0
- package/dist/sse/parse.d.ts +50 -0
- package/dist/sse/parse.js +149 -0
- package/dist/sse-wire.d.ts +10 -0
- package/dist/sse-wire.js +31 -0
- package/dist/switching-proxy.d.ts +15 -0
- package/dist/switching-proxy.js +232 -0
- package/dist/test/acp-agent.test.d.ts +1 -0
- package/dist/test/acp-agent.test.js +66 -0
- package/dist/test/acp-registry.test.d.ts +1 -0
- package/dist/test/acp-registry.test.js +70 -0
- package/dist/test/anthropic.test.d.ts +1 -0
- package/dist/test/anthropic.test.js +793 -0
- package/dist/test/auth.test.d.ts +1 -0
- package/dist/test/auth.test.js +25 -0
- package/dist/test/boundary.test.d.ts +1 -0
- package/dist/test/boundary.test.js +32 -0
- package/dist/test/chat.test.d.ts +1 -0
- package/dist/test/chat.test.js +418 -0
- package/dist/test/cost.test.d.ts +1 -0
- package/dist/test/cost.test.js +60 -0
- package/dist/test/cursor.test.d.ts +1 -0
- package/dist/test/cursor.test.js +100 -0
- package/dist/test/drain.test.d.ts +1 -0
- package/dist/test/drain.test.js +116 -0
- package/dist/test/dropped.test.d.ts +1 -0
- package/dist/test/dropped.test.js +80 -0
- package/dist/test/endpoint-health.test.d.ts +1 -0
- package/dist/test/endpoint-health.test.js +73 -0
- package/dist/test/provenance.test.d.ts +1 -0
- package/dist/test/provenance.test.js +176 -0
- package/dist/test/provider-backends.test.d.ts +1 -0
- package/dist/test/provider-backends.test.js +699 -0
- package/dist/test/responses.test.d.ts +1 -0
- package/dist/test/responses.test.js +813 -0
- package/dist/test/routed-backend.test.d.ts +1 -0
- package/dist/test/routed-backend.test.js +39 -0
- package/dist/test/router.test.d.ts +1 -0
- package/dist/test/router.test.js +297 -0
- package/dist/test/server-resilience.test.d.ts +1 -0
- package/dist/test/server-resilience.test.js +169 -0
- package/dist/test/sse-codec.test.d.ts +1 -0
- package/dist/test/sse-codec.test.js +186 -0
- package/dist/test/web-search-loop.test.d.ts +1 -0
- package/dist/test/web-search-loop.test.js +469 -0
- package/dist/test/wire-validation.test.d.ts +1 -0
- package/dist/test/wire-validation.test.js +140 -0
- package/package.json +48 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI Responses adapter. Codex speaks the Responses API exclusively
|
|
3
|
+
* (`wire_api="responses"`; Chat Completions support was removed), so to back it
|
|
4
|
+
* with a local model we translate `/v1/responses` to and from the gateway's
|
|
5
|
+
* OpenAI Chat Completions core. The pure translation functions are exported for
|
|
6
|
+
* testing; the handler returns a `Response` the server pipes (JSON or SSE).
|
|
7
|
+
*
|
|
8
|
+
* This is the highest-fidelity adapter: it maps Responses `input` items
|
|
9
|
+
* (messages, function calls, function-call outputs) into chat messages, and
|
|
10
|
+
* emits the Responses streaming event sequence (`response.created`,
|
|
11
|
+
* `response.output_item.added`, `response.output_text.delta`,
|
|
12
|
+
* `response.function_call_arguments.delta`, `response.completed`, …) from chat
|
|
13
|
+
* completion chunks.
|
|
14
|
+
*/
|
|
15
|
+
import type { Backend, BackendRequestOptions } from "../backend.js";
|
|
16
|
+
import { type OpenAiChoice } from "./openai-chat-wire.js";
|
|
17
|
+
import type { ExecutedSearch } from "./server-tool-loop.js";
|
|
18
|
+
export { openAiSseToResponses } from "./responses-stream.js";
|
|
19
|
+
type ResponsesContentPart = {
|
|
20
|
+
type: string;
|
|
21
|
+
text?: string;
|
|
22
|
+
image_url?: string;
|
|
23
|
+
[key: string]: unknown;
|
|
24
|
+
};
|
|
25
|
+
type ResponsesInputItem = {
|
|
26
|
+
type?: "message";
|
|
27
|
+
role: "user" | "assistant" | "system" | "developer";
|
|
28
|
+
content: string | ResponsesContentPart[];
|
|
29
|
+
} | {
|
|
30
|
+
type: "function_call";
|
|
31
|
+
call_id?: string;
|
|
32
|
+
id?: string;
|
|
33
|
+
name: string;
|
|
34
|
+
arguments: string;
|
|
35
|
+
} | {
|
|
36
|
+
type: "function_call_output";
|
|
37
|
+
call_id: string;
|
|
38
|
+
output: unknown;
|
|
39
|
+
} | {
|
|
40
|
+
type: "custom_tool_call";
|
|
41
|
+
call_id?: string;
|
|
42
|
+
id?: string;
|
|
43
|
+
name: string;
|
|
44
|
+
input?: string;
|
|
45
|
+
} | {
|
|
46
|
+
type: "custom_tool_call_output";
|
|
47
|
+
call_id: string;
|
|
48
|
+
output: unknown;
|
|
49
|
+
} | {
|
|
50
|
+
type: string;
|
|
51
|
+
[key: string]: unknown;
|
|
52
|
+
};
|
|
53
|
+
/** A tool declaration on a Responses request: a function tool (JSON-schema
|
|
54
|
+
* `parameters`), a freeform "custom" tool (a grammar/text `format` and raw
|
|
55
|
+
* string input — e.g. Codex's `apply_patch` for GPT-5-family models), or a
|
|
56
|
+
* *typed* tool identified only by its `type` (e.g. Codex's `tool_search` /
|
|
57
|
+
* `web_search` entries, which carry no `name`). */
|
|
58
|
+
type ResponsesTool = {
|
|
59
|
+
type?: string;
|
|
60
|
+
name?: string;
|
|
61
|
+
description?: string;
|
|
62
|
+
parameters?: unknown;
|
|
63
|
+
strict?: boolean;
|
|
64
|
+
format?: {
|
|
65
|
+
type?: string;
|
|
66
|
+
syntax?: string;
|
|
67
|
+
definition?: string;
|
|
68
|
+
};
|
|
69
|
+
/** Typed tools declare who executes them ("client" for CLI-side tools). */
|
|
70
|
+
execution?: string;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Codex encodes "unset" as an explicit JSON `null` for several optional fields
|
|
74
|
+
* (e.g. `"reasoning": null` whenever the selected model's metadata advertises
|
|
75
|
+
* no reasoning levels — the default for many custom-provider models). Every
|
|
76
|
+
* nullable field below must be read with a null-tolerant guard; reading
|
|
77
|
+
* `.effort` off a null `reasoning` previously failed every such Codex turn.
|
|
78
|
+
*/
|
|
79
|
+
export type ResponsesRequest = {
|
|
80
|
+
model?: string;
|
|
81
|
+
instructions?: string;
|
|
82
|
+
input?: string | ResponsesInputItem[];
|
|
83
|
+
tools?: ResponsesTool[];
|
|
84
|
+
tool_choice?: "auto" | "none" | "required" | {
|
|
85
|
+
type: string;
|
|
86
|
+
name?: string;
|
|
87
|
+
} | null;
|
|
88
|
+
max_output_tokens?: number;
|
|
89
|
+
temperature?: number;
|
|
90
|
+
top_p?: number;
|
|
91
|
+
parallel_tool_calls?: boolean;
|
|
92
|
+
/**
|
|
93
|
+
* Codex serializes `reasoning: null` (not an absent key) for models whose
|
|
94
|
+
* catalog metadata carries no reasoning level — every custom provider
|
|
95
|
+
* member slug (e.g. `grok-4`, `deepseek`) resolves to Codex's fallback model
|
|
96
|
+
* info, which has none. Null must translate as "no reasoning", never throw.
|
|
97
|
+
*/
|
|
98
|
+
reasoning?: {
|
|
99
|
+
effort?: string | null;
|
|
100
|
+
[key: string]: unknown;
|
|
101
|
+
} | null;
|
|
102
|
+
text?: {
|
|
103
|
+
format?: {
|
|
104
|
+
type?: string;
|
|
105
|
+
name?: string;
|
|
106
|
+
schema?: unknown;
|
|
107
|
+
strict?: boolean;
|
|
108
|
+
[key: string]: unknown;
|
|
109
|
+
};
|
|
110
|
+
} | null;
|
|
111
|
+
previous_response_id?: string | null;
|
|
112
|
+
truncation?: string | unknown;
|
|
113
|
+
metadata?: Record<string, unknown> | null;
|
|
114
|
+
include?: unknown[] | null;
|
|
115
|
+
stream?: boolean;
|
|
116
|
+
};
|
|
117
|
+
type OpenAiUsage = {
|
|
118
|
+
prompt_tokens?: number;
|
|
119
|
+
completion_tokens?: number;
|
|
120
|
+
};
|
|
121
|
+
type OpenAiResponse = {
|
|
122
|
+
id?: string;
|
|
123
|
+
choices?: OpenAiChoice[];
|
|
124
|
+
usage?: OpenAiUsage;
|
|
125
|
+
provider_cost?: unknown;
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* How a declared tool must be emitted when the model calls it:
|
|
129
|
+
* - `function`: a plain `function_call` item (JSON-schema function tools, and
|
|
130
|
+
* tools discovered mid-conversation via `tool_search_output`).
|
|
131
|
+
* - `custom`: a `custom_tool_call` item carrying raw string input (freeform
|
|
132
|
+
* tools like Codex's `apply_patch`).
|
|
133
|
+
* - `typed`: the tool's own native item type (`<type>_call`, e.g.
|
|
134
|
+
* `tool_search_call`) — Codex dispatches these by payload shape, and a
|
|
135
|
+
* `function_call` under the same name fails with "handler received
|
|
136
|
+
* unsupported payload".
|
|
137
|
+
* - `server`: a server-executed tool (`web_search`) the *gateway* runs via the
|
|
138
|
+
* server-tool loop. Its calls never surface as callable items — the loop
|
|
139
|
+
* intercepts them and the egress renders native `web_search_call` items.
|
|
140
|
+
*/
|
|
141
|
+
export type ResponsesToolKind = "function" | "custom" | "typed" | "server";
|
|
142
|
+
export type ResponsesToolEntry = {
|
|
143
|
+
kind: ResponsesToolKind;
|
|
144
|
+
/**
|
|
145
|
+
* The tool's namespace, for tools *discovered* through a `tool_search`
|
|
146
|
+
* execution (e.g. `spawn_agent` under `multi_agent_v1`). Codex routes a
|
|
147
|
+
* discovered tool's `function_call` by name **and** namespace — without the
|
|
148
|
+
* namespace the call fails with "unsupported call".
|
|
149
|
+
*/
|
|
150
|
+
namespace?: string;
|
|
151
|
+
};
|
|
152
|
+
export type ResponsesToolRegistry = ReadonlyMap<string, ResponsesToolEntry>;
|
|
153
|
+
/** The name the gateway-executed web search tool is projected under chat-side. */
|
|
154
|
+
export declare const WEB_SEARCH_TOOL_NAME = "web_search";
|
|
155
|
+
/** Options gating server-executed tool projection (on iff an executor exists). */
|
|
156
|
+
export type ResponsesTranslationOptions = {
|
|
157
|
+
serverTools?: boolean;
|
|
158
|
+
};
|
|
159
|
+
/**
|
|
160
|
+
* The per-request tool registry: every callable tool the request declares or
|
|
161
|
+
* has discovered, keyed by the name the chat-side model calls it under, mapped
|
|
162
|
+
* to how its calls must be emitted. Typed tools are keyed by their `type`;
|
|
163
|
+
* discovered tools carry their namespace for egress dispatch.
|
|
164
|
+
*/
|
|
165
|
+
export declare function responsesToolRegistry(body: ResponsesRequest, options?: ResponsesTranslationOptions): ResponsesToolRegistry;
|
|
166
|
+
/**
|
|
167
|
+
* Back-compat helper: the names of the freeform ("custom") tools a Responses
|
|
168
|
+
* request declares (see {@link responsesToolRegistry}).
|
|
169
|
+
*/
|
|
170
|
+
export declare function customToolNames(body: ResponsesRequest): ReadonlySet<string>;
|
|
171
|
+
/** Translate a Responses request to an OpenAI Chat Completions body. */
|
|
172
|
+
export declare function responsesToChat(body: ResponsesRequest, backendModel: string | undefined, options?: ResponsesTranslationOptions): Record<string, unknown>;
|
|
173
|
+
export declare function chatToResponses(openai: OpenAiResponse, model: string, toolRegistry?: ResponsesToolRegistry, searches?: readonly ExecutedSearch[]): Record<string, unknown>;
|
|
174
|
+
export declare function handleResponses(backend: Backend, body: ResponsesRequest, modelCallId?: string, signal?: AbortSignal, backendOptions?: BackendRequestOptions): Promise<Response>;
|