agentfootprint 11.4.0 → 12.0.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/CAPABILITIES.md +3 -1
- package/dist/adapters/code/agentcore.js +295 -214
- package/dist/adapters/code/agentcore.js.map +1 -1
- package/dist/adapters/code/agentcoreClient.js +178 -0
- package/dist/adapters/code/agentcoreClient.js.map +1 -0
- package/dist/adapters/code/agentcoreWire.js +348 -0
- package/dist/adapters/code/agentcoreWire.js.map +1 -0
- package/dist/adapters/code/fileName.js +100 -0
- package/dist/adapters/code/fileName.js.map +1 -0
- package/dist/adapters/code/local.js +529 -183
- package/dist/adapters/code/local.js.map +1 -1
- package/dist/adapters/code/output.js +140 -0
- package/dist/adapters/code/output.js.map +1 -0
- package/dist/adapters/mcp/agentcoreRuntime/invoke.js +7 -6
- package/dist/adapters/mcp/agentcoreRuntime/invoke.js.map +1 -1
- package/dist/adapters/mcp/agentcoreRuntime/sessionBusy.js +36 -2
- package/dist/adapters/mcp/agentcoreRuntime/sessionBusy.js.map +1 -1
- package/dist/adapters/mcp/agentcoreRuntime/transport.js +3 -1
- package/dist/adapters/mcp/agentcoreRuntime/transport.js.map +1 -1
- package/dist/core/codeRunnerTool.js +52 -7
- package/dist/core/codeRunnerTool.js.map +1 -1
- package/dist/doors/providers.js.map +1 -1
- package/dist/esm/adapters/code/agentcore.d.ts +65 -68
- package/dist/esm/adapters/code/agentcore.js +293 -212
- package/dist/esm/adapters/code/agentcore.js.map +1 -1
- package/dist/esm/adapters/code/agentcoreClient.d.ts +193 -0
- package/dist/esm/adapters/code/agentcoreClient.js +173 -0
- package/dist/esm/adapters/code/agentcoreClient.js.map +1 -0
- package/dist/esm/adapters/code/agentcoreWire.d.ts +119 -0
- package/dist/esm/adapters/code/agentcoreWire.js +334 -0
- package/dist/esm/adapters/code/agentcoreWire.js.map +1 -0
- package/dist/esm/adapters/code/fileName.d.ts +43 -0
- package/dist/esm/adapters/code/fileName.js +96 -0
- package/dist/esm/adapters/code/fileName.js.map +1 -0
- package/dist/esm/adapters/code/local.d.ts +91 -12
- package/dist/esm/adapters/code/local.js +528 -182
- package/dist/esm/adapters/code/local.js.map +1 -1
- package/dist/esm/adapters/code/output.d.ts +70 -0
- package/dist/esm/adapters/code/output.js +129 -0
- package/dist/esm/adapters/code/output.js.map +1 -0
- package/dist/esm/adapters/mcp/agentcoreRuntime/invoke.d.ts +7 -6
- package/dist/esm/adapters/mcp/agentcoreRuntime/invoke.js +7 -6
- package/dist/esm/adapters/mcp/agentcoreRuntime/invoke.js.map +1 -1
- package/dist/esm/adapters/mcp/agentcoreRuntime/sessionBusy.d.ts +32 -1
- package/dist/esm/adapters/mcp/agentcoreRuntime/sessionBusy.js +35 -1
- package/dist/esm/adapters/mcp/agentcoreRuntime/sessionBusy.js.map +1 -1
- package/dist/esm/adapters/mcp/agentcoreRuntime/transport.js +4 -2
- package/dist/esm/adapters/mcp/agentcoreRuntime/transport.js.map +1 -1
- package/dist/esm/core/codeRunnerTool.d.ts +15 -3
- package/dist/esm/core/codeRunnerTool.js +52 -7
- package/dist/esm/core/codeRunnerTool.js.map +1 -1
- package/dist/esm/doors/providers.d.ts +1 -1
- package/dist/esm/doors/providers.js.map +1 -1
- package/dist/esm/events/payloads.d.ts +144 -29
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/mcp/callLifetime.d.ts +57 -14
- package/dist/esm/mcp/callLifetime.js +67 -19
- package/dist/esm/mcp/callLifetime.js.map +1 -1
- package/dist/esm/mcp/callMarker.d.ts +43 -0
- package/dist/esm/mcp/callMarker.js +69 -0
- package/dist/esm/mcp/callMarker.js.map +1 -0
- package/dist/esm/mcp/connectionRefusals.js +7 -0
- package/dist/esm/mcp/connectionRefusals.js.map +1 -1
- package/dist/esm/mcp/index.d.ts +2 -0
- package/dist/esm/mcp/index.js +3 -0
- package/dist/esm/mcp/index.js.map +1 -1
- package/dist/esm/mcp/mcpClient.js +93 -26
- package/dist/esm/mcp/mcpClient.js.map +1 -1
- package/dist/esm/mcp/replay.d.ts +291 -0
- package/dist/esm/mcp/replay.js +405 -0
- package/dist/esm/mcp/replay.js.map +1 -0
- package/dist/esm/mcp/replayUnavailable.d.ts +68 -0
- package/dist/esm/mcp/replayUnavailable.js +87 -0
- package/dist/esm/mcp/replayUnavailable.js.map +1 -0
- package/dist/esm/mcp/requestLedger.d.ts +115 -32
- package/dist/esm/mcp/requestLedger.js +193 -52
- package/dist/esm/mcp/requestLedger.js.map +1 -1
- package/dist/esm/mcp/seriesEvidence.d.ts +73 -15
- package/dist/esm/mcp/seriesEvidence.js +114 -21
- package/dist/esm/mcp/seriesEvidence.js.map +1 -1
- package/dist/esm/mcp/throttleRetry.d.ts +86 -42
- package/dist/esm/mcp/throttleRetry.js +158 -50
- package/dist/esm/mcp/throttleRetry.js.map +1 -1
- package/dist/esm/mcp/toolResult.d.ts +6 -0
- package/dist/esm/mcp/toolResult.js +15 -0
- package/dist/esm/mcp/toolResult.js.map +1 -1
- package/dist/esm/mcp/types.d.ts +73 -8
- package/dist/esm/provider-contract/codeSandbox.d.ts +89 -0
- package/dist/esm/provider-contract/codeSandbox.js +119 -0
- package/dist/esm/provider-contract/codeSandbox.js.map +1 -0
- package/dist/esm/provider-contract/sessionExpired.d.ts +31 -0
- package/dist/esm/provider-contract/sessionExpired.js +40 -0
- package/dist/esm/provider-contract/sessionExpired.js.map +1 -0
- package/dist/esm/provider-contract/types.d.ts +166 -17
- package/dist/esm/provider-contract/types.js +9 -0
- package/dist/esm/provider-contract/types.js.map +1 -1
- package/dist/esm/redaction/knownStrings.js +16 -0
- package/dist/esm/redaction/knownStrings.js.map +1 -1
- package/dist/esm/tool-providers/index.d.ts +2 -2
- package/dist/esm/tool-providers/index.js +4 -0
- package/dist/esm/tool-providers/index.js.map +1 -1
- package/dist/esm/tools/requestEvidence.js +60 -0
- package/dist/esm/tools/requestEvidence.js.map +1 -1
- package/dist/index.js +12 -4
- package/dist/index.js.map +1 -1
- package/dist/mcp/callLifetime.js +66 -18
- package/dist/mcp/callLifetime.js.map +1 -1
- package/dist/mcp/callMarker.js +74 -0
- package/dist/mcp/callMarker.js.map +1 -0
- package/dist/mcp/connectionRefusals.js +7 -0
- package/dist/mcp/connectionRefusals.js.map +1 -1
- package/dist/mcp/index.js +5 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/mcpClient.js +91 -24
- package/dist/mcp/mcpClient.js.map +1 -1
- package/dist/mcp/replay.js +415 -0
- package/dist/mcp/replay.js.map +1 -0
- package/dist/mcp/replayUnavailable.js +92 -0
- package/dist/mcp/replayUnavailable.js.map +1 -0
- package/dist/mcp/requestLedger.js +193 -52
- package/dist/mcp/requestLedger.js.map +1 -1
- package/dist/mcp/seriesEvidence.js +116 -22
- package/dist/mcp/seriesEvidence.js.map +1 -1
- package/dist/mcp/throttleRetry.js +160 -51
- package/dist/mcp/throttleRetry.js.map +1 -1
- package/dist/mcp/toolResult.js +17 -1
- package/dist/mcp/toolResult.js.map +1 -1
- package/dist/provider-contract/codeSandbox.js +125 -0
- package/dist/provider-contract/codeSandbox.js.map +1 -0
- package/dist/provider-contract/sessionExpired.js +44 -0
- package/dist/provider-contract/sessionExpired.js.map +1 -0
- package/dist/provider-contract/types.js +12 -1
- package/dist/provider-contract/types.js.map +1 -1
- package/dist/redaction/knownStrings.js +16 -0
- package/dist/redaction/knownStrings.js.map +1 -1
- package/dist/tool-providers/index.js +5 -1
- package/dist/tool-providers/index.js.map +1 -1
- package/dist/tools/requestEvidence.js +60 -0
- package/dist/tools/requestEvidence.js.map +1 -1
- package/dist/types/adapters/code/agentcore.d.ts +65 -68
- package/dist/types/adapters/code/agentcore.d.ts.map +1 -1
- package/dist/types/adapters/code/agentcoreClient.d.ts +194 -0
- package/dist/types/adapters/code/agentcoreClient.d.ts.map +1 -0
- package/dist/types/adapters/code/agentcoreWire.d.ts +120 -0
- package/dist/types/adapters/code/agentcoreWire.d.ts.map +1 -0
- package/dist/types/adapters/code/fileName.d.ts +44 -0
- package/dist/types/adapters/code/fileName.d.ts.map +1 -0
- package/dist/types/adapters/code/local.d.ts +91 -12
- package/dist/types/adapters/code/local.d.ts.map +1 -1
- package/dist/types/adapters/code/output.d.ts +71 -0
- package/dist/types/adapters/code/output.d.ts.map +1 -0
- package/dist/types/adapters/mcp/agentcoreRuntime/invoke.d.ts +7 -6
- package/dist/types/adapters/mcp/agentcoreRuntime/invoke.d.ts.map +1 -1
- package/dist/types/adapters/mcp/agentcoreRuntime/sessionBusy.d.ts +32 -1
- package/dist/types/adapters/mcp/agentcoreRuntime/sessionBusy.d.ts.map +1 -1
- package/dist/types/adapters/mcp/agentcoreRuntime/transport.d.ts.map +1 -1
- package/dist/types/core/codeRunnerTool.d.ts +15 -3
- package/dist/types/core/codeRunnerTool.d.ts.map +1 -1
- package/dist/types/doors/providers.d.ts +1 -1
- package/dist/types/doors/providers.d.ts.map +1 -1
- package/dist/types/events/payloads.d.ts +144 -29
- package/dist/types/events/payloads.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/mcp/callLifetime.d.ts +57 -14
- package/dist/types/mcp/callLifetime.d.ts.map +1 -1
- package/dist/types/mcp/callMarker.d.ts +44 -0
- package/dist/types/mcp/callMarker.d.ts.map +1 -0
- package/dist/types/mcp/index.d.ts +2 -0
- package/dist/types/mcp/index.d.ts.map +1 -1
- package/dist/types/mcp/mcpClient.d.ts.map +1 -1
- package/dist/types/mcp/replay.d.ts +292 -0
- package/dist/types/mcp/replay.d.ts.map +1 -0
- package/dist/types/mcp/replayUnavailable.d.ts +69 -0
- package/dist/types/mcp/replayUnavailable.d.ts.map +1 -0
- package/dist/types/mcp/requestLedger.d.ts +115 -32
- package/dist/types/mcp/requestLedger.d.ts.map +1 -1
- package/dist/types/mcp/seriesEvidence.d.ts +73 -15
- package/dist/types/mcp/seriesEvidence.d.ts.map +1 -1
- package/dist/types/mcp/throttleRetry.d.ts +86 -42
- package/dist/types/mcp/throttleRetry.d.ts.map +1 -1
- package/dist/types/mcp/toolResult.d.ts +6 -0
- package/dist/types/mcp/toolResult.d.ts.map +1 -1
- package/dist/types/mcp/types.d.ts +73 -8
- package/dist/types/mcp/types.d.ts.map +1 -1
- package/dist/types/provider-contract/codeSandbox.d.ts +90 -0
- package/dist/types/provider-contract/codeSandbox.d.ts.map +1 -0
- package/dist/types/provider-contract/sessionExpired.d.ts +32 -0
- package/dist/types/provider-contract/sessionExpired.d.ts.map +1 -0
- package/dist/types/provider-contract/types.d.ts +166 -17
- package/dist/types/provider-contract/types.d.ts.map +1 -1
- package/dist/types/redaction/knownStrings.d.ts.map +1 -1
- package/dist/types/tool-providers/index.d.ts +2 -2
- package/dist/types/tool-providers/index.d.ts.map +1 -1
- package/dist/types/tools/requestEvidence.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/esm/mcp/types.d.ts
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
import type { Tool } from '../tools/tools.js';
|
|
24
24
|
import type { CredentialProvider } from '../identity/types.js';
|
|
25
25
|
import type { RetryOnThrottle } from './throttleRetry.js';
|
|
26
|
+
import type { McpReplayOptions } from './replay.js';
|
|
26
27
|
import type { FetchLike } from './gatewayTransport.js';
|
|
27
28
|
/**
|
|
28
29
|
* `stdio` transport — spawns a local subprocess and speaks MCP over
|
|
@@ -207,14 +208,17 @@ export interface McpClientOptions {
|
|
|
207
208
|
* the transport's `retry` values as the call's overall limits and these as
|
|
208
209
|
* limits on the 429 retries inside them.
|
|
209
210
|
*
|
|
210
|
-
* **
|
|
211
|
-
* the
|
|
212
|
-
*
|
|
213
|
-
*
|
|
214
|
-
*
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
211
|
+
* **Who may ask again is {@link McpClientOptions.replay}'s.** These
|
|
212
|
+
* options set the BUDGET of a call's retries; whether a tool call is sent
|
|
213
|
+
* again at all is the replay policy's. Under the default (`'compatibility'`)
|
|
214
|
+
* a 429 is repeated for every tool, ASSUMING the server refused it before
|
|
215
|
+
* running it — HTTP 429 says only that the request was rate-limited (RFC 6585
|
|
216
|
+
* §4) — and every such repeat records that assumption. A tool you declare as
|
|
217
|
+
* making changes is never repeated without a deduplication key, and
|
|
218
|
+
* `'app-authorized'` repeats only what you declare. `retryOnThrottle: false`
|
|
219
|
+
* turns 429 retries off for this server, and nothing else: a tool declared
|
|
220
|
+
* repeatable on `'network'`, and the `'app-authorized'` policy, keep their
|
|
221
|
+
* series and their record. A 5xx is an answer and is never repeated.
|
|
218
222
|
*
|
|
219
223
|
* **Why this is on by default.** Managed gateways rate-limit per principal by
|
|
220
224
|
* design, and without this a designed, self-clearing condition reached the
|
|
@@ -223,6 +227,65 @@ export interface McpClientOptions {
|
|
|
223
227
|
* Ignored for `stdio`, which has no HTTP status to read.
|
|
224
228
|
*/
|
|
225
229
|
readonly retryOnThrottle?: RetryOnThrottle;
|
|
230
|
+
/**
|
|
231
|
+
* Who may send a tool call again, declared by YOU for this server's tools —
|
|
232
|
+
* never by the model, a tool's description or the server's annotations
|
|
233
|
+
* (`readOnlyHint`). Read once, here; a field it does not know is refused.
|
|
234
|
+
*
|
|
235
|
+
* ```ts
|
|
236
|
+
* const orders = await mcpClient({
|
|
237
|
+
* name: 'orders',
|
|
238
|
+
* transport: { transport: 'http', url },
|
|
239
|
+
* replay: {
|
|
240
|
+
* policy: 'app-authorized',
|
|
241
|
+
* tools: {
|
|
242
|
+
* search_orders: { on: ['throttle', 'network'] },
|
|
243
|
+
* create_order: { on: ['throttle'], changes: true },
|
|
244
|
+
* },
|
|
245
|
+
* deduplicates: { argument: 'idempotency_key' },
|
|
246
|
+
* },
|
|
247
|
+
* });
|
|
248
|
+
* ```
|
|
249
|
+
*
|
|
250
|
+
* - `policy: 'compatibility'` (the default, kept in 12.0) — today's
|
|
251
|
+
* behaviour, by name: a 429 is sent again for every tool, assuming the
|
|
252
|
+
* server refused it before running it. Each such retry records that
|
|
253
|
+
* assumption (`permission: { by: 'compatibility', assumes: 'refused-before-execution' }`).
|
|
254
|
+
* It gains none of the strict guarantees below.
|
|
255
|
+
* - `policy: 'app-authorized'` (opt-in, by name) — a 429
|
|
256
|
+
* (`'throttle'`) or a request that failed without an answer
|
|
257
|
+
* (`'network'`) is sent again only for a tool whose entry names it.
|
|
258
|
+
* - `changes: true` — the tool makes changes: never sent again
|
|
259
|
+
* automatically, under either policy, unless `deduplicates` is declared
|
|
260
|
+
* and the call carries the key. A key protects only when the server uses it.
|
|
261
|
+
*
|
|
262
|
+
* Under both policies the adapter you chose retries its own refusal —
|
|
263
|
+
* AgentCore Runtime's session-busy reply — within the budget, as its policy:
|
|
264
|
+
* each repeat records what it assumes, never proof that nothing ran. A
|
|
265
|
+
* repeat re-sends the SAME request: the same arguments, server and session,
|
|
266
|
+
* as the same identity. Each attempt's run record says what is known of its
|
|
267
|
+
* effect — `unknown` for anything sent that did not complete, `applied` when
|
|
268
|
+
* the call completed (never proof of a write) — and what permitted the next
|
|
269
|
+
* one. Under `'app-authorized'`, a received refusal or error (a 429, a 503,
|
|
270
|
+
* a JSON-RPC or tool error) reaches the caller as the server sent it, its
|
|
271
|
+
* effect still unknown; a call that genuinely lacked an answer somewhere —
|
|
272
|
+
* a request with no response, or one accepted over HTTP whose JSON-RPC
|
|
273
|
+
* answer never came — and then fails, fails as "may have run"
|
|
274
|
+
* (footprintjs's `UnknownEffectError`, its final error as the `cause`).
|
|
275
|
+
* Under `'compatibility'` the caller sees the error it always did.
|
|
276
|
+
*
|
|
277
|
+
* `'app-authorized'` needs each request matched to its call and each answer
|
|
278
|
+
* seen. A connection that cannot give both refuses each tool call BEFORE its
|
|
279
|
+
* request is sent, with `McpReplayUnavailableError` and a typed `reason`: an
|
|
280
|
+
* MCP SDK whose `connect` replaces the transport's `onmessage` handler
|
|
281
|
+
* (`'answers-unobserved'`), one that drops the params' `_meta`
|
|
282
|
+
* (`'request-unmatched'`), or a transport whose requests the library cannot
|
|
283
|
+
* watch, such as `stdio` (`'requests-unwatched'`). Connecting and listing
|
|
284
|
+
* tools still run; only the tool invocation is refused. An explicit
|
|
285
|
+
* `'app-authorized'` never falls back to `'compatibility'`. Under
|
|
286
|
+
* `'compatibility'`, `stdio` ignores it: it has no retry series.
|
|
287
|
+
*/
|
|
288
|
+
readonly replay?: McpReplayOptions;
|
|
226
289
|
/**
|
|
227
290
|
* Pre-resolved SDK modules. Give these and the library never touches its Node
|
|
228
291
|
* `require` loader — which is what lets a browser bundle speak MCP over
|
|
@@ -295,6 +358,8 @@ export interface McpConnectionOptions {
|
|
|
295
358
|
readonly clientInfo?: undefined;
|
|
296
359
|
/** @see McpClientOptions — never set on this arm. */
|
|
297
360
|
readonly retryOnThrottle?: undefined;
|
|
361
|
+
/** @see McpClientOptions — never set on this arm. */
|
|
362
|
+
readonly replay?: undefined;
|
|
298
363
|
/** @internal @see McpClientOptions — never set on this arm. */
|
|
299
364
|
readonly _client?: undefined;
|
|
300
365
|
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The code-session port's refusals and its one path rule.
|
|
3
|
+
*
|
|
4
|
+
* Every adapter behind the `CodeSession` port refuses the same things with the
|
|
5
|
+
* same error, and reads a session path by the same rule, so a caller that
|
|
6
|
+
* swaps `localCodeRunner` for `agentCoreCodeRunner` catches the same names.
|
|
7
|
+
* The rule lives here, beside the port, rather than in either adapter: two
|
|
8
|
+
* copies of a path rule are two rules.
|
|
9
|
+
*/
|
|
10
|
+
/** Why a code-session operation was refused. */
|
|
11
|
+
export type CodeSandboxRefusal =
|
|
12
|
+
/** The path is absolute, climbs above the working directory, or is not a path. */
|
|
13
|
+
'path-refused'
|
|
14
|
+
/** A read found a file larger than its `maxBytes`. Nothing was returned. */
|
|
15
|
+
| 'file-too-large'
|
|
16
|
+
/** The backend answered a read with no file for the path. */
|
|
17
|
+
| 'file-not-returned'
|
|
18
|
+
/** The backend returned a file without saying which path it is. */
|
|
19
|
+
| 'uri-missing'
|
|
20
|
+
/** The backend returned a file for a path other than the one asked for. */
|
|
21
|
+
| 'uri-mismatch'
|
|
22
|
+
/** The backend returned several files for one path, or a file with both text and bytes, or neither. */
|
|
23
|
+
| 'content-ambiguous'
|
|
24
|
+
/** One request would be larger than the backend accepts in a single call. Nothing was sent. */
|
|
25
|
+
| 'request-too-large'
|
|
26
|
+
/** The backend did not confirm a write. */
|
|
27
|
+
| 'write-failed'
|
|
28
|
+
/** The caller's `timeoutMs` passed before the backend answered. */
|
|
29
|
+
| 'timed-out'
|
|
30
|
+
/** A process started, then the runtime reported an error for it. It was
|
|
31
|
+
* stopped; whether it finished, and what it changed, is unknown. */
|
|
32
|
+
| 'error-after-start'
|
|
33
|
+
/** The staged-input manifest could not be set where the next run reads it. */
|
|
34
|
+
| 'staged-inputs-unset';
|
|
35
|
+
/**
|
|
36
|
+
* A code-session operation refused — before anything was sent, or because
|
|
37
|
+
* what came back could not be trusted as the answer.
|
|
38
|
+
*
|
|
39
|
+
* Carries the path, sizes and limits as data. Never a file's contents and
|
|
40
|
+
* never a command's text: those are the two things a code session holds that
|
|
41
|
+
* an error message must not repeat, because error messages reach logs, traces
|
|
42
|
+
* and the model.
|
|
43
|
+
*/
|
|
44
|
+
export declare class CodeSandboxError extends Error {
|
|
45
|
+
readonly code: "ERR_CODE_SANDBOX";
|
|
46
|
+
/** What was refused. */
|
|
47
|
+
readonly reason: CodeSandboxRefusal;
|
|
48
|
+
/** The session path involved, when there was one. */
|
|
49
|
+
readonly path?: string;
|
|
50
|
+
/** The size that was measured, in bytes, when the refusal is about size. */
|
|
51
|
+
readonly bytes?: number;
|
|
52
|
+
/** The limit that size was held to, in bytes. */
|
|
53
|
+
readonly limit?: number;
|
|
54
|
+
constructor(reason: CodeSandboxRefusal, message: string, details?: {
|
|
55
|
+
readonly path?: string;
|
|
56
|
+
readonly bytes?: number;
|
|
57
|
+
readonly limit?: number;
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* One session path, checked and put in canonical form — THE path rule every
|
|
62
|
+
* adapter applies before it reads a file.
|
|
63
|
+
*
|
|
64
|
+
* Refused, by name, before anything is sent:
|
|
65
|
+
* - an empty path, and one that names the working directory itself (`.`);
|
|
66
|
+
* - an absolute path (`/etc/passwd`) and a drive (`C:…`);
|
|
67
|
+
* - a leading `~`, which a shell would read as a home directory;
|
|
68
|
+
* - any backslash — a separator on one platform and an ordinary character
|
|
69
|
+
* on another, so `a\..\..\x` cannot be judged the same way everywhere;
|
|
70
|
+
* - a NUL, which ends a path early in the operating system's own calls;
|
|
71
|
+
* - a `..` that climbs above the working directory (`../x`, `a/../../x`).
|
|
72
|
+
*
|
|
73
|
+
* A `..` that stays inside is resolved here (`a/../b` → `b`), `.` and empty
|
|
74
|
+
* segments are dropped (`./out//a.csv` → `out/a.csv`), and the result never
|
|
75
|
+
* contains `..` at all — so no backend is ever handed a parent hop to
|
|
76
|
+
* interpret. Lexical, not physical: on the caller's own machine a symbolic
|
|
77
|
+
* link can still point elsewhere, which `localCodeRunner` checks separately.
|
|
78
|
+
*
|
|
79
|
+
* @throws CodeSandboxError with reason `'path-refused'`.
|
|
80
|
+
*/
|
|
81
|
+
export declare function sandboxPath(path: string): string;
|
|
82
|
+
/**
|
|
83
|
+
* The one check of a `maxBytes` bound: a positive whole number, or a
|
|
84
|
+
* `TypeError` naming the option. A read with no bound, or with a bound of
|
|
85
|
+
* zero, is a programming error rather than a file that happened to be large.
|
|
86
|
+
*/
|
|
87
|
+
export declare function readBound(options: {
|
|
88
|
+
readonly maxBytes?: unknown;
|
|
89
|
+
} | undefined): number;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The code-session port's refusals and its one path rule.
|
|
3
|
+
*
|
|
4
|
+
* Every adapter behind the `CodeSession` port refuses the same things with the
|
|
5
|
+
* same error, and reads a session path by the same rule, so a caller that
|
|
6
|
+
* swaps `localCodeRunner` for `agentCoreCodeRunner` catches the same names.
|
|
7
|
+
* The rule lives here, beside the port, rather than in either adapter: two
|
|
8
|
+
* copies of a path rule are two rules.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* A code-session operation refused — before anything was sent, or because
|
|
12
|
+
* what came back could not be trusted as the answer.
|
|
13
|
+
*
|
|
14
|
+
* Carries the path, sizes and limits as data. Never a file's contents and
|
|
15
|
+
* never a command's text: those are the two things a code session holds that
|
|
16
|
+
* an error message must not repeat, because error messages reach logs, traces
|
|
17
|
+
* and the model.
|
|
18
|
+
*/
|
|
19
|
+
export class CodeSandboxError extends Error {
|
|
20
|
+
code = 'ERR_CODE_SANDBOX';
|
|
21
|
+
/** What was refused. */
|
|
22
|
+
reason;
|
|
23
|
+
/** The session path involved, when there was one. */
|
|
24
|
+
path;
|
|
25
|
+
/** The size that was measured, in bytes, when the refusal is about size. */
|
|
26
|
+
bytes;
|
|
27
|
+
/** The limit that size was held to, in bytes. */
|
|
28
|
+
limit;
|
|
29
|
+
constructor(reason, message, details = {}) {
|
|
30
|
+
super(message);
|
|
31
|
+
this.name = 'CodeSandboxError';
|
|
32
|
+
this.reason = reason;
|
|
33
|
+
if (details.path !== undefined)
|
|
34
|
+
this.path = details.path;
|
|
35
|
+
if (details.bytes !== undefined)
|
|
36
|
+
this.bytes = details.bytes;
|
|
37
|
+
if (details.limit !== undefined)
|
|
38
|
+
this.limit = details.limit;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/** The longest stretch of a refused path a message quotes. */
|
|
42
|
+
const QUOTED_PATH_MAX = 200;
|
|
43
|
+
function quoted(path) {
|
|
44
|
+
const shown = path.length > QUOTED_PATH_MAX ? `${path.slice(0, QUOTED_PATH_MAX)}…` : path;
|
|
45
|
+
return JSON.stringify(shown);
|
|
46
|
+
}
|
|
47
|
+
function refused(path, why) {
|
|
48
|
+
return new CodeSandboxError('path-refused', `code session: the path ${quoted(path)} ${why}. A session path is relative to the ` +
|
|
49
|
+
"session's working directory and stays inside it — name the file as the session's code " +
|
|
50
|
+
'would, for example `out/result.csv`.', { path });
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* One session path, checked and put in canonical form — THE path rule every
|
|
54
|
+
* adapter applies before it reads a file.
|
|
55
|
+
*
|
|
56
|
+
* Refused, by name, before anything is sent:
|
|
57
|
+
* - an empty path, and one that names the working directory itself (`.`);
|
|
58
|
+
* - an absolute path (`/etc/passwd`) and a drive (`C:…`);
|
|
59
|
+
* - a leading `~`, which a shell would read as a home directory;
|
|
60
|
+
* - any backslash — a separator on one platform and an ordinary character
|
|
61
|
+
* on another, so `a\..\..\x` cannot be judged the same way everywhere;
|
|
62
|
+
* - a NUL, which ends a path early in the operating system's own calls;
|
|
63
|
+
* - a `..` that climbs above the working directory (`../x`, `a/../../x`).
|
|
64
|
+
*
|
|
65
|
+
* A `..` that stays inside is resolved here (`a/../b` → `b`), `.` and empty
|
|
66
|
+
* segments are dropped (`./out//a.csv` → `out/a.csv`), and the result never
|
|
67
|
+
* contains `..` at all — so no backend is ever handed a parent hop to
|
|
68
|
+
* interpret. Lexical, not physical: on the caller's own machine a symbolic
|
|
69
|
+
* link can still point elsewhere, which `localCodeRunner` checks separately.
|
|
70
|
+
*
|
|
71
|
+
* @throws CodeSandboxError with reason `'path-refused'`.
|
|
72
|
+
*/
|
|
73
|
+
export function sandboxPath(path) {
|
|
74
|
+
if (typeof path !== 'string') {
|
|
75
|
+
throw refused(String(path), 'is not a string');
|
|
76
|
+
}
|
|
77
|
+
if (path.length === 0)
|
|
78
|
+
throw refused(path, 'is empty');
|
|
79
|
+
if (path.includes('\0'))
|
|
80
|
+
throw refused(path, 'contains a NUL character');
|
|
81
|
+
if (path.includes('\\')) {
|
|
82
|
+
throw refused(path, 'contains a backslash, which is a separator on one platform and an ordinary character on another');
|
|
83
|
+
}
|
|
84
|
+
if (path.startsWith('/'))
|
|
85
|
+
throw refused(path, 'is absolute');
|
|
86
|
+
if (/^[A-Za-z]:/.test(path))
|
|
87
|
+
throw refused(path, 'names a drive');
|
|
88
|
+
if (path.startsWith('~'))
|
|
89
|
+
throw refused(path, "starts with '~', which a shell reads as a home directory");
|
|
90
|
+
const kept = [];
|
|
91
|
+
for (const segment of path.split('/')) {
|
|
92
|
+
if (segment === '' || segment === '.')
|
|
93
|
+
continue;
|
|
94
|
+
if (segment === '..') {
|
|
95
|
+
if (kept.length === 0)
|
|
96
|
+
throw refused(path, 'climbs above the working directory');
|
|
97
|
+
kept.pop();
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
kept.push(segment);
|
|
101
|
+
}
|
|
102
|
+
if (kept.length === 0)
|
|
103
|
+
throw refused(path, 'names the working directory itself, not a file');
|
|
104
|
+
return kept.join('/');
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* The one check of a `maxBytes` bound: a positive whole number, or a
|
|
108
|
+
* `TypeError` naming the option. A read with no bound, or with a bound of
|
|
109
|
+
* zero, is a programming error rather than a file that happened to be large.
|
|
110
|
+
*/
|
|
111
|
+
export function readBound(options) {
|
|
112
|
+
const maxBytes = options?.maxBytes;
|
|
113
|
+
if (typeof maxBytes !== 'number' || !Number.isSafeInteger(maxBytes) || maxBytes <= 0) {
|
|
114
|
+
throw new TypeError('code session: readFile needs `maxBytes`, a positive whole number of bytes — a read names ' +
|
|
115
|
+
'its bound, and a file over it is refused rather than cut.');
|
|
116
|
+
}
|
|
117
|
+
return maxBytes;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=codeSandbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codeSandbox.js","sourceRoot":"","sources":["../../../src/provider-contract/codeSandbox.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `SessionExpiredError` — a remote session that is gone, said ONE way.
|
|
3
|
+
*
|
|
4
|
+
* A managed backend reaps its sessions on its own schedule (a timeout, a stop,
|
|
5
|
+
* a restart), and each service words that differently: AgentCore's Code
|
|
6
|
+
* Interpreter answers with a `ValidationException` saying the session is "not
|
|
7
|
+
* active", a stream error naming an inactive session, or a
|
|
8
|
+
* `ResourceNotFoundException` on a call that addresses nothing but the session.
|
|
9
|
+
* A caller that has to recognise all of those by message text will miss the
|
|
10
|
+
* next one. An adapter recognises them once and raises this instead, so "start
|
|
11
|
+
* a new session" is one `instanceof` away.
|
|
12
|
+
*
|
|
13
|
+
* Raised only on evidence that names the session. A "not found" that could be
|
|
14
|
+
* about something else in the session (a file a read asked for) is not taken
|
|
15
|
+
* as proof the session is gone.
|
|
16
|
+
*
|
|
17
|
+
* It names the session and the signal that said so — never the request that
|
|
18
|
+
* hit it. Nothing reconnects: the session's files and state are gone, and a
|
|
19
|
+
* session name is not an address (names are not unique), so the only honest
|
|
20
|
+
* next step is a new session.
|
|
21
|
+
*/
|
|
22
|
+
export declare class SessionExpiredError extends Error {
|
|
23
|
+
readonly code: "ERR_SESSION_EXPIRED";
|
|
24
|
+
/** The adapter that raised it, e.g. `'agentCoreCodeRunner'`. */
|
|
25
|
+
readonly backend: string;
|
|
26
|
+
/** The backend's id for the session that is gone. */
|
|
27
|
+
readonly sessionId: string;
|
|
28
|
+
/** The service's own name for the signal that said so, e.g. `'ResourceNotFoundException'`. */
|
|
29
|
+
readonly evidence: string;
|
|
30
|
+
constructor(backend: string, sessionId: string, evidence: string);
|
|
31
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `SessionExpiredError` — a remote session that is gone, said ONE way.
|
|
3
|
+
*
|
|
4
|
+
* A managed backend reaps its sessions on its own schedule (a timeout, a stop,
|
|
5
|
+
* a restart), and each service words that differently: AgentCore's Code
|
|
6
|
+
* Interpreter answers with a `ValidationException` saying the session is "not
|
|
7
|
+
* active", a stream error naming an inactive session, or a
|
|
8
|
+
* `ResourceNotFoundException` on a call that addresses nothing but the session.
|
|
9
|
+
* A caller that has to recognise all of those by message text will miss the
|
|
10
|
+
* next one. An adapter recognises them once and raises this instead, so "start
|
|
11
|
+
* a new session" is one `instanceof` away.
|
|
12
|
+
*
|
|
13
|
+
* Raised only on evidence that names the session. A "not found" that could be
|
|
14
|
+
* about something else in the session (a file a read asked for) is not taken
|
|
15
|
+
* as proof the session is gone.
|
|
16
|
+
*
|
|
17
|
+
* It names the session and the signal that said so — never the request that
|
|
18
|
+
* hit it. Nothing reconnects: the session's files and state are gone, and a
|
|
19
|
+
* session name is not an address (names are not unique), so the only honest
|
|
20
|
+
* next step is a new session.
|
|
21
|
+
*/
|
|
22
|
+
export class SessionExpiredError extends Error {
|
|
23
|
+
code = 'ERR_SESSION_EXPIRED';
|
|
24
|
+
/** The adapter that raised it, e.g. `'agentCoreCodeRunner'`. */
|
|
25
|
+
backend;
|
|
26
|
+
/** The backend's id for the session that is gone. */
|
|
27
|
+
sessionId;
|
|
28
|
+
/** The service's own name for the signal that said so, e.g. `'ResourceNotFoundException'`. */
|
|
29
|
+
evidence;
|
|
30
|
+
constructor(backend, sessionId, evidence) {
|
|
31
|
+
super(`${backend}: session ${sessionId} is no longer active (${evidence}). The service ends a ` +
|
|
32
|
+
'session at its timeout or when it is stopped, and its files and state end with it. ' +
|
|
33
|
+
'Start a new session; nothing reconnects to this one.');
|
|
34
|
+
this.name = 'SessionExpiredError';
|
|
35
|
+
this.backend = backend;
|
|
36
|
+
this.sessionId = sessionId;
|
|
37
|
+
this.evidence = evidence;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=sessionExpired.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessionExpired.js","sourceRoot":"","sources":["../../../src/provider-contract/sessionExpired.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IACnC,IAAI,GAAG,qBAA8B,CAAC;IAC/C,gEAAgE;IACvD,OAAO,CAAS;IACzB,qDAAqD;IAC5C,SAAS,CAAS;IAC3B,8FAA8F;IACrF,QAAQ,CAAS;IAE1B,YAAY,OAAe,EAAE,SAAiB,EAAE,QAAgB;QAC9D,KAAK,CACH,GAAG,OAAO,aAAa,SAAS,yBAAyB,QAAQ,wBAAwB;YACvF,qFAAqF;YACrF,sDAAsD,CACzD,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;QAClC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;CACF"}
|
|
@@ -1165,6 +1165,42 @@ export interface CodeSession {
|
|
|
1165
1165
|
* the accepted-and-silently-wrong failure.
|
|
1166
1166
|
*/
|
|
1167
1167
|
stageInputs?(inputs: readonly CodeInput[]): Promise<readonly StagedCodeInput[]>;
|
|
1168
|
+
/**
|
|
1169
|
+
* OPTIONAL — read ONE file back out of the session, whole or not at all.
|
|
1170
|
+
*
|
|
1171
|
+
* `path` is relative to the session's working directory and may not leave
|
|
1172
|
+
* it. An absolute path, a `..` that climbs above the working directory, a
|
|
1173
|
+
* backslash, a leading `~` or a NUL is refused by name before anything is
|
|
1174
|
+
* sent (`CodeSandboxError`, reason `'path-refused'`) — one rule,
|
|
1175
|
+
* `sandboxPath`, shared by every adapter.
|
|
1176
|
+
*
|
|
1177
|
+
* The answer is the file the BACKEND returned for that path, paired to it
|
|
1178
|
+
* by what the backend said it returned. A file the adapter cannot pair with
|
|
1179
|
+
* the path it asked for is refused, never guessed at — a backend that
|
|
1180
|
+
* answers with another file, or with two, has not answered this read.
|
|
1181
|
+
*
|
|
1182
|
+
* `maxBytes` is required: a read names its bound. A file over it is refused
|
|
1183
|
+
* (reason `'file-too-large'`), never cut — a truncated file handed back as
|
|
1184
|
+
* the file is the silent success this port refuses everywhere else.
|
|
1185
|
+
*
|
|
1186
|
+
* Feature-detect with `canReadCodeFiles(session)`.
|
|
1187
|
+
*/
|
|
1188
|
+
readFile?(path: string, options: CodeReadOptions): Promise<CodeFile>;
|
|
1189
|
+
/**
|
|
1190
|
+
* OPTIONAL — run ONE shell command in the session.
|
|
1191
|
+
*
|
|
1192
|
+
* It runs arbitrary shell, so an adapter offers it only when the runner was
|
|
1193
|
+
* built with `commands: true`; otherwise the member is ABSENT. Feature-detect
|
|
1194
|
+
* with `canRunCodeCommands(session)`. The command runs in the session's
|
|
1195
|
+
* working directory with the environment `execute` gets, staged-input
|
|
1196
|
+
* manifest included.
|
|
1197
|
+
*
|
|
1198
|
+
* The result says only what the backend reported. The exit status comes
|
|
1199
|
+
* from the backend or not at all: when it reported none, `exitCode` is
|
|
1200
|
+
* absent — unknown, never inferred from an error flag and never defaulted.
|
|
1201
|
+
* stdout and stderr are bounded, and a cut is stated on `truncated`.
|
|
1202
|
+
*/
|
|
1203
|
+
runCommand?(command: string, options?: CodeCommandOptions): Promise<CodeCommandResult>;
|
|
1168
1204
|
/**
|
|
1169
1205
|
* Release the session.
|
|
1170
1206
|
*
|
|
@@ -1177,13 +1213,138 @@ export interface CodeSession {
|
|
|
1177
1213
|
/** Can this session accept staged inputs? The feature-detection law: read the
|
|
1178
1214
|
* member, never assume it from the adapter's name. */
|
|
1179
1215
|
export declare function canStageCodeInputs(session: CodeSession): session is CodeSession & Required<Pick<CodeSession, 'stageInputs'>>;
|
|
1216
|
+
/** Can this session read files back out? Read the member, never the adapter's name. */
|
|
1217
|
+
export declare function canReadCodeFiles(session: CodeSession): session is CodeSession & Required<Pick<CodeSession, 'readFile'>>;
|
|
1218
|
+
/** Can this session run shell commands? Absent unless the runner was built
|
|
1219
|
+
* with `commands: true`. Read the member, never the adapter's name. */
|
|
1220
|
+
export declare function canRunCodeCommands(session: CodeSession): session is CodeSession & Required<Pick<CodeSession, 'runCommand'>>;
|
|
1221
|
+
/** How one {@link CodeSession.readFile} is bounded. */
|
|
1222
|
+
export interface CodeReadOptions {
|
|
1223
|
+
/**
|
|
1224
|
+
* The most bytes this read may return. Required, and a positive whole
|
|
1225
|
+
* number: a file larger than this is refused, never cut.
|
|
1226
|
+
*/
|
|
1227
|
+
readonly maxBytes: number;
|
|
1228
|
+
/** Stop waiting for the read. */
|
|
1229
|
+
readonly signal?: AbortSignal;
|
|
1230
|
+
}
|
|
1231
|
+
/** One file read back out of a code session — exactly as the backend returned it. */
|
|
1232
|
+
export interface CodeFile {
|
|
1233
|
+
/** The path that was read, in the canonical form the backend was asked for
|
|
1234
|
+
* (`./out//a.csv` → `out/a.csv`). */
|
|
1235
|
+
readonly path: string;
|
|
1236
|
+
/**
|
|
1237
|
+
* The contents. A string when the backend returned TEXT, bytes when it
|
|
1238
|
+
* returned BYTES — decided by which of the two the backend filled, never by
|
|
1239
|
+
* the file's name or extension. A backend that draws no such line
|
|
1240
|
+
* (`localCodeRunner`: a file on disk is bytes) returns bytes, and never
|
|
1241
|
+
* guesses an encoding.
|
|
1242
|
+
*/
|
|
1243
|
+
readonly data: string | Uint8Array;
|
|
1244
|
+
/** The size of `data` in bytes (a string's UTF-8 length). */
|
|
1245
|
+
readonly bytes: number;
|
|
1246
|
+
/** The backend's own statement of the media type, when it made one. Never guessed. */
|
|
1247
|
+
readonly mediaType?: string;
|
|
1248
|
+
}
|
|
1249
|
+
/** How one {@link CodeSession.runCommand} is bounded. */
|
|
1250
|
+
export interface CodeCommandOptions {
|
|
1251
|
+
/**
|
|
1252
|
+
* Stop waiting after this many milliseconds. What happens to the command
|
|
1253
|
+
* depends on the backend, and the error says which: a local child process is
|
|
1254
|
+
* killed; a managed sandbox may keep running it.
|
|
1255
|
+
*/
|
|
1256
|
+
readonly timeoutMs?: number;
|
|
1257
|
+
/** Stop waiting when this fires. */
|
|
1258
|
+
readonly signal?: AbortSignal;
|
|
1259
|
+
/** Per-stream ceiling for this command's output, in characters. The
|
|
1260
|
+
* runner's own `maxOutputChars` when absent. A cut is stated on `truncated`. */
|
|
1261
|
+
readonly maxOutputChars?: number;
|
|
1262
|
+
/**
|
|
1263
|
+
* A line the command prints when it reaches a point you care about — for
|
|
1264
|
+
* example `make && echo STEP_DONE` with `checkpoint: 'STEP_DONE'`. The
|
|
1265
|
+
* result then says, on `checkpointSeen`, whether stdout held that exact line,
|
|
1266
|
+
* read BEFORE any cut, so a marker printed past `maxOutputChars` is still
|
|
1267
|
+
* found.
|
|
1268
|
+
*
|
|
1269
|
+
* It proves the command reached that line and nothing more: not that it
|
|
1270
|
+
* exited cleanly, and not that anything after it ran. Its absence proves
|
|
1271
|
+
* nothing about why. One line, no line breaks.
|
|
1272
|
+
*/
|
|
1273
|
+
readonly checkpoint?: string;
|
|
1274
|
+
}
|
|
1275
|
+
/** What one shell command produced — only what the backend reported. */
|
|
1276
|
+
export interface CodeCommandResult {
|
|
1277
|
+
readonly stdout: string;
|
|
1278
|
+
readonly stderr: string;
|
|
1279
|
+
/**
|
|
1280
|
+
* The exit status the backend reported. ABSENT when it reported none: the
|
|
1281
|
+
* outcome is unknown. Never inferred from {@link CodeCommandResult.isError},
|
|
1282
|
+
* never defaulted, never derived from the output.
|
|
1283
|
+
*/
|
|
1284
|
+
readonly exitCode?: number;
|
|
1285
|
+
/**
|
|
1286
|
+
* The backend's own error flag, as it reported it (AgentCore's `isError`);
|
|
1287
|
+
* absent when it reported none. It is NOT an exit status — a command can
|
|
1288
|
+
* fail without it, and it can be set with no exit status at all.
|
|
1289
|
+
*/
|
|
1290
|
+
readonly isError?: boolean;
|
|
1291
|
+
/** The signal that ended the command before it exited, when the runner knows
|
|
1292
|
+
* it (`'SIGKILL'`). There is no `exitCode` then, and none is made up. */
|
|
1293
|
+
readonly terminatedBy?: string;
|
|
1294
|
+
/** Present IFF output was cut — see {@link CodeTruncation}. */
|
|
1295
|
+
readonly truncated?: CodeTruncation;
|
|
1296
|
+
/** Present IFF a `checkpoint` was asked for: whether stdout held that line. */
|
|
1297
|
+
readonly checkpointSeen?: boolean;
|
|
1298
|
+
}
|
|
1299
|
+
/**
|
|
1300
|
+
* Present IFF output was cut, and then it says by how much.
|
|
1301
|
+
*
|
|
1302
|
+
* Load-bearing, not politeness. A runner exists so big data is computed
|
|
1303
|
+
* outside the context window instead of pasted into it; a runner that
|
|
1304
|
+
* quietly slices its own output to fit is the same bug wearing a different
|
|
1305
|
+
* hat, and the model would go on to reason over a truncated table it was
|
|
1306
|
+
* never told was truncated. An unstated slice is a silent success.
|
|
1307
|
+
*/
|
|
1308
|
+
export interface CodeTruncation {
|
|
1309
|
+
readonly stdout?: boolean;
|
|
1310
|
+
readonly stderr?: boolean;
|
|
1311
|
+
/** The pre-truncation length, in characters, of whichever stream was cut. */
|
|
1312
|
+
readonly ofChars?: number;
|
|
1313
|
+
}
|
|
1180
1314
|
/** What one execution produced. */
|
|
1181
1315
|
export interface CodeResult {
|
|
1182
|
-
/**
|
|
1183
|
-
|
|
1316
|
+
/**
|
|
1317
|
+
* Did the code run to completion without an error exit? WHAT THE RUNNER
|
|
1318
|
+
* REPORTED, nothing more.
|
|
1319
|
+
*
|
|
1320
|
+
* `true` or `false` only when the backend said so: an exit status, or its
|
|
1321
|
+
* own error verdict. ABSENT when it reported neither — the outcome is
|
|
1322
|
+
* unknown, and an absent `ok` is never success. (Before this was optional,
|
|
1323
|
+
* `agentCoreCodeRunner` filled `true` from silence.) A `false` is told
|
|
1324
|
+
* apart by the fields below: a program that exited non-zero (`exitCode`), a
|
|
1325
|
+
* backend error with no exit status (`serviceError`, where the run is
|
|
1326
|
+
* unconfirmed), and a process ended before it exited (`terminatedBy`).
|
|
1327
|
+
*/
|
|
1328
|
+
readonly ok?: boolean;
|
|
1184
1329
|
readonly stdout: string;
|
|
1185
1330
|
readonly stderr: string;
|
|
1331
|
+
/** The exit status — exactly when the runner reported one. Never inferred
|
|
1332
|
+
* from an error flag, never defaulted. */
|
|
1186
1333
|
readonly exitCode?: number;
|
|
1334
|
+
/**
|
|
1335
|
+
* `true` when the backend flagged its answer as an error and reported NO
|
|
1336
|
+
* exit status: whether the code ran at all is not confirmed. That is not a
|
|
1337
|
+
* program that failed — a program that ran and failed has an `exitCode`.
|
|
1338
|
+
* `ok` is `false` alongside it.
|
|
1339
|
+
*/
|
|
1340
|
+
readonly serviceError?: true;
|
|
1341
|
+
/**
|
|
1342
|
+
* The signal that ended the process before it exited, when the runner knows
|
|
1343
|
+
* it (`'SIGKILL'`): there is no exit status then, and none is made up. A
|
|
1344
|
+
* local child the operating system ended, or one the runner ended because
|
|
1345
|
+
* its output passed the buffer ceiling. `ok` is `false` alongside it.
|
|
1346
|
+
*/
|
|
1347
|
+
readonly terminatedBy?: string;
|
|
1187
1348
|
/** Files the run produced, described rather than inlined — the whole point is
|
|
1188
1349
|
* that big data does not enter the window. All fields beyond the original
|
|
1189
1350
|
* `{ name, bytes, uri? }` are ADDITIVE (9.22.0) and honest about absence:
|
|
@@ -1221,19 +1382,7 @@ export interface CodeResult {
|
|
|
1221
1382
|
readonly data?: string | Uint8Array;
|
|
1222
1383
|
readonly ref?: string;
|
|
1223
1384
|
}[];
|
|
1224
|
-
/**
|
|
1225
|
-
*
|
|
1226
|
-
|
|
1227
|
-
* Load-bearing, not politeness. A runner exists so big data is computed
|
|
1228
|
-
* outside the context window instead of pasted into it; a runner that
|
|
1229
|
-
* quietly slices its own output to fit is the same bug wearing a different
|
|
1230
|
-
* hat, and the model would go on to reason over a truncated table it was
|
|
1231
|
-
* never told was truncated. An unstated slice is a silent success.
|
|
1232
|
-
*/
|
|
1233
|
-
readonly truncated?: {
|
|
1234
|
-
readonly stdout?: boolean;
|
|
1235
|
-
readonly stderr?: boolean;
|
|
1236
|
-
/** The pre-truncation length, in characters, of whichever stream was cut. */
|
|
1237
|
-
readonly ofChars?: number;
|
|
1238
|
-
};
|
|
1385
|
+
/** Present IFF output was cut — see {@link CodeTruncation}. An unstated
|
|
1386
|
+
* slice is a silent success. */
|
|
1387
|
+
readonly truncated?: CodeTruncation;
|
|
1239
1388
|
}
|
|
@@ -50,4 +50,13 @@ export const STAGED_INPUTS_ENV = 'AF_STAGED_INPUTS';
|
|
|
50
50
|
export function canStageCodeInputs(session) {
|
|
51
51
|
return typeof session.stageInputs === 'function';
|
|
52
52
|
}
|
|
53
|
+
/** Can this session read files back out? Read the member, never the adapter's name. */
|
|
54
|
+
export function canReadCodeFiles(session) {
|
|
55
|
+
return typeof session.readFile === 'function';
|
|
56
|
+
}
|
|
57
|
+
/** Can this session run shell commands? Absent unless the runner was built
|
|
58
|
+
* with `commands: true`. Read the member, never the adapter's name. */
|
|
59
|
+
export function canRunCodeCommands(session) {
|
|
60
|
+
return typeof session.runCommand === 'function';
|
|
61
|
+
}
|
|
53
62
|
//# sourceMappingURL=types.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/provider-contract/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AA8OH;;;;GAIG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAwB,MAAM,CAAC,MAAM,CAAC;IAC5E,MAAM;IACN,WAAW;CACZ,CAAC,CAAC;AA0sBH;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAC5B,OAAsC,EACtC,UAAgC;IAEhC,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAC3B,IAAI,UAAU,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IAC5C,OAAO,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;AACxD,CAAC;AAqID;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/provider-contract/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AA8OH;;;;GAIG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAwB,MAAM,CAAC,MAAM,CAAC;IAC5E,MAAM;IACN,WAAW;CACZ,CAAC,CAAC;AA0sBH;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAC5B,OAAsC,EACtC,UAAgC;IAEhC,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAC3B,IAAI,UAAU,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IAC5C,OAAO,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;AACxD,CAAC;AAqID;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,kBAAkB,CAAC;AAoIpD;uDACuD;AACvD,MAAM,UAAU,kBAAkB,CAChC,OAAoB;IAEpB,OAAO,OAAO,OAAO,CAAC,WAAW,KAAK,UAAU,CAAC;AACnD,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,gBAAgB,CAC9B,OAAoB;IAEpB,OAAO,OAAO,OAAO,CAAC,QAAQ,KAAK,UAAU,CAAC;AAChD,CAAC;AAED;wEACwE;AACxE,MAAM,UAAU,kBAAkB,CAChC,OAAoB;IAEpB,OAAO,OAAO,OAAO,CAAC,UAAU,KAAK,UAAU,CAAC;AAClD,CAAC"}
|