@zackbart/connecta 0.37.1 → 0.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +31 -0
- package/README.md +2 -2
- package/bin/connecta.mjs +1 -39
- package/bin/version.mjs +1 -1
- package/dist/access-tokens.js +2 -4
- package/dist/agent-identity.js +1 -1
- package/dist/auth/clerk-sdk/generated.js +2 -1
- package/dist/auth/downstream-oauth.js +19 -153
- package/dist/auth/downstream-revocation.js +1 -1
- package/dist/auth/oauth-grant.js +11 -0
- package/dist/auth/oauth-token-response.js +1 -1
- package/dist/auth/vercel-agent.js +2 -1
- package/dist/auth-elicitation.js +2 -2
- package/dist/branding.d.ts +1 -15
- package/dist/branding.js +2 -2
- package/dist/bytes.js +42 -0
- package/dist/call-admission-context.js +2 -5
- package/dist/call-recovery.js +0 -3
- package/dist/catalog-fingerprint.js +2 -18
- package/dist/catalog-service.js +1 -1
- package/dist/config-defaults.d.ts +1 -0
- package/dist/config-defaults.js +1 -0
- package/dist/config-schema.d.ts +1 -1
- package/dist/config-schema.js +6 -2
- package/dist/config.d.ts +41 -14
- package/dist/config.js +21 -71
- package/dist/connectors/api-connector.js +4 -3
- package/dist/connectors/guarded-fetch.d.ts +0 -6
- package/dist/connectors/guarded-fetch.js +1 -11
- package/dist/connectors/remote-mcp.js +10 -43
- package/dist/connectors/resource-uri.js +0 -4
- package/dist/d1.d.ts +0 -89
- package/dist/d1.js +0 -34
- package/dist/downstream-input.js +2 -2
- package/dist/execute.js +22 -13
- package/dist/executor-result.js +2 -1
- package/dist/executors/quickjs-runtime.js +2 -25
- package/dist/executors/quickjs.js +1 -1
- package/dist/guest-runtime.js +5 -3
- package/dist/guest-types.d.ts +5 -5
- package/dist/http/client.js +1 -1
- package/dist/http/errors.js +2 -2
- package/dist/http/json-schema.js +1 -1
- package/dist/http/node-transport.js +0 -1
- package/dist/http/oauth.js +1 -1
- package/dist/http/paging.js +6 -9
- package/dist/http/provider.js +1 -1
- package/dist/http/safety.js +1 -1
- package/dist/http/services.js +1 -8
- package/dist/http/tools.js +1 -7
- package/dist/http/vendor.js +7 -7
- package/dist/identity.js +2 -6
- package/dist/invocation-auth.js +2 -1
- package/dist/meta-tools.js +27 -27
- package/dist/native-tools.js +2 -1
- package/dist/oauth-handoff.js +2 -2
- package/dist/operation-vocabulary.js +1 -1
- package/dist/operator-record.js +1 -49
- package/dist/operator-ui/contract.d.ts +2 -2
- package/dist/operator-ui/generated.js +3 -3
- package/dist/program-writes.js +3 -8
- package/dist/provider-call.js +0 -7
- package/dist/provider.d.ts +1 -1
- package/dist/providers/_shared/google/kit.js +1 -6
- package/dist/providers/_shared/google/service-account.js +1 -3
- package/dist/providers/_shared/google/workspace.d.ts +1 -1
- package/dist/providers/_shared/guide.js +3 -0
- package/dist/providers/_shared/json.js +12 -0
- package/dist/providers/_shared/rest/compact-index.js +1 -1
- package/dist/providers/_shared/rest/kit.js +1 -3
- package/dist/providers/_shared/rest/operation-index.js +1 -3
- package/dist/providers/_shared/rest/value-safety.js +26 -28
- package/dist/providers/breeze/api.js +2 -7
- package/dist/providers/breeze/index.js +4 -2
- package/dist/providers/breeze/tools.js +3 -4
- package/dist/providers/ccb/api.js +1 -6
- package/dist/providers/ccb/index.js +2 -1
- package/dist/providers/ccb/tools.js +1 -6
- package/dist/providers/cloudflare/api.js +2 -2
- package/dist/providers/cloudflare/index.js +2 -1
- package/dist/providers/cloudflare/safety.js +3 -3
- package/dist/providers/docs/tools.js +2 -10
- package/dist/providers/drive/tools.js +12 -25
- package/dist/providers/forms/tools.js +1 -9
- package/dist/providers/gmail/tools.js +5 -21
- package/dist/providers/overflow/api.js +1 -3
- package/dist/providers/overflow/index.js +2 -1
- package/dist/providers/overflow/tools.js +3 -7
- package/dist/providers/planning-center/api.js +2 -1
- package/dist/providers/planning-center/lib/constants.d.ts +1 -1
- package/dist/providers/planning-center/lib/json-api.js +1 -9
- package/dist/providers/planning-center/tools.js +2 -1
- package/dist/providers/sheets/tools.js +1 -9
- package/dist/providers/slides/tools.js +4 -13
- package/dist/providers/stripe/index.js +2 -1
- package/dist/providers/stripe/safety.js +2 -2
- package/dist/providers/tithely/api.js +2 -7
- package/dist/providers/tithely/index.js +3 -2
- package/dist/providers/tithely/tools.js +7 -5
- package/dist/providers/vercel/api.js +1 -6
- package/dist/providers/vercel/lib/pin.js +1 -1
- package/dist/providers/vercel/safety.js +1 -1
- package/dist/providers/vercel/tools.js +2 -1
- package/dist/redaction-marker.js +2 -2
- package/dist/registry.d.ts +1 -1
- package/dist/registry.js +5 -7
- package/dist/request-principal.js +1 -1
- package/dist/request-state.js +2 -2
- package/dist/routes/access-tokens.js +1 -1
- package/dist/routes/activity-disclosure.js +1 -1
- package/dist/routes/connect.js +2 -2
- package/dist/routes/credentials.js +1 -1
- package/dist/routes/mcp.js +4 -3
- package/dist/routes/oauth-management.js +1 -1
- package/dist/routes/operator.js +4 -3
- package/dist/routes/shared.d.ts +8 -8
- package/dist/routes/shared.js +9 -9
- package/dist/routes/ui-config.js +1 -1
- package/dist/routes/ui.js +1 -1
- package/dist/runtime/call-admission.js +1 -1
- package/dist/runtime/call.js +1 -1
- package/dist/runtime/settlement.js +1 -1
- package/dist/runtime/shared-read.js +2 -15
- package/dist/sent-secrets.d.ts +1 -2
- package/dist/sent-secrets.js +3 -8
- package/dist/server.js +4 -4
- package/dist/skills.js +8 -35
- package/dist/sqlite.d.ts +0 -19
- package/dist/sqlite.js +2 -83
- package/dist/storage/keys.js +16 -125
- package/dist/storage/sql-native.js +0 -101
- package/dist/storage/sql.d.ts +1 -24
- package/dist/storage/sql.js +1 -12
- package/dist/tool-error.js +4 -0
- package/dist/url-safety.js +0 -4
- package/dist/usage-guide.js +2 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/worker.js +1 -1
- package/documentation/README.md +6 -42
- package/documentation/architecture.md +86 -496
- package/documentation/auth.md +12 -25
- package/documentation/code-mode.md +90 -66
- package/documentation/deploying.md +19 -40
- package/documentation/integrating.md +4 -19
- package/documentation/meta-tools.md +6 -6
- package/documentation/migration-0.33.md +5 -5
- package/documentation/migration-0.34.md +2 -4
- package/documentation/migration-retired-layouts.md +74 -0
- package/documentation/operator-tests.md +19 -119
- package/documentation/operator-ui.md +3 -4
- package/documentation/provider-auth-migration.md +4 -10
- package/documentation/provider-migration-0.29.md +4 -15
- package/examples/worker/AGENTS.md +4 -6
- package/examples/worker/README.md +20 -115
- package/guides/connecting-agents.md +7 -30
- package/guides/how-it-works.md +2 -2
- package/guides/safety-and-trust.md +4 -1
- package/package.json +19 -19
- package/templates/node/README.md +9 -26
- package/templates/node/package.json +1 -1
- package/dist/auth/oauth-v2-migration.js +0 -135
- package/dist/provider-call-facts.d.ts +0 -115
- package/dist/provider-call.d.ts +0 -112
- package/dist/storage/d1-copy.js +0 -255
- package/dist/storage/sql-schema.d.ts +0 -6
- package/examples/worker/kv-to-d1.wrangler.jsonc +0 -26
- package/examples/worker/scripts/copy-kv-to-d1.mjs +0 -162
package/dist/meta-tools.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { toolError } from "./tool-error.js";
|
|
1
2
|
import { upwardStep } from "./upward.js";
|
|
2
3
|
import { authCall, authInvoke, authFlow, authMethod, authStorage, registerAuth } from "./auth/native.js";
|
|
3
4
|
import { registryProgram } from "./runtime/registry.js";
|
|
@@ -20,7 +21,7 @@ import { AUTHORIZE_OUTPUT, SEARCH_OUTPUT, SKILLS_OUTPUT } from "./meta-output.js
|
|
|
20
21
|
import { RESULT_TTL_SECONDS, resultKeys } from "./storage/keys.js";
|
|
21
22
|
import { agentOutputOperations, sentSecretsForRequest } from "./sent-secrets.js";
|
|
22
23
|
import { captureDownstreamInput } from "./downstream-input.js";
|
|
23
|
-
import { PROGRAM_RESULT_WIRE_BYTES } from "./program-result.js";
|
|
24
|
+
import { PROGRAM_RESULT_PAGE_BYTES, PROGRAM_RESULT_WIRE_BYTES } from "./program-result.js";
|
|
24
25
|
export { MAX_DESCRIBE_ADDRESSES, MAX_DISCOVERY_RESULT_BYTES, MAX_SEARCH_LIMIT };
|
|
25
26
|
const enc = new TextEncoder();
|
|
26
27
|
// Each page is a slice of payload bytes, so a leading U+FEFF is data.
|
|
@@ -37,15 +38,7 @@ function errorResult(message) {
|
|
|
37
38
|
return { content: [{ type: "text", text: message }], isError: true };
|
|
38
39
|
}
|
|
39
40
|
function discoveryErrorResult(error) {
|
|
40
|
-
|
|
41
|
-
error: {
|
|
42
|
-
code: error.code,
|
|
43
|
-
message: error.message,
|
|
44
|
-
retryable: false,
|
|
45
|
-
},
|
|
46
|
-
});
|
|
47
|
-
result.isError = true;
|
|
48
|
-
return result;
|
|
41
|
+
return toolError({ code: error.code, message: error.message, retryable: false });
|
|
49
42
|
}
|
|
50
43
|
const discoveryResult = function (operation, hint) {
|
|
51
44
|
return authFlow(function* () {
|
|
@@ -86,8 +79,8 @@ function isValidResultOffset(value) {
|
|
|
86
79
|
* Backwards, never forwards: re-serving a few bytes the caller already has is
|
|
87
80
|
* recoverable, silently skipping the rest of a character is not. Offsets the
|
|
88
81
|
* server itself produced (`nextOffset`) are already boundaries and come back
|
|
89
|
-
* unchanged, so this only moves an offset a client computed on its own
|
|
90
|
-
*
|
|
82
|
+
* unchanged, so this only moves an offset a client computed on its own.
|
|
83
|
+
* An offset at or past `bytes.length` is left alone — there is no
|
|
91
84
|
* character there to split.
|
|
92
85
|
*/
|
|
93
86
|
function alignStartToCharBoundary(bytes, offset) {
|
|
@@ -149,6 +142,15 @@ function base64Of(bytes) {
|
|
|
149
142
|
}
|
|
150
143
|
return out;
|
|
151
144
|
}
|
|
145
|
+
/**
|
|
146
|
+
* The page a notice's nextAction asks a program to read: it fits the program's
|
|
147
|
+
* return even if every byte escapes to six JSON characters, with room for the
|
|
148
|
+
* page envelope, and never asks for more than the stash or bridge will serve.
|
|
149
|
+
*/
|
|
150
|
+
function programPageBytes(results) {
|
|
151
|
+
const fits = Math.floor(((results.programChars ?? MAX_EXECUTE_RESULT_CHARS) - 1024) / 6);
|
|
152
|
+
return Math.max(4, Math.min(fits, results.cap, PROGRAM_RESULT_PAGE_BYTES));
|
|
153
|
+
}
|
|
152
154
|
/** Opens a write's notice, ahead of any paging instruction. */
|
|
153
155
|
const WRITE_ALREADY_RAN = "This write already ran: do not call it again to see its result.";
|
|
154
156
|
/** UTF-8 cannot represent lone UTF-16 surrogates without changing them. */
|
|
@@ -229,7 +231,7 @@ const stashResult = function (bytes, results, preview, rawText) {
|
|
|
229
231
|
try {
|
|
230
232
|
// Base64 permits byte-range decoding, and splitting the envelope across
|
|
231
233
|
// keys keeps a page's storage read proportional to the page instead of to
|
|
232
|
-
// the whole result
|
|
234
|
+
// the whole result. Chunk 0 carries the header; the connecta.result
|
|
233
235
|
// reader below maps a byte offset back to chunk index and base64 quad.
|
|
234
236
|
const chunkBytes = resultChunkBytes(totalBytes);
|
|
235
237
|
const binding = base64Of(enc.encode(JSON.stringify(results.binding)));
|
|
@@ -280,7 +282,7 @@ const stashResult = function (bytes, results, preview, rawText) {
|
|
|
280
282
|
// A byte may cost six JSON characters when escaped. Leave room for the
|
|
281
283
|
// result id, page counters, and continuation metadata in the returned page.
|
|
282
284
|
arguments: {
|
|
283
|
-
code: `async () => await connecta.result(${JSON.stringify(id)}, { offset: ${preview.kind === "prefix" ? preview.bytes : 0}, maxBytes: ${
|
|
285
|
+
code: `async () => await connecta.result(${JSON.stringify(id)}, { offset: ${preview.kind === "prefix" ? preview.bytes : 0}, maxBytes: ${programPageBytes(results)} })`,
|
|
284
286
|
},
|
|
285
287
|
},
|
|
286
288
|
};
|
|
@@ -325,10 +327,10 @@ const pageProgramResultNative = /* @__PURE__ */ registerAuth(pageProgramResult,
|
|
|
325
327
|
});
|
|
326
328
|
});
|
|
327
329
|
/** Program returns share the direct stash, with all host-admitted call dependencies. */
|
|
328
|
-
export function guardProgramReturn(value, registry, baseUrl, dependencies, secrets, logger, maxChars, completedWrite) {
|
|
329
|
-
return runEdge(guardProgramReturnNative(value, registry, baseUrl, dependencies, secrets, logger, maxChars, completedWrite));
|
|
330
|
+
export function guardProgramReturn(value, registry, baseUrl, dependencies, secrets, logger, maxChars, completedWrite, programChars) {
|
|
331
|
+
return runEdge(guardProgramReturnNative(value, registry, baseUrl, dependencies, secrets, logger, maxChars, completedWrite, programChars));
|
|
330
332
|
}
|
|
331
|
-
const guardProgramReturnNative = /* @__PURE__ */ registerAuth(guardProgramReturn, function (value, registry, baseUrl, dependencies, secrets, logger, maxChars, completedWrite) {
|
|
333
|
+
const guardProgramReturnNative = /* @__PURE__ */ registerAuth(guardProgramReturn, function (value, registry, baseUrl, dependencies, secrets, logger, maxChars, completedWrite, programChars) {
|
|
332
334
|
return authFlow(function* () {
|
|
333
335
|
const serialized = serializeResultText(value);
|
|
334
336
|
if (serialized.length <= maxChars)
|
|
@@ -347,6 +349,7 @@ const guardProgramReturnNative = /* @__PURE__ */ registerAuth(guardProgramReturn
|
|
|
347
349
|
},
|
|
348
350
|
write: completedWrite,
|
|
349
351
|
cap,
|
|
352
|
+
...(programChars !== undefined ? { programChars } : {}),
|
|
350
353
|
set: authMethod((id, chunks, ttl) => registryProgram(registry, "stashResult", id, chunks, ttl)),
|
|
351
354
|
warn: () => logFailure(logger, "result paging unavailable", failureRecord({})),
|
|
352
355
|
};
|
|
@@ -453,16 +456,11 @@ function escapedHeadOf(bytes, cap) {
|
|
|
453
456
|
* Bound a downstream MCP `content` array by `cap`.
|
|
454
457
|
*
|
|
455
458
|
* A lone text block is measured, stashed, previewed, and paged as its text:
|
|
456
|
-
* its envelope adds nothing but a wrapper and a second layer of JSON escaping
|
|
457
|
-
* which made a JSON payload's preview unreadable and inflated every page.
|
|
459
|
+
* its envelope adds nothing but a wrapper and a second layer of JSON escaping.
|
|
458
460
|
*
|
|
459
461
|
* Anything else is measured as the serialized envelope — the same string that
|
|
460
462
|
* gets stashed and paged, and the one that counts every block rather than only
|
|
461
|
-
* the text ones.
|
|
462
|
-
* meant an oversized all-image result scored zero bytes and was returned inline
|
|
463
|
-
* unbounded, with no `resultId` to page from; and measuring one string while
|
|
464
|
-
* truncating another left `totalBytes` describing something the cap was never
|
|
465
|
-
* compared against.
|
|
463
|
+
* the text ones. Measure the same representation that gets truncated and paged.
|
|
466
464
|
*
|
|
467
465
|
* Over the cap, what a client gets depends on whether a preview is usable.
|
|
468
466
|
* Several text blocks preview as their text joined by newlines, while
|
|
@@ -624,6 +622,7 @@ function metaToolsForRequest(registry, baseUrl, opts = {}) {
|
|
|
624
622
|
write: resolved.definition.classification !== "read",
|
|
625
623
|
cap,
|
|
626
624
|
...(opts.pagingTool ? { pagingTool: opts.pagingTool } : {}),
|
|
625
|
+
...(opts.maxProgramResultChars !== undefined ? { programChars: opts.maxProgramResultChars } : {}),
|
|
627
626
|
set: authMethod((id, value, ttlSeconds) => registryProgram(registry, "stashResult", id, value, ttlSeconds)),
|
|
628
627
|
// The catalog entry, never `toolName`: a record names a tool
|
|
629
628
|
// only through the grammar check (src/operator-record.ts).
|
|
@@ -670,7 +669,7 @@ function metaToolsForRequest(registry, baseUrl, opts = {}) {
|
|
|
670
669
|
const structuredRecovery = outcome.error.nextAction !== undefined;
|
|
671
670
|
const recoveryRequired = structuredRecovery ||
|
|
672
671
|
// Sanitized `unavailable` diagnostics ride the structured shape too;
|
|
673
|
-
// the plain-text path would drop them
|
|
672
|
+
// the plain-text path would drop them.
|
|
674
673
|
outcome.error.details !== undefined ||
|
|
675
674
|
// So does a conflict's `current`: where things stand is the retry.
|
|
676
675
|
outcome.error.current !== undefined ||
|
|
@@ -733,7 +732,7 @@ function metaToolsForRequest(registry, baseUrl, opts = {}) {
|
|
|
733
732
|
content: [
|
|
734
733
|
{
|
|
735
734
|
type: "text",
|
|
736
|
-
text:
|
|
735
|
+
text: "Available skills. Fetch one by exact name with this tool.\n\n" +
|
|
737
736
|
listing.map((skill) => `- \`${skill.name}\` — ${skill.description}`).join("\n"),
|
|
738
737
|
},
|
|
739
738
|
],
|
|
@@ -949,7 +948,7 @@ function metaToolsForRequest(registry, baseUrl, opts = {}) {
|
|
|
949
948
|
// client that computes its own offsets can land inside a multi-byte
|
|
950
949
|
// character, which would decode as U+FFFD; the offset actually served is
|
|
951
950
|
// the boundary at or before it, and it is what the response reports back
|
|
952
|
-
// as `offset
|
|
951
|
+
// as `offset`.
|
|
953
952
|
const offset = start + alignStartToCharBoundary(bytes, requestedOffset - start);
|
|
954
953
|
// Both sides of `maxBytes` are validated by now — the argument above, the
|
|
955
954
|
// cap at intake — so `offset + maxBytes` always reaches past `offset`.
|
|
@@ -1084,6 +1083,7 @@ const AUTHORIZE_INPUT = advertisedSchema(z.object({
|
|
|
1084
1083
|
*/
|
|
1085
1084
|
export function registerMetaTools(server, registry, ctx) {
|
|
1086
1085
|
const mt = createMetaTools(registry, ctx.baseUrl, {
|
|
1086
|
+
maxProgramResultChars: ctx.maxProgramResultChars,
|
|
1087
1087
|
...(ctx.native && !ctx.native.executeCode ? { pagingTool: "read_result" } : {}),
|
|
1088
1088
|
...(ctx.native ? { activitySource: "native" } : {}),
|
|
1089
1089
|
downstreamInput: Boolean(ctx.authElicitation),
|
package/dist/native-tools.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { bytesToHex } from "./bytes.js";
|
|
1
2
|
import { duringViewEffect } from "./runtime/call.js";
|
|
2
3
|
import { RequestScope, requestOwner } from "./runtime/request-scope.js";
|
|
3
4
|
import { Effect } from "effect";
|
|
@@ -35,7 +36,7 @@ function shortHash(text) {
|
|
|
35
36
|
const shortHashNative = /* @__PURE__ */ registerAuth(shortHash, function (text) {
|
|
36
37
|
return authFlow(function* () {
|
|
37
38
|
const digest = new Uint8Array(yield* upwardStep(authInvoke(crypto.subtle, "digest", ["SHA-256", enc.encode(text)])));
|
|
38
|
-
return
|
|
39
|
+
return bytesToHex(digest.subarray(0, HASH_CHARS / 2));
|
|
39
40
|
});
|
|
40
41
|
});
|
|
41
42
|
/**
|
package/dist/oauth-handoff.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { decodeBase64url } from "./bytes.js";
|
|
1
2
|
import { upwardStep } from "./upward.js";
|
|
2
3
|
import { authCall, authInvoke, authFlow, authStorage, registerAuth } from "./auth/native.js";
|
|
3
4
|
import { runEdge } from "./runtime/run.js";
|
|
@@ -58,8 +59,7 @@ function encodeSegment(value) {
|
|
|
58
59
|
function decodeSegment(value) {
|
|
59
60
|
if (!/^[A-Za-z0-9_-]+$/.test(value))
|
|
60
61
|
throw new Error("Invalid handoff encoding");
|
|
61
|
-
const
|
|
62
|
-
const decoded = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(Uint8Array.from(binary, (char) => char.charCodeAt(0)));
|
|
62
|
+
const decoded = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(decodeBase64url(value));
|
|
63
63
|
if (encodeSegment(decoded) !== value)
|
|
64
64
|
throw new Error("Noncanonical handoff encoding");
|
|
65
65
|
return decoded;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { lexicalSearchContent, lexicalQueryTerms } from "./catalog.js";
|
|
3
3
|
const tools = new WeakMap();
|
|
4
4
|
const connectors = new WeakMap();
|
|
5
|
-
|
|
5
|
+
const OPERATION_VOCABULARY_BOUNDS = {
|
|
6
6
|
operations: 8192,
|
|
7
7
|
rowChars: 1024,
|
|
8
8
|
chars: 2_097_152,
|
package/dist/operator-record.js
CHANGED
|
@@ -1,52 +1,4 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Web-API only — no node: imports here.
|
|
3
|
-
//
|
|
4
|
-
// Inbound identity-provider text never enters operator logs or status, even
|
|
5
|
-
// when it fits a grammar. Activity retains its separate typed actor fields.
|
|
6
|
-
//
|
|
7
|
-
// Threat model. INV-6 here covers records of calls and failures: logs,
|
|
8
|
-
// activity rows, status and statusFor, health, doctor output, and any native
|
|
9
|
-
// runtime output connecta triggers (workerd's console). Text a downstream
|
|
10
|
-
// server, HTTP API, or client authored, and anything derived from it, never
|
|
11
|
-
// reaches one as arbitrary text. Self-declared client name/version facts in
|
|
12
|
-
// activity use the bounded ASCII grammars in activityClientFact; invalid values are
|
|
13
|
-
// absent at recording, SQL write/read, and operator UI boundaries. Client
|
|
14
|
-
// capabilities and other metadata are never recorded. Every typed field
|
|
15
|
-
// connecta records is checked against a closed set or a grammar. Operator-
|
|
16
|
-
// authored code (custom connectors, plugin `status()`, decorators) is trusted
|
|
17
|
-
// to follow the contract, and connecta still checks
|
|
18
|
-
// the typed fields it records from it; deliberately adversarial operator code
|
|
19
|
-
// is out of scope.
|
|
20
|
-
//
|
|
21
|
-
// Catalog metadata a connector serves is configuration the operator chose to
|
|
22
|
-
// load, and agents already see it: a tool name that fits MCP's tool-name
|
|
23
|
-
// grammar, a description, and input and output schemas may appear in the
|
|
24
|
-
// authenticated operator page's catalog views, and such a name may be
|
|
25
|
-
// logged. A name outside the grammar is withheld everywhere operator-facing,
|
|
26
|
-
// the page included. Names containing C0, DEL, or C1 are dropped at catalog
|
|
27
|
-
// intake; spaces and non-ASCII names remain callable with withheld records.
|
|
28
|
-
//
|
|
29
|
-
// INV-6 says logs carry no arguments, results, code, or raw downstream error
|
|
30
|
-
// text. Filtering errors where they arise kept missing sources: a validator's
|
|
31
|
-
// diagnostic, a stream's TypeError, a JSON-RPC error the agent may see. So the
|
|
32
|
-
// rule is enforced here, at the sink. A failure reaches an operator only as
|
|
33
|
-
// the fields of a `FailureRecord`, which `failureRecord` alone builds: each
|
|
34
|
-
// one copied from an explicit list, checked against a constant table or a
|
|
35
|
-
// grammar, and never taken from an error's message, cause, stack, data,
|
|
36
|
-
// nested errors, or name. `logFailure` writes nothing else, and every status
|
|
37
|
-
// message about a failure comes from `describeFailure`
|
|
38
|
-
// (test/operator-record-sources.node.test.ts holds src/ to that).
|
|
39
|
-
//
|
|
40
|
-
// Provenance is by identity, never by shape. Text that merely looks like
|
|
41
|
-
// connecta's (an error named like one of its classes, a status sentence
|
|
42
|
-
// shaped like a record) carries no weight: a class label comes from the
|
|
43
|
-
// prototype chain, a status message from the status object connecta built.
|
|
44
|
-
//
|
|
45
|
-
// Agent-facing results are a different surface with a different rule: a
|
|
46
|
-
// downstream's own answer to a call may reach the agent that made it (see
|
|
47
|
-
// documentation/architecture.md, "Errors and records"). Core's sent-secrets
|
|
48
|
-
// boundary removes credentials used by the upstream request from those answers, including
|
|
49
|
-
// allowed diagnostics, tool results and nested error causes/data (INV-5).
|
|
1
|
+
// Payload-free operator failure records. See documentation/architecture.md, "Errors and records".
|
|
50
2
|
import { carryProviderFailure } from "./provider-call-facts.js";
|
|
51
3
|
import { followRedactedCopies, keepErrorName } from "./redaction-identity.js";
|
|
52
4
|
import { classificationCode, ConnectorCallError, NETWORK_ERROR_CODES, WithheldTextError, } from "./errors.js";
|
|
@@ -26,7 +26,7 @@ export interface OperatorConnectorOverlay {
|
|
|
26
26
|
/** Latest visible call in the bounded activity window, or null when unknown. */
|
|
27
27
|
lastCall: OperatorLastCall | null;
|
|
28
28
|
}
|
|
29
|
-
/** Whole connector access, or exact tool grants. `requireReadOnly` is always false since guarded grants were removed
|
|
29
|
+
/** Whole connector access, or exact tool grants. `requireReadOnly` is always false since guarded grants were removed. */
|
|
30
30
|
export interface OperatorGrant {
|
|
31
31
|
connectorId: string;
|
|
32
32
|
tools: "all" | Array<{
|
|
@@ -197,5 +197,5 @@ export interface OperatorUiContractV2 {
|
|
|
197
197
|
viewerKey: string;
|
|
198
198
|
};
|
|
199
199
|
}
|
|
200
|
-
/** The operator contract `GET /ui/api/config` serves; schema version 1 was removed
|
|
200
|
+
/** The operator contract `GET /ui/api/config` serves; schema version 1 was removed. */
|
|
201
201
|
export type OperatorUiContract = OperatorUiContractV2;
|