@tangle-network/sandbox 0.0.0-develop.20260514223840.b2abd84
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 +11 -0
- package/README.md +736 -0
- package/dist/auth/index.d.ts +2 -0
- package/dist/auth/index.js +1 -0
- package/dist/client-CO5cnRwn.js +1 -0
- package/dist/collaboration/index.d.ts +2 -0
- package/dist/collaboration/index.js +1 -0
- package/dist/collaboration-CRyb5e8F.js +1 -0
- package/dist/core.d.ts +3 -0
- package/dist/core.js +1 -0
- package/dist/errors-CljiGR__.js +1 -0
- package/dist/errors-Cy5W2uYq.d.ts +1116 -0
- package/dist/index-CCsA3S0D.d.ts +136 -0
- package/dist/index-Cka6RuZB.d.ts +371 -0
- package/dist/index-Dpj1oB5i.d.ts +220 -0
- package/dist/index.d.ts +555 -0
- package/dist/index.js +1 -0
- package/dist/openai/index.d.ts +642 -0
- package/dist/openai/index.js +1 -0
- package/dist/platform-integrations.d.ts +2 -0
- package/dist/platform-integrations.js +1 -0
- package/dist/sandbox-193cSjQB.js +1 -0
- package/dist/sandbox-CTe9fN5m.d.ts +4857 -0
- package/dist/session-gateway/index.d.ts +448 -0
- package/dist/session-gateway/index.js +1 -0
- package/dist/tangle/index.d.ts +2 -0
- package/dist/tangle/index.js +1 -0
- package/dist/tangle-B4_UoyBS.js +1 -0
- package/package.json +105 -0
|
@@ -0,0 +1,642 @@
|
|
|
1
|
+
import { Response, ResponseCreateParamsBase, ResponseOutputItem, ResponseStreamEvent, ResponseUsage } from "openai/resources/responses/responses";
|
|
2
|
+
import { ChatCompletionChunk, ChatCompletionMessageParam, ChatCompletionTool } from "openai/resources/chat/completions/completions";
|
|
3
|
+
import { Completion } from "openai/resources/completions";
|
|
4
|
+
import { EmbeddingCreateParams } from "openai/resources/embeddings";
|
|
5
|
+
|
|
6
|
+
//#region src/openai/hooks.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* Tool-call hook surface.
|
|
9
|
+
*
|
|
10
|
+
* Every tool dispatched by the Run executor flows through an ordered
|
|
11
|
+
* `HookChain`. Hooks observe the call (`beforeToolCall`) and the result
|
|
12
|
+
* (`afterToolCall`) and may allow, rewrite, block, override, or
|
|
13
|
+
* terminate. The chain composes built-in hooks (audit-log, egress
|
|
14
|
+
* policy, cost cap, rate limit, destructive-action guard, screenshot
|
|
15
|
+
* redaction) with partner-supplied hooks. The route layer wires the
|
|
16
|
+
* chain into the Run state machine in `runs.ts`.
|
|
17
|
+
*
|
|
18
|
+
* Semantics:
|
|
19
|
+
* - `beforeToolCall`: `allow` → next hook; `rewrite` → mutates the
|
|
20
|
+
* args carried into subsequent hooks and the executor; `block` →
|
|
21
|
+
* short-circuits the chain and is surfaced as an error tool result.
|
|
22
|
+
* - `afterToolCall`: `pass` → next hook; `override` → mutates the
|
|
23
|
+
* result carried into subsequent hooks and the response; `terminate`
|
|
24
|
+
* → short-circuits and ends the run with the supplied reason.
|
|
25
|
+
*/
|
|
26
|
+
interface ToolCallContext {
|
|
27
|
+
runId: string;
|
|
28
|
+
threadId?: string;
|
|
29
|
+
partnerId: string;
|
|
30
|
+
toolName: string;
|
|
31
|
+
args: unknown;
|
|
32
|
+
callId: string;
|
|
33
|
+
timestamp: number;
|
|
34
|
+
}
|
|
35
|
+
interface ToolResult {
|
|
36
|
+
content: unknown;
|
|
37
|
+
isError?: boolean;
|
|
38
|
+
details?: Record<string, unknown>;
|
|
39
|
+
}
|
|
40
|
+
type BeforeHookOutcome = {
|
|
41
|
+
action: "allow";
|
|
42
|
+
} | {
|
|
43
|
+
action: "block";
|
|
44
|
+
reason: string;
|
|
45
|
+
} | {
|
|
46
|
+
action: "rewrite";
|
|
47
|
+
args: unknown;
|
|
48
|
+
};
|
|
49
|
+
type AfterHookOutcome = {
|
|
50
|
+
action: "pass";
|
|
51
|
+
} | {
|
|
52
|
+
action: "override";
|
|
53
|
+
result: ToolResult;
|
|
54
|
+
} | {
|
|
55
|
+
action: "terminate";
|
|
56
|
+
reason: string;
|
|
57
|
+
};
|
|
58
|
+
interface HookSurface {
|
|
59
|
+
beforeToolCall?(ctx: ToolCallContext): Promise<BeforeHookOutcome>;
|
|
60
|
+
afterToolCall?(ctx: ToolCallContext, result: ToolResult): Promise<AfterHookOutcome>;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Sequential hook composer. Hooks run in registration order; `block` and
|
|
64
|
+
* `terminate` short-circuit. `rewrite` and `override` thread their
|
|
65
|
+
* mutated payloads through to the remaining hooks so subsequent hooks
|
|
66
|
+
* observe the rewritten args / overridden result.
|
|
67
|
+
*/
|
|
68
|
+
declare class HookChain {
|
|
69
|
+
private readonly hooks;
|
|
70
|
+
constructor(hooks?: HookSurface[]);
|
|
71
|
+
/** Number of hooks in the chain. */
|
|
72
|
+
get size(): number;
|
|
73
|
+
/**
|
|
74
|
+
* Run every `beforeToolCall` in registration order. Returns the first
|
|
75
|
+
* non-`allow` outcome (block/rewrite), or `allow` if the chain ran
|
|
76
|
+
* clean. `rewrite` outcomes are threaded forward so later hooks see
|
|
77
|
+
* the mutated args.
|
|
78
|
+
*/
|
|
79
|
+
runBefore(ctx: ToolCallContext): Promise<BeforeHookOutcome>;
|
|
80
|
+
/**
|
|
81
|
+
* Run every `afterToolCall` in registration order. Returns the first
|
|
82
|
+
* `terminate` outcome immediately. `override` outcomes are threaded
|
|
83
|
+
* forward so later hooks see the mutated result; the final result is
|
|
84
|
+
* surfaced as the last `override`, or `pass` if no hook overrode.
|
|
85
|
+
*/
|
|
86
|
+
runAfter(ctx: ToolCallContext, result: ToolResult): Promise<AfterHookOutcome>;
|
|
87
|
+
}
|
|
88
|
+
interface AuditEvent {
|
|
89
|
+
phase: "before" | "after";
|
|
90
|
+
runId: string;
|
|
91
|
+
threadId?: string;
|
|
92
|
+
partnerId: string;
|
|
93
|
+
toolName: string;
|
|
94
|
+
callId: string;
|
|
95
|
+
timestamp: number;
|
|
96
|
+
args?: unknown;
|
|
97
|
+
result?: ToolResult;
|
|
98
|
+
}
|
|
99
|
+
interface AuditLogOptions {
|
|
100
|
+
sink?: (event: AuditEvent) => Promise<void> | void;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Emits a structured `AuditEvent` for every tool call (before + after).
|
|
104
|
+
* Default sink is `console.info`. The route layer swaps the sink for
|
|
105
|
+
* the eval-runs DuckDB writer.
|
|
106
|
+
*/
|
|
107
|
+
declare function auditLogHook(opts?: AuditLogOptions): HookSurface;
|
|
108
|
+
interface EgressPolicyOptions {
|
|
109
|
+
allowList?: string[];
|
|
110
|
+
denyList?: string[];
|
|
111
|
+
allowFn?: (ctx: ToolCallContext) => Promise<boolean>;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Best-effort allow/deny filter for tool-call URLs.
|
|
115
|
+
*
|
|
116
|
+
* Block tool calls that look network-ish (toolName matches the network
|
|
117
|
+
* regex OR args contain url-like fields) when the resolved host hits
|
|
118
|
+
* the deny list. The allow list is treated as an explicit allowance —
|
|
119
|
+
* when set, only listed hosts pass; unmatched hosts are blocked.
|
|
120
|
+
* `allowFn` overrides both lists when present.
|
|
121
|
+
*
|
|
122
|
+
* **What this hook does NOT catch.** It inspects URL-shaped strings in
|
|
123
|
+
* the tool-call arguments only. The following bypass it silently:
|
|
124
|
+
*
|
|
125
|
+
* - URLs encoded as base64 / hex / `Buffer.from(...)` literals
|
|
126
|
+
* - URLs assembled at execution time from string fragments
|
|
127
|
+
* - URLs reached via redirects, DNS rebinding, or proxy hosts that
|
|
128
|
+
* match the allow list but forward to denied destinations
|
|
129
|
+
* - Network calls made by spawned subprocesses, generated code, or
|
|
130
|
+
* tools whose argument schema does not name a URL field
|
|
131
|
+
*
|
|
132
|
+
* Treat this hook as a UX guardrail (clearer error messages,
|
|
133
|
+
* short-circuiting obvious mistakes) on top of a real egress boundary
|
|
134
|
+
* — not as one. When egress containment is a security requirement
|
|
135
|
+
* (exfil prevention, data residency), enforce it at the runtime
|
|
136
|
+
* sandbox layer (egress firewall, CNI policy, outbound proxy with
|
|
137
|
+
* mTLS) where the agent cannot evade it.
|
|
138
|
+
*/
|
|
139
|
+
declare function egressPolicyHook(opts?: EgressPolicyOptions): HookSurface;
|
|
140
|
+
interface CostCapOptions {
|
|
141
|
+
ceiling: number;
|
|
142
|
+
getCurrentCost?: (partnerId: string) => Promise<number>;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Terminates the run when the partner's accumulated cost is at or
|
|
146
|
+
* above `ceiling`. The cost lookup is injected so any usage ledger can
|
|
147
|
+
* back it.
|
|
148
|
+
*/
|
|
149
|
+
declare function costCapHook(opts: CostCapOptions): HookSurface;
|
|
150
|
+
interface ActionRateLimitOptions {
|
|
151
|
+
perSecondPerSession: number;
|
|
152
|
+
/** Optional clock injection for tests. Defaults to `Date.now`. */
|
|
153
|
+
now?: () => number;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Token-bucket rate limiter scoped per session id (`runId`) over
|
|
157
|
+
* `computer-use:*` tool calls. Excess calls are blocked with a clear
|
|
158
|
+
* reason. Non-`computer-use` tools pass through untouched.
|
|
159
|
+
*/
|
|
160
|
+
declare function actionRateLimitHook(opts: ActionRateLimitOptions): HookSurface;
|
|
161
|
+
interface RedactionRegion {
|
|
162
|
+
x: number;
|
|
163
|
+
y: number;
|
|
164
|
+
w: number;
|
|
165
|
+
h: number;
|
|
166
|
+
}
|
|
167
|
+
interface ScreenshotRedactionOptions {
|
|
168
|
+
regions?: RedactionRegion[];
|
|
169
|
+
/** Optional logger for the no-sharp warning path. Defaults to `console.warn`. */
|
|
170
|
+
warn?: (msg: string) => void;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Applied AFTER `computer-use:screenshot`. v1 ships without the
|
|
174
|
+
* `sharp` dependency: when regions are configured, we surface a warning
|
|
175
|
+
* exactly once per process and pass the screenshot through untouched.
|
|
176
|
+
* Pixel-blur lands in a follow-up that introduces `sharp` deliberately.
|
|
177
|
+
*/
|
|
178
|
+
declare function screenshotRedactionHook(opts?: ScreenshotRedactionOptions): HookSurface;
|
|
179
|
+
interface DestructiveActionGuardOptions {
|
|
180
|
+
denyPatterns: RegExp[];
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Block before-execute when a `computer-use:type` text or
|
|
184
|
+
* `computer-use:click` label matches any deny pattern. Mitigates
|
|
185
|
+
* destructive-action sequences (e.g. "delete account", "wire transfer")
|
|
186
|
+
* before they hit the OS.
|
|
187
|
+
*/
|
|
188
|
+
declare function destructiveActionGuardHook(opts: DestructiveActionGuardOptions): HookSurface;
|
|
189
|
+
//#endregion
|
|
190
|
+
//#region src/openai/types.d.ts
|
|
191
|
+
/**
|
|
192
|
+
* Internal types for the OpenAI translator core.
|
|
193
|
+
*
|
|
194
|
+
* The translator is a pure function layer between OpenAI's wire formats
|
|
195
|
+
* (chat.completions, completions, responses, embeddings) and the Tangle
|
|
196
|
+
* sandbox run input/output. Types defined here are SDK-internal — public
|
|
197
|
+
* OpenAI shapes are imported from `openai/resources/...` directly so the
|
|
198
|
+
* translator's outputs satisfy the upstream type system at compile time.
|
|
199
|
+
*/
|
|
200
|
+
/**
|
|
201
|
+
* A Tangle SSE event as emitted by the sandbox runtime. The event union is
|
|
202
|
+
* intentionally open at the data level — every concrete Tangle event has a
|
|
203
|
+
* known `type` plus a payload whose shape depends on the type. Translators
|
|
204
|
+
* narrow on `type` and read the fields they need.
|
|
205
|
+
*
|
|
206
|
+
* Event types currently emitted by the runtime:
|
|
207
|
+
* - `start` — handshake, no payload of interest.
|
|
208
|
+
* - `execution.started` — run has begun, no payload of interest.
|
|
209
|
+
* - `status` — signal frames (build_passed, tests_failed, etc.).
|
|
210
|
+
* - `token` — incremental text token.
|
|
211
|
+
* - `message.part.updated` — provider-native part updates (text deltas,
|
|
212
|
+
* tool state transitions, reasoning blocks).
|
|
213
|
+
* - `raw` — provider-native passthrough, including
|
|
214
|
+
* `tool-invocation` and `computer-use` payloads.
|
|
215
|
+
* - `session.updated` — session metadata, no payload of interest.
|
|
216
|
+
* - `error` — terminal error frame.
|
|
217
|
+
* - `done` — terminal completion frame, optionally with usage.
|
|
218
|
+
*/
|
|
219
|
+
interface TangleSSEEvent {
|
|
220
|
+
type: string;
|
|
221
|
+
[key: string]: unknown;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* A single multimodal part on a user/assistant turn. Mirrors the structural
|
|
225
|
+
* shape of OpenAI's `ChatCompletionContentPart` so we can pass it through
|
|
226
|
+
* unchanged to providers that accept the OpenAI shape natively, while still
|
|
227
|
+
* letting non-vision providers reject at the capability layer.
|
|
228
|
+
*/
|
|
229
|
+
type MultimodalPart = {
|
|
230
|
+
type: "text";
|
|
231
|
+
text: string;
|
|
232
|
+
} | {
|
|
233
|
+
type: "image_url";
|
|
234
|
+
image_url: {
|
|
235
|
+
url: string;
|
|
236
|
+
detail?: "auto" | "low" | "high";
|
|
237
|
+
};
|
|
238
|
+
} | {
|
|
239
|
+
type: "input_audio";
|
|
240
|
+
input_audio: {
|
|
241
|
+
data: string;
|
|
242
|
+
format: "wav" | "mp3";
|
|
243
|
+
};
|
|
244
|
+
};
|
|
245
|
+
/**
|
|
246
|
+
* One reconstructed prior turn for the sandbox run input. The translator
|
|
247
|
+
* collapses an OpenAI-shape message thread (system / user / assistant /
|
|
248
|
+
* tool) into an ordered list of prior turns plus a single trailing task.
|
|
249
|
+
*/
|
|
250
|
+
interface PriorTurn {
|
|
251
|
+
/** Final assistant text on this turn, if any. Tool-only turns omit this. */
|
|
252
|
+
assistantText?: string;
|
|
253
|
+
/** Tool calls the assistant emitted on this turn. */
|
|
254
|
+
toolCalls?: PriorToolCall[];
|
|
255
|
+
/** Tool results threaded back from the user side, keyed to `toolCalls[i].id`. */
|
|
256
|
+
toolResults?: PriorToolResult[];
|
|
257
|
+
/** User-side multimodal content for the turn, when the user sent parts. */
|
|
258
|
+
userParts?: MultimodalPart[];
|
|
259
|
+
}
|
|
260
|
+
interface PriorToolCall {
|
|
261
|
+
id: string;
|
|
262
|
+
name: string;
|
|
263
|
+
/** JSON-stringified arguments as emitted by the model. */
|
|
264
|
+
arguments: string;
|
|
265
|
+
}
|
|
266
|
+
interface PriorToolResult {
|
|
267
|
+
/** Matches the `toolCalls[i].id` from the assistant turn. */
|
|
268
|
+
toolCallId: string;
|
|
269
|
+
/** Tool output as a string (OpenAI tool messages carry a string body). */
|
|
270
|
+
content: string;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Shape of a tool descriptor preserved from the OpenAI request. The
|
|
274
|
+
* translator does not interpret tool schemas — it forwards them so the
|
|
275
|
+
* provider receives the same schema the caller authored.
|
|
276
|
+
*/
|
|
277
|
+
interface SandboxToolSpec {
|
|
278
|
+
type: "function";
|
|
279
|
+
function: {
|
|
280
|
+
name: string;
|
|
281
|
+
description?: string;
|
|
282
|
+
parameters?: Record<string, unknown> | null;
|
|
283
|
+
strict?: boolean | null;
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Resolved input handed to the sandbox run executor. The fields are
|
|
288
|
+
* provider-agnostic; the executor materializes them into whatever shape
|
|
289
|
+
* the chosen provider expects.
|
|
290
|
+
*/
|
|
291
|
+
interface SandboxRunInput {
|
|
292
|
+
/** Provider id stripped of the `tangle/` prefix (e.g. `claude-code`). */
|
|
293
|
+
provider: string;
|
|
294
|
+
/** Optional variant after the provider id (e.g. `sonnet` for `tangle/opencode/sonnet`). */
|
|
295
|
+
variant?: string;
|
|
296
|
+
/** Concatenated system / developer instructions. */
|
|
297
|
+
instructions?: string;
|
|
298
|
+
/** Trailing user task — the message the agent acts on. */
|
|
299
|
+
task: string;
|
|
300
|
+
/** Multimodal parts attached to the trailing user task, when present. */
|
|
301
|
+
taskParts?: MultimodalPart[];
|
|
302
|
+
/** Reconstructed history before `task`, ordered oldest → newest. */
|
|
303
|
+
priorTurns?: PriorTurn[];
|
|
304
|
+
/** Forwarded tool descriptors (function tools only at this layer). */
|
|
305
|
+
tools?: SandboxToolSpec[];
|
|
306
|
+
/** Capability hints derived from the request (e.g. computer_use). */
|
|
307
|
+
capabilities?: string[];
|
|
308
|
+
/** True when any user message contained non-text parts. */
|
|
309
|
+
multimodal?: boolean;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Mutable per-stream context threaded through the chunk translators. The
|
|
313
|
+
* translator is a pure function over (event, ctx); the context tracks
|
|
314
|
+
* cross-event state that must persist for the lifetime of one stream
|
|
315
|
+
* (chunk index, tool-call buffering, the synthetic message id).
|
|
316
|
+
*/
|
|
317
|
+
interface TranslatorContext {
|
|
318
|
+
/** Stable id assigned to the run; used as the `id` on every chunk. */
|
|
319
|
+
runId: string;
|
|
320
|
+
/** Model id echoed back on every chunk (caller-supplied, e.g. `tangle/claude-code`). */
|
|
321
|
+
modelId: string;
|
|
322
|
+
/** Monotonic chunk index — each emitted chunk increments. */
|
|
323
|
+
chunkIndex: number;
|
|
324
|
+
/** Tool calls observed during the stream, keyed by call id. */
|
|
325
|
+
toolCallBuffer: Map<string, BufferedToolCall>;
|
|
326
|
+
/** Unix timestamp (seconds) when the stream was opened. */
|
|
327
|
+
createdAt: number;
|
|
328
|
+
}
|
|
329
|
+
interface BufferedToolCall {
|
|
330
|
+
/** Position in the order tool calls were observed. */
|
|
331
|
+
index: number;
|
|
332
|
+
id: string;
|
|
333
|
+
name: string;
|
|
334
|
+
/** JSON-stringified arguments. */
|
|
335
|
+
arguments: string;
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Construct a fresh translator context. The factory is deliberately tiny
|
|
339
|
+
* — call sites that need to override fields can do so via the partial.
|
|
340
|
+
*/
|
|
341
|
+
declare function createTranslatorContext(init: Pick<TranslatorContext, "runId" | "modelId"> & Partial<TranslatorContext>): TranslatorContext;
|
|
342
|
+
//#endregion
|
|
343
|
+
//#region src/openai/translate/responses.d.ts
|
|
344
|
+
/**
|
|
345
|
+
* Persistence interface for `previous_response_id` chains. The route layer
|
|
346
|
+
* supplies a concrete impl (DuckDB-backed in production, in-memory in
|
|
347
|
+
* tests). The translator is store-agnostic.
|
|
348
|
+
*/
|
|
349
|
+
interface ResponseStore {
|
|
350
|
+
/** Look up the prior turns recorded under a previous response id. */
|
|
351
|
+
getPriorTurns(responseId: string): Promise<PriorTurn[] | null>;
|
|
352
|
+
/** Persist the prior turns produced by a response. */
|
|
353
|
+
putPriorTurns(responseId: string, priorTurns: PriorTurn[]): Promise<void>;
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Resolve a `previous_response_id` into the prior-turns prefix that
|
|
357
|
+
* gets prepended to the new request. Throws when the id is supplied but
|
|
358
|
+
* unknown — silently dropping it would corrupt conversation continuity.
|
|
359
|
+
*/
|
|
360
|
+
declare function resolvePreviousResponseId(prevId: string | undefined, store: ResponseStore): Promise<{
|
|
361
|
+
priorTurns: PriorTurn[];
|
|
362
|
+
}>;
|
|
363
|
+
/**
|
|
364
|
+
* Aggregate a Tangle SSE event sequence into the Responses-API output[]
|
|
365
|
+
* array plus a usage envelope. This is the non-streaming path: callers
|
|
366
|
+
* collect every event, hand them all in, and get back a settled response
|
|
367
|
+
* payload ready to return as JSON.
|
|
368
|
+
*/
|
|
369
|
+
declare function assembleResponseOutput(events: TangleSSEEvent[]): {
|
|
370
|
+
output: ResponseOutputItem[];
|
|
371
|
+
usage: ResponseUsage;
|
|
372
|
+
};
|
|
373
|
+
/**
|
|
374
|
+
* Fold every usage frame in a Tangle event sequence into a single
|
|
375
|
+
* ResponseUsage envelope. Multiple `done` events are tolerated (e.g.
|
|
376
|
+
* during retries) by summing.
|
|
377
|
+
*/
|
|
378
|
+
declare function usageFromEvents(events: TangleSSEEvent[]): ResponseUsage;
|
|
379
|
+
declare class ResponsesValidationError extends Error {
|
|
380
|
+
readonly type = "invalid_request_error";
|
|
381
|
+
readonly code: string;
|
|
382
|
+
readonly param: string | undefined;
|
|
383
|
+
constructor(message: string, code: string, param?: string);
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Reject Responses requests that ask for tool types Tangle cannot
|
|
387
|
+
* service. Function tools, the OpenAI computer-use preview tool, and
|
|
388
|
+
* the code interpreter (every Tangle sandbox can run code) are
|
|
389
|
+
* accepted; web_search and file_search are explicitly rejected with
|
|
390
|
+
* the OpenAI error shape.
|
|
391
|
+
*/
|
|
392
|
+
declare function validateResponsesRequest(req: ResponseCreateParamsBase): void;
|
|
393
|
+
/**
|
|
394
|
+
* Build a settled `Response` shell from an aggregated output + usage.
|
|
395
|
+
* Caller fills in the runtime-specific fields (id, model, created_at,
|
|
396
|
+
* status, instructions, etc.) to avoid having to re-derive them inside
|
|
397
|
+
* the translator.
|
|
398
|
+
*/
|
|
399
|
+
declare function buildResponseShell(args: {
|
|
400
|
+
id: string;
|
|
401
|
+
model: string;
|
|
402
|
+
createdAt: number;
|
|
403
|
+
output: ResponseOutputItem[];
|
|
404
|
+
usage: ResponseUsage;
|
|
405
|
+
instructions?: string | null;
|
|
406
|
+
previousResponseId?: string | null;
|
|
407
|
+
}): Response;
|
|
408
|
+
//#endregion
|
|
409
|
+
//#region src/openai/responses-store.d.ts
|
|
410
|
+
declare class InMemoryResponseStore implements ResponseStore {
|
|
411
|
+
private readonly chains;
|
|
412
|
+
getPriorTurns(responseId: string): Promise<PriorTurn[] | null>;
|
|
413
|
+
putPriorTurns(responseId: string, priorTurns: PriorTurn[]): Promise<void>;
|
|
414
|
+
/** Convenience accessor for tests / debug; not part of `ResponseStore`. */
|
|
415
|
+
size(): number;
|
|
416
|
+
/** Drop a chain. */
|
|
417
|
+
delete(responseId: string): boolean;
|
|
418
|
+
/** Drop everything. Useful between test cases. */
|
|
419
|
+
clear(): void;
|
|
420
|
+
}
|
|
421
|
+
//#endregion
|
|
422
|
+
//#region src/openai/runs.d.ts
|
|
423
|
+
/**
|
|
424
|
+
* Tangle-internal run events surfaced to consumers of `Run.events()`.
|
|
425
|
+
* The low-level `runEvents()` iterator emits the raw sandbox event
|
|
426
|
+
* frames (`TangleSSEEvent`) directly; the high-level state machine
|
|
427
|
+
* wraps each frame in a typed envelope plus emits its own
|
|
428
|
+
* status-transition and tool-dispatch events for consumers that don't
|
|
429
|
+
* want to parse SSE shapes themselves.
|
|
430
|
+
*/
|
|
431
|
+
type RunEvent = {
|
|
432
|
+
type: "status";
|
|
433
|
+
status: RunStatus;
|
|
434
|
+
previous: RunStatus | null;
|
|
435
|
+
} | {
|
|
436
|
+
type: "stream";
|
|
437
|
+
event: TangleSSEEvent;
|
|
438
|
+
} | {
|
|
439
|
+
type: "tool_call";
|
|
440
|
+
ctx: ToolCallContext;
|
|
441
|
+
} | {
|
|
442
|
+
type: "tool_result";
|
|
443
|
+
ctx: ToolCallContext;
|
|
444
|
+
result: ToolResult;
|
|
445
|
+
} | {
|
|
446
|
+
type: "tool_blocked";
|
|
447
|
+
ctx: ToolCallContext;
|
|
448
|
+
reason: string;
|
|
449
|
+
} | {
|
|
450
|
+
type: "requires_action";
|
|
451
|
+
pendingCallIds: string[];
|
|
452
|
+
} | {
|
|
453
|
+
type: "completed";
|
|
454
|
+
} | {
|
|
455
|
+
type: "failed";
|
|
456
|
+
reason: string;
|
|
457
|
+
} | {
|
|
458
|
+
type: "cancelled";
|
|
459
|
+
reason?: string;
|
|
460
|
+
};
|
|
461
|
+
type RunStatus = "queued" | "in_progress" | "requires_action" | "completed" | "failed" | "cancelled" | "expired";
|
|
462
|
+
/**
|
|
463
|
+
* Minimal interface the low-level `runEvents()` consumes. The route
|
|
464
|
+
* layer adapts the concrete `SandboxClient` SSE stream onto this
|
|
465
|
+
* surface so the Run executor stays decoupled from any specific HTTP
|
|
466
|
+
* shape. `cancel()` is best-effort — the source should stop producing
|
|
467
|
+
* events as soon as it observes a cancellation.
|
|
468
|
+
*/
|
|
469
|
+
interface RunEventSource {
|
|
470
|
+
open(threadId: string | undefined, runId: string): AsyncIterable<TangleSSEEvent>;
|
|
471
|
+
/** Optional: append a steer message and re-open the stream for the same run. */
|
|
472
|
+
steer?(threadId: string | undefined, runId: string, message: {
|
|
473
|
+
role: "user";
|
|
474
|
+
content: string;
|
|
475
|
+
}): Promise<void>;
|
|
476
|
+
/** Optional: submit tool outputs and resume from `requires_action`. */
|
|
477
|
+
submitToolOutputs?(threadId: string | undefined, runId: string, outputs: ToolOutput[]): Promise<void>;
|
|
478
|
+
/** Optional: server-side cancel hint. */
|
|
479
|
+
cancel?(threadId: string | undefined, runId: string): Promise<void>;
|
|
480
|
+
}
|
|
481
|
+
interface ToolOutput {
|
|
482
|
+
toolCallId: string;
|
|
483
|
+
output: ToolResult;
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* Pure async iterator over the underlying source. No state, no
|
|
487
|
+
* buffering. Iteration ends when the source closes or yields a
|
|
488
|
+
* terminal frame; the iterator itself does not classify frames.
|
|
489
|
+
*/
|
|
490
|
+
declare function runEvents(threadId: string | undefined, runId: string, source: RunEventSource): AsyncIterable<TangleSSEEvent>;
|
|
491
|
+
interface RunOptions {
|
|
492
|
+
id: string;
|
|
493
|
+
threadId?: string;
|
|
494
|
+
partnerId: string;
|
|
495
|
+
source: RunEventSource;
|
|
496
|
+
hooks?: HookChain;
|
|
497
|
+
/** Caller-supplied tool executor. Required when the underlying stream
|
|
498
|
+
* does not auto-execute tools server-side (the typical Tangle path). */
|
|
499
|
+
executeTool?: (ctx: ToolCallContext) => Promise<ToolResult>;
|
|
500
|
+
onStatusChange?: (status: RunStatus, previous: RunStatus | null) => void;
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* High-level `Run`. Drives the underlying `RunEventSource`, manages
|
|
504
|
+
* status transitions, dispatches tool calls through the hook chain,
|
|
505
|
+
* and surfaces a typed `RunEvent` stream to consumers.
|
|
506
|
+
*/
|
|
507
|
+
declare class Run {
|
|
508
|
+
readonly id: string;
|
|
509
|
+
readonly threadId: string | undefined;
|
|
510
|
+
readonly partnerId: string;
|
|
511
|
+
private _status;
|
|
512
|
+
private readonly source;
|
|
513
|
+
private readonly hooks;
|
|
514
|
+
private readonly executeTool;
|
|
515
|
+
private readonly onStatusChange;
|
|
516
|
+
private readonly queue;
|
|
517
|
+
private startPromise;
|
|
518
|
+
private pendingCalls;
|
|
519
|
+
private cancelRequested;
|
|
520
|
+
constructor(opts: RunOptions);
|
|
521
|
+
get status(): RunStatus;
|
|
522
|
+
/**
|
|
523
|
+
* Subscribe to typed events. May only be consumed once per Run.
|
|
524
|
+
*
|
|
525
|
+
* The single-consumer constraint is permanent for the lifetime of
|
|
526
|
+
* the Run instance, including AFTER the run completes — calling
|
|
527
|
+
* `events()` a second time always throws, even if the first
|
|
528
|
+
* consumer drained the iterator to completion. This is intentional:
|
|
529
|
+
* the queue is a one-shot stream, not a re-readable buffer, and
|
|
530
|
+
* events are dropped after delivery to avoid unbounded retention.
|
|
531
|
+
* Callers that need to revisit terminal state should keep a handle
|
|
532
|
+
* to the original iterator's drained values, or use the Run's
|
|
533
|
+
* status/result accessors.
|
|
534
|
+
*/
|
|
535
|
+
events(): AsyncIterable<RunEvent>;
|
|
536
|
+
/**
|
|
537
|
+
* Drive the underlying stream to completion. Idempotent: subsequent
|
|
538
|
+
* calls return the same in-flight promise.
|
|
539
|
+
*/
|
|
540
|
+
start(): Promise<void>;
|
|
541
|
+
/**
|
|
542
|
+
* Cancel an in-flight run. Sets status to `cancelled` and closes
|
|
543
|
+
* the event queue. Tries the source-level cancel hint as a
|
|
544
|
+
* best-effort heads-up to the upstream stream.
|
|
545
|
+
*/
|
|
546
|
+
cancel(reason?: string): Promise<void>;
|
|
547
|
+
/**
|
|
548
|
+
* Append a user message to the thread and restart the stream. The
|
|
549
|
+
* source's `steer` hook is invoked when present; otherwise we throw
|
|
550
|
+
* because a stateless source cannot honor a steer.
|
|
551
|
+
*/
|
|
552
|
+
steer(message: {
|
|
553
|
+
role: "user";
|
|
554
|
+
content: string;
|
|
555
|
+
}): Promise<void>;
|
|
556
|
+
/**
|
|
557
|
+
* Resume a `requires_action` run by submitting tool outputs. The
|
|
558
|
+
* outputs are forwarded to the source so the upstream agent can
|
|
559
|
+
* continue. Status transitions back to `in_progress`.
|
|
560
|
+
*/
|
|
561
|
+
submitToolOutputs(outputs: ToolOutput[]): Promise<void>;
|
|
562
|
+
/** Externally drive the run into the `expired` terminal status. */
|
|
563
|
+
expire(): void;
|
|
564
|
+
private transition;
|
|
565
|
+
private driveStream;
|
|
566
|
+
private handleToolCall;
|
|
567
|
+
}
|
|
568
|
+
//#endregion
|
|
569
|
+
//#region src/openai/translate/chunks.d.ts
|
|
570
|
+
declare function sandboxEventToChatChunk(event: TangleSSEEvent, ctx: TranslatorContext): ChatCompletionChunk | null;
|
|
571
|
+
declare function sandboxEventToCompletionChunk(event: TangleSSEEvent, ctx: TranslatorContext): Completion | null;
|
|
572
|
+
declare function sandboxEventToResponsesEvent(event: TangleSSEEvent, ctx: TranslatorContext): ResponseStreamEvent | null;
|
|
573
|
+
//#endregion
|
|
574
|
+
//#region src/openai/translate/embeddings.d.ts
|
|
575
|
+
type NormalizedEmbeddingInput = {
|
|
576
|
+
kind: "text";
|
|
577
|
+
values: string[];
|
|
578
|
+
} | {
|
|
579
|
+
kind: "tokens";
|
|
580
|
+
values: number[][];
|
|
581
|
+
};
|
|
582
|
+
interface NormalizedEmbeddingRequest {
|
|
583
|
+
model: string;
|
|
584
|
+
input: NormalizedEmbeddingInput;
|
|
585
|
+
dimensions?: number;
|
|
586
|
+
encodingFormat: "float" | "base64";
|
|
587
|
+
user?: string;
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* Error shape used for rejecting embedding requests. The route layer
|
|
591
|
+
* lifts these into OpenAI's `{ error: { type, code, message } }` body.
|
|
592
|
+
*/
|
|
593
|
+
declare class EmbeddingValidationError extends Error {
|
|
594
|
+
readonly type = "invalid_request_error";
|
|
595
|
+
readonly code: string;
|
|
596
|
+
readonly param: string | undefined;
|
|
597
|
+
constructor(message: string, code: string, param?: string);
|
|
598
|
+
}
|
|
599
|
+
/**
|
|
600
|
+
* Validate and normalize an embedding request. Throws
|
|
601
|
+
* `EmbeddingValidationError` on any rejection.
|
|
602
|
+
*/
|
|
603
|
+
declare function validateEmbeddingRequest(req: EmbeddingCreateParams): NormalizedEmbeddingRequest;
|
|
604
|
+
//#endregion
|
|
605
|
+
//#region src/openai/translate/finish-reason.d.ts
|
|
606
|
+
/**
|
|
607
|
+
* Map a Tangle outcome string + tool-call presence to an OpenAI
|
|
608
|
+
* `finish_reason`. Shared across chat / completions / responses
|
|
609
|
+
* translators so all three surfaces report the same termination reason
|
|
610
|
+
* for the same underlying outcome.
|
|
611
|
+
*
|
|
612
|
+
* Inputs:
|
|
613
|
+
* - `outcome` is the Tangle terminal status (`success`, `failure`,
|
|
614
|
+
* `length_exceeded`, `content_filtered`, `error`, `cancelled`, ...).
|
|
615
|
+
* - `hasToolCall` is true when the run emitted at least one tool call
|
|
616
|
+
* before terminating.
|
|
617
|
+
*
|
|
618
|
+
* Mapping:
|
|
619
|
+
* - `success` + tool_call → `tool_calls` (model handed control back).
|
|
620
|
+
* - `success` → `stop`.
|
|
621
|
+
* - `length_exceeded` → `length`.
|
|
622
|
+
* - `content_filtered` → `content_filter`.
|
|
623
|
+
* - everything else → `stop` (route layer surfaces the error).
|
|
624
|
+
*/
|
|
625
|
+
type OpenAIFinishReason = "stop" | "length" | "tool_calls" | "content_filter";
|
|
626
|
+
declare function outcomeToFinishReason(outcome: string, hasToolCall: boolean): OpenAIFinishReason;
|
|
627
|
+
//#endregion
|
|
628
|
+
//#region src/openai/translate/messages.d.ts
|
|
629
|
+
/**
|
|
630
|
+
* Translate an OpenAI chat-shape message thread into a SandboxRunInput.
|
|
631
|
+
*
|
|
632
|
+
* @param messages Ordered messages as the OpenAI client would send them.
|
|
633
|
+
* @param tools Optional function tool descriptors to forward unchanged.
|
|
634
|
+
* @param model Caller-supplied model id (`tangle/<provider>[/<variant>]`).
|
|
635
|
+
*
|
|
636
|
+
* @throws when the resolved provider id is empty, when the message thread
|
|
637
|
+
* lacks any user message, or when an `assistant` `tool_calls` item
|
|
638
|
+
* is malformed (missing id/name/arguments).
|
|
639
|
+
*/
|
|
640
|
+
declare function openaiMessagesToSandboxInput(messages: ChatCompletionMessageParam[], tools: ChatCompletionTool[] | undefined, model: string): SandboxRunInput;
|
|
641
|
+
//#endregion
|
|
642
|
+
export { type ActionRateLimitOptions, type AfterHookOutcome, type AuditEvent, type AuditLogOptions, type BeforeHookOutcome, type BufferedToolCall, type CostCapOptions, type DestructiveActionGuardOptions, type EgressPolicyOptions, EmbeddingValidationError, HookChain, type HookSurface, InMemoryResponseStore, type MultimodalPart, type NormalizedEmbeddingInput, type NormalizedEmbeddingRequest, type OpenAIFinishReason, type PriorToolCall, type PriorToolResult, type PriorTurn, type RedactionRegion, type ResponseStore, ResponsesValidationError, Run, type RunEvent, type RunEventSource, type RunOptions, type RunStatus, type SandboxRunInput, type SandboxToolSpec, type ScreenshotRedactionOptions, type TangleSSEEvent, type ToolCallContext, type ToolOutput, type ToolResult, type TranslatorContext, actionRateLimitHook, assembleResponseOutput, auditLogHook, buildResponseShell, costCapHook, createTranslatorContext, destructiveActionGuardHook, egressPolicyHook, openaiMessagesToSandboxInput, outcomeToFinishReason, resolvePreviousResponseId, runEvents, sandboxEventToChatChunk, sandboxEventToCompletionChunk, sandboxEventToResponsesEvent, screenshotRedactionHook, usageFromEvents, validateEmbeddingRequest, validateResponsesRequest };
|