antpath 0.2.1 → 0.3.1
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 +55 -40
- package/dist/_shared/cleanup-policy.d.ts +8 -0
- package/dist/_shared/cleanup-policy.js +24 -0
- package/dist/_shared/config.d.ts +47 -0
- package/dist/_shared/config.js +150 -0
- package/dist/_shared/dev-stack.d.ts +19 -0
- package/dist/_shared/dev-stack.js +105 -0
- package/dist/_shared/errors.d.ts +8 -0
- package/dist/_shared/errors.js +18 -0
- package/dist/_shared/http.d.ts +20 -0
- package/dist/_shared/http.js +94 -0
- package/dist/_shared/index.d.ts +17 -0
- package/dist/_shared/index.js +20 -0
- package/dist/{providers → _shared}/known-events.d.ts +10 -10
- package/dist/{providers → _shared}/known-events.js +9 -9
- package/dist/_shared/operations.d.ts +19 -0
- package/dist/_shared/operations.js +42 -0
- package/dist/_shared/proxy-protocol.d.ts +148 -0
- package/dist/_shared/proxy-protocol.js +113 -0
- package/dist/_shared/proxy-validation.d.ts +19 -0
- package/dist/_shared/proxy-validation.js +51 -0
- package/dist/_shared/runtime-types.d.ts +90 -0
- package/dist/_shared/runtime-types.js +2 -0
- package/dist/{errors.d.ts → _shared/sdk-errors.d.ts} +10 -1
- package/dist/{errors.js → _shared/sdk-errors.js} +15 -2
- package/dist/{utils/secrets.js → _shared/sdk-secrets.js} +1 -1
- package/dist/_shared/secrets.d.ts +7 -0
- package/dist/_shared/secrets.js +20 -0
- package/dist/_shared/status.d.ts +8 -0
- package/dist/_shared/status.js +46 -0
- package/dist/_shared/submission.d.ts +142 -0
- package/dist/_shared/submission.js +681 -0
- package/dist/{template → _shared/template}/compiler.js +3 -3
- package/dist/{template/index.d.ts → _shared/template/helpers.d.ts} +0 -2
- package/dist/{template/index.js → _shared/template/helpers.js} +1 -2
- package/dist/_shared/template/index.d.ts +4 -0
- package/dist/_shared/template/index.js +4 -0
- package/dist/_shared/template/mapper.d.ts +11 -0
- package/dist/_shared/template/mapper.js +70 -0
- package/dist/cli.mjs +1234 -64
- package/dist/cli.mjs.sha256 +1 -1
- package/dist/client.d.ts +93 -8
- package/dist/client.js +192 -30
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +16 -10
- package/dist/index.js +16 -7
- package/dist/index.js.map +1 -1
- package/docs/cleanup.md +7 -4
- package/docs/credentials.md +12 -12
- package/docs/events.md +19 -82
- package/docs/outputs.md +15 -4
- package/docs/quickstart.md +42 -5
- package/docs/skills.md +1 -1
- package/docs/templates.md +1 -1
- package/docs/testing.md +11 -8
- package/examples/mcp-static-bearer.ts +14 -9
- package/examples/quickstart.ts +8 -6
- package/package.json +4 -5
- package/references/implementation-plan.md +1 -1
- package/dist/credentials.d.ts +0 -3
- package/dist/credentials.js +0 -56
- package/dist/credentials.js.map +0 -1
- package/dist/errors.js.map +0 -1
- package/dist/files/downloader.d.ts +0 -3
- package/dist/files/downloader.js +0 -43
- package/dist/files/downloader.js.map +0 -1
- package/dist/platform/client.d.ts +0 -204
- package/dist/platform/client.js +0 -203
- package/dist/platform/client.js.map +0 -1
- package/dist/platform/index.d.ts +0 -1
- package/dist/platform/index.js +0 -2
- package/dist/platform/index.js.map +0 -1
- package/dist/providers/anthropic/provider.d.ts +0 -36
- package/dist/providers/anthropic/provider.js +0 -380
- package/dist/providers/anthropic/provider.js.map +0 -1
- package/dist/providers/known-events.js.map +0 -1
- package/dist/providers/types.d.ts +0 -42
- package/dist/providers/types.js.map +0 -1
- package/dist/run/controller.d.ts +0 -30
- package/dist/run/controller.js +0 -314
- package/dist/run/controller.js.map +0 -1
- package/dist/skills/packager.d.ts +0 -11
- package/dist/skills/packager.js +0 -76
- package/dist/skills/packager.js.map +0 -1
- package/dist/template/compiler.js.map +0 -1
- package/dist/template/index.js.map +0 -1
- package/dist/template/types.js +0 -2
- package/dist/template/types.js.map +0 -1
- package/dist/types.d.ts +0 -149
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
- package/dist/utils/events.d.ts +0 -27
- package/dist/utils/events.js +0 -120
- package/dist/utils/events.js.map +0 -1
- package/dist/utils/paths.d.ts +0 -3
- package/dist/utils/paths.js +0 -27
- package/dist/utils/paths.js.map +0 -1
- package/dist/utils/secrets.js.map +0 -1
- package/dist/utils/stable.js.map +0 -1
- /package/dist/{utils/secrets.d.ts → _shared/sdk-secrets.d.ts} +0 -0
- /package/dist/{utils → _shared}/stable.d.ts +0 -0
- /package/dist/{utils → _shared}/stable.js +0 -0
- /package/dist/{template → _shared/template}/compiler.d.ts +0 -0
- /package/dist/{template → _shared/template}/types.d.ts +0 -0
- /package/dist/{providers → _shared/template}/types.js +0 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export * from "./cleanup-policy.js";
|
|
2
|
+
export * from "./config.js";
|
|
3
|
+
export * from "./dev-stack.js";
|
|
4
|
+
export * from "./errors.js";
|
|
5
|
+
export * from "./proxy-protocol.js";
|
|
6
|
+
export * from "./secrets.js";
|
|
7
|
+
export * from "./status.js";
|
|
8
|
+
export * from "./submission.js";
|
|
9
|
+
export * from "./stable.js";
|
|
10
|
+
export * from "./sdk-secrets.js";
|
|
11
|
+
export * from "./sdk-errors.js";
|
|
12
|
+
export * from "./template/index.js";
|
|
13
|
+
export * from "./runtime-types.js";
|
|
14
|
+
export * from "./known-events.js";
|
|
15
|
+
export * from "./http.js";
|
|
16
|
+
export * as operations from "./operations.js";
|
|
17
|
+
export * from "./proxy-validation.js";
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export * from "./cleanup-policy.js";
|
|
2
|
+
export * from "./config.js";
|
|
3
|
+
export * from "./dev-stack.js";
|
|
4
|
+
export * from "./errors.js";
|
|
5
|
+
export * from "./proxy-protocol.js";
|
|
6
|
+
export * from "./secrets.js";
|
|
7
|
+
export * from "./status.js";
|
|
8
|
+
export * from "./submission.js";
|
|
9
|
+
// SDK + CLI shared surface — moved here so the published `antpath` SDK
|
|
10
|
+
// and the in-container `antpath` CLI consume the SAME implementation.
|
|
11
|
+
export * from "./stable.js";
|
|
12
|
+
export * from "./sdk-secrets.js";
|
|
13
|
+
export * from "./sdk-errors.js";
|
|
14
|
+
export * from "./template/index.js";
|
|
15
|
+
export * from "./runtime-types.js";
|
|
16
|
+
export * from "./known-events.js";
|
|
17
|
+
export * from "./http.js";
|
|
18
|
+
export * as operations from "./operations.js";
|
|
19
|
+
export * from "./proxy-validation.js";
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ProviderEvent } from "
|
|
1
|
+
import type { ProviderEvent } from "./runtime-types.js";
|
|
2
2
|
/**
|
|
3
3
|
* Type guards that narrow a `ProviderEvent` by the documented Claude Managed
|
|
4
4
|
* Agents event `type` strings. These do not assert anything about the event
|
|
@@ -22,33 +22,33 @@ export declare function isSpanEvent<E extends ProviderEvent>(event: E): event is
|
|
|
22
22
|
export declare function isAgentMessage<E extends ProviderEvent>(event: E): event is E & {
|
|
23
23
|
type: "agent.message";
|
|
24
24
|
};
|
|
25
|
-
export declare function isAgentThinking<E extends ProviderEvent>(event: E): event is E & {
|
|
26
|
-
type: "agent.thinking";
|
|
27
|
-
};
|
|
28
25
|
export declare function isAgentToolUse<E extends ProviderEvent>(event: E): event is E & {
|
|
29
26
|
type: "agent.tool_use";
|
|
30
27
|
};
|
|
31
28
|
export declare function isAgentToolResult<E extends ProviderEvent>(event: E): event is E & {
|
|
32
29
|
type: "agent.tool_result";
|
|
33
30
|
};
|
|
31
|
+
export declare function isAgentThinking<E extends ProviderEvent>(event: E): event is E & {
|
|
32
|
+
type: "agent.thinking";
|
|
33
|
+
};
|
|
34
|
+
export declare function isAgentCustomToolUse<E extends ProviderEvent>(event: E): event is E & {
|
|
35
|
+
type: "agent.custom_tool_use";
|
|
36
|
+
};
|
|
34
37
|
export declare function isAgentMcpToolUse<E extends ProviderEvent>(event: E): event is E & {
|
|
35
38
|
type: "agent.mcp_tool_use";
|
|
36
39
|
};
|
|
37
40
|
export declare function isAgentMcpToolResult<E extends ProviderEvent>(event: E): event is E & {
|
|
38
41
|
type: "agent.mcp_tool_result";
|
|
39
42
|
};
|
|
40
|
-
export declare function isAgentCustomToolUse<E extends ProviderEvent>(event: E): event is E & {
|
|
41
|
-
type: "agent.custom_tool_use";
|
|
42
|
-
};
|
|
43
43
|
export declare function isUserMessage<E extends ProviderEvent>(event: E): event is E & {
|
|
44
44
|
type: "user.message";
|
|
45
45
|
};
|
|
46
|
-
export declare function isSessionStatusRunning<E extends ProviderEvent>(event: E): event is E & {
|
|
47
|
-
type: "session.status_running";
|
|
48
|
-
};
|
|
49
46
|
export declare function isSessionStatusIdle<E extends ProviderEvent>(event: E): event is E & {
|
|
50
47
|
type: "session.status_idle";
|
|
51
48
|
};
|
|
49
|
+
export declare function isSessionStatusRunning<E extends ProviderEvent>(event: E): event is E & {
|
|
50
|
+
type: "session.status_running";
|
|
51
|
+
};
|
|
52
52
|
export declare function isSessionStatusRescheduled<E extends ProviderEvent>(event: E): event is E & {
|
|
53
53
|
type: "session.status_rescheduled";
|
|
54
54
|
};
|
|
@@ -23,35 +23,35 @@ export function isSpanEvent(event) {
|
|
|
23
23
|
export function isAgentMessage(event) {
|
|
24
24
|
return event.type === "agent.message";
|
|
25
25
|
}
|
|
26
|
-
export function isAgentThinking(event) {
|
|
27
|
-
return event.type === "agent.thinking";
|
|
28
|
-
}
|
|
29
26
|
export function isAgentToolUse(event) {
|
|
30
27
|
return event.type === "agent.tool_use";
|
|
31
28
|
}
|
|
32
29
|
export function isAgentToolResult(event) {
|
|
33
30
|
return event.type === "agent.tool_result";
|
|
34
31
|
}
|
|
32
|
+
export function isAgentThinking(event) {
|
|
33
|
+
return event.type === "agent.thinking";
|
|
34
|
+
}
|
|
35
|
+
export function isAgentCustomToolUse(event) {
|
|
36
|
+
return event.type === "agent.custom_tool_use";
|
|
37
|
+
}
|
|
35
38
|
export function isAgentMcpToolUse(event) {
|
|
36
39
|
return event.type === "agent.mcp_tool_use";
|
|
37
40
|
}
|
|
38
41
|
export function isAgentMcpToolResult(event) {
|
|
39
42
|
return event.type === "agent.mcp_tool_result";
|
|
40
43
|
}
|
|
41
|
-
export function isAgentCustomToolUse(event) {
|
|
42
|
-
return event.type === "agent.custom_tool_use";
|
|
43
|
-
}
|
|
44
44
|
// User events.
|
|
45
45
|
export function isUserMessage(event) {
|
|
46
46
|
return event.type === "user.message";
|
|
47
47
|
}
|
|
48
48
|
// Session events.
|
|
49
|
-
export function isSessionStatusRunning(event) {
|
|
50
|
-
return event.type === "session.status_running";
|
|
51
|
-
}
|
|
52
49
|
export function isSessionStatusIdle(event) {
|
|
53
50
|
return event.type === "session.status_idle";
|
|
54
51
|
}
|
|
52
|
+
export function isSessionStatusRunning(event) {
|
|
53
|
+
return event.type === "session.status_running";
|
|
54
|
+
}
|
|
55
55
|
export function isSessionStatusRescheduled(event) {
|
|
56
56
|
return event.type === "session.status_rescheduled";
|
|
57
57
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { HttpClient } from "./http.js";
|
|
2
|
+
import type { Output, Run, RunEvent, SignedOutputLink, WhoAmI } from "./runtime-types.js";
|
|
3
|
+
import type { PlatformRunSubmissionRequest } from "./submission.js";
|
|
4
|
+
/**
|
|
5
|
+
* The single source of truth for SDK<->BFF transport. The SDK class
|
|
6
|
+
* AND the CLI subcommands both call these functions; neither
|
|
7
|
+
* surface re-implements HTTP requests against the dashboard.
|
|
8
|
+
*
|
|
9
|
+
* Every function takes an HttpClient (so callers control auth + fetch
|
|
10
|
+
* injection) and returns parsed responses.
|
|
11
|
+
*/
|
|
12
|
+
export declare function submitRun(http: HttpClient, request: PlatformRunSubmissionRequest): Promise<Run>;
|
|
13
|
+
export declare function getRun(http: HttpClient, workspaceId: string, runId: string): Promise<Run>;
|
|
14
|
+
export declare function listRunEvents(http: HttpClient, workspaceId: string, runId: string): Promise<readonly RunEvent[]>;
|
|
15
|
+
export declare function listOutputs(http: HttpClient, workspaceId: string, runId: string): Promise<readonly Output[]>;
|
|
16
|
+
export declare function createOutputLink(http: HttpClient, workspaceId: string, runId: string, outputId: string): Promise<SignedOutputLink>;
|
|
17
|
+
export declare function cancelRun(http: HttpClient, workspaceId: string, runId: string): Promise<void>;
|
|
18
|
+
export declare function deleteRun(http: HttpClient, workspaceId: string, runId: string): Promise<void>;
|
|
19
|
+
export declare function whoami(http: HttpClient): Promise<WhoAmI>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single source of truth for SDK<->BFF transport. The SDK class
|
|
3
|
+
* AND the CLI subcommands both call these functions; neither
|
|
4
|
+
* surface re-implements HTTP requests against the dashboard.
|
|
5
|
+
*
|
|
6
|
+
* Every function takes an HttpClient (so callers control auth + fetch
|
|
7
|
+
* injection) and returns parsed responses.
|
|
8
|
+
*/
|
|
9
|
+
export async function submitRun(http, request) {
|
|
10
|
+
return http.request("/api/runs", {
|
|
11
|
+
method: "POST",
|
|
12
|
+
body: JSON.stringify(request)
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
export async function getRun(http, workspaceId, runId) {
|
|
16
|
+
const result = await http.request(`/api/runs/${encodeURIComponent(runId)}`, {}, { workspaceId });
|
|
17
|
+
return hasRun(result) ? result.run : result;
|
|
18
|
+
}
|
|
19
|
+
export async function listRunEvents(http, workspaceId, runId) {
|
|
20
|
+
const result = await http.request(`/api/runs/${encodeURIComponent(runId)}/events`, {}, { workspaceId });
|
|
21
|
+
return result.events;
|
|
22
|
+
}
|
|
23
|
+
export async function listOutputs(http, workspaceId, runId) {
|
|
24
|
+
const result = await http.request(`/api/runs/${encodeURIComponent(runId)}/outputs`, {}, { workspaceId });
|
|
25
|
+
return result.outputs;
|
|
26
|
+
}
|
|
27
|
+
export async function createOutputLink(http, workspaceId, runId, outputId) {
|
|
28
|
+
return http.request(`/api/runs/${encodeURIComponent(runId)}/outputs/${encodeURIComponent(outputId)}/link`, { method: "POST" }, { workspaceId });
|
|
29
|
+
}
|
|
30
|
+
export async function cancelRun(http, workspaceId, runId) {
|
|
31
|
+
await http.request(`/api/runs/${encodeURIComponent(runId)}/cancel`, { method: "POST" }, { workspaceId });
|
|
32
|
+
}
|
|
33
|
+
export async function deleteRun(http, workspaceId, runId) {
|
|
34
|
+
await http.request(`/api/runs/${encodeURIComponent(runId)}`, { method: "DELETE" }, { workspaceId });
|
|
35
|
+
}
|
|
36
|
+
export async function whoami(http) {
|
|
37
|
+
return http.request("/api/whoami");
|
|
38
|
+
}
|
|
39
|
+
function hasRun(value) {
|
|
40
|
+
return Boolean(value && typeof value === "object" && "run" in value);
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=operations.js.map
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire-protocol version. Bumped on any breaking change to the request or
|
|
3
|
+
* response shape. The CLI sends this in the `X-Antpath-Proxy-Protocol`
|
|
4
|
+
* header on every request; the BFF rejects mismatches with HTTP 426
|
|
5
|
+
* `unsupported_protocol`.
|
|
6
|
+
*
|
|
7
|
+
* Bumps are coordinated: CLI and BFF release together, the worker
|
|
8
|
+
* bundles the matching CLI artifact, and the e2e suite runs both with
|
|
9
|
+
* the new version. See plan.md "CLI design".
|
|
10
|
+
*/
|
|
11
|
+
export declare const PROXY_PROTOCOL_VERSION: "1";
|
|
12
|
+
export declare const PROXY_PROTOCOL_HEADER = "x-antpath-proxy-protocol";
|
|
13
|
+
export declare const PROXY_METHOD_HEADER = "x-antpath-method";
|
|
14
|
+
export declare const PROXY_PATH_HEADER = "x-antpath-path";
|
|
15
|
+
export declare const PROXY_QUERY_HEADER = "x-antpath-query";
|
|
16
|
+
export declare const PROXY_HEADERS_HEADER = "x-antpath-headers";
|
|
17
|
+
export declare const PROXY_RESPONSE_MODE_HEADER = "x-antpath-response-mode";
|
|
18
|
+
export declare const PROXY_ALLOWED_METHODS: readonly ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD"];
|
|
19
|
+
export type ProxyMethod = (typeof PROXY_ALLOWED_METHODS)[number];
|
|
20
|
+
export declare const PROXY_RESPONSE_MODES: readonly ["status_only", "headers_only", "full"];
|
|
21
|
+
export type ProxyResponseMode = (typeof PROXY_RESPONSE_MODES)[number];
|
|
22
|
+
/**
|
|
23
|
+
* Returns the narrower of the two response modes (lower width wins).
|
|
24
|
+
* Pure function so the CLI and BFF can both call it without import cycles.
|
|
25
|
+
*/
|
|
26
|
+
export declare function narrowResponseMode(policy: ProxyResponseMode, requested: ProxyResponseMode): ProxyResponseMode;
|
|
27
|
+
/**
|
|
28
|
+
* Error codes returned by the proxy route. Stable strings — the CLI
|
|
29
|
+
* matches against them in scripts. Adding a new code is non-breaking;
|
|
30
|
+
* removing or renaming an existing code requires a protocol bump.
|
|
31
|
+
*/
|
|
32
|
+
export declare const PROXY_ERROR_CODES: readonly ["unsupported_protocol", "unauthorized", "endpoint_not_found", "policy_denied", "rate_limited", "budget_exceeded", "ssrf_denied", "upstream_timeout", "upstream_error", "exceeded_cap", "bad_request", "internal_error"];
|
|
33
|
+
export type ProxyErrorCode = (typeof PROXY_ERROR_CODES)[number];
|
|
34
|
+
/**
|
|
35
|
+
* Shape of the JSON written to `/antpath/index.json` inside the container.
|
|
36
|
+
*
|
|
37
|
+
* Always present (every run), regardless of whether any proxy endpoints
|
|
38
|
+
* were declared. With zero endpoints, `endpoints` is `[]` and
|
|
39
|
+
* `proxyBaseUrl` is `null` — this keeps `antpath --help` working
|
|
40
|
+
* uniformly and makes the always-on surface observable in tests.
|
|
41
|
+
*
|
|
42
|
+
* Auth values NEVER appear in this file. The file is mounted into the
|
|
43
|
+
* container; treat it as world-readable from the agent's perspective.
|
|
44
|
+
*/
|
|
45
|
+
export interface ProxyIndexFile {
|
|
46
|
+
readonly protocolVersion: typeof PROXY_PROTOCOL_VERSION;
|
|
47
|
+
readonly runId: string;
|
|
48
|
+
readonly proxyBaseUrl: string | null;
|
|
49
|
+
readonly endpoints: readonly ProxyIndexEntry[];
|
|
50
|
+
}
|
|
51
|
+
export interface ProxyIndexEntry {
|
|
52
|
+
readonly name: string;
|
|
53
|
+
readonly baseUrl: string;
|
|
54
|
+
readonly authShape: ProxyAuthShape;
|
|
55
|
+
readonly allowMethods: readonly ProxyMethod[];
|
|
56
|
+
readonly allowPathPrefixes: readonly string[];
|
|
57
|
+
readonly allowHeaders: readonly string[];
|
|
58
|
+
readonly responseMode: ProxyResponseMode;
|
|
59
|
+
readonly maxRequestBytes: number;
|
|
60
|
+
readonly maxResponseBytes: number;
|
|
61
|
+
readonly timeoutMs: number;
|
|
62
|
+
readonly perCallBudget: number;
|
|
63
|
+
readonly responseByteBudget: number;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Structural description of how the upstream endpoint expects auth.
|
|
67
|
+
* The actual auth value lives in the run's Vault bundle under
|
|
68
|
+
* `secrets.proxyEndpointAuth[i].value` and is never reflected back
|
|
69
|
+
* into the container or index file.
|
|
70
|
+
*/
|
|
71
|
+
export type ProxyAuthShape = {
|
|
72
|
+
readonly type: "bearer";
|
|
73
|
+
} | {
|
|
74
|
+
readonly type: "basic";
|
|
75
|
+
} | {
|
|
76
|
+
readonly type: "header";
|
|
77
|
+
readonly name: string;
|
|
78
|
+
} | {
|
|
79
|
+
readonly type: "query";
|
|
80
|
+
readonly name: string;
|
|
81
|
+
};
|
|
82
|
+
export type ProxyAuthType = ProxyAuthShape["type"];
|
|
83
|
+
/**
|
|
84
|
+
* Header name (lowercase) that an upstream auth shape uses as its
|
|
85
|
+
* carrier. Returns `undefined` for query-based auth.
|
|
86
|
+
*
|
|
87
|
+
* Used by the submission parser to forbid `allowHeaders` from listing
|
|
88
|
+
* the auth header (avoids leaks via caller-supplied headers), and by
|
|
89
|
+
* the proxy route to strip any caller header that would collide with
|
|
90
|
+
* the auth carrier at request time.
|
|
91
|
+
*/
|
|
92
|
+
export declare function authShapeHeaderName(shape: ProxyAuthShape): string | undefined;
|
|
93
|
+
/**
|
|
94
|
+
* Query-string key that an upstream query-based auth shape uses as its
|
|
95
|
+
* carrier. Returns `undefined` for non-query shapes.
|
|
96
|
+
*/
|
|
97
|
+
export declare function authShapeQueryName(shape: ProxyAuthShape): string | undefined;
|
|
98
|
+
/**
|
|
99
|
+
* JSON body returned on a successful proxy call. The actual HTTP
|
|
100
|
+
* response from the BFF to the CLI is always 200 once the BFF accepts
|
|
101
|
+
* the request; the upstream's status/headers/body are reflected inside
|
|
102
|
+
* this envelope so the CLI can decide what to write to stdout/stderr.
|
|
103
|
+
*/
|
|
104
|
+
export interface ProxyResponseEnvelope {
|
|
105
|
+
readonly endpointName: string;
|
|
106
|
+
readonly upstreamStatus: number;
|
|
107
|
+
/** Lowercase header names → values. Allowlist-filtered by the BFF. */
|
|
108
|
+
readonly upstreamHeaders: Readonly<Record<string, string>>;
|
|
109
|
+
/**
|
|
110
|
+
* Base64-encoded upstream body. Present only when the effective
|
|
111
|
+
* response mode is `full`. Truncated to `maxResponseBytes`; if the
|
|
112
|
+
* upstream exceeded the cap, `truncated` is `true`.
|
|
113
|
+
*/
|
|
114
|
+
readonly upstreamBodyBase64?: string;
|
|
115
|
+
readonly truncated?: boolean;
|
|
116
|
+
/**
|
|
117
|
+
* Echoed back so the CLI can warn the agent when its requested mode
|
|
118
|
+
* was clamped against the policy ceiling.
|
|
119
|
+
*/
|
|
120
|
+
readonly effectiveResponseMode: ProxyResponseMode;
|
|
121
|
+
readonly modeClamped: boolean;
|
|
122
|
+
/** Remaining per-endpoint per-run budget after this call. */
|
|
123
|
+
readonly remainingCalls: number;
|
|
124
|
+
readonly remainingResponseBytes: number;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* JSON body returned on any error. The CLI emits this verbatim on
|
|
128
|
+
* stderr and exits non-zero. Audit row carries the same `code`.
|
|
129
|
+
*/
|
|
130
|
+
export interface ProxyErrorBody {
|
|
131
|
+
readonly error: ProxyErrorCode;
|
|
132
|
+
/** Human-readable message. Never includes auth values. */
|
|
133
|
+
readonly message: string;
|
|
134
|
+
/**
|
|
135
|
+
* Optional diagnostic fields. Always safe to surface — auth values
|
|
136
|
+
* and full URLs are stripped at the BFF.
|
|
137
|
+
*/
|
|
138
|
+
readonly endpointName?: string;
|
|
139
|
+
readonly upstreamStatus?: number;
|
|
140
|
+
/** Server-supplied protocol version on `unsupported_protocol`. */
|
|
141
|
+
readonly serverProtocolVersion?: string;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Status code → error code mapping used by the BFF to ensure the audit
|
|
145
|
+
* row's error code and the HTTP response line up. Kept here so callers
|
|
146
|
+
* can do a sanity check in tests.
|
|
147
|
+
*/
|
|
148
|
+
export declare const PROXY_ERROR_HTTP_STATUS: Record<ProxyErrorCode, number>;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// Wire format between the in-container CLI (`/antpath/antpath`) and the
|
|
2
|
+
// dashboard BFF proxy route (`POST /api/runs/:runId/proxy/:endpointName`).
|
|
3
|
+
//
|
|
4
|
+
// This module is the single source of truth for the request shape, the
|
|
5
|
+
// response shape, the error-code enum, and the protocol version header.
|
|
6
|
+
// CLI and BFF both import from here; drift becomes a build-time type error.
|
|
7
|
+
//
|
|
8
|
+
// References:
|
|
9
|
+
// - plan.md sections "Proxy route" and "CLI design"
|
|
10
|
+
// - references/development-principles.md (Agent-first surface design)
|
|
11
|
+
/**
|
|
12
|
+
* Wire-protocol version. Bumped on any breaking change to the request or
|
|
13
|
+
* response shape. The CLI sends this in the `X-Antpath-Proxy-Protocol`
|
|
14
|
+
* header on every request; the BFF rejects mismatches with HTTP 426
|
|
15
|
+
* `unsupported_protocol`.
|
|
16
|
+
*
|
|
17
|
+
* Bumps are coordinated: CLI and BFF release together, the worker
|
|
18
|
+
* bundles the matching CLI artifact, and the e2e suite runs both with
|
|
19
|
+
* the new version. See plan.md "CLI design".
|
|
20
|
+
*/
|
|
21
|
+
export const PROXY_PROTOCOL_VERSION = "1";
|
|
22
|
+
export const PROXY_PROTOCOL_HEADER = "x-antpath-proxy-protocol";
|
|
23
|
+
export const PROXY_METHOD_HEADER = "x-antpath-method";
|
|
24
|
+
export const PROXY_PATH_HEADER = "x-antpath-path";
|
|
25
|
+
export const PROXY_QUERY_HEADER = "x-antpath-query";
|
|
26
|
+
export const PROXY_HEADERS_HEADER = "x-antpath-headers";
|
|
27
|
+
export const PROXY_RESPONSE_MODE_HEADER = "x-antpath-response-mode";
|
|
28
|
+
export const PROXY_ALLOWED_METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD"];
|
|
29
|
+
export const PROXY_RESPONSE_MODES = ["status_only", "headers_only", "full"];
|
|
30
|
+
/**
|
|
31
|
+
* Narrowing order: a request may only narrow below the policy ceiling.
|
|
32
|
+
* `status_only` is narrowest, `full` is widest. The BFF computes
|
|
33
|
+
* `narrowest(policyMode, headerMode)` and ignores escalation attempts,
|
|
34
|
+
* auditing them as `mode_clamped`.
|
|
35
|
+
*/
|
|
36
|
+
const RESPONSE_MODE_WIDTH = {
|
|
37
|
+
status_only: 0,
|
|
38
|
+
headers_only: 1,
|
|
39
|
+
full: 2
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Returns the narrower of the two response modes (lower width wins).
|
|
43
|
+
* Pure function so the CLI and BFF can both call it without import cycles.
|
|
44
|
+
*/
|
|
45
|
+
export function narrowResponseMode(policy, requested) {
|
|
46
|
+
return RESPONSE_MODE_WIDTH[requested] < RESPONSE_MODE_WIDTH[policy] ? requested : policy;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Error codes returned by the proxy route. Stable strings — the CLI
|
|
50
|
+
* matches against them in scripts. Adding a new code is non-breaking;
|
|
51
|
+
* removing or renaming an existing code requires a protocol bump.
|
|
52
|
+
*/
|
|
53
|
+
export const PROXY_ERROR_CODES = [
|
|
54
|
+
"unsupported_protocol",
|
|
55
|
+
"unauthorized",
|
|
56
|
+
"endpoint_not_found",
|
|
57
|
+
"policy_denied",
|
|
58
|
+
"rate_limited",
|
|
59
|
+
"budget_exceeded",
|
|
60
|
+
"ssrf_denied",
|
|
61
|
+
"upstream_timeout",
|
|
62
|
+
"upstream_error",
|
|
63
|
+
"exceeded_cap",
|
|
64
|
+
"bad_request",
|
|
65
|
+
"internal_error"
|
|
66
|
+
];
|
|
67
|
+
/**
|
|
68
|
+
* Header name (lowercase) that an upstream auth shape uses as its
|
|
69
|
+
* carrier. Returns `undefined` for query-based auth.
|
|
70
|
+
*
|
|
71
|
+
* Used by the submission parser to forbid `allowHeaders` from listing
|
|
72
|
+
* the auth header (avoids leaks via caller-supplied headers), and by
|
|
73
|
+
* the proxy route to strip any caller header that would collide with
|
|
74
|
+
* the auth carrier at request time.
|
|
75
|
+
*/
|
|
76
|
+
export function authShapeHeaderName(shape) {
|
|
77
|
+
switch (shape.type) {
|
|
78
|
+
case "bearer":
|
|
79
|
+
case "basic":
|
|
80
|
+
return "authorization";
|
|
81
|
+
case "header":
|
|
82
|
+
return shape.name.toLowerCase();
|
|
83
|
+
case "query":
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Query-string key that an upstream query-based auth shape uses as its
|
|
89
|
+
* carrier. Returns `undefined` for non-query shapes.
|
|
90
|
+
*/
|
|
91
|
+
export function authShapeQueryName(shape) {
|
|
92
|
+
return shape.type === "query" ? shape.name : undefined;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Status code → error code mapping used by the BFF to ensure the audit
|
|
96
|
+
* row's error code and the HTTP response line up. Kept here so callers
|
|
97
|
+
* can do a sanity check in tests.
|
|
98
|
+
*/
|
|
99
|
+
export const PROXY_ERROR_HTTP_STATUS = {
|
|
100
|
+
unsupported_protocol: 426,
|
|
101
|
+
unauthorized: 401,
|
|
102
|
+
endpoint_not_found: 404,
|
|
103
|
+
policy_denied: 403,
|
|
104
|
+
rate_limited: 429,
|
|
105
|
+
budget_exceeded: 429,
|
|
106
|
+
ssrf_denied: 403,
|
|
107
|
+
upstream_timeout: 504,
|
|
108
|
+
upstream_error: 502,
|
|
109
|
+
exceeded_cap: 502,
|
|
110
|
+
bad_request: 400,
|
|
111
|
+
internal_error: 500
|
|
112
|
+
};
|
|
113
|
+
//# sourceMappingURL=proxy-protocol.js.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { PlatformProxyEndpoint, PlatformProxyEndpointAuth } from "./submission.js";
|
|
2
|
+
/**
|
|
3
|
+
* Cross-validate a `proxyEndpoints` policy list against a
|
|
4
|
+
* `secrets.proxyEndpointAuth` value list. Throws on the first mismatch
|
|
5
|
+
* with an actionable, field-named error message.
|
|
6
|
+
*
|
|
7
|
+
* Mirrors the BFF's authoritative validator so misconfigured submissions
|
|
8
|
+
* fail fast in the SDK/CLI before going over the wire.
|
|
9
|
+
*/
|
|
10
|
+
export declare function validateProxyAuth(endpoints: readonly PlatformProxyEndpoint[], auth: readonly PlatformProxyEndpointAuth[] | undefined): void;
|
|
11
|
+
/**
|
|
12
|
+
* Build an `allowedHosts` list for `environment.network` that includes
|
|
13
|
+
* the antpath proxy host (and optionally Anthropic's MCP host) when the
|
|
14
|
+
* caller is hand-rolling networking.
|
|
15
|
+
*/
|
|
16
|
+
export declare function buildPlatformAllowedHosts(input: {
|
|
17
|
+
readonly dashboardBaseUrl: string;
|
|
18
|
+
readonly extraHosts?: readonly string[];
|
|
19
|
+
}): readonly string[];
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-validate a `proxyEndpoints` policy list against a
|
|
3
|
+
* `secrets.proxyEndpointAuth` value list. Throws on the first mismatch
|
|
4
|
+
* with an actionable, field-named error message.
|
|
5
|
+
*
|
|
6
|
+
* Mirrors the BFF's authoritative validator so misconfigured submissions
|
|
7
|
+
* fail fast in the SDK/CLI before going over the wire.
|
|
8
|
+
*/
|
|
9
|
+
export function validateProxyAuth(endpoints, auth) {
|
|
10
|
+
const authList = auth ?? [];
|
|
11
|
+
const endpointNames = new Set(endpoints.map((e) => e.name));
|
|
12
|
+
const authNames = new Set();
|
|
13
|
+
for (const entry of authList) {
|
|
14
|
+
if (authNames.has(entry.name)) {
|
|
15
|
+
throw new Error(`secrets.proxyEndpointAuth contains duplicate name '${entry.name}'`);
|
|
16
|
+
}
|
|
17
|
+
authNames.add(entry.name);
|
|
18
|
+
if (!endpointNames.has(entry.name)) {
|
|
19
|
+
throw new Error(`secrets.proxyEndpointAuth[].name='${entry.name}' has no matching proxyEndpoints[].name`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
for (const endpoint of endpoints) {
|
|
23
|
+
const match = authList.find((a) => a.name === endpoint.name);
|
|
24
|
+
if (!match) {
|
|
25
|
+
throw new Error(`proxyEndpoints[].name='${endpoint.name}' is missing a matching secrets.proxyEndpointAuth entry`);
|
|
26
|
+
}
|
|
27
|
+
if (match.value.type !== endpoint.authShape.type) {
|
|
28
|
+
throw new Error(`secrets.proxyEndpointAuth[name='${endpoint.name}'].value.type='${match.value.type}' does not match proxyEndpoints[name='${endpoint.name}'].authShape.type='${endpoint.authShape.type}'`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Build an `allowedHosts` list for `environment.network` that includes
|
|
34
|
+
* the antpath proxy host (and optionally Anthropic's MCP host) when the
|
|
35
|
+
* caller is hand-rolling networking.
|
|
36
|
+
*/
|
|
37
|
+
export function buildPlatformAllowedHosts(input) {
|
|
38
|
+
const result = [];
|
|
39
|
+
try {
|
|
40
|
+
result.push(new URL(input.dashboardBaseUrl).host);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
throw new Error("buildPlatformAllowedHosts: dashboardBaseUrl must be an absolute URL");
|
|
44
|
+
}
|
|
45
|
+
for (const host of input.extraHosts ?? []) {
|
|
46
|
+
if (!result.includes(host))
|
|
47
|
+
result.push(host);
|
|
48
|
+
}
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=proxy-validation.js.map
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { JsonValue, PlatformInlineSecrets, PlatformProxyEndpoint } from "./submission.js";
|
|
2
|
+
/**
|
|
3
|
+
* Loose record describing a run as the dashboard BFF returns it. Concrete
|
|
4
|
+
* dashboard-managed fields appear in the index signature; the SDK and CLI
|
|
5
|
+
* may surface them without strong typing per-field.
|
|
6
|
+
*/
|
|
7
|
+
export interface Run {
|
|
8
|
+
readonly id: string;
|
|
9
|
+
readonly status: string;
|
|
10
|
+
readonly workspaceId?: string;
|
|
11
|
+
readonly templateName?: string;
|
|
12
|
+
readonly templateHash?: string;
|
|
13
|
+
readonly createdAt?: string;
|
|
14
|
+
readonly updatedAt?: string;
|
|
15
|
+
readonly terminalAt?: string | null;
|
|
16
|
+
readonly errorMessage?: string | null;
|
|
17
|
+
readonly usage?: UsageSummary;
|
|
18
|
+
readonly [key: string]: unknown;
|
|
19
|
+
}
|
|
20
|
+
export interface UsageSummary {
|
|
21
|
+
readonly inputTokens?: number;
|
|
22
|
+
readonly outputTokens?: number;
|
|
23
|
+
readonly cacheReadInputTokens?: number;
|
|
24
|
+
readonly cacheCreationInputTokens?: number;
|
|
25
|
+
readonly totalTokens?: number;
|
|
26
|
+
readonly estimatedCostUsd?: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* A run event as recorded by the dashboard. Includes the `type` field
|
|
30
|
+
* that the `is*Event` type guards narrow on plus any provider payload.
|
|
31
|
+
*/
|
|
32
|
+
export interface RunEvent {
|
|
33
|
+
readonly id: string;
|
|
34
|
+
readonly type: string;
|
|
35
|
+
readonly runId?: string;
|
|
36
|
+
readonly recordedAt?: string;
|
|
37
|
+
readonly [key: string]: unknown;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Provider-emitted event payload, kept structurally identical to the
|
|
41
|
+
* upstream Claude Managed Agents event so type guards work uniformly
|
|
42
|
+
* whether the event came from the worker (live) or the dashboard
|
|
43
|
+
* (replayed).
|
|
44
|
+
*/
|
|
45
|
+
export interface ProviderEvent {
|
|
46
|
+
readonly type: string;
|
|
47
|
+
readonly id?: string | undefined;
|
|
48
|
+
readonly created_at?: string | undefined;
|
|
49
|
+
readonly [key: string]: unknown;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* One captured output file as the dashboard reports it. Use
|
|
53
|
+
* `createOutputLink` to get a short-lived signed URL for download.
|
|
54
|
+
*/
|
|
55
|
+
export interface Output {
|
|
56
|
+
readonly id: string;
|
|
57
|
+
readonly filename?: string;
|
|
58
|
+
readonly sizeBytes?: number;
|
|
59
|
+
readonly contentType?: string;
|
|
60
|
+
readonly createdAt?: string;
|
|
61
|
+
readonly [key: string]: unknown;
|
|
62
|
+
}
|
|
63
|
+
export interface SignedOutputLink {
|
|
64
|
+
readonly url: string;
|
|
65
|
+
readonly expiresAt?: string;
|
|
66
|
+
readonly [key: string]: unknown;
|
|
67
|
+
}
|
|
68
|
+
export interface WhoAmI {
|
|
69
|
+
readonly principalType: "api_token" | "user";
|
|
70
|
+
readonly workspaceId?: string;
|
|
71
|
+
readonly tokenId?: string;
|
|
72
|
+
readonly tokenName?: string | null;
|
|
73
|
+
readonly scopes?: readonly string[];
|
|
74
|
+
readonly [key: string]: unknown;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Full submission as the SDK and CLI assemble it before posting. The
|
|
78
|
+
* `template` is the SDK-level ResolvedTemplate (or a JSON-encoded one);
|
|
79
|
+
* the SDK/CLI converts to PlatformTemplateSubmission via the mapper.
|
|
80
|
+
*/
|
|
81
|
+
export interface RunSubmissionInput {
|
|
82
|
+
readonly workspaceId: string;
|
|
83
|
+
readonly idempotencyKey?: string;
|
|
84
|
+
readonly variables?: Record<string, JsonValue>;
|
|
85
|
+
readonly secrets: PlatformInlineSecrets;
|
|
86
|
+
readonly proxyEndpoints?: readonly PlatformProxyEndpoint[];
|
|
87
|
+
readonly cleanup?: {
|
|
88
|
+
readonly session?: "retain" | "delete";
|
|
89
|
+
};
|
|
90
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type AntpathErrorCode = "TEMPLATE_INVALID" | "CREDENTIAL_INVALID" | "PROVIDER_ERROR" | "RUN_STATE_ERROR" | "CLEANUP_ERROR";
|
|
1
|
+
export type AntpathErrorCode = "TEMPLATE_INVALID" | "CREDENTIAL_INVALID" | "PROVIDER_ERROR" | "RUN_STATE_ERROR" | "CLEANUP_ERROR" | "API_ERROR";
|
|
2
2
|
export declare class AntpathError extends Error {
|
|
3
3
|
readonly code: AntpathErrorCode;
|
|
4
4
|
readonly details?: unknown;
|
|
@@ -23,3 +23,12 @@ export declare class RunStateError extends AntpathError {
|
|
|
23
23
|
export declare class CleanupError extends AntpathError {
|
|
24
24
|
constructor(message: string, details?: unknown);
|
|
25
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* Thrown by SDK and CLI operations when the dashboard BFF returns a non-2xx
|
|
28
|
+
* response. Carries the HTTP status and parsed body for the caller to inspect.
|
|
29
|
+
*/
|
|
30
|
+
export declare class AntpathApiError extends AntpathError {
|
|
31
|
+
readonly status: number;
|
|
32
|
+
readonly body: unknown;
|
|
33
|
+
constructor(status: number, message: string, body: unknown);
|
|
34
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { redactSecrets } from "./
|
|
1
|
+
import { redactSecrets } from "./sdk-secrets.js";
|
|
2
2
|
export class AntpathError extends Error {
|
|
3
3
|
code;
|
|
4
4
|
details;
|
|
@@ -36,4 +36,17 @@ export class CleanupError extends AntpathError {
|
|
|
36
36
|
super("CLEANUP_ERROR", message, details);
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
|
-
|
|
39
|
+
/**
|
|
40
|
+
* Thrown by SDK and CLI operations when the dashboard BFF returns a non-2xx
|
|
41
|
+
* response. Carries the HTTP status and parsed body for the caller to inspect.
|
|
42
|
+
*/
|
|
43
|
+
export class AntpathApiError extends AntpathError {
|
|
44
|
+
status;
|
|
45
|
+
body;
|
|
46
|
+
constructor(status, message, body) {
|
|
47
|
+
super("API_ERROR", message, body);
|
|
48
|
+
this.status = status;
|
|
49
|
+
this.body = redactSecrets(body);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=sdk-errors.js.map
|