antpath 0.1.0 → 0.1.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 +66 -67
- package/dist/credentials.js +34 -5
- package/dist/credentials.js.map +1 -1
- package/dist/files/downloader.js +8 -0
- package/dist/files/downloader.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/platform/client.d.ts +73 -0
- package/dist/platform/client.js +107 -0
- package/dist/platform/client.js.map +1 -0
- package/dist/platform/index.d.ts +1 -0
- package/dist/platform/index.js +2 -0
- package/dist/platform/index.js.map +1 -0
- package/dist/providers/anthropic/provider.d.ts +6 -0
- package/dist/providers/anthropic/provider.js +90 -12
- package/dist/providers/anthropic/provider.js.map +1 -1
- package/dist/utils/paths.js +9 -3
- package/dist/utils/paths.js.map +1 -1
- package/docs/cleanup.md +15 -15
- package/docs/credentials.md +23 -23
- package/docs/mcp.md +18 -18
- package/docs/outputs.md +16 -16
- package/docs/quickstart.md +13 -13
- package/docs/release.md +22 -22
- package/docs/skills.md +16 -16
- package/docs/templates.md +24 -24
- package/docs/testing.md +26 -27
- package/examples/mcp-static-bearer.ts +30 -30
- package/examples/quickstart.ts +23 -23
- package/package.json +46 -51
- package/references/architecture-decisions.md +427 -203
- package/references/implementation-plan.md +430 -527
- package/references/research-sources.md +41 -30
- package/references/testing-strategy.md +29 -108
package/README.md
CHANGED
|
@@ -1,67 +1,66 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: antpath
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# antpath
|
|
6
|
-
|
|
7
|
-
antpath is a TypeScript-first SDK for running autonomous Claude Managed Agents sessions from code-defined, secret-free Templates.
|
|
8
|
-
|
|
9
|
-
## MVP boundaries
|
|
10
|
-
|
|
11
|
-
- SDK-only.
|
|
12
|
-
- Claude Managed Agents only.
|
|
13
|
-
- Caller-held provider key.
|
|
14
|
-
- No stored provider keys, MCP credentials, or output file contents.
|
|
15
|
-
- Manual cleanup by default.
|
|
16
|
-
|
|
17
|
-
## Quickstart
|
|
18
|
-
|
|
19
|
-
```ts
|
|
20
|
-
import { AntpathClient, defineTemplate, string } from "antpath";
|
|
21
|
-
|
|
22
|
-
const client = new AntpathClient({
|
|
23
|
-
anthropicApiKey: process.env.ANTHROPIC_API_KEY
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
const template = defineTemplate({
|
|
27
|
-
name: "hello",
|
|
28
|
-
model: "claude-haiku-4-5",
|
|
29
|
-
system: "You are a concise automation agent.",
|
|
30
|
-
messages: ["Write a short answer about {{topic}}."],
|
|
31
|
-
variables: {
|
|
32
|
-
topic: string()
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
const handle = await client.run(template, {
|
|
37
|
-
variables: { topic: "test-first SDK design" }
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
const result = await handle.wait();
|
|
41
|
-
console.log(result.status, await handle.usage());
|
|
42
|
-
await handle.downloadOutputs("./outputs");
|
|
43
|
-
await handle.cleanup();
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
## Test commands
|
|
47
|
-
|
|
48
|
-
```text
|
|
49
|
-
npm run test:unit
|
|
50
|
-
npm run test:
|
|
51
|
-
npm run test:
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
- [
|
|
60
|
-
- [
|
|
61
|
-
- [
|
|
62
|
-
- [
|
|
63
|
-
- [
|
|
64
|
-
- [
|
|
65
|
-
- [
|
|
66
|
-
- [
|
|
67
|
-
- [Release](docs/release.md)
|
|
1
|
+
---
|
|
2
|
+
title: antpath
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# antpath
|
|
6
|
+
|
|
7
|
+
antpath is a TypeScript-first SDK for running autonomous Claude Managed Agents sessions from code-defined, secret-free Templates.
|
|
8
|
+
|
|
9
|
+
## MVP boundaries
|
|
10
|
+
|
|
11
|
+
- SDK-only.
|
|
12
|
+
- Claude Managed Agents only.
|
|
13
|
+
- Caller-held provider key.
|
|
14
|
+
- No stored provider keys, MCP credentials, or output file contents.
|
|
15
|
+
- Manual cleanup by default.
|
|
16
|
+
|
|
17
|
+
## Quickstart
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { AntpathClient, defineTemplate, string } from "antpath";
|
|
21
|
+
|
|
22
|
+
const client = new AntpathClient({
|
|
23
|
+
anthropicApiKey: process.env.ANTHROPIC_API_KEY
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const template = defineTemplate({
|
|
27
|
+
name: "hello",
|
|
28
|
+
model: "claude-haiku-4-5",
|
|
29
|
+
system: "You are a concise automation agent.",
|
|
30
|
+
messages: ["Write a short answer about {{topic}}."],
|
|
31
|
+
variables: {
|
|
32
|
+
topic: string()
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const handle = await client.run(template, {
|
|
37
|
+
variables: { topic: "test-first SDK design" }
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const result = await handle.wait();
|
|
41
|
+
console.log(result.status, await handle.usage());
|
|
42
|
+
await handle.downloadOutputs("./outputs");
|
|
43
|
+
await handle.cleanup();
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Test commands
|
|
47
|
+
|
|
48
|
+
```text
|
|
49
|
+
npm run test:unit
|
|
50
|
+
npm run test:unit:recorded
|
|
51
|
+
npm run test:e2e:live
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Unit tests are deterministic and may use fakes or sanitized recorded snapshots. Live e2e tests run when `pnpm test:e2e:live` is invoked with `.env.local` containing `ANTHROPIC_API_KEY`.
|
|
55
|
+
|
|
56
|
+
## Guides
|
|
57
|
+
|
|
58
|
+
- [Quickstart](docs/quickstart.md)
|
|
59
|
+
- [Templates](docs/templates.md)
|
|
60
|
+
- [Credentials](docs/credentials.md)
|
|
61
|
+
- [MCP](docs/mcp.md)
|
|
62
|
+
- [Skills](docs/skills.md)
|
|
63
|
+
- [Outputs](docs/outputs.md)
|
|
64
|
+
- [Cleanup](docs/cleanup.md)
|
|
65
|
+
- [Testing](docs/testing.md)
|
|
66
|
+
- [Release](docs/release.md)
|
package/dist/credentials.js
CHANGED
|
@@ -2,9 +2,12 @@ import { CredentialValidationError } from "./errors.js";
|
|
|
2
2
|
export function validateCredentials(template, credentials = {}) {
|
|
3
3
|
for (const [key, requirement] of Object.entries(template.credentialRequirements)) {
|
|
4
4
|
const credential = credentials[key];
|
|
5
|
-
if (
|
|
5
|
+
if (credential === undefined) {
|
|
6
6
|
throw new CredentialValidationError(`Missing credential for MCP server '${key}'`);
|
|
7
7
|
}
|
|
8
|
+
if (!isRecord(credential)) {
|
|
9
|
+
throw new CredentialValidationError(`Credential for MCP server '${key}' must be an object`);
|
|
10
|
+
}
|
|
8
11
|
if (credential.type !== requirement.type) {
|
|
9
12
|
throw new CredentialValidationError(`Credential for MCP server '${key}' must be '${requirement.type}'`);
|
|
10
13
|
}
|
|
@@ -17,11 +20,37 @@ export function validateCredentials(template, credentials = {}) {
|
|
|
17
20
|
}
|
|
18
21
|
}
|
|
19
22
|
function validateCredentialValue(key, credential) {
|
|
20
|
-
if (
|
|
21
|
-
throw new CredentialValidationError(`
|
|
23
|
+
if (!isRecord(credential)) {
|
|
24
|
+
throw new CredentialValidationError(`Credential for MCP server '${key}' must be an object`);
|
|
25
|
+
}
|
|
26
|
+
if (credential.type === "static_bearer") {
|
|
27
|
+
assertAllowedFields(key, credential, ["type", "token"]);
|
|
28
|
+
if (typeof credential.token !== "string" || credential.token.length === 0) {
|
|
29
|
+
throw new CredentialValidationError(`Static bearer credential for '${key}' requires token`);
|
|
30
|
+
}
|
|
31
|
+
return;
|
|
22
32
|
}
|
|
23
|
-
if (credential.type === "oauth_access_token"
|
|
24
|
-
|
|
33
|
+
if (credential.type === "oauth_access_token") {
|
|
34
|
+
assertAllowedFields(key, credential, ["type", "accessToken", "expiresAt"]);
|
|
35
|
+
if (typeof credential.accessToken !== "string" || credential.accessToken.length === 0) {
|
|
36
|
+
throw new CredentialValidationError(`OAuth credential for '${key}' requires accessToken`);
|
|
37
|
+
}
|
|
38
|
+
if (credential.expiresAt !== undefined && (typeof credential.expiresAt !== "string" || credential.expiresAt.length === 0)) {
|
|
39
|
+
throw new CredentialValidationError(`OAuth credential for '${key}' has invalid expiresAt`);
|
|
40
|
+
}
|
|
41
|
+
return;
|
|
25
42
|
}
|
|
43
|
+
throw new CredentialValidationError(`Credential for MCP server '${key}' has unsupported type`);
|
|
44
|
+
}
|
|
45
|
+
function assertAllowedFields(key, credential, allowed) {
|
|
46
|
+
const allowedSet = new Set(allowed);
|
|
47
|
+
for (const field of Object.keys(credential)) {
|
|
48
|
+
if (!allowedSet.has(field)) {
|
|
49
|
+
throw new CredentialValidationError(`Credential for MCP server '${key}' contains unsupported field '${field}'`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function isRecord(input) {
|
|
54
|
+
return typeof input === "object" && input !== null && !Array.isArray(input);
|
|
26
55
|
}
|
|
27
56
|
//# sourceMappingURL=credentials.js.map
|
package/dist/credentials.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAIxD,MAAM,UAAU,mBAAmB,CAAC,QAA0B,EAAE,cAA+C,EAAE;IAC/G,KAAK,MAAM,CAAC,GAAG,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,CAAC;QACjF,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,
|
|
1
|
+
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"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"}
|
package/dist/files/downloader.js
CHANGED
|
@@ -11,8 +11,16 @@ export async function downloadOutputs(provider, sessionId, options) {
|
|
|
11
11
|
throw new Error(`Refusing to download ${totalBytes} bytes; maxTotalBytes exceeded`);
|
|
12
12
|
}
|
|
13
13
|
const manifest = { directory: options.directory, files: [] };
|
|
14
|
+
let downloadedBytes = 0;
|
|
14
15
|
for (const file of files) {
|
|
15
16
|
const content = await provider.downloadFile(file.id);
|
|
17
|
+
if (file.sizeBytes !== undefined && content.byteLength !== file.sizeBytes) {
|
|
18
|
+
throw new Error(`Downloaded byte size for ${file.id} did not match provider metadata`);
|
|
19
|
+
}
|
|
20
|
+
downloadedBytes += content.byteLength;
|
|
21
|
+
if (downloadedBytes > (options.maxTotalBytes ?? DEFAULT_MAX_BYTES)) {
|
|
22
|
+
throw new Error(`Downloaded outputs exceeded maxTotalBytes`);
|
|
23
|
+
}
|
|
16
24
|
const localPath = await writeFileSafe(options.directory, file.filename, content);
|
|
17
25
|
const entry = {
|
|
18
26
|
providerFileId: file.id,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"downloader.js","sourceRoot":"","sources":["../../src/files/downloader.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAC9B,MAAM,iBAAiB,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC;AAE5C,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,QAA8B,EAC9B,SAAiB,EACjB,OAA+B;IAE/B,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,QAAQ,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,CAAC;IACxE,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,QAAQ,IAAI,iBAAiB,CAAC,EAAE,CAAC;QAC3D,MAAM,IAAI,KAAK,CAAC,wBAAwB,KAAK,CAAC,MAAM,2BAA2B,CAAC,CAAC;IACnF,CAAC;IACD,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC/E,IAAI,UAAU,GAAG,CAAC,OAAO,CAAC,aAAa,IAAI,iBAAiB,CAAC,EAAE,CAAC;QAC9D,MAAM,IAAI,KAAK,CAAC,wBAAwB,UAAU,gCAAgC,CAAC,CAAC;IACtF,CAAC;IACD,MAAM,QAAQ,GAAG,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,KAAK,EAAE,EAAgD,EAAE,CAAC;IAC3G,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrD,MAAM,SAAS,GAAG,MAAM,aAAa,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACjF,MAAM,KAAK,GAAG;YACZ,cAAc,EAAE,IAAI,CAAC,EAAE;YACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,SAAS;SACV,CAAC;QACF,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IACtG,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,CAAC;AACtB,CAAC;AAED,SAAS,WAAW,CAAC,KAAqB,EAAE,OAA+B;IACzE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACrB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,OAAO,CAAC,OAAO,YAAY,MAAM,EAAE,CAAC;QACtC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,YAAY,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC1G,CAAC;IACD,OAAO,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AACvC,CAAC"}
|
|
1
|
+
{"version":3,"file":"downloader.js","sourceRoot":"","sources":["../../src/files/downloader.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
export { AntpathClient } from "./client.js";
|
|
2
|
+
export { AntpathPlatformClient, PlatformApiError } from "./platform/index.js";
|
|
3
|
+
export { AnthropicManagedAgentsProvider } from "./providers/anthropic/provider.js";
|
|
4
|
+
export type { ManagedAgentProvider, ProviderSkillRef, SessionResourceInput, UploadFileInput } from "./providers/types.js";
|
|
5
|
+
export type { PlatformEvent, PlatformOutput, PlatformRun, SignedOutputLink } from "./platform/index.js";
|
|
2
6
|
export { compileTemplate, defineTemplate, requiredOAuthAccessToken, requiredStaticBearer, string, type TemplateDefinition, type TemplateVariableDefinition } from "./template/index.js";
|
|
3
|
-
export type { CleanupPolicy, CredentialInput, DownloadOutputsOptions, DownloadOutputsResult, Logger, OutputManifest, RunEvent, RunHandle, RunOptions, RunResult, RunStatus, UsageSummary } from "./types.js";
|
|
7
|
+
export type { CleanupPolicy, CleanupResult, CredentialInput, DownloadOutputsOptions, DownloadOutputsResult, Logger, OutputManifest, ProviderEvent, ProviderFile, ProviderResourceIds, RunEvent, RunHandle, RunOptions, RunResult, RunStatus, UsageSummary } from "./types.js";
|
|
4
8
|
export { SecretString, redactSecrets } from "./utils/secrets.js";
|
|
5
9
|
export { AntpathError, CleanupError, CredentialValidationError, ProviderError, RunStateError, TemplateValidationError } from "./errors.js";
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { AntpathClient } from "./client.js";
|
|
2
|
+
export { AntpathPlatformClient, PlatformApiError } from "./platform/index.js";
|
|
3
|
+
export { AnthropicManagedAgentsProvider } from "./providers/anthropic/provider.js";
|
|
2
4
|
export { compileTemplate, defineTemplate, requiredOAuthAccessToken, requiredStaticBearer, string } from "./template/index.js";
|
|
3
5
|
export { SecretString, redactSecrets } from "./utils/secrets.js";
|
|
4
6
|
export { AntpathError, CleanupError, CredentialValidationError, ProviderError, RunStateError, TemplateValidationError } from "./errors.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EACL,eAAe,EACf,cAAc,EACd,wBAAwB,EACxB,oBAAoB,EACpB,MAAM,EAGP,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EAAE,8BAA8B,EAAE,MAAM,mCAAmC,CAAC;AAGnF,OAAO,EACL,eAAe,EACf,cAAc,EACd,wBAAwB,EACxB,oBAAoB,EACpB,MAAM,EAGP,MAAM,qBAAqB,CAAC;AAmB7B,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,yBAAyB,EACzB,aAAa,EACb,aAAa,EACb,uBAAuB,EACxB,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
type FetchLike = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
|
|
2
|
+
export type PlatformJsonPrimitive = string | number | boolean | null;
|
|
3
|
+
export type PlatformJsonValue = PlatformJsonPrimitive | readonly PlatformJsonValue[] | {
|
|
4
|
+
readonly [key: string]: PlatformJsonValue;
|
|
5
|
+
};
|
|
6
|
+
export interface PlatformTemplateSubmission {
|
|
7
|
+
readonly name: string;
|
|
8
|
+
readonly model: string;
|
|
9
|
+
readonly templateHash: string;
|
|
10
|
+
readonly system?: string;
|
|
11
|
+
readonly messages: readonly string[];
|
|
12
|
+
readonly metadata?: Record<string, PlatformJsonValue>;
|
|
13
|
+
}
|
|
14
|
+
export interface PlatformOutputPolicy {
|
|
15
|
+
readonly capture: boolean;
|
|
16
|
+
readonly globs?: readonly string[];
|
|
17
|
+
}
|
|
18
|
+
export type PlatformClaudeSessionCleanup = "retain" | "delete";
|
|
19
|
+
export interface PlatformCleanupPolicy {
|
|
20
|
+
readonly claudeSession?: PlatformClaudeSessionCleanup;
|
|
21
|
+
}
|
|
22
|
+
export interface PlatformRunSubmissionRequest {
|
|
23
|
+
readonly workspaceId: string;
|
|
24
|
+
readonly providerConnectionId: string;
|
|
25
|
+
readonly idempotencyKey: string;
|
|
26
|
+
readonly template: PlatformTemplateSubmission;
|
|
27
|
+
readonly variables?: Record<string, PlatformJsonValue>;
|
|
28
|
+
readonly credentialReferences?: Record<string, string>;
|
|
29
|
+
readonly output?: PlatformOutputPolicy;
|
|
30
|
+
readonly cleanup?: PlatformCleanupPolicy;
|
|
31
|
+
}
|
|
32
|
+
export interface AntpathPlatformClientOptions {
|
|
33
|
+
readonly baseUrl: string;
|
|
34
|
+
readonly apiToken: string;
|
|
35
|
+
readonly fetch?: FetchLike;
|
|
36
|
+
}
|
|
37
|
+
export interface PlatformRun {
|
|
38
|
+
readonly id: string;
|
|
39
|
+
readonly status: string;
|
|
40
|
+
readonly [key: string]: unknown;
|
|
41
|
+
}
|
|
42
|
+
export interface PlatformEvent {
|
|
43
|
+
readonly id: string;
|
|
44
|
+
readonly [key: string]: unknown;
|
|
45
|
+
}
|
|
46
|
+
export interface PlatformOutput {
|
|
47
|
+
readonly id: string;
|
|
48
|
+
readonly [key: string]: unknown;
|
|
49
|
+
}
|
|
50
|
+
export interface SignedOutputLink {
|
|
51
|
+
readonly url: string;
|
|
52
|
+
readonly [key: string]: unknown;
|
|
53
|
+
}
|
|
54
|
+
export declare class PlatformApiError extends Error {
|
|
55
|
+
readonly status: number;
|
|
56
|
+
readonly details: unknown;
|
|
57
|
+
constructor(status: number, message: string, details: unknown);
|
|
58
|
+
}
|
|
59
|
+
export declare class AntpathPlatformClient {
|
|
60
|
+
private readonly baseUrl;
|
|
61
|
+
private readonly apiToken;
|
|
62
|
+
private readonly fetchImpl;
|
|
63
|
+
constructor(options: AntpathPlatformClientOptions);
|
|
64
|
+
submitRun(request: PlatformRunSubmissionRequest): Promise<PlatformRun>;
|
|
65
|
+
getRun(workspaceId: string, runId: string): Promise<PlatformRun>;
|
|
66
|
+
listRunEvents(workspaceId: string, runId: string): Promise<readonly PlatformEvent[]>;
|
|
67
|
+
listOutputs(workspaceId: string, runId: string): Promise<readonly PlatformOutput[]>;
|
|
68
|
+
createOutputLink(workspaceId: string, runId: string, outputId: string): Promise<SignedOutputLink>;
|
|
69
|
+
cancelRun(workspaceId: string, runId: string): Promise<void>;
|
|
70
|
+
deleteRun(workspaceId: string, runId: string): Promise<void>;
|
|
71
|
+
private request;
|
|
72
|
+
}
|
|
73
|
+
export {};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
export class PlatformApiError extends Error {
|
|
2
|
+
status;
|
|
3
|
+
details;
|
|
4
|
+
constructor(status, message, details) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.name = "PlatformApiError";
|
|
7
|
+
this.status = status;
|
|
8
|
+
this.details = details;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export class AntpathPlatformClient {
|
|
12
|
+
baseUrl;
|
|
13
|
+
apiToken;
|
|
14
|
+
fetchImpl;
|
|
15
|
+
constructor(options) {
|
|
16
|
+
const record = options;
|
|
17
|
+
if ("anthropicApiKey" in record || "providerApiKey" in record) {
|
|
18
|
+
throw new Error("Platform client does not accept provider keys");
|
|
19
|
+
}
|
|
20
|
+
if (!options.apiToken) {
|
|
21
|
+
throw new Error("apiToken is required");
|
|
22
|
+
}
|
|
23
|
+
this.baseUrl = new URL(options.baseUrl.endsWith("/") ? options.baseUrl : `${options.baseUrl}/`);
|
|
24
|
+
this.apiToken = options.apiToken;
|
|
25
|
+
this.fetchImpl = options.fetch ?? fetch;
|
|
26
|
+
}
|
|
27
|
+
async submitRun(request) {
|
|
28
|
+
return this.request("/api/runs", {
|
|
29
|
+
method: "POST",
|
|
30
|
+
body: JSON.stringify(request)
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
async getRun(workspaceId, runId) {
|
|
34
|
+
const response = await this.request(`/api/runs/${encodeURIComponent(runId)}`, {}, { workspaceId });
|
|
35
|
+
return hasRun(response) ? response.run : response;
|
|
36
|
+
}
|
|
37
|
+
async listRunEvents(workspaceId, runId) {
|
|
38
|
+
const response = await this.request(`/api/runs/${encodeURIComponent(runId)}/events`, {}, { workspaceId });
|
|
39
|
+
return response.events;
|
|
40
|
+
}
|
|
41
|
+
async listOutputs(workspaceId, runId) {
|
|
42
|
+
const response = await this.request(`/api/runs/${encodeURIComponent(runId)}/outputs`, {}, { workspaceId });
|
|
43
|
+
return response.outputs;
|
|
44
|
+
}
|
|
45
|
+
async createOutputLink(workspaceId, runId, outputId) {
|
|
46
|
+
return this.request(`/api/runs/${encodeURIComponent(runId)}/outputs/${encodeURIComponent(outputId)}/link`, { method: "POST" }, { workspaceId });
|
|
47
|
+
}
|
|
48
|
+
async cancelRun(workspaceId, runId) {
|
|
49
|
+
await this.request(`/api/runs/${encodeURIComponent(runId)}/cancel`, { method: "POST" }, { workspaceId });
|
|
50
|
+
}
|
|
51
|
+
async deleteRun(workspaceId, runId) {
|
|
52
|
+
await this.request(`/api/runs/${encodeURIComponent(runId)}`, { method: "DELETE" }, { workspaceId });
|
|
53
|
+
}
|
|
54
|
+
async request(path, init = {}, query = {}) {
|
|
55
|
+
const url = new URL(path.replace(/^\//, ""), this.baseUrl);
|
|
56
|
+
for (const [key, value] of Object.entries(query)) {
|
|
57
|
+
url.searchParams.set(key, value);
|
|
58
|
+
}
|
|
59
|
+
const headers = {
|
|
60
|
+
accept: "application/json",
|
|
61
|
+
...(init.body ? { "content-type": "application/json" } : {}),
|
|
62
|
+
authorization: `Bearer ${this.apiToken}`,
|
|
63
|
+
...normalizeHeaders(init.headers)
|
|
64
|
+
};
|
|
65
|
+
const response = await this.fetchImpl(url, { ...init, headers });
|
|
66
|
+
const body = await readJson(response);
|
|
67
|
+
if (!response.ok) {
|
|
68
|
+
throw new PlatformApiError(response.status, extractErrorMessage(body), body);
|
|
69
|
+
}
|
|
70
|
+
return body;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function normalizeHeaders(headers) {
|
|
74
|
+
if (!headers) {
|
|
75
|
+
return {};
|
|
76
|
+
}
|
|
77
|
+
if (headers instanceof Headers) {
|
|
78
|
+
return Object.fromEntries(headers.entries());
|
|
79
|
+
}
|
|
80
|
+
if (Array.isArray(headers)) {
|
|
81
|
+
return Object.fromEntries(headers);
|
|
82
|
+
}
|
|
83
|
+
return headers;
|
|
84
|
+
}
|
|
85
|
+
async function readJson(response) {
|
|
86
|
+
const text = await response.text();
|
|
87
|
+
if (text.length === 0) {
|
|
88
|
+
return {};
|
|
89
|
+
}
|
|
90
|
+
return JSON.parse(text);
|
|
91
|
+
}
|
|
92
|
+
function extractErrorMessage(body) {
|
|
93
|
+
if (body && typeof body === "object" && "error" in body) {
|
|
94
|
+
const error = body.error;
|
|
95
|
+
if (error && typeof error === "object" && "message" in error) {
|
|
96
|
+
const message = error.message;
|
|
97
|
+
if (typeof message === "string") {
|
|
98
|
+
return message;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return "Platform request failed";
|
|
103
|
+
}
|
|
104
|
+
function hasRun(input) {
|
|
105
|
+
return Boolean(input && typeof input === "object" && "run" in input);
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/platform/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./client.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/platform/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC"}
|
|
@@ -3,10 +3,16 @@ import { SecretString } from "../../utils/secrets.js";
|
|
|
3
3
|
import type { ResolvedTemplate } from "../../template/compiler.js";
|
|
4
4
|
import type { CleanupResult } from "../../types.js";
|
|
5
5
|
import type { CreatedCredential, ManagedAgentProvider, ProviderSkillRef, SessionResourceInput, UploadFileInput } from "../types.js";
|
|
6
|
+
export interface AnthropicProviderRetryOptions {
|
|
7
|
+
maxAttempts?: number | undefined;
|
|
8
|
+
baseDelayMs?: number | undefined;
|
|
9
|
+
maxDelayMs?: number | undefined;
|
|
10
|
+
}
|
|
6
11
|
export interface AnthropicManagedAgentsProviderOptions {
|
|
7
12
|
apiKey: string | SecretString;
|
|
8
13
|
baseUrl?: string;
|
|
9
14
|
fetch?: typeof fetch;
|
|
15
|
+
retry?: AnthropicProviderRetryOptions | undefined;
|
|
10
16
|
}
|
|
11
17
|
export declare class AnthropicManagedAgentsProvider implements ManagedAgentProvider {
|
|
12
18
|
#private;
|
|
@@ -3,14 +3,21 @@ import { redactSecrets, SecretString } from "../../utils/secrets.js";
|
|
|
3
3
|
const DEFAULT_BASE_URL = "https://api.anthropic.com";
|
|
4
4
|
const ANTHROPIC_VERSION = "2023-06-01";
|
|
5
5
|
const BETA_HEADER = "managed-agents-2026-04-01,files-api-2025-04-14,skills-2025-10-02";
|
|
6
|
+
const DEFAULT_RETRY_OPTIONS = {
|
|
7
|
+
maxAttempts: 3,
|
|
8
|
+
baseDelayMs: 100,
|
|
9
|
+
maxDelayMs: 1_000
|
|
10
|
+
};
|
|
6
11
|
export class AnthropicManagedAgentsProvider {
|
|
7
12
|
#apiKey;
|
|
8
13
|
#baseUrl;
|
|
9
14
|
#fetch;
|
|
15
|
+
#retry;
|
|
10
16
|
constructor(options) {
|
|
11
17
|
this.#apiKey = options.apiKey instanceof SecretString ? options.apiKey : new SecretString(options.apiKey, "anthropicApiKey");
|
|
12
18
|
this.#baseUrl = options.baseUrl ?? DEFAULT_BASE_URL;
|
|
13
19
|
this.#fetch = options.fetch ?? fetch;
|
|
20
|
+
this.#retry = normalizeRetryOptions(options.retry);
|
|
14
21
|
}
|
|
15
22
|
async createEnvironment(template) {
|
|
16
23
|
const body = {
|
|
@@ -244,22 +251,93 @@ export class AnthropicManagedAgentsProvider {
|
|
|
244
251
|
return await response.json();
|
|
245
252
|
}
|
|
246
253
|
async #raw(path, init) {
|
|
247
|
-
const
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
+
const method = normalizeMethod(init.method);
|
|
255
|
+
const retryable = isRetryableMethod(method);
|
|
256
|
+
let attempt = 0;
|
|
257
|
+
while (true) {
|
|
258
|
+
attempt += 1;
|
|
259
|
+
try {
|
|
260
|
+
const response = await this.#fetch(`${this.#baseUrl}${path}`, {
|
|
261
|
+
...init,
|
|
262
|
+
method,
|
|
263
|
+
headers: {
|
|
264
|
+
"x-api-key": this.#apiKey.unwrap(),
|
|
265
|
+
"anthropic-version": ANTHROPIC_VERSION,
|
|
266
|
+
"anthropic-beta": BETA_HEADER,
|
|
267
|
+
...init.headers
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
if (response.ok) {
|
|
271
|
+
return response;
|
|
272
|
+
}
|
|
273
|
+
if (retryable && isRetryableStatus(response.status) && attempt < this.#retry.maxAttempts) {
|
|
274
|
+
await discardBody(response);
|
|
275
|
+
await delayBeforeRetry(attempt, this.#retry, init.signal);
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
const body = await response.text().catch(() => "");
|
|
279
|
+
throw new ProviderError(`Anthropic API request failed: ${response.status} ${redactSecrets(body)}`, { status: response.status });
|
|
280
|
+
}
|
|
281
|
+
catch (error) {
|
|
282
|
+
if (error instanceof ProviderError || isAbortError(error) || !retryable || attempt >= this.#retry.maxAttempts) {
|
|
283
|
+
if (error instanceof ProviderError) {
|
|
284
|
+
throw error;
|
|
285
|
+
}
|
|
286
|
+
throw new ProviderError(`Anthropic API request failed before response: ${redactSecrets(errorMessage(error))}`);
|
|
287
|
+
}
|
|
288
|
+
await delayBeforeRetry(attempt, this.#retry, init.signal);
|
|
254
289
|
}
|
|
255
|
-
});
|
|
256
|
-
if (!response.ok) {
|
|
257
|
-
const body = await response.text().catch(() => "");
|
|
258
|
-
throw new ProviderError(`Anthropic API request failed: ${response.status} ${redactSecrets(body)}`, { status: response.status });
|
|
259
290
|
}
|
|
260
|
-
return response;
|
|
261
291
|
}
|
|
262
292
|
}
|
|
293
|
+
function normalizeRetryOptions(options) {
|
|
294
|
+
return {
|
|
295
|
+
maxAttempts: Math.max(1, Math.floor(options?.maxAttempts ?? DEFAULT_RETRY_OPTIONS.maxAttempts)),
|
|
296
|
+
baseDelayMs: Math.max(0, options?.baseDelayMs ?? DEFAULT_RETRY_OPTIONS.baseDelayMs),
|
|
297
|
+
maxDelayMs: Math.max(0, options?.maxDelayMs ?? DEFAULT_RETRY_OPTIONS.maxDelayMs)
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
function normalizeMethod(method) {
|
|
301
|
+
return (method ?? "GET").toUpperCase();
|
|
302
|
+
}
|
|
303
|
+
function isRetryableMethod(method) {
|
|
304
|
+
return method === "GET" || method === "HEAD" || method === "DELETE";
|
|
305
|
+
}
|
|
306
|
+
function isRetryableStatus(status) {
|
|
307
|
+
return status === 408 || status === 429 || status >= 500;
|
|
308
|
+
}
|
|
309
|
+
async function discardBody(response) {
|
|
310
|
+
await response.body?.cancel().catch(() => undefined);
|
|
311
|
+
}
|
|
312
|
+
async function delayBeforeRetry(attempt, options, signal) {
|
|
313
|
+
const delayMs = Math.min(options.maxDelayMs, options.baseDelayMs * 2 ** Math.max(0, attempt - 1));
|
|
314
|
+
if (delayMs === 0) {
|
|
315
|
+
throwIfAborted(signal);
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
throwIfAborted(signal);
|
|
319
|
+
await new Promise((resolve, reject) => {
|
|
320
|
+
const timeout = setTimeout(resolve, delayMs);
|
|
321
|
+
signal?.addEventListener("abort", () => {
|
|
322
|
+
clearTimeout(timeout);
|
|
323
|
+
reject(abortError(signal));
|
|
324
|
+
}, { once: true });
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
function throwIfAborted(signal) {
|
|
328
|
+
if (signal?.aborted) {
|
|
329
|
+
throw abortError(signal);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
function abortError(signal) {
|
|
333
|
+
return signal.reason instanceof Error ? signal.reason : new Error("Request aborted");
|
|
334
|
+
}
|
|
335
|
+
function isAbortError(error) {
|
|
336
|
+
return error instanceof Error && (error.name === "AbortError" || error.message === "Request aborted");
|
|
337
|
+
}
|
|
338
|
+
function errorMessage(error) {
|
|
339
|
+
return error instanceof Error ? error.message : String(error);
|
|
340
|
+
}
|
|
263
341
|
function mapNetworking(template) {
|
|
264
342
|
const network = template.environment.network ?? "restricted";
|
|
265
343
|
if (network === "unrestricted") {
|