@zackbart/connecta 0.15.1 → 0.16.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/AGENTS.md +40 -20
- package/CHANGELOG.md +653 -0
- package/README.md +25 -5
- package/bin/connecta.mjs +44 -3
- package/dist/access-tokens.d.ts +0 -1
- package/dist/access-tokens.js +0 -1
- package/dist/activity.d.ts +50 -2
- package/dist/activity.js +34 -1
- package/dist/apps-shell.d.ts +0 -1
- package/dist/apps-shell.js +0 -1
- package/dist/auth/bearer.d.ts +0 -1
- package/dist/auth/bearer.js +0 -1
- package/dist/auth/clerk.d.ts +0 -1
- package/dist/auth/clerk.js +45 -9
- package/dist/auth/downstream-oauth.d.ts +0 -1
- package/dist/auth/downstream-oauth.js +0 -1
- package/dist/call-admission.d.ts +0 -1
- package/dist/call-admission.js +0 -1
- package/dist/catalog-drift.d.ts +99 -0
- package/dist/catalog-drift.js +251 -0
- package/dist/catalog-fingerprint.d.ts +0 -1
- package/dist/catalog-fingerprint.js +0 -1
- package/dist/catalog-limits.d.ts +0 -1
- package/dist/catalog-limits.js +0 -1
- package/dist/catalog-service.d.ts +0 -1
- package/dist/catalog-service.js +41 -5
- package/dist/catalog.d.ts +11 -1
- package/dist/catalog.js +20 -1
- package/dist/concurrency.d.ts +0 -1
- package/dist/concurrency.js +0 -1
- package/dist/connector-scope.d.ts +0 -1
- package/dist/connector-scope.js +0 -1
- package/dist/connectors/api.d.ts +29 -21
- package/dist/connectors/api.js +45 -19
- package/dist/connectors/guarded-fetch.d.ts +106 -0
- package/dist/connectors/guarded-fetch.js +289 -0
- package/dist/connectors/remote-mcp.d.ts +0 -1
- package/dist/connectors/remote-mcp.js +0 -1
- package/dist/credentials.d.ts +0 -1
- package/dist/credentials.js +0 -1
- package/dist/errors.d.ts +30 -3
- package/dist/errors.js +1 -1
- package/dist/execute.d.ts +0 -1
- package/dist/execute.js +0 -1
- package/dist/executor-admission.d.ts +11 -1
- package/dist/executor-admission.js +28 -1
- package/dist/executor-result.d.ts +0 -1
- package/dist/executor-result.js +0 -1
- package/dist/executors/quickjs-child.d.ts +0 -1
- package/dist/executors/quickjs-child.js +0 -1
- package/dist/executors/quickjs-protocol.d.ts +0 -1
- package/dist/executors/quickjs-protocol.js +0 -1
- package/dist/executors/quickjs-runtime.d.ts +0 -1
- package/dist/executors/quickjs-runtime.js +0 -1
- package/dist/executors/quickjs.d.ts +0 -1
- package/dist/executors/quickjs.js +2 -1
- package/dist/favicon.d.ts +0 -1
- package/dist/favicon.js +0 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.js +24 -7
- package/dist/invocation.d.ts +0 -1
- package/dist/invocation.js +0 -1
- package/dist/json-schema.d.ts +0 -1
- package/dist/json-schema.js +0 -1
- package/dist/mcp-result.d.ts +0 -1
- package/dist/mcp-result.js +0 -1
- package/dist/meta-tools.d.ts +0 -1
- package/dist/meta-tools.js +0 -1
- package/dist/node.d.ts +0 -1
- package/dist/node.js +0 -1
- package/dist/operator-ui/generated.d.ts +2 -3
- package/dist/operator-ui/generated.js +3 -4
- package/dist/operator-ui/model.d.ts +10 -1
- package/dist/operator-ui/model.js +0 -1
- package/dist/operator-ui/view.d.ts +167 -0
- package/dist/operator-ui/view.js +270 -0
- package/dist/providers/cloudflare.d.ts +0 -1
- package/dist/providers/cloudflare.js +261 -299
- package/dist/providers/linear.d.ts +26 -5
- package/dist/providers/linear.js +32 -61
- package/dist/providers/mixpanel.d.ts +35 -4
- package/dist/providers/mixpanel.js +53 -79
- package/dist/providers/notion.d.ts +0 -1
- package/dist/providers/notion.js +87 -42
- package/dist/providers/stripe.d.ts +13 -1
- package/dist/providers/stripe.js +31 -60
- package/dist/registry.d.ts +34 -2
- package/dist/registry.js +85 -5
- package/dist/retired-toolkits.d.ts +0 -1
- package/dist/retired-toolkits.js +0 -1
- package/dist/routes/access-tokens.d.ts +0 -1
- package/dist/routes/access-tokens.js +0 -1
- package/dist/routes/activity.d.ts +0 -1
- package/dist/routes/activity.js +0 -1
- package/dist/routes/credentials.d.ts +0 -1
- package/dist/routes/credentials.js +0 -1
- package/dist/routes/mcp.d.ts +0 -1
- package/dist/routes/mcp.js +0 -1
- package/dist/routes/oauth.d.ts +0 -1
- package/dist/routes/oauth.js +0 -1
- package/dist/routes/shared.d.ts +2 -1
- package/dist/routes/shared.js +0 -1
- package/dist/routes/ui.d.ts +0 -1
- package/dist/routes/ui.js +0 -1
- package/dist/server.d.ts +0 -1
- package/dist/server.js +11 -1
- package/dist/skills.d.ts +0 -1
- package/dist/skills.js +0 -1
- package/dist/storage/file.d.ts +0 -1
- package/dist/storage/file.js +0 -1
- package/dist/storage/memory.d.ts +0 -1
- package/dist/storage/memory.js +0 -1
- package/dist/timeout.d.ts +0 -1
- package/dist/timeout.js +0 -1
- package/dist/tool-safety.d.ts +0 -1
- package/dist/tool-safety.js +0 -1
- package/dist/types.d.ts +45 -1
- package/dist/types.js +0 -1
- package/dist/ui.d.ts +0 -1
- package/dist/ui.js +13 -137
- package/dist/validate.d.ts +13 -15
- package/dist/validate.js +24 -11
- package/dist/version.d.ts +1 -2
- package/dist/version.js +1 -2
- package/documentation/architecture.md +186 -5
- package/documentation/auth.md +11 -0
- package/documentation/call-admission.md +142 -6
- package/documentation/cloudflare.md +92 -10
- package/documentation/code-first-exploration.md +2 -2
- package/documentation/code-mode.md +14 -14
- package/documentation/connector-guides.md +172 -5
- package/documentation/connectors.md +89 -0
- package/documentation/linear.md +20 -2
- package/documentation/mcp-ui-design.md +2 -2
- package/documentation/meta-tools.md +7 -1
- package/documentation/mixpanel.md +42 -9
- package/documentation/notion.md +23 -2
- package/documentation/operations.md +325 -5
- package/documentation/operator-ui.md +120 -5
- package/documentation/provider-audit.md +160 -0
- package/documentation/provider-conventions.md +667 -0
- package/documentation/request-admission.md +167 -5
- package/documentation/rich-output-design.md +1 -2
- package/documentation/stripe.md +15 -0
- package/documentation/upgrading.md +454 -0
- package/ethos.md +14 -9
- package/examples/worker/README.md +102 -12
- package/examples/worker/src/index.ts +46 -1
- package/examples/worker/wrangler.jsonc +14 -1
- package/package.json +10 -6
- package/templates/node/.dockerignore +10 -0
- package/templates/node/.env.example +40 -3
- package/templates/node/AGENTS.md +16 -1
- package/templates/node/Dockerfile +49 -0
- package/templates/node/README.md +117 -2
- package/templates/node/docker-compose.yml +39 -0
- package/templates/node/package.json +1 -1
- package/templates/node/src/file-activity.ts +182 -0
- package/templates/node/src/index.ts +80 -4
- package/assets/connecta-clay-hero.png +0 -0
- package/dist/access-tokens.d.ts.map +0 -1
- package/dist/access-tokens.js.map +0 -1
- package/dist/activity.d.ts.map +0 -1
- package/dist/activity.js.map +0 -1
- package/dist/apps-shell.d.ts.map +0 -1
- package/dist/apps-shell.js.map +0 -1
- package/dist/auth/bearer.d.ts.map +0 -1
- package/dist/auth/bearer.js.map +0 -1
- package/dist/auth/clerk.d.ts.map +0 -1
- package/dist/auth/clerk.js.map +0 -1
- package/dist/auth/downstream-oauth.d.ts.map +0 -1
- package/dist/auth/downstream-oauth.js.map +0 -1
- package/dist/call-admission.d.ts.map +0 -1
- package/dist/call-admission.js.map +0 -1
- package/dist/catalog-fingerprint.d.ts.map +0 -1
- package/dist/catalog-fingerprint.js.map +0 -1
- package/dist/catalog-limits.d.ts.map +0 -1
- package/dist/catalog-limits.js.map +0 -1
- package/dist/catalog-service.d.ts.map +0 -1
- package/dist/catalog-service.js.map +0 -1
- package/dist/catalog.d.ts.map +0 -1
- package/dist/catalog.js.map +0 -1
- package/dist/concurrency.d.ts.map +0 -1
- package/dist/concurrency.js.map +0 -1
- package/dist/connector-scope.d.ts.map +0 -1
- package/dist/connector-scope.js.map +0 -1
- package/dist/connectors/api.d.ts.map +0 -1
- package/dist/connectors/api.js.map +0 -1
- package/dist/connectors/remote-mcp.d.ts.map +0 -1
- package/dist/connectors/remote-mcp.js.map +0 -1
- package/dist/credentials.d.ts.map +0 -1
- package/dist/credentials.js.map +0 -1
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js.map +0 -1
- package/dist/execute.d.ts.map +0 -1
- package/dist/execute.js.map +0 -1
- package/dist/executor-admission.d.ts.map +0 -1
- package/dist/executor-admission.js.map +0 -1
- package/dist/executor-result.d.ts.map +0 -1
- package/dist/executor-result.js.map +0 -1
- package/dist/executors/quickjs-child.d.ts.map +0 -1
- package/dist/executors/quickjs-child.js.map +0 -1
- package/dist/executors/quickjs-protocol.d.ts.map +0 -1
- package/dist/executors/quickjs-protocol.js.map +0 -1
- package/dist/executors/quickjs-runtime.d.ts.map +0 -1
- package/dist/executors/quickjs-runtime.js.map +0 -1
- package/dist/executors/quickjs.d.ts.map +0 -1
- package/dist/executors/quickjs.js.map +0 -1
- package/dist/favicon.d.ts.map +0 -1
- package/dist/favicon.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/invocation.d.ts.map +0 -1
- package/dist/invocation.js.map +0 -1
- package/dist/json-schema.d.ts.map +0 -1
- package/dist/json-schema.js.map +0 -1
- package/dist/mcp-result.d.ts.map +0 -1
- package/dist/mcp-result.js.map +0 -1
- package/dist/meta-tools.d.ts.map +0 -1
- package/dist/meta-tools.js.map +0 -1
- package/dist/node.d.ts.map +0 -1
- package/dist/node.js.map +0 -1
- package/dist/operator-ui/generated.d.ts.map +0 -1
- package/dist/operator-ui/generated.js.map +0 -1
- package/dist/operator-ui/model.d.ts.map +0 -1
- package/dist/operator-ui/model.js.map +0 -1
- package/dist/providers/cloudflare.d.ts.map +0 -1
- package/dist/providers/cloudflare.js.map +0 -1
- package/dist/providers/linear.d.ts.map +0 -1
- package/dist/providers/linear.js.map +0 -1
- package/dist/providers/mixpanel.d.ts.map +0 -1
- package/dist/providers/mixpanel.js.map +0 -1
- package/dist/providers/notion.d.ts.map +0 -1
- package/dist/providers/notion.js.map +0 -1
- package/dist/providers/stripe.d.ts.map +0 -1
- package/dist/providers/stripe.js.map +0 -1
- package/dist/registry.d.ts.map +0 -1
- package/dist/registry.js.map +0 -1
- package/dist/retired-toolkits.d.ts.map +0 -1
- package/dist/retired-toolkits.js.map +0 -1
- package/dist/routes/access-tokens.d.ts.map +0 -1
- package/dist/routes/access-tokens.js.map +0 -1
- package/dist/routes/activity.d.ts.map +0 -1
- package/dist/routes/activity.js.map +0 -1
- package/dist/routes/credentials.d.ts.map +0 -1
- package/dist/routes/credentials.js.map +0 -1
- package/dist/routes/mcp.d.ts.map +0 -1
- package/dist/routes/mcp.js.map +0 -1
- package/dist/routes/oauth.d.ts.map +0 -1
- package/dist/routes/oauth.js.map +0 -1
- package/dist/routes/shared.d.ts.map +0 -1
- package/dist/routes/shared.js.map +0 -1
- package/dist/routes/ui.d.ts.map +0 -1
- package/dist/routes/ui.js.map +0 -1
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js.map +0 -1
- package/dist/skills.d.ts.map +0 -1
- package/dist/skills.js.map +0 -1
- package/dist/storage/file.d.ts.map +0 -1
- package/dist/storage/file.js.map +0 -1
- package/dist/storage/memory.d.ts.map +0 -1
- package/dist/storage/memory.js.map +0 -1
- package/dist/timeout.d.ts.map +0 -1
- package/dist/timeout.js.map +0 -1
- package/dist/tool-safety.d.ts.map +0 -1
- package/dist/tool-safety.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/ui.d.ts.map +0 -1
- package/dist/ui.js.map +0 -1
- package/dist/validate.d.ts.map +0 -1
- package/dist/validate.js.map +0 -1
- package/dist/version.d.ts.map +0 -1
- package/dist/version.js.map +0 -1
- package/examples/node/README.md +0 -52
- package/examples/node/src/index.ts +0 -71
- package/src/access-tokens.ts +0 -289
- package/src/activity.ts +0 -234
- package/src/apps-shell.ts +0 -370
- package/src/auth/bearer.ts +0 -61
- package/src/auth/clerk.ts +0 -553
- package/src/auth/downstream-oauth.ts +0 -575
- package/src/call-admission.ts +0 -521
- package/src/catalog-fingerprint.ts +0 -52
- package/src/catalog-limits.ts +0 -11
- package/src/catalog-service.ts +0 -1153
- package/src/catalog.ts +0 -790
- package/src/concurrency.ts +0 -39
- package/src/connector-scope.ts +0 -66
- package/src/connectors/api.ts +0 -159
- package/src/connectors/remote-mcp.ts +0 -1090
- package/src/credentials.ts +0 -428
- package/src/errors.ts +0 -364
- package/src/execute.ts +0 -1406
- package/src/executor-admission.ts +0 -328
- package/src/executor-result.ts +0 -107
- package/src/executors/quickjs-child.ts +0 -172
- package/src/executors/quickjs-protocol.ts +0 -99
- package/src/executors/quickjs-runtime.ts +0 -470
- package/src/executors/quickjs.ts +0 -776
- package/src/favicon.ts +0 -53
- package/src/index.ts +0 -666
- package/src/invocation.ts +0 -655
- package/src/json-schema.ts +0 -11
- package/src/mcp-result.ts +0 -43
- package/src/meta-tools.ts +0 -1607
- package/src/node.ts +0 -206
- package/src/operator-ui/browser.css +0 -423
- package/src/operator-ui/browser.ts +0 -1281
- package/src/operator-ui/generated.ts +0 -4
- package/src/operator-ui/model.ts +0 -111
- package/src/providers/cloudflare.ts +0 -3999
- package/src/providers/linear.ts +0 -302
- package/src/providers/mixpanel.ts +0 -229
- package/src/providers/notion.ts +0 -1879
- package/src/providers/stripe.ts +0 -307
- package/src/registry.ts +0 -1085
- package/src/retired-toolkits.ts +0 -14
- package/src/routes/access-tokens.ts +0 -115
- package/src/routes/activity.ts +0 -215
- package/src/routes/credentials.ts +0 -254
- package/src/routes/mcp.ts +0 -429
- package/src/routes/oauth.ts +0 -322
- package/src/routes/shared.ts +0 -247
- package/src/routes/ui.ts +0 -152
- package/src/server.ts +0 -195
- package/src/skills.ts +0 -271
- package/src/storage/file.ts +0 -123
- package/src/storage/memory.ts +0 -44
- package/src/timeout.ts +0 -84
- package/src/tool-safety.ts +0 -15
- package/src/types.ts +0 -523
- package/src/ui.ts +0 -744
- package/src/validate.ts +0 -387
- package/src/version.ts +0 -7
package/src/errors.ts
DELETED
|
@@ -1,364 +0,0 @@
|
|
|
1
|
-
// Typed failure contract for connector tool calls. Web-API only — no node:
|
|
2
|
-
// imports here.
|
|
3
|
-
|
|
4
|
-
/** Machine-readable classification of a failed connector tool call. */
|
|
5
|
-
export type ConnectorCallErrorCode =
|
|
6
|
-
| "timeout"
|
|
7
|
-
| "auth_required"
|
|
8
|
-
| "rate_limited"
|
|
9
|
-
| "unavailable"
|
|
10
|
-
| "invalid_args"
|
|
11
|
-
| "input_required_unsupported"
|
|
12
|
-
| "connector_call_failed";
|
|
13
|
-
|
|
14
|
-
/** One bounded, payload-free explanation of an input-schema mismatch. */
|
|
15
|
-
export interface ArgumentValidationIssue {
|
|
16
|
-
/** JSON Pointer into the submitted arguments; "/" means the root value. */
|
|
17
|
-
path: string;
|
|
18
|
-
/** JSON Schema keyword that rejected the argument. */
|
|
19
|
-
code: string;
|
|
20
|
-
/** Expected shape only — never the submitted value. */
|
|
21
|
-
expected: string;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export interface ArgumentValidationDetails {
|
|
25
|
-
issues: ArgumentValidationIssue[];
|
|
26
|
-
/** More findings existed but were omitted from the bounded response. */
|
|
27
|
-
truncated?: true;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export const MAX_ARGUMENT_VALIDATION_ISSUES = 3;
|
|
31
|
-
const MAX_ARGUMENT_ISSUE_PATH_CHARS = 256;
|
|
32
|
-
const MAX_ARGUMENT_ISSUE_CODE_CHARS = 64;
|
|
33
|
-
const MAX_ARGUMENT_ISSUE_EXPECTED_CHARS = 128;
|
|
34
|
-
|
|
35
|
-
function boundedIssueText(
|
|
36
|
-
value: string,
|
|
37
|
-
maxChars: number,
|
|
38
|
-
): { value: string; truncated: boolean } {
|
|
39
|
-
if (value.length <= maxChars) return { value, truncated: false };
|
|
40
|
-
return {
|
|
41
|
-
value: `${value.slice(0, Math.max(0, maxChars - 1))}…`,
|
|
42
|
-
truncated: true,
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* How many bytes of the caller's own arguments an error envelope will echo
|
|
48
|
-
* back to it. Small on purpose: an error result is not size-guarded the way a
|
|
49
|
-
* *result* is, so an unbounded echo turns a 50 KB argument object into a 100 KB
|
|
50
|
-
* refusal against a deployment that capped results at 1 KB — twice over, since
|
|
51
|
-
* the payload lands in both the text content and `structuredContent`. The agent
|
|
52
|
-
* already holds what it sent; the echo is a convenience, never the record.
|
|
53
|
-
*/
|
|
54
|
-
const MAX_ECHOED_ARGS_BYTES = 512;
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* The same budget spent on caller-authored *text* — the address it mistyped,
|
|
58
|
-
* the discovery query derived from it — rather than on its arguments.
|
|
59
|
-
*
|
|
60
|
-
* Text is clamped where {@link echoedCallArgs} drops: an address is the thing
|
|
61
|
-
* the refusal exists to correct, so a refusal that named nothing would be
|
|
62
|
-
* useless, while a clipped one still carries the prefix that identifies the
|
|
63
|
-
* mistake. The marker says it was clipped, so nothing reads a clamped address
|
|
64
|
-
* as the address that was sent. Arguments get the opposite rule because they
|
|
65
|
-
* end at a human approving one specific call.
|
|
66
|
-
*
|
|
67
|
-
* The number is not cosmetic. An error result is not size-guarded the way a
|
|
68
|
-
* result is, and every echoed byte lands twice (text content *and*
|
|
69
|
-
* `structuredContent`), so an unbounded address turned a 50 KB typo into a
|
|
70
|
-
* 200 KB refusal against a deployment that capped results at 1 KB.
|
|
71
|
-
*/
|
|
72
|
-
const MAX_ECHOED_TEXT_BYTES = 512;
|
|
73
|
-
|
|
74
|
-
const echoEncoder = new TextEncoder();
|
|
75
|
-
const echoDecoder = new TextDecoder();
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Clamp a string to a UTF-8 byte budget, appending `…` when it clipped.
|
|
79
|
-
* Short strings — the common case, and the one that has to stay exact — are
|
|
80
|
-
* returned unchanged and untagged.
|
|
81
|
-
*/
|
|
82
|
-
export function boundedEchoText(
|
|
83
|
-
value: string,
|
|
84
|
-
maxBytes: number = MAX_ECHOED_TEXT_BYTES,
|
|
85
|
-
): string {
|
|
86
|
-
const bytes = echoEncoder.encode(value);
|
|
87
|
-
if (bytes.length <= maxBytes) return value;
|
|
88
|
-
// Never split a codepoint: walk back off UTF-8 continuation bytes (10xxxxxx)
|
|
89
|
-
// so the clamp cannot manufacture a replacement character.
|
|
90
|
-
let end = Math.max(0, maxBytes);
|
|
91
|
-
while (end > 0 && ((bytes[end] ?? 0) & 0xc0) === 0x80) end--;
|
|
92
|
-
return `${echoDecoder.decode(bytes.slice(0, end))}…`;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* `{ args }` when the caller's arguments fit {@link MAX_ECHOED_ARGS_BYTES},
|
|
97
|
-
* `{}` when they do not. All or nothing: a clipped echo would be a *different*
|
|
98
|
-
* call than the one that was refused, and the routes this feeds end at a human
|
|
99
|
-
* approving one. Unserializable arguments are treated the same way as oversized
|
|
100
|
-
* ones — there is nothing honest to put in the field.
|
|
101
|
-
*/
|
|
102
|
-
export function echoedCallArgs(args: unknown): { args?: unknown } {
|
|
103
|
-
if (args === undefined) return {};
|
|
104
|
-
let text: string | undefined;
|
|
105
|
-
try {
|
|
106
|
-
text = JSON.stringify(args);
|
|
107
|
-
} catch {
|
|
108
|
-
return {};
|
|
109
|
-
}
|
|
110
|
-
if (text === undefined) return {};
|
|
111
|
-
return echoEncoder.encode(text).length <= MAX_ECHOED_ARGS_BYTES
|
|
112
|
-
? { args }
|
|
113
|
-
: {};
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function boundedValidation(
|
|
117
|
-
details: ArgumentValidationDetails | undefined,
|
|
118
|
-
): ArgumentValidationDetails | undefined {
|
|
119
|
-
if (!details) return undefined;
|
|
120
|
-
let truncated =
|
|
121
|
-
details.truncated === true ||
|
|
122
|
-
details.issues.length > MAX_ARGUMENT_VALIDATION_ISSUES;
|
|
123
|
-
const issues = details.issues
|
|
124
|
-
.slice(0, MAX_ARGUMENT_VALIDATION_ISSUES)
|
|
125
|
-
.map((issue) => {
|
|
126
|
-
const path = boundedIssueText(
|
|
127
|
-
issue.path,
|
|
128
|
-
MAX_ARGUMENT_ISSUE_PATH_CHARS,
|
|
129
|
-
);
|
|
130
|
-
const code = boundedIssueText(
|
|
131
|
-
issue.code,
|
|
132
|
-
MAX_ARGUMENT_ISSUE_CODE_CHARS,
|
|
133
|
-
);
|
|
134
|
-
const expected = boundedIssueText(
|
|
135
|
-
issue.expected,
|
|
136
|
-
MAX_ARGUMENT_ISSUE_EXPECTED_CHARS,
|
|
137
|
-
);
|
|
138
|
-
truncated ||= path.truncated || code.truncated || expected.truncated;
|
|
139
|
-
return {
|
|
140
|
-
path: path.value,
|
|
141
|
-
code: code.value,
|
|
142
|
-
expected: expected.value,
|
|
143
|
-
};
|
|
144
|
-
});
|
|
145
|
-
return {
|
|
146
|
-
issues,
|
|
147
|
-
...(truncated ? { truncated: true as const } : {}),
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/** Agent-visible recovery class attached only to `auth_required` failures. */
|
|
152
|
-
export type AuthRecoveryMode =
|
|
153
|
-
| "oauth"
|
|
154
|
-
| "operator_config"
|
|
155
|
-
| "unavailable";
|
|
156
|
-
|
|
157
|
-
const RETRYABLE_BY_CODE: Record<ConnectorCallErrorCode, boolean> = {
|
|
158
|
-
timeout: true,
|
|
159
|
-
rate_limited: true,
|
|
160
|
-
unavailable: true,
|
|
161
|
-
auth_required: false,
|
|
162
|
-
invalid_args: false,
|
|
163
|
-
input_required_unsupported: false,
|
|
164
|
-
connector_call_failed: false,
|
|
165
|
-
};
|
|
166
|
-
|
|
167
|
-
/** Non-negative integer milliseconds, or undefined for anything else. */
|
|
168
|
-
function normalizeRetryAfterMs(value: number | undefined): number | undefined {
|
|
169
|
-
if (value === undefined) return undefined;
|
|
170
|
-
if (!Number.isFinite(value) || value < 0) return undefined;
|
|
171
|
-
return Math.trunc(value);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Throw from `Connector.callTool` (or anything beneath it) to classify a
|
|
176
|
-
* failure exactly. Untyped errors fall back to a message-text heuristic, so a
|
|
177
|
-
* connector whose legitimate error text mentions "timeout" is misread as a
|
|
178
|
-
* retryable timeout — this class is the escape hatch. `retryable` defaults per
|
|
179
|
-
* code (timeout, rate_limited, and unavailable retry; the rest do not) and may
|
|
180
|
-
* be overridden.
|
|
181
|
-
*
|
|
182
|
-
* `retryAfterMs` carries a wait window the connector already knows — a
|
|
183
|
-
* `Retry-After` header, say — so the engine can wait that long instead of
|
|
184
|
-
* guessing, and so an agent that receives the failure can decide when to
|
|
185
|
-
* re-issue.
|
|
186
|
-
*/
|
|
187
|
-
export class ConnectorCallError extends Error {
|
|
188
|
-
readonly code: ConnectorCallErrorCode;
|
|
189
|
-
readonly retryable: boolean;
|
|
190
|
-
/**
|
|
191
|
-
* Connector-known wait window in ms before this call is worth repeating,
|
|
192
|
-
* or undefined when the connector reported none. Always an own property —
|
|
193
|
-
* under ES2022 class fields the declaration itself defines it, so guarding
|
|
194
|
-
* the assignment would not keep it off the instance. Keeping the window out
|
|
195
|
-
* of the wire format is `classifyCallError`'s job, not this constructor's.
|
|
196
|
-
*/
|
|
197
|
-
readonly retryAfterMs: number | undefined;
|
|
198
|
-
/** Bounded schema findings for `invalid_args`; never submitted values. */
|
|
199
|
-
readonly validation: ArgumentValidationDetails | undefined;
|
|
200
|
-
|
|
201
|
-
constructor(
|
|
202
|
-
code: ConnectorCallErrorCode,
|
|
203
|
-
message: string,
|
|
204
|
-
opts: {
|
|
205
|
-
retryable?: boolean;
|
|
206
|
-
retryAfterMs?: number;
|
|
207
|
-
cause?: unknown;
|
|
208
|
-
validation?: ArgumentValidationDetails;
|
|
209
|
-
} = {},
|
|
210
|
-
) {
|
|
211
|
-
super(
|
|
212
|
-
message,
|
|
213
|
-
opts.cause !== undefined ? { cause: opts.cause } : undefined,
|
|
214
|
-
);
|
|
215
|
-
this.name = "ConnectorCallError";
|
|
216
|
-
this.code = code;
|
|
217
|
-
this.retryable = opts.retryable ?? RETRYABLE_BY_CODE[code];
|
|
218
|
-
this.retryAfterMs = normalizeRetryAfterMs(opts.retryAfterMs);
|
|
219
|
-
this.validation =
|
|
220
|
-
code === "invalid_args" ? boundedValidation(opts.validation) : undefined;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
/** The `error` object surfaced in value-mode call results and connecta.batch entries. */
|
|
225
|
-
export interface CallErrorDetails {
|
|
226
|
-
code: string;
|
|
227
|
-
message: string;
|
|
228
|
-
retryable: boolean;
|
|
229
|
-
/**
|
|
230
|
-
* Connector-reported wait window in ms, when known. Reported verbatim — the
|
|
231
|
-
* engine bounds how long it will itself wait, but the caller sees the real
|
|
232
|
-
* window so it can schedule a re-issue.
|
|
233
|
-
*/
|
|
234
|
-
retryAfterMs?: number;
|
|
235
|
-
/** Bounded input-schema findings; paths and expectations, never values. */
|
|
236
|
-
validation?: ArgumentValidationDetails;
|
|
237
|
-
/** Connector whose failed operation needs recovery. */
|
|
238
|
-
connector?: string;
|
|
239
|
-
/** Canonical downstream address the agent may retry after recovery. */
|
|
240
|
-
operation?: string;
|
|
241
|
-
/** Which safe recovery path `authorize_connector` will return. */
|
|
242
|
-
recovery?: AuthRecoveryMode;
|
|
243
|
-
/** The single model-facing entry point for every credential class. */
|
|
244
|
-
nextAction?: {
|
|
245
|
-
tool: "authorize_connector";
|
|
246
|
-
arguments: { connector: string };
|
|
247
|
-
operatorHandoff: string;
|
|
248
|
-
} | {
|
|
249
|
-
tool: "search_tools";
|
|
250
|
-
arguments: {
|
|
251
|
-
query: string;
|
|
252
|
-
connector?: string;
|
|
253
|
-
includeSchemas: "compact";
|
|
254
|
-
};
|
|
255
|
-
purpose: string;
|
|
256
|
-
} | {
|
|
257
|
-
tool: "call_destructive_tool";
|
|
258
|
-
arguments: {
|
|
259
|
-
address: string;
|
|
260
|
-
/**
|
|
261
|
-
* The caller's own arguments, echoed only when they fit
|
|
262
|
-
* {@link MAX_ECHOED_ARGS_BYTES} — and then whole, never clipped. Absent
|
|
263
|
-
* means "re-send exactly what you sent": a half-copied argument object
|
|
264
|
-
* routed into a human approval prompt would describe a call nobody made.
|
|
265
|
-
*/
|
|
266
|
-
args?: unknown;
|
|
267
|
-
};
|
|
268
|
-
purpose: string;
|
|
269
|
-
} | {
|
|
270
|
-
/**
|
|
271
|
-
* The same scoped discovery as the `search_tools` route above, addressed to
|
|
272
|
-
* a caller inside `execute_code`, which cannot call a tool. Which of the two
|
|
273
|
-
* a routing failure emits follows the route the caller took, not the
|
|
274
|
-
* deployment's advertised surface.
|
|
275
|
-
*/
|
|
276
|
-
function: "connecta.search";
|
|
277
|
-
arguments: {
|
|
278
|
-
query: string;
|
|
279
|
-
connector?: string;
|
|
280
|
-
includeSchemas: "compact";
|
|
281
|
-
};
|
|
282
|
-
purpose: string;
|
|
283
|
-
} | {
|
|
284
|
-
function: "connecta.call";
|
|
285
|
-
addresses: string[];
|
|
286
|
-
purpose: string;
|
|
287
|
-
};
|
|
288
|
-
/** Explicit retry guidance; recovery never retries or mutates by itself. */
|
|
289
|
-
retry?: string;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
/**
|
|
293
|
-
* Codes whose retryability is a fact about connecta's own framing, never a
|
|
294
|
-
* guess from text. The message embeds the address the caller asked for, so a
|
|
295
|
-
* connector named `svc-503` or `temporary-export` would otherwise flip a policy
|
|
296
|
-
* refusal into `retryable: true` through the heuristic below — and a caller that
|
|
297
|
-
* trusts the flag would cheerfully retry a refusal forever.
|
|
298
|
-
*/
|
|
299
|
-
const NEVER_RETRYABLE_FRAMING = new Set([
|
|
300
|
-
"unknown_address",
|
|
301
|
-
"unknown_tool",
|
|
302
|
-
"ambiguous_tool_alias",
|
|
303
|
-
"destructive_tool_requires_approval",
|
|
304
|
-
]);
|
|
305
|
-
|
|
306
|
-
/**
|
|
307
|
-
* Details for a failure connecta itself framed — an address it could not
|
|
308
|
-
* resolve, a tool it refuses to run — rather than one a connector threw.
|
|
309
|
-
*/
|
|
310
|
-
export function framingError(code: string, message: string): CallErrorDetails {
|
|
311
|
-
return {
|
|
312
|
-
code,
|
|
313
|
-
message,
|
|
314
|
-
retryable: NEVER_RETRYABLE_FRAMING.has(code)
|
|
315
|
-
? false
|
|
316
|
-
: messageLooksRetryable(message),
|
|
317
|
-
};
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
const RETRYABLE_MESSAGE_RE =
|
|
321
|
-
/timeout|timed out|econnreset|econnrefused|temporar|rate.?limit|429|502|503|504|refcountedcanceler|different request/i;
|
|
322
|
-
const TIMEOUT_MESSAGE_RE = /timed out|timeout/i;
|
|
323
|
-
|
|
324
|
-
/** Message-text fallback used when an error carries no typed classification. */
|
|
325
|
-
function messageLooksRetryable(message: string): boolean {
|
|
326
|
-
return RETRYABLE_MESSAGE_RE.test(message);
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
/**
|
|
330
|
-
* Classify a value thrown by a connector call. A `ConnectorCallError` is
|
|
331
|
-
* authoritative; anything else falls back to the historical message-text
|
|
332
|
-
* heuristic.
|
|
333
|
-
*/
|
|
334
|
-
export function classifyCallError(
|
|
335
|
-
err: unknown,
|
|
336
|
-
fallbackCode = "connector_call_failed",
|
|
337
|
-
): CallErrorDetails {
|
|
338
|
-
if (err instanceof ConnectorCallError) {
|
|
339
|
-
return {
|
|
340
|
-
code: err.code,
|
|
341
|
-
message: err.message,
|
|
342
|
-
retryable: err.retryable,
|
|
343
|
-
...(err.retryAfterMs !== undefined
|
|
344
|
-
? { retryAfterMs: err.retryAfterMs }
|
|
345
|
-
: {}),
|
|
346
|
-
...(err.validation ? { validation: err.validation } : {}),
|
|
347
|
-
};
|
|
348
|
-
}
|
|
349
|
-
// An aborted fetch rejects with a DOMException named "AbortError" whose
|
|
350
|
-
// message ("The operation was aborted", and variants across runtimes) matches
|
|
351
|
-
// neither heuristic below — so a call the engine itself cancelled would read
|
|
352
|
-
// as a non-retryable failure, the opposite of the truth. Note this also
|
|
353
|
-
// covers an abort the connector triggered for its own reasons; running out of
|
|
354
|
-
// time is by far the likelier cause and retryable/timeout is the safer read.
|
|
355
|
-
if (err instanceof Error && err.name === "AbortError") {
|
|
356
|
-
return { code: "timeout", message: err.message, retryable: true };
|
|
357
|
-
}
|
|
358
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
359
|
-
return {
|
|
360
|
-
code: TIMEOUT_MESSAGE_RE.test(message) ? "timeout" : fallbackCode,
|
|
361
|
-
message,
|
|
362
|
-
retryable: RETRYABLE_MESSAGE_RE.test(message),
|
|
363
|
-
};
|
|
364
|
-
}
|