@aexhq/sdk 0.35.0 → 0.36.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/README.md +16 -15
- package/dist/_contracts/index.d.ts +3 -4
- package/dist/_contracts/index.js +1 -4
- package/dist/_contracts/operations.d.ts +2 -1
- package/dist/_contracts/operations.js +10 -0
- package/dist/_contracts/run-config.d.ts +1 -3
- package/dist/_contracts/run-config.js +2 -7
- package/dist/_contracts/run-trace.d.ts +0 -86
- package/dist/_contracts/run-trace.js +1 -184
- package/dist/_contracts/run-unit.d.ts +2 -25
- package/dist/_contracts/run-unit.js +1 -2
- package/dist/_contracts/runtime-manifest.d.ts +1 -1
- package/dist/_contracts/runtime-security-profile.d.ts +0 -2
- package/dist/_contracts/runtime-security-profile.js +0 -9
- package/dist/_contracts/runtime-types.d.ts +25 -4
- package/dist/_contracts/stable.d.ts +1 -1
- package/dist/_contracts/stable.js +1 -1
- package/dist/_contracts/submission.d.ts +4 -72
- package/dist/_contracts/submission.js +5 -472
- package/dist/cli.mjs +20 -442
- package/dist/cli.mjs.sha256 +1 -1
- package/dist/client.d.ts +30 -25
- package/dist/client.js +251 -66
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +7 -15
- package/dist/index.js +5 -17
- package/dist/index.js.map +1 -1
- package/dist/secret.d.ts +2 -2
- package/dist/secret.js +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/concepts/composition.md +8 -14
- package/docs/credentials.md +59 -101
- package/docs/defaults.md +0 -8
- package/docs/events.md +8 -9
- package/docs/limits-and-quotas.md +1 -4
- package/docs/limits.md +2 -6
- package/docs/mcp.md +4 -5
- package/docs/networking.md +6 -16
- package/docs/outputs.md +0 -4
- package/docs/public-surface.json +3 -3
- package/docs/quickstart.md +3 -7
- package/docs/run-config.md +6 -3
- package/docs/secrets.md +1 -1
- package/docs/skills.md +3 -3
- package/docs/vision-skills.md +52 -101
- package/examples/feature-tour.ts +4 -21
- package/package.json +1 -1
- package/dist/_contracts/proxy-protocol.d.ts +0 -305
- package/dist/_contracts/proxy-protocol.js +0 -297
- package/dist/_contracts/proxy-validation.d.ts +0 -19
- package/dist/_contracts/proxy-validation.js +0 -51
- package/dist/data-tools.d.ts +0 -82
- package/dist/data-tools.js +0 -251
- package/dist/data-tools.js.map +0 -1
- package/dist/proxy-endpoint.d.ts +0 -131
- package/dist/proxy-endpoint.js +0 -144
- package/dist/proxy-endpoint.js.map +0 -1
- package/examples/chat-corpus.ts +0 -84
package/README.md
CHANGED
|
@@ -8,9 +8,9 @@ aex is an agent execution platform for launching autonomous agents from a simple
|
|
|
8
8
|
|
|
9
9
|
The package ships:
|
|
10
10
|
|
|
11
|
-
- `Aex`
|
|
11
|
+
- `Aex` for sessions, one-shot runs, inspect, download, cancel, and delete.
|
|
12
12
|
- `sessions` / `openSession()` for durable, resumable agent sessions.
|
|
13
|
-
- Typed run primitives: `Models`, `Providers`, `Sizes`, `Tool` / `Tools` (skill-tools), `AgentsMd`, `File`, `McpServer`,
|
|
13
|
+
- Typed run primitives: `Models`, `Providers`, `Sizes`, `Tool` / `Tools` (skill-tools), `AgentsMd`, `File`, `McpServer`, and `Secret`.
|
|
14
14
|
- A bundled `aex` CLI with the same run, status, events, outputs, download, cancel, delete, and whoami operations.
|
|
15
15
|
|
|
16
16
|
## Install
|
|
@@ -119,33 +119,34 @@ you can `catch` by code; CLI failures print a JSON envelope carrying the HTTP
|
|
|
119
119
|
`status`, a one-line `remedy`, and the `runId` where known, and a wrong `--model`,
|
|
120
120
|
`--provider`, or `--runtime-size` gets a "did you mean?" suggestion.
|
|
121
121
|
|
|
122
|
-
##
|
|
122
|
+
## Continue with sessions
|
|
123
123
|
|
|
124
|
-
|
|
125
|
-
`
|
|
126
|
-
|
|
127
|
-
`search_outputs`) — every tool refuses a session outside the corpus. Drive them
|
|
128
|
-
with any LLM; `examples/chat-corpus.ts` shows the direct-Claude loop
|
|
129
|
-
(`@anthropic-ai/sdk`) on top of the LLM-vendor-free SDK.
|
|
124
|
+
Use sessions for conversational flows. `run()` is the one-shot convenience; a
|
|
125
|
+
`SessionHandle` is the lower-level surface when you want multiple turns,
|
|
126
|
+
streaming, messages, events, outputs, or downloads.
|
|
130
127
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
128
|
+
```ts
|
|
129
|
+
const session = await aex.openSession(result.runId);
|
|
130
|
+
const next = await session.send("Turn this into a checklist.").done();
|
|
131
|
+
console.log(next.text);
|
|
132
|
+
|
|
133
|
+
const messages = await session.messages().list();
|
|
134
|
+
const outputs = await aex.sessions.outputs(session.id).list();
|
|
135
|
+
```
|
|
134
136
|
|
|
135
137
|
## Feature Areas
|
|
136
138
|
|
|
137
139
|
- **Agent runtime:** managed autonomous runs with filesystem read/edit, grep/glob/head/tail, open web fetch/search, background commands, code execution, git, and subagents.
|
|
138
140
|
- **Durable infrastructure:** run records, status, wait/cancel/delete, idempotency, typed events, output capture, downloads, timeouts, and runtime sizes.
|
|
139
|
-
- **Agent composition:** skills, files, AGENTS.md, remote MCP servers,
|
|
141
|
+
- **Agent composition:** skills, files, AGENTS.md, remote MCP servers, environment variables, packages, and networking controls.
|
|
140
142
|
- **Subagents:** typed parent/child lineage for async child runs, output handoff, and bounded agent delegation.
|
|
141
143
|
- **Models and providers:** Anthropic, DeepSeek, OpenAI, Gemini, Mistral, OpenRouter, Doubao, and Doubao China behind one submission shape.
|
|
142
|
-
- **Typed control surface:** strongly typed SDK inputs, CLI parity, BYOK
|
|
144
|
+
- **Typed control surface:** strongly typed SDK inputs, CLI parity, BYOK provider keys, workspace secrets, redaction, and output modes.
|
|
143
145
|
|
|
144
146
|
## Docs
|
|
145
147
|
|
|
146
148
|
- [Quickstart](docs/quickstart.md)
|
|
147
149
|
- [Run configuration](docs/run-config.md)
|
|
148
|
-
- [Agent tools](docs/concepts/agent-tools.md)
|
|
149
150
|
- [Composition](docs/concepts/composition.md)
|
|
150
151
|
- [Secrets](docs/secrets.md)
|
|
151
152
|
- [Limits](docs/limits.md)
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
export * from "./proxy-protocol.js";
|
|
2
1
|
export * from "./provider-support.js";
|
|
3
2
|
export * from "./models.js";
|
|
4
3
|
export * from "./status.js";
|
|
5
|
-
export
|
|
4
|
+
export { AEX_RESERVED_ENV_PREFIX, BUILTIN_TOOL_NAMES, BuiltinTools, DEFAULT_BUILTIN_TOOLS, DEFAULT_OUTPUT_MODE, DEFAULT_RUN_PROVIDER, ENV_VARS_MAX_ENTRIES, ENV_VARS_MAX_TOTAL_BYTES, ENV_VARS_MAX_VALUE_BYTES, OUTPUT_MODES, PLATFORM_PACKAGE_ECOSYSTEMS, Providers, RUN_PROVIDERS, SECRETS_KEY, SECRET_ENV_NAME_PATTERN, SECRET_HANDLE_PATTERN, crossValidateSecretEnvAndValues, packageInstallString, parseInlineSecrets, parseRunLimits, parseRunProvider, parseRunSubmissionRequest, parseRunWebhook, parseSubmission, resolveBuiltinToolNames } from "./submission.js";
|
|
5
|
+
export type { BuiltinToolName, JsonPrimitive, JsonValue, OutputMode, ParseRunSubmissionOptions, PlatformEnvironment, PlatformEnvironmentInput, PlatformInlineSecrets, PlatformInjectionConfig, PlatformMcpServerSecret, PlatformNetworking, PlatformOutputCaptureConfig, PlatformPackage, PlatformPackageEcosystem, PlatformPackageInput, PlatformRunSubmissionInput, PlatformRunSubmissionRequest, PlatformSecretEnvEntry, PlatformSubmission, RunLimits, RunMachine, RunProvider, RunWebhookSpec } from "./submission.js";
|
|
6
6
|
export * from "./runtime-sizes.js";
|
|
7
7
|
export * from "./runner-event.js";
|
|
8
8
|
export * from "./event-envelope.js";
|
|
9
9
|
export * from "./connection-ticket.js";
|
|
10
10
|
export * from "./event-stream-client.js";
|
|
11
11
|
export * from "./run-unit.js";
|
|
12
|
-
export
|
|
12
|
+
export type { AssistantTextEntry, RunTrace, ToolCallResult, ToolCallTrace } from "./run-trace.js";
|
|
13
13
|
export * from "./runtime-manifest.js";
|
|
14
14
|
export * from "./runtime-security-profile.js";
|
|
15
15
|
export * from "./run-record.js";
|
|
@@ -26,7 +26,6 @@ export * from "./webhook-verify.js";
|
|
|
26
26
|
export * from "./http.js";
|
|
27
27
|
export * from "./run-artifacts.js";
|
|
28
28
|
export * as operations from "./operations.js";
|
|
29
|
-
export * from "./proxy-validation.js";
|
|
30
29
|
export * from "./sse.js";
|
|
31
30
|
export { isRunFinished, isTextMessage, isToolCallResult, isToolCallStart } from "./event-guards.js";
|
|
32
31
|
export type { RunFinishedRunEvent, TextMessageRunEvent, ToolCallResultRunEvent, ToolCallStartRunEvent } from "./event-guards.js";
|
package/dist/_contracts/index.js
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
export * from "./proxy-protocol.js";
|
|
2
1
|
export * from "./provider-support.js";
|
|
3
2
|
export * from "./models.js";
|
|
4
3
|
export * from "./status.js";
|
|
5
|
-
export
|
|
4
|
+
export { AEX_RESERVED_ENV_PREFIX, BUILTIN_TOOL_NAMES, BuiltinTools, DEFAULT_BUILTIN_TOOLS, DEFAULT_OUTPUT_MODE, DEFAULT_RUN_PROVIDER, ENV_VARS_MAX_ENTRIES, ENV_VARS_MAX_TOTAL_BYTES, ENV_VARS_MAX_VALUE_BYTES, OUTPUT_MODES, PLATFORM_PACKAGE_ECOSYSTEMS, Providers, RUN_PROVIDERS, SECRETS_KEY, SECRET_ENV_NAME_PATTERN, SECRET_HANDLE_PATTERN, crossValidateSecretEnvAndValues, packageInstallString, parseInlineSecrets, parseRunLimits, parseRunProvider, parseRunSubmissionRequest, parseRunWebhook, parseSubmission, resolveBuiltinToolNames } from "./submission.js";
|
|
6
5
|
export * from "./runtime-sizes.js";
|
|
7
6
|
export * from "./runner-event.js";
|
|
8
7
|
export * from "./event-envelope.js";
|
|
9
8
|
export * from "./connection-ticket.js";
|
|
10
9
|
export * from "./event-stream-client.js";
|
|
11
10
|
export * from "./run-unit.js";
|
|
12
|
-
export * from "./run-trace.js";
|
|
13
11
|
export * from "./runtime-manifest.js";
|
|
14
12
|
export * from "./runtime-security-profile.js";
|
|
15
13
|
export * from "./run-record.js";
|
|
@@ -26,7 +24,6 @@ export * from "./webhook-verify.js";
|
|
|
26
24
|
export * from "./http.js";
|
|
27
25
|
export * from "./run-artifacts.js";
|
|
28
26
|
export * as operations from "./operations.js";
|
|
29
|
-
export * from "./proxy-validation.js";
|
|
30
27
|
export * from "./sse.js";
|
|
31
28
|
// Explicit re-export (shadows the same-named `AexEvent` guards from
|
|
32
29
|
// `event-envelope.js`): the public `is*` guards narrow the loose `RunEvent`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { HttpClient } from "./http.js";
|
|
2
2
|
import type { RunUnit } from "./run-unit.js";
|
|
3
|
-
import type { AgentsMdRecord, FileRecord, Output, OutputLink, OutputLinkOptions, OutputFileDownload, OutputFileSelector, OutputFileType, OutputQuery, OutputText, ReadOutputTextOptions, Run, RunEvent, RunListPage, RunListQuery, Session, SessionCreateRequest, SessionEvent, SessionListPage, SessionListQuery, SessionMessageAccepted, SessionMessageRequest, SessionStateChangeAccepted, RunWebhookDelivery, SecretRecord, SecretReveal, WhoAmI } from "./runtime-types.js";
|
|
3
|
+
import type { AgentsMdRecord, FileRecord, Output, OutputLink, OutputLinkOptions, OutputFileDownload, OutputFileSelector, OutputFileType, OutputQuery, OutputText, ReadOutputTextOptions, Run, RunEvent, RunListPage, RunListQuery, Session, SessionCreateRequest, SessionEvent, SessionListPage, SessionListQuery, SessionMessageAccepted, SessionMessageRequest, SessionMessagesPage, SessionMessagesQuery, SessionStateChangeAccepted, RunWebhookDelivery, SecretRecord, SecretReveal, WhoAmI } from "./runtime-types.js";
|
|
4
4
|
import type { PlatformRunSubmissionInput } from "./submission.js";
|
|
5
5
|
/**
|
|
6
6
|
* The single source of truth for SDK<->BFF transport. The SDK class
|
|
@@ -43,6 +43,7 @@ export declare function createSession(http: HttpClient, request: SessionCreateRe
|
|
|
43
43
|
export declare function getSession(http: HttpClient, sessionId: string): Promise<Session>;
|
|
44
44
|
export declare function listSessions(http: HttpClient, query?: SessionListQuery): Promise<SessionListPage>;
|
|
45
45
|
export declare function sendSessionMessage(http: HttpClient, sessionId: string, request: SessionMessageRequest, options?: IdempotencyOptions): Promise<SessionMessageAccepted>;
|
|
46
|
+
export declare function listSessionMessages(http: HttpClient, sessionId: string, query?: SessionMessagesQuery): Promise<SessionMessagesPage>;
|
|
46
47
|
export declare function suspendSession(http: HttpClient, sessionId: string, options?: IdempotencyOptions): Promise<SessionStateChangeAccepted>;
|
|
47
48
|
export declare function cancelSession(http: HttpClient, sessionId: string, options?: IdempotencyOptions): Promise<SessionStateChangeAccepted>;
|
|
48
49
|
export declare function resumeSession(http: HttpClient, sessionId: string, options?: IdempotencyOptions): Promise<SessionStateChangeAccepted>;
|
|
@@ -87,6 +87,16 @@ export async function sendSessionMessage(http, sessionId, request, options) {
|
|
|
87
87
|
body: JSON.stringify(request)
|
|
88
88
|
});
|
|
89
89
|
}
|
|
90
|
+
export async function listSessionMessages(http, sessionId, query) {
|
|
91
|
+
const params = {};
|
|
92
|
+
if (query?.limit !== undefined)
|
|
93
|
+
params.limit = String(query.limit);
|
|
94
|
+
if (query?.cursor !== undefined)
|
|
95
|
+
params.cursor = query.cursor;
|
|
96
|
+
if (query?.since !== undefined)
|
|
97
|
+
params.since = query.since;
|
|
98
|
+
return http.request(`/api/sessions/${encodeURIComponent(sessionId)}/messages`, {}, params);
|
|
99
|
+
}
|
|
90
100
|
export async function suspendSession(http, sessionId, options) {
|
|
91
101
|
const headers = idempotencyHeaders(options);
|
|
92
102
|
return http.request(`/api/sessions/${encodeURIComponent(sessionId)}/suspend`, { method: "POST", ...(headers ? { headers } : {}) });
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
* Keep this as the public source of truth for the SDK/CLI composition
|
|
31
31
|
* boundary.
|
|
32
32
|
*/
|
|
33
|
-
import { type JsonValue, type
|
|
33
|
+
import { type JsonValue, type PlatformEnvironment } from "./submission.js";
|
|
34
34
|
import { type RunModel } from "./models.js";
|
|
35
35
|
import type { RuntimeSize } from "./runtime-sizes.js";
|
|
36
36
|
/**
|
|
@@ -305,7 +305,6 @@ export interface RunRequestConfig {
|
|
|
305
305
|
readonly runtimeSize?: RuntimeSize;
|
|
306
306
|
/** Run deadline as a duration string (`"1h"`, `"30m"`); bounded [1m, 6h] server-side. */
|
|
307
307
|
readonly timeout?: string;
|
|
308
|
-
readonly proxyEndpoints?: readonly PlatformProxyEndpoint[];
|
|
309
308
|
readonly metadata?: Readonly<Record<string, JsonValue>>;
|
|
310
309
|
}
|
|
311
310
|
/**
|
|
@@ -331,7 +330,6 @@ export interface NormalisedRunRequestConfig {
|
|
|
331
330
|
readonly prompt: readonly string[];
|
|
332
331
|
readonly mcpServers: readonly McpServerRef[];
|
|
333
332
|
readonly environment?: PlatformEnvironment;
|
|
334
|
-
readonly proxyEndpoints?: readonly PlatformProxyEndpoint[];
|
|
335
333
|
readonly metadata?: Readonly<Record<string, JsonValue>>;
|
|
336
334
|
/**
|
|
337
335
|
* MCP servers whose run-config entry carried `headers`. Keyed by the `name`
|
|
@@ -602,7 +602,6 @@ export function parseRunRequestConfig(input) {
|
|
|
602
602
|
"environment",
|
|
603
603
|
"runtimeSize",
|
|
604
604
|
"timeout",
|
|
605
|
-
"proxyEndpoints",
|
|
606
605
|
"metadata"
|
|
607
606
|
]);
|
|
608
607
|
for (const key of Object.keys(record)) {
|
|
@@ -622,8 +621,8 @@ export function parseRunRequestConfig(input) {
|
|
|
622
621
|
...(system !== undefined ? { system } : {}),
|
|
623
622
|
prompt,
|
|
624
623
|
...(mcpServers !== undefined ? { mcpServers } : {}),
|
|
625
|
-
// environment /
|
|
626
|
-
//
|
|
624
|
+
// environment / metadata: passed through as-is — the BFF revalidates
|
|
625
|
+
// them via `parseRunSubmissionRequest`,
|
|
627
626
|
// so duplicating the heavyweight parsers here would mean two sources
|
|
628
627
|
// of truth. The CLI surfaces structural errors at submission time.
|
|
629
628
|
...(record.environment !== undefined
|
|
@@ -635,9 +634,6 @@ export function parseRunRequestConfig(input) {
|
|
|
635
634
|
...(record.timeout !== undefined
|
|
636
635
|
? { timeout: record.timeout }
|
|
637
636
|
: {}),
|
|
638
|
-
...(record.proxyEndpoints !== undefined
|
|
639
|
-
? { proxyEndpoints: record.proxyEndpoints }
|
|
640
|
-
: {}),
|
|
641
637
|
...(record.metadata !== undefined
|
|
642
638
|
? { metadata: record.metadata }
|
|
643
639
|
: {})
|
|
@@ -699,7 +695,6 @@ export function normaliseRunRequestConfig(config) {
|
|
|
699
695
|
prompt,
|
|
700
696
|
mcpServers,
|
|
701
697
|
...(config.environment !== undefined ? { environment: config.environment } : {}),
|
|
702
|
-
...(config.proxyEndpoints !== undefined ? { proxyEndpoints: config.proxyEndpoints } : {}),
|
|
703
698
|
...(config.metadata !== undefined ? { metadata: config.metadata } : {}),
|
|
704
699
|
mcpServerSecrets
|
|
705
700
|
};
|
|
@@ -1,114 +1,28 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Typed decoders for a `listEvents(runId)` stream.
|
|
3
|
-
*
|
|
4
|
-
* `listEvents` returns the loose {@link RunEvent} wire shape: `type` at the top
|
|
5
|
-
* level, but the tool name at `data.name`, the call args at `data.arguments`,
|
|
6
|
-
* assistant text at `data.text`, and — the awkward part — a `TOOL_CALL_RESULT`
|
|
7
|
-
* carries no name, so a consumer must correlate each result back to its
|
|
8
|
-
* `TOOL_CALL_START` by `data.id` (the tool-call id). Every consumer ended up
|
|
9
|
-
* re-implementing that correlation; these helpers do it once, typed and pure.
|
|
10
|
-
*
|
|
11
|
-
* They are total and side-effect-free: pass the array `listEvents` returns and
|
|
12
|
-
* get back structured traces. Unknown event types are ignored (forward-compat),
|
|
13
|
-
* a result with no matching start surfaces as an orphan (never dropped silently),
|
|
14
|
-
* and timing falls back gracefully when a `recordedAt` is absent.
|
|
15
|
-
*
|
|
16
|
-
* `summarizeRunUsage` remains tolerant of historical/internal `aex.usage`
|
|
17
|
-
* CUSTOM records when a caller has them, but the normal public `listEvents`
|
|
18
|
-
* stream is not the live usage-reporting surface. Settled provider/runtime
|
|
19
|
-
* usage is exposed through the run's `costTelemetry`.
|
|
20
|
-
*/
|
|
21
1
|
import type { UsageSummary } from "./runtime-types.js";
|
|
22
|
-
/**
|
|
23
|
-
* One decoded tool call: the `TOOL_CALL_START` and its correlated
|
|
24
|
-
* `TOOL_CALL_RESULT` (when present), with timing. `result` is undefined while a
|
|
25
|
-
* call is still in flight (the start has arrived but not the result), so a
|
|
26
|
-
* mid-run decode shows in-progress calls honestly rather than dropping them.
|
|
27
|
-
*/
|
|
28
2
|
export interface ToolCallTrace {
|
|
29
|
-
/** The tool-call id (`data.id`) that pairs the start with its result. */
|
|
30
3
|
readonly id: string;
|
|
31
|
-
/** The tool name (from the `TOOL_CALL_START`). */
|
|
32
4
|
readonly name: string;
|
|
33
|
-
/** The call arguments (`data.arguments`), or `{}` when absent. */
|
|
34
5
|
readonly args: Readonly<Record<string, unknown>>;
|
|
35
|
-
/** The id of the assistant message that issued the call, when present. */
|
|
36
6
|
readonly messageId?: string;
|
|
37
|
-
/** Event sequence of the `TOOL_CALL_START` (ordering within the run). */
|
|
38
7
|
readonly startSeq?: number;
|
|
39
|
-
/** ISO-8601 time of the `TOOL_CALL_START`, when the event carried one. */
|
|
40
8
|
readonly startedAt?: string;
|
|
41
|
-
/** The correlated result; undefined while the call is still in flight. */
|
|
42
9
|
readonly result?: ToolCallResult;
|
|
43
|
-
/** Result wall-clock minus start wall-clock (ms); undefined if either time is missing. */
|
|
44
10
|
readonly durationMs?: number;
|
|
45
11
|
}
|
|
46
|
-
/** The result half of a {@link ToolCallTrace}, decoded from `TOOL_CALL_RESULT`. */
|
|
47
12
|
export interface ToolCallResult {
|
|
48
|
-
/** True when the tool reported an error (`data.isError`). */
|
|
49
13
|
readonly isError: boolean;
|
|
50
|
-
/** The tool's result content, passed through verbatim (`data.content`). */
|
|
51
14
|
readonly content: unknown;
|
|
52
|
-
/** Event sequence of the `TOOL_CALL_RESULT`. */
|
|
53
15
|
readonly seq?: number;
|
|
54
|
-
/** ISO-8601 time of the `TOOL_CALL_RESULT`, when the event carried one. */
|
|
55
16
|
readonly recordedAt?: string;
|
|
56
17
|
}
|
|
57
|
-
/** One assistant text block, decoded from a `TEXT_MESSAGE_CONTENT` event. */
|
|
58
18
|
export interface AssistantTextEntry {
|
|
59
19
|
readonly text: string;
|
|
60
20
|
readonly messageId?: string;
|
|
61
21
|
readonly seq?: number;
|
|
62
22
|
readonly recordedAt?: string;
|
|
63
23
|
}
|
|
64
|
-
/**
|
|
65
|
-
* A decoded view of a run's event stream: the correlated tool calls, the
|
|
66
|
-
* aggregate token usage, and the assistant text — everything a consumer
|
|
67
|
-
* previously hand-decoded from `listEvents`.
|
|
68
|
-
*/
|
|
69
24
|
export interface RunTrace {
|
|
70
25
|
readonly toolCalls: readonly ToolCallTrace[];
|
|
71
26
|
readonly usage: UsageSummary;
|
|
72
27
|
readonly text: readonly AssistantTextEntry[];
|
|
73
28
|
}
|
|
74
|
-
/** The loose event shape these decoders read — the {@link RunEvent} subset they touch. */
|
|
75
|
-
interface TraceEvent {
|
|
76
|
-
readonly type: string;
|
|
77
|
-
readonly seq?: number;
|
|
78
|
-
readonly recordedAt?: string;
|
|
79
|
-
readonly data?: unknown;
|
|
80
|
-
readonly [key: string]: unknown;
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Decode a `listEvents` stream into correlated tool-call traces, in start order.
|
|
84
|
-
*
|
|
85
|
-
* Each `TOOL_CALL_START` opens a trace keyed by `data.id`; the matching
|
|
86
|
-
* `TOOL_CALL_RESULT` (same `data.id`) fills in `result` + `durationMs`. A result
|
|
87
|
-
* whose id never had a start is surfaced as an orphan trace (empty `name`, no
|
|
88
|
-
* `args`) rather than dropped, so a partial/mis-ordered stream never hides a
|
|
89
|
-
* result. Pure — no I/O, input is not mutated.
|
|
90
|
-
*/
|
|
91
|
-
export declare function decodeToolCalls(events: readonly TraceEvent[]): readonly ToolCallTrace[];
|
|
92
|
-
/**
|
|
93
|
-
* Sum any `aex.usage` CUSTOM events present in the supplied stream into one
|
|
94
|
-
* {@link UsageSummary}. This is mainly for historical/internal event arrays;
|
|
95
|
-
* current public reads expose settled provider usage through cost telemetry.
|
|
96
|
-
* `totalTokens` is the sum of input + output tokens. Pure.
|
|
97
|
-
*/
|
|
98
|
-
export declare function summarizeRunUsage(events: readonly TraceEvent[]): UsageSummary;
|
|
99
|
-
/**
|
|
100
|
-
* The run's final assistant text: every `TEXT_MESSAGE_CONTENT` block in stream
|
|
101
|
-
* order, concatenated. The one-line "what did the agent say" accessor over
|
|
102
|
-
* {@link decodeAssistantText} (buffered mode yields whole messages, stream mode
|
|
103
|
-
* yields token deltas — both concatenate correctly). Pure.
|
|
104
|
-
*/
|
|
105
|
-
export declare function textOf(events: readonly TraceEvent[]): string;
|
|
106
|
-
/** Decode the assistant text blocks (`TEXT_MESSAGE_CONTENT`) in stream order. Pure. */
|
|
107
|
-
export declare function decodeAssistantText(events: readonly TraceEvent[]): readonly AssistantTextEntry[];
|
|
108
|
-
/**
|
|
109
|
-
* Decode a whole `listEvents` stream in one pass: correlated tool calls,
|
|
110
|
-
* aggregate {@link UsageSummary}, and assistant text. Convenience over the three
|
|
111
|
-
* focused decoders; pure.
|
|
112
|
-
*/
|
|
113
|
-
export declare function summarizeRunTrace(events: readonly TraceEvent[]): RunTrace;
|
|
114
|
-
export {};
|
|
@@ -1,185 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
* Typed decoders for a `listEvents(runId)` stream.
|
|
3
|
-
*
|
|
4
|
-
* `listEvents` returns the loose {@link RunEvent} wire shape: `type` at the top
|
|
5
|
-
* level, but the tool name at `data.name`, the call args at `data.arguments`,
|
|
6
|
-
* assistant text at `data.text`, and — the awkward part — a `TOOL_CALL_RESULT`
|
|
7
|
-
* carries no name, so a consumer must correlate each result back to its
|
|
8
|
-
* `TOOL_CALL_START` by `data.id` (the tool-call id). Every consumer ended up
|
|
9
|
-
* re-implementing that correlation; these helpers do it once, typed and pure.
|
|
10
|
-
*
|
|
11
|
-
* They are total and side-effect-free: pass the array `listEvents` returns and
|
|
12
|
-
* get back structured traces. Unknown event types are ignored (forward-compat),
|
|
13
|
-
* a result with no matching start surfaces as an orphan (never dropped silently),
|
|
14
|
-
* and timing falls back gracefully when a `recordedAt` is absent.
|
|
15
|
-
*
|
|
16
|
-
* `summarizeRunUsage` remains tolerant of historical/internal `aex.usage`
|
|
17
|
-
* CUSTOM records when a caller has them, but the normal public `listEvents`
|
|
18
|
-
* stream is not the live usage-reporting surface. Settled provider/runtime
|
|
19
|
-
* usage is exposed through the run's `costTelemetry`.
|
|
20
|
-
*/
|
|
21
|
-
const CUSTOM_USAGE_NAME = "aex.usage";
|
|
22
|
-
/** snake_case `aex.usage` field → the camelCase {@link UsageSummary} field. */
|
|
23
|
-
const USAGE_FIELD_MAP = {
|
|
24
|
-
input_tokens: "inputTokens",
|
|
25
|
-
output_tokens: "outputTokens",
|
|
26
|
-
cache_read_input_tokens: "cacheReadInputTokens",
|
|
27
|
-
cache_creation_input_tokens: "cacheCreationInputTokens"
|
|
28
|
-
};
|
|
29
|
-
/**
|
|
30
|
-
* Decode a `listEvents` stream into correlated tool-call traces, in start order.
|
|
31
|
-
*
|
|
32
|
-
* Each `TOOL_CALL_START` opens a trace keyed by `data.id`; the matching
|
|
33
|
-
* `TOOL_CALL_RESULT` (same `data.id`) fills in `result` + `durationMs`. A result
|
|
34
|
-
* whose id never had a start is surfaced as an orphan trace (empty `name`, no
|
|
35
|
-
* `args`) rather than dropped, so a partial/mis-ordered stream never hides a
|
|
36
|
-
* result. Pure — no I/O, input is not mutated.
|
|
37
|
-
*/
|
|
38
|
-
export function decodeToolCalls(events) {
|
|
39
|
-
const order = [];
|
|
40
|
-
const byId = new Map();
|
|
41
|
-
for (const event of events) {
|
|
42
|
-
const data = asRecord(event.data);
|
|
43
|
-
if (event.type === "TOOL_CALL_START") {
|
|
44
|
-
const id = asString(data.id);
|
|
45
|
-
if (id === undefined)
|
|
46
|
-
continue;
|
|
47
|
-
const trace = {
|
|
48
|
-
id,
|
|
49
|
-
name: asString(data.name) ?? "",
|
|
50
|
-
args: asRecord(data.arguments)
|
|
51
|
-
};
|
|
52
|
-
const messageId = asString(data.messageId);
|
|
53
|
-
if (messageId !== undefined)
|
|
54
|
-
trace.messageId = messageId;
|
|
55
|
-
if (typeof event.seq === "number")
|
|
56
|
-
trace.startSeq = event.seq;
|
|
57
|
-
if (typeof event.recordedAt === "string")
|
|
58
|
-
trace.startedAt = event.recordedAt;
|
|
59
|
-
if (!byId.has(id))
|
|
60
|
-
order.push(id);
|
|
61
|
-
byId.set(id, trace);
|
|
62
|
-
continue;
|
|
63
|
-
}
|
|
64
|
-
if (event.type === "TOOL_CALL_RESULT") {
|
|
65
|
-
const id = asString(data.id);
|
|
66
|
-
if (id === undefined)
|
|
67
|
-
continue;
|
|
68
|
-
const result = {
|
|
69
|
-
isError: data.isError === true,
|
|
70
|
-
content: data.content ?? null
|
|
71
|
-
};
|
|
72
|
-
if (typeof event.seq === "number")
|
|
73
|
-
result.seq = event.seq;
|
|
74
|
-
if (typeof event.recordedAt === "string")
|
|
75
|
-
result.recordedAt = event.recordedAt;
|
|
76
|
-
let trace = byId.get(id);
|
|
77
|
-
if (trace === undefined) {
|
|
78
|
-
// Orphan result (no matching start) — surface it, never drop it.
|
|
79
|
-
trace = { id, name: "", args: {} };
|
|
80
|
-
order.push(id);
|
|
81
|
-
byId.set(id, trace);
|
|
82
|
-
}
|
|
83
|
-
trace.result = result;
|
|
84
|
-
const duration = durationMs(trace.startedAt, result.recordedAt);
|
|
85
|
-
if (duration !== undefined)
|
|
86
|
-
trace.durationMs = duration;
|
|
87
|
-
continue;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
return order.map((id) => byId.get(id));
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Sum any `aex.usage` CUSTOM events present in the supplied stream into one
|
|
94
|
-
* {@link UsageSummary}. This is mainly for historical/internal event arrays;
|
|
95
|
-
* current public reads expose settled provider usage through cost telemetry.
|
|
96
|
-
* `totalTokens` is the sum of input + output tokens. Pure.
|
|
97
|
-
*/
|
|
98
|
-
export function summarizeRunUsage(events) {
|
|
99
|
-
const totals = { inputTokens: 0, outputTokens: 0, cacheReadInputTokens: 0, cacheCreationInputTokens: 0 };
|
|
100
|
-
let seen = false;
|
|
101
|
-
for (const event of events) {
|
|
102
|
-
if (event.type !== "CUSTOM")
|
|
103
|
-
continue;
|
|
104
|
-
const data = asRecord(event.data);
|
|
105
|
-
if (asString(data.name) !== CUSTOM_USAGE_NAME)
|
|
106
|
-
continue;
|
|
107
|
-
const value = asRecord(data.value);
|
|
108
|
-
for (const [snake, camel] of Object.entries(USAGE_FIELD_MAP)) {
|
|
109
|
-
const n = value[snake];
|
|
110
|
-
if (typeof n === "number" && Number.isFinite(n)) {
|
|
111
|
-
totals[camel] += n;
|
|
112
|
-
seen = true;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
if (!seen)
|
|
117
|
-
return {};
|
|
118
|
-
return {
|
|
119
|
-
inputTokens: totals.inputTokens,
|
|
120
|
-
outputTokens: totals.outputTokens,
|
|
121
|
-
cacheReadInputTokens: totals.cacheReadInputTokens,
|
|
122
|
-
cacheCreationInputTokens: totals.cacheCreationInputTokens,
|
|
123
|
-
totalTokens: totals.inputTokens + totals.outputTokens
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* The run's final assistant text: every `TEXT_MESSAGE_CONTENT` block in stream
|
|
128
|
-
* order, concatenated. The one-line "what did the agent say" accessor over
|
|
129
|
-
* {@link decodeAssistantText} (buffered mode yields whole messages, stream mode
|
|
130
|
-
* yields token deltas — both concatenate correctly). Pure.
|
|
131
|
-
*/
|
|
132
|
-
export function textOf(events) {
|
|
133
|
-
return decodeAssistantText(events).map((entry) => entry.text).join("");
|
|
134
|
-
}
|
|
135
|
-
/** Decode the assistant text blocks (`TEXT_MESSAGE_CONTENT`) in stream order. Pure. */
|
|
136
|
-
export function decodeAssistantText(events) {
|
|
137
|
-
const out = [];
|
|
138
|
-
for (const event of events) {
|
|
139
|
-
if (event.type !== "TEXT_MESSAGE_CONTENT")
|
|
140
|
-
continue;
|
|
141
|
-
const data = asRecord(event.data);
|
|
142
|
-
const text = asString(data.text);
|
|
143
|
-
if (text === undefined)
|
|
144
|
-
continue;
|
|
145
|
-
const entry = { text };
|
|
146
|
-
const messageId = asString(data.messageId);
|
|
147
|
-
if (messageId !== undefined)
|
|
148
|
-
entry.messageId = messageId;
|
|
149
|
-
if (typeof event.seq === "number")
|
|
150
|
-
entry.seq = event.seq;
|
|
151
|
-
if (typeof event.recordedAt === "string")
|
|
152
|
-
entry.recordedAt = event.recordedAt;
|
|
153
|
-
out.push(entry);
|
|
154
|
-
}
|
|
155
|
-
return out;
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* Decode a whole `listEvents` stream in one pass: correlated tool calls,
|
|
159
|
-
* aggregate {@link UsageSummary}, and assistant text. Convenience over the three
|
|
160
|
-
* focused decoders; pure.
|
|
161
|
-
*/
|
|
162
|
-
export function summarizeRunTrace(events) {
|
|
163
|
-
return {
|
|
164
|
-
toolCalls: decodeToolCalls(events),
|
|
165
|
-
usage: summarizeRunUsage(events),
|
|
166
|
-
text: decodeAssistantText(events)
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
function asRecord(value) {
|
|
170
|
-
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
171
|
-
}
|
|
172
|
-
function asString(value) {
|
|
173
|
-
return typeof value === "string" ? value : undefined;
|
|
174
|
-
}
|
|
175
|
-
function durationMs(start, end) {
|
|
176
|
-
if (start === undefined || end === undefined)
|
|
177
|
-
return undefined;
|
|
178
|
-
const a = Date.parse(start);
|
|
179
|
-
const b = Date.parse(end);
|
|
180
|
-
if (!Number.isFinite(a) || !Number.isFinite(b))
|
|
181
|
-
return undefined;
|
|
182
|
-
const delta = b - a;
|
|
183
|
-
return delta >= 0 ? delta : undefined;
|
|
184
|
-
}
|
|
1
|
+
export {};
|
|
185
2
|
//# sourceMappingURL=run-trace.js.map
|
|
@@ -3,8 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* One canonical struct that captures every non-secret artifact persisted
|
|
5
5
|
* for a single run: parsed submission inputs, status/lifecycle, attempts,
|
|
6
|
-
* indexed events, raw-event Storage manifest, outputs
|
|
7
|
-
* failures), and the proxy-call audit log.
|
|
6
|
+
* indexed events, raw-event Storage manifest, outputs, and capture failures.
|
|
8
7
|
*
|
|
9
8
|
* Wire contract for `GET /api/runs/:runId`, the per-run archive's
|
|
10
9
|
* `run.json`/`submission.json`/`caps.json`, and the SDK/CLI
|
|
@@ -19,7 +18,7 @@
|
|
|
19
18
|
* detail response stays bounded). The archive zip carries the bytes.
|
|
20
19
|
*/
|
|
21
20
|
import type { CleanupStatus } from "./status.js";
|
|
22
|
-
import type { JsonValue, PlatformSubmission
|
|
21
|
+
import type { JsonValue, PlatformSubmission } from "./submission.js";
|
|
23
22
|
/**
|
|
24
23
|
* Parsed view of the legacy run snapshot jsonb. Stored shape is
|
|
25
24
|
* `{kind:"submission", submission}` written by the hosted API's
|
|
@@ -97,26 +96,6 @@ export interface RunUnitOutputCaptureFailure {
|
|
|
97
96
|
readonly errorMessage?: string;
|
|
98
97
|
readonly createdAt: string;
|
|
99
98
|
}
|
|
100
|
-
export interface RunUnitProxyCall {
|
|
101
|
-
readonly id: string;
|
|
102
|
-
readonly endpointName: string;
|
|
103
|
-
readonly method: string;
|
|
104
|
-
readonly requestPathRedacted: string | null;
|
|
105
|
-
readonly requestByteSize: number;
|
|
106
|
-
readonly responseStatus: number | null;
|
|
107
|
-
readonly responseByteSize: number;
|
|
108
|
-
readonly outcome: string;
|
|
109
|
-
readonly errorClass: string | null;
|
|
110
|
-
readonly startedAt: string;
|
|
111
|
-
readonly finishedAt: string | null;
|
|
112
|
-
readonly durationMs: number | null;
|
|
113
|
-
}
|
|
114
|
-
export interface RunUnitProxyCallPage {
|
|
115
|
-
readonly entries: readonly RunUnitProxyCall[];
|
|
116
|
-
readonly totalCount: number;
|
|
117
|
-
readonly truncated: boolean;
|
|
118
|
-
readonly nextCursor?: string;
|
|
119
|
-
}
|
|
120
99
|
export interface RunUnit {
|
|
121
100
|
readonly id: string;
|
|
122
101
|
readonly workspaceId: string;
|
|
@@ -131,14 +110,12 @@ export interface RunUnit {
|
|
|
131
110
|
readonly attemptCount: number;
|
|
132
111
|
readonly submission: RunUnitSubmission;
|
|
133
112
|
readonly capsSnapshot?: Record<string, JsonValue>;
|
|
134
|
-
readonly proxyEndpointsSnapshot?: readonly PlatformProxyEndpoint[];
|
|
135
113
|
readonly attempts: readonly RunUnitAttempt[];
|
|
136
114
|
readonly events: RunUnitEventPage;
|
|
137
115
|
readonly rawEventPages: readonly RunUnitRawEventPage[];
|
|
138
116
|
readonly outputs: readonly RunUnitOutput[];
|
|
139
117
|
readonly outputCaptureFailures: readonly RunUnitOutputCaptureFailure[];
|
|
140
118
|
readonly costTelemetry?: import("./run-cost.js").RunCostTelemetry;
|
|
141
|
-
readonly proxyCalls: RunUnitProxyCallPage;
|
|
142
119
|
/**
|
|
143
120
|
* Per-run, per-provider runtime manifest — derived from the validated
|
|
144
121
|
* submission + the chosen provider (`buildRuntimeManifest`). Tells
|
|
@@ -3,8 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* One canonical struct that captures every non-secret artifact persisted
|
|
5
5
|
* for a single run: parsed submission inputs, status/lifecycle, attempts,
|
|
6
|
-
* indexed events, raw-event Storage manifest, outputs
|
|
7
|
-
* failures), and the proxy-call audit log.
|
|
6
|
+
* indexed events, raw-event Storage manifest, outputs, and capture failures.
|
|
8
7
|
*
|
|
9
8
|
* Wire contract for `GET /api/runs/:runId`, the per-run archive's
|
|
10
9
|
* `run.json`/`submission.json`/`caps.json`, and the SDK/CLI
|
|
@@ -39,7 +39,7 @@ export interface RuntimeManifest {
|
|
|
39
39
|
readonly assetsRoot: string;
|
|
40
40
|
/** Absolute path of the in-container aex runtime bridge (invoke via `bun`). */
|
|
41
41
|
readonly aexCli: string;
|
|
42
|
-
/** Absolute path of the
|
|
42
|
+
/** Absolute path of the in-container aex runtime index. */
|
|
43
43
|
readonly indexJson: string;
|
|
44
44
|
/** Absolute path of the always-mounted aex runtime contract README. */
|
|
45
45
|
readonly readme: string;
|
|
@@ -6,14 +6,12 @@ export interface RuntimeSecurityProfile {
|
|
|
6
6
|
readonly allowOpenNetworking: boolean;
|
|
7
7
|
readonly allowRuntimePackages: boolean;
|
|
8
8
|
readonly allowCustomerEnvVars: boolean;
|
|
9
|
-
readonly allowProxyEndpoints: boolean;
|
|
10
9
|
readonly allowMcpServers: boolean;
|
|
11
10
|
}
|
|
12
11
|
export interface RuntimeSecurityProfileEvaluationInput {
|
|
13
12
|
readonly networkingMode?: "limited" | "open";
|
|
14
13
|
readonly packageCount?: number;
|
|
15
14
|
readonly customerEnvVarCount?: number;
|
|
16
|
-
readonly proxyEndpointCount?: number;
|
|
17
15
|
readonly mcpServerCount?: number;
|
|
18
16
|
}
|
|
19
17
|
export interface RuntimeSecurityProfileViolation {
|
|
@@ -6,7 +6,6 @@ export const RUNTIME_SECURITY_PROFILE_CONFIG = Object.freeze({
|
|
|
6
6
|
allowOpenNetworking: false,
|
|
7
7
|
allowRuntimePackages: false,
|
|
8
8
|
allowCustomerEnvVars: true,
|
|
9
|
-
allowProxyEndpoints: true,
|
|
10
9
|
allowMcpServers: true
|
|
11
10
|
}),
|
|
12
11
|
standard: Object.freeze({
|
|
@@ -15,7 +14,6 @@ export const RUNTIME_SECURITY_PROFILE_CONFIG = Object.freeze({
|
|
|
15
14
|
allowOpenNetworking: true,
|
|
16
15
|
allowRuntimePackages: true,
|
|
17
16
|
allowCustomerEnvVars: true,
|
|
18
|
-
allowProxyEndpoints: true,
|
|
19
17
|
allowMcpServers: true
|
|
20
18
|
}),
|
|
21
19
|
developer: Object.freeze({
|
|
@@ -24,7 +22,6 @@ export const RUNTIME_SECURITY_PROFILE_CONFIG = Object.freeze({
|
|
|
24
22
|
allowOpenNetworking: true,
|
|
25
23
|
allowRuntimePackages: true,
|
|
26
24
|
allowCustomerEnvVars: true,
|
|
27
|
-
allowProxyEndpoints: true,
|
|
28
25
|
allowMcpServers: true
|
|
29
26
|
})
|
|
30
27
|
});
|
|
@@ -65,12 +62,6 @@ export function evaluateRuntimeSecurityProfile(profileName, input) {
|
|
|
65
62
|
reason: `${profile.name} does not allow customer runtime env vars`
|
|
66
63
|
});
|
|
67
64
|
}
|
|
68
|
-
if ((input.proxyEndpointCount ?? 0) > 0 && !profile.allowProxyEndpoints) {
|
|
69
|
-
violations.push({
|
|
70
|
-
field: "proxyEndpoints",
|
|
71
|
-
reason: `${profile.name} does not allow HTTP proxy endpoints`
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
65
|
if ((input.mcpServerCount ?? 0) > 0 && !profile.allowMcpServers) {
|
|
75
66
|
violations.push({
|
|
76
67
|
field: "submission.mcpServers",
|