@zackbart/connecta 0.29.0 → 0.31.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 +99 -0
- package/README.md +126 -134
- package/bin/connecta.mjs +13 -2
- package/bin/version.mjs +1 -1
- package/dist/argument-redaction.js +230 -0
- package/dist/auth-elicitation.js +14 -9
- package/dist/authorization-handoff.js +111 -0
- package/dist/call-recovery.js +25 -0
- package/dist/catalog-cache.js +2 -2
- package/dist/catalog-service.js +103 -63
- package/dist/config-schema.d.ts +14 -7
- package/dist/config-schema.js +29 -10
- package/dist/config.d.ts +2 -0
- package/dist/config.js +12 -7
- package/dist/connectors/guarded-fetch.d.ts +9 -1
- package/dist/connectors/guarded-fetch.js +17 -5
- package/dist/connectors/negotiation-cache.js +1 -1
- package/dist/downstream-input-context.js +9 -0
- package/dist/downstream-input.js +13 -11
- package/dist/errors.d.ts +38 -12
- package/dist/errors.js +19 -9
- package/dist/execute.js +375 -43
- package/dist/executor-result.js +11 -9
- package/dist/executors/quickjs-child.js +12 -5
- package/dist/executors/quickjs-protocol.js +5 -6
- package/dist/executors/quickjs-runtime.js +6 -1
- package/dist/executors/quickjs.js +20 -4
- package/dist/guest-runtime.js +52 -2
- package/dist/guest-types.d.ts +47 -5
- package/dist/index.d.ts +1 -1
- package/dist/invocation.js +72 -14
- package/dist/meta-output.js +0 -15
- package/dist/meta-tools.js +166 -95
- package/dist/oauth-handoff.js +88 -11
- package/dist/operator-ui/generated.js +2 -2
- package/dist/operator-ui/view.d.ts +9 -0
- package/dist/operator-ui/view.js +11 -0
- package/dist/program-result.js +5 -0
- package/dist/program-writes.js +7 -48
- package/dist/provider.d.ts +8 -6
- package/dist/provider.js +3 -4
- package/dist/providers/_shared/google/workspace.d.ts +1 -1
- package/dist/providers/_shared/request-token.js +83 -0
- package/dist/providers/_shared/rest/dispatch.js +41 -0
- package/dist/providers/_shared/rest/operation-index.d.ts +133 -0
- package/dist/providers/_shared/rest/operation-index.js +527 -0
- package/dist/providers/_shared/rest/tools.d.ts +141 -0
- package/dist/providers/_shared/rest/tools.js +569 -0
- package/dist/providers/_shared/rest/value-safety.d.ts +151 -0
- package/dist/providers/_shared/rest/value-safety.js +580 -0
- package/dist/providers/cloudflare/graphql.js +385 -0
- package/dist/providers/cloudflare/index.d.ts +47 -51
- package/dist/providers/cloudflare/index.js +188 -1997
- package/dist/providers/cloudflare/openapi.generated.js +3347 -0
- package/dist/providers/cloudflare/rest.d.ts +37 -0
- package/dist/providers/cloudflare/rest.js +1056 -0
- package/dist/providers/cloudflare/skill.generated.js +7 -4
- package/dist/providers/cloudflare/value-safety.js +1247 -0
- package/dist/providers/infisical/index.d.ts +7 -0
- package/dist/providers/infisical/index.js +713 -0
- package/dist/providers/infisical/skill.generated.js +8 -0
- package/dist/providers/notion/index.d.ts +35 -31
- package/dist/providers/notion/index.js +60 -1499
- package/dist/providers/notion/openapi.generated.js +75 -0
- package/dist/providers/notion/rest.d.ts +24 -0
- package/dist/providers/notion/rest.js +1067 -0
- package/dist/providers/notion/skill.generated.js +5 -4
- package/dist/providers/notion/value-safety.js +31 -0
- package/dist/providers/stripe/index.d.ts +26 -20
- package/dist/providers/stripe/index.js +103 -130
- package/dist/providers/stripe/openapi.generated.js +649 -0
- package/dist/providers/stripe/rest.d.ts +14 -0
- package/dist/providers/stripe/rest.js +395 -0
- package/dist/providers/stripe/skill.generated.js +7 -5
- package/dist/providers/stripe/value-safety.js +705 -0
- package/dist/providers/vercel/index.d.ts +31 -22
- package/dist/providers/vercel/index.js +96 -853
- package/dist/providers/vercel/openapi.generated.js +456 -0
- package/dist/providers/vercel/rest.d.ts +20 -0
- package/dist/providers/vercel/rest.js +1002 -0
- package/dist/providers/vercel/skill.generated.js +4 -5
- package/dist/providers/vercel/value-safety.js +328 -0
- package/dist/registry.d.ts +8 -6
- package/dist/registry.js +134 -61
- package/dist/resource-read.js +4 -1
- package/dist/routes/mcp.js +11 -2
- package/dist/sent-secrets.d.ts +54 -13
- package/dist/sent-secrets.js +770 -231
- package/dist/skills.js +26 -16
- package/dist/sqlite.js +21 -6
- package/dist/storage/keys.js +20 -5
- package/dist/storage/memory.js +9 -4
- package/dist/storage/sql.js +18 -9
- package/dist/types.d.ts +17 -3
- package/dist/usage-guide.js +49 -40
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/worker.js +2 -1
- package/dist/write-outcome.js +47 -0
- package/documentation/README.md +64 -0
- package/documentation/architecture.md +241 -97
- package/documentation/auth.md +138 -5
- package/documentation/code-mode.md +224 -107
- package/documentation/deploying.md +146 -0
- package/documentation/integrating.md +170 -0
- package/documentation/meta-tools.md +142 -30
- package/documentation/operating.md +135 -0
- package/documentation/operator-tests.md +4 -0
- package/documentation/operator-ui.md +132 -0
- package/documentation/provider-auth-migration.md +307 -0
- package/documentation/provider-migration-0.29.md +22 -5
- package/examples/worker/README.md +9 -2
- package/package.json +9 -2
- package/templates/node/README.md +9 -2
- package/templates/node/package.json +1 -1
- package/dist/providers/vercel/mcp-ownership.js +0 -212
|
@@ -11,6 +11,26 @@ a third executor is implementable from this document alone.
|
|
|
11
11
|
[`meta-tools.md`](./meta-tools.md) owns the top-level tool contract, and clause
|
|
12
12
|
identifiers (`A1`, `E3`, …) are stable and cited by [Verification](#verification).
|
|
13
13
|
|
|
14
|
+
## Task routes
|
|
15
|
+
|
|
16
|
+
For normal endpoint work, start with [Operating an endpoint](./operating.md).
|
|
17
|
+
Use this reference for exact guest behavior or executor implementation.
|
|
18
|
+
[Agent index](./README.md) routes other work.
|
|
19
|
+
|
|
20
|
+
| Task | Sections |
|
|
21
|
+
| -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
22
|
+
| Wire a shipped or custom executor | [Deploy-time capability](#deploy-time-capability), [executor requirements](#what-an-executor-must-implement), [exceptions](#executor-exceptions) |
|
|
23
|
+
| Write a portable program | [Program form](#the-program), [addresses](#addressing), [guest functions](#the-surface) |
|
|
24
|
+
| Discover and call tools | [Search](#connectasearch), [describe](#connectadescribe), [call](#connectacall), [parallel calls](#parallel-calls) |
|
|
25
|
+
| Page results, load skills or read resources | [Result and skill](#connectaresult-and-connectaskill), [read](#connectaread), [projection](#results-and-projection) |
|
|
26
|
+
| Emit incremental output | [emit](#connectaemit), [emitted output](#emitted-output) |
|
|
27
|
+
| Handle errors, writes, or cancellation | [Errors](#errors), [retries](#retry-semantics), [limits](#cancellation-and-limits), [writes](#writes), [activity](#activity) |
|
|
28
|
+
| Change the contract or check executor parity | [Verification](#verification), then the tests indexed by clause |
|
|
29
|
+
|
|
30
|
+
Clause IDs remain stable, including retired IDs. Check current behavior against
|
|
31
|
+
source and the verification table; do not reuse a retired clause to introduce
|
|
32
|
+
new behavior.
|
|
33
|
+
|
|
14
34
|
## Deploy-time capability
|
|
15
35
|
|
|
16
36
|
The `executor` passed to `createConnecta()` is required. `tools/list` is exactly
|
|
@@ -333,11 +353,27 @@ const { data: run, format } = await connecta.call("ci.get_run", { runId: 42 });
|
|
|
333
353
|
**S5.** Takes a canonical address, optional arguments, and optional
|
|
334
354
|
`{ timeoutMs }`; the object form is `{ address, args?, timeoutMs? }`. A malformed
|
|
335
355
|
signature fails with `invalid_args` and both exact signatures, before discovery.
|
|
336
|
-
|
|
356
|
+
Normally returns `{ data, format: "json" | "text" }`. Oversized values may return
|
|
357
|
+
a `format: "paged"` handle for `connecta.result`, as described in `L6` below.
|
|
358
|
+
MCP `toolResult` or
|
|
337
359
|
`structuredContent` is JSON; all-text content is JSON when it parses, otherwise
|
|
338
360
|
text. API string values are text, other API values are JSON. Check `format`
|
|
339
361
|
before treating `data` as an object. A downstream `isError` throws.
|
|
340
362
|
|
|
363
|
+
An inline MCP result containing image, audio, resource, or resource_link blocks
|
|
364
|
+
also exposes `content?: GuestNativeBlock[]`, even when `data` comes from
|
|
365
|
+
`structuredContent` or `toolResult`. `data` keeps its existing shape.
|
|
366
|
+
`connecta.emit(result)` forwards all native blocks; iterating `result.content`
|
|
367
|
+
and calling `connecta.emit(block)` forwards selected blocks. Both forward the
|
|
368
|
+
host-retained originals, so guest edits do not change native output. Results
|
|
369
|
+
over the 1 MiB inline cap return paging handles without native content; page
|
|
370
|
+
and reduce them as described in `L6`. If only the native presentation is too
|
|
371
|
+
large or its transfer fails, `data` stays intact and `contentResult` carries
|
|
372
|
+
its paging handle or an unavailable-paging notice for presentation that exceeds
|
|
373
|
+
bounded traversal limits or is cyclic. When a result ID exists,
|
|
374
|
+
`connecta.result(result.contentResult)` pages the original MCP envelope;
|
|
375
|
+
`emit(result)` refuses with `result_too_large`.
|
|
376
|
+
|
|
341
377
|
**S6.** Every call goes through the same catalog, fail-closed read-only
|
|
342
378
|
predicate, admission, credential containment, timeout classification, health
|
|
343
379
|
accounting, and activity recording as an ordinary meta-tool call. The predicate
|
|
@@ -348,11 +384,14 @@ it can reach.
|
|
|
348
384
|
|
|
349
385
|
### connecta.result and connecta.skill
|
|
350
386
|
|
|
351
|
-
`await connecta.result(
|
|
352
|
-
result bound to the admitted subject, principal, endpoint/pool, request origin,
|
|
387
|
+
`await connecta.result(handleOrId, { page?, offset?, maxBytes? })` reads a stashed direct-call
|
|
388
|
+
or program-call result bound to the admitted subject, principal, endpoint/pool, request origin,
|
|
353
389
|
connector, and tool. It returns
|
|
354
390
|
`{ resultId, offset, bytes, totalBytes, hasMore, nextOffset?, format: "text", text }`.
|
|
355
|
-
Offsets and sizes are UTF-8 bytes
|
|
391
|
+
Offsets and sizes are UTF-8 bytes. Pages obey the original call's inline cap
|
|
392
|
+
and a 32 KiB bridge ceiling. `page` is zero-based and mutually exclusive with
|
|
393
|
+
`offset`; keep `maxBytes` fixed while incrementing pages. Nominal page windows
|
|
394
|
+
are at least four bytes wide and align both edges to UTF-8 boundaries.
|
|
356
395
|
Follow `nextOffset`, reassemble inside the program, and return a reduced value.
|
|
357
396
|
Before returning a page, the host rechecks current authentication, connector/tool
|
|
358
397
|
grants, pool membership, and endpoint trust against both the original and current
|
|
@@ -465,7 +504,9 @@ or upward proxy to programs. Native upward skill resources are separate
|
|
|
465
504
|
### connecta.emit
|
|
466
505
|
|
|
467
506
|
```js
|
|
468
|
-
await connecta.
|
|
507
|
+
const badge = await connecta.call("assets.get_badge_image", {});
|
|
508
|
+
connecta.emit(badge);
|
|
509
|
+
// Or: for (const block of badge.content ?? []) connecta.emit(block);
|
|
469
510
|
```
|
|
470
511
|
|
|
471
512
|
The rich-output channel, delivered after the JSON envelope on success. Its
|
|
@@ -477,17 +518,17 @@ clauses are [Emitted output](#emitted-output) (`M1`–`M10`).
|
|
|
477
518
|
caught or uncaught. Host-call budget exhaustion ends the host run and blocks host
|
|
478
519
|
access (`L4`); Workers guest computation may continue briefly until teardown (`X3`).
|
|
479
520
|
|
|
480
|
-
| Channel | Shape
|
|
481
|
-
| ------------------------------------------------------------------------- |
|
|
482
|
-
| A caught Connecta host failure | `Error` with `message`, `code`, `retryable`, and `details`
|
|
483
|
-
| An uncaught **tool, resource or discovery** failure, as the model sees it | `{ error: { code, message, retryable, … } }` with `isError`
|
|
484
|
-
| Program or execution failure (`E5`, `E6`, a bridge bound in `L6`) | `{ error: { code, message, retryable, details? } }`
|
|
521
|
+
| Channel | Shape | Typed? |
|
|
522
|
+
| ------------------------------------------------------------------------- | ------------------------------------------------------------------ | ------ |
|
|
523
|
+
| A caught Connecta host failure | `Error` with `message`, `code`, `retryable`, `data`, and `details` | yes |
|
|
524
|
+
| An uncaught **tool, resource or discovery** failure, as the model sees it | `{ error: { code, message, retryable, … } }` with `isError` | yes |
|
|
525
|
+
| Program or execution failure (`E5`, `E6`, a bridge bound in `L6`) | `{ error: { code, message, retryable, details? } }` | yes |
|
|
485
526
|
|
|
486
527
|
Both executor bridges rebuild typed host rejections as guest Errors and retain
|
|
487
528
|
their identity in executor-owned state (`X11`). `message` stays human text, capped at 2,000
|
|
488
529
|
JSON-serialized characters including quotes and an `…` marker when clipped.
|
|
489
|
-
`code` and `retryable` are the stable branch fields; `details`
|
|
490
|
-
classification
|
|
530
|
+
`code` and `retryable` are the stable branch fields; `data` and `details` carry the same host
|
|
531
|
+
classification, which fits 3,700 serialized characters. Optional recovery metadata
|
|
491
532
|
that would exceed that bound is omitted whole, preserving `code`, `message`,
|
|
492
533
|
`retryable`, and `retryAfterMs`, because a clipped recovery address or argument
|
|
493
534
|
describes a different call. This covers `call`, `read`, `search`, `describe`, `result`, `skill`, `emit`, and
|
|
@@ -497,6 +538,17 @@ HTTP(S) origin of at most 253 UTF-8 bytes, and `details.code`, a validated
|
|
|
497
538
|
network errno, undici transport code, or `timeout` of at most 32 bytes; neither
|
|
498
539
|
enters activity.
|
|
499
540
|
|
|
541
|
+
On hosts without URL elicitation, `connecta.call` auth failures carry `recovery`,
|
|
542
|
+
`nextAction`, and the handoff in `error.data`, also exposed as `error.details`.
|
|
543
|
+
An OAuth handoff includes `authorizationUrl` and `instructions`; operator
|
|
544
|
+
credential recovery includes `operatorUrl`, declared credential fields, and
|
|
545
|
+
instructions. `connecta.search` catalog errors and `connecta.describe`
|
|
546
|
+
`errorDetails` carry the same fields. When an auth error includes a handoff, give
|
|
547
|
+
it to the user or operator. One program run reuses one handoff per connector,
|
|
548
|
+
including concurrent call and catalog errors. Errors never request a forced
|
|
549
|
+
restart. Use `authorize_connector` for an explicit connection or a fresh link.
|
|
550
|
+
URL-elicitation hosts retain their existing flow.
|
|
551
|
+
|
|
500
552
|
**E2.** The taxonomy: `retryable` is what connecta reports, `Y3` what a program
|
|
501
553
|
may do. A provider maps each downstream failure to the code that tells the
|
|
502
554
|
caller what to do next, and never invents a cause it was not told.
|
|
@@ -533,8 +585,9 @@ and let the failure reach the model.
|
|
|
533
585
|
program unless the pool is trusted (`W12`). It is refused with
|
|
534
586
|
`destructive_tool_requires_approval` before validation and before anything is
|
|
535
587
|
sent, `nextAction` carrying its canonical address to `call_destructive_tool`
|
|
536
|
-
|
|
537
|
-
|
|
588
|
+
and a schema-filtered snapshot within the 512-byte echo budget. `argsRedacted`
|
|
589
|
+
marks partial or withheld arguments; use the original arguments if this flag is
|
|
590
|
+
set or `args` is absent. Snapshots are never clipped. The host's prompt on that
|
|
538
591
|
call is the approval, and the only one: generated code can neither mint the
|
|
539
592
|
capability nor approve its own write, and the model's short `reason` grants no
|
|
540
593
|
authority and never goes downstream.
|
|
@@ -606,33 +659,45 @@ fields. Program-authored projection saved bytes; host heuristics could drop
|
|
|
606
659
|
deliberately returned fields. Helpers need [#222](https://github.com/zackbart/connecta/issues/222)
|
|
607
660
|
evidence that programs fail to project.
|
|
608
661
|
|
|
609
|
-
**R2.** The boundary is 24,000 serialized characters (~6k tokens)
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
**
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
662
|
+
**R2.** The boundary is 24,000 serialized characters (~6k tokens), shared with
|
|
663
|
+
emitted text. An oversized return is stashed as compact JSON through the same
|
|
664
|
+
result store as direct calls. The returned notice carries `truncated`, `resultId`,
|
|
665
|
+
`totalBytes`, `hint`, `nextOffset: 0`, and an executable `nextAction` that pages
|
|
666
|
+
with `connecta.result`. It also retains `totalChars` and a bounded `preview`.
|
|
667
|
+
The recovery action and hint precede the preview, so clients that spill results
|
|
668
|
+
after the first 2,000 characters retain the handle and the instruction.
|
|
669
|
+
Small returns pass through unchanged; Connecta does not select fields.
|
|
670
|
+
|
|
671
|
+
**R3.** Truncation is a _successful_ result. The program completed and its full
|
|
672
|
+
return can be read without running it again. Prefer filtering or reducing reads
|
|
673
|
+
before returning them. If the run completed a write, the notice opens with
|
|
674
|
+
"This write already ran: do not call it again to see its result."
|
|
675
|
+
This warning uses host accounting for writes completed in this run. Paging an
|
|
676
|
+
earlier write result does not count as a new write.
|
|
677
|
+
|
|
678
|
+
**R4.** Program returns share direct-call stash envelopes, 15-minute expiry,
|
|
679
|
+
aggregate capacity charges, and credential redaction before persistence.
|
|
680
|
+
Their pages bind the admitted subject, principal, endpoint/pool, origin, and
|
|
681
|
+
all contributing tool calls, resource and skill reads, and catalog metadata.
|
|
682
|
+
Downstream skill and resource dependencies require a whole-connector grant.
|
|
683
|
+
Local guides and catalog dependencies require visibility of the contributing connector or tool, even
|
|
684
|
+
when the metadata describes a write on a read-only endpoint.
|
|
685
|
+
Caught call failures retain that connector visibility when catalog loading or
|
|
686
|
+
tool resolution fails. Recovery messages listing configured connectors or
|
|
687
|
+
local guides retain visibility of those contributors too.
|
|
688
|
+
Each page rechecks current auth,
|
|
689
|
+
grants, pool membership, and trust. Reading a stash inside a program carries
|
|
690
|
+
its dependencies forward to any new return stash. The page cap is the smallest
|
|
691
|
+
of the deployment cap and contributing connectors' effective `maxResultBytes`.
|
|
692
|
+
Read-only endpoints cannot page write results. A UUID is a handle, never a grant.
|
|
693
|
+
|
|
694
|
+
If paging is unavailable because the stash is full, storage fails, or text
|
|
695
|
+
cannot round-trip as UTF-8, the successful return keeps the existing bounded
|
|
696
|
+
`{ truncated, preview, totalChars, hint }` fallback. Its hint explains that
|
|
697
|
+
paging is unavailable and retains the instruction to filter/map/slice. A write's
|
|
698
|
+
hint still says it already ran. Never rerun a write to recover its output.
|
|
699
|
+
JSON serialization preserves lone surrogates as escapes, so ordinary
|
|
700
|
+
JSON-returning programs can page them losslessly.
|
|
636
701
|
|
|
637
702
|
**R5.** `console.log`, `console.warn`, and `console.error` are captured in call
|
|
638
703
|
order and returned as one `logs` string, capped at 4,000 characters with a
|
|
@@ -665,17 +730,37 @@ request; it is not activity, a session, or a stream.
|
|
|
665
730
|
|
|
666
731
|
## Emitted output
|
|
667
732
|
|
|
668
|
-
|
|
733
|
+
Guest-authored images accept only `image/png`, `image/jpeg`, `image/gif`, or `image/webp`
|
|
669
734
|
and nonempty canonical base64. Whitespace, URL-safe alphabets, bad padding,
|
|
670
735
|
and nonzero pad bits are rejected before collection. Size budgets still apply.
|
|
671
736
|
|
|
672
737
|
MCP-native output a return value cannot carry: base64 is not projectable, so a
|
|
673
|
-
block that
|
|
738
|
+
block that fits the inline call limit (`S5`, `L6`) can use the separate
|
|
739
|
+
emission transport budget instead of the `R2` return guard.
|
|
674
740
|
The earlier alternatives are in [decision history](https://github.com/zackbart/connecta/blob/main/decisions/0001-ethos-verdict-table.md)
|
|
675
741
|
([#267](https://github.com/zackbart/connecta/issues/267),
|
|
676
742
|
[#270](https://github.com/zackbart/connecta/issues/270)).
|
|
677
743
|
|
|
678
|
-
**M1.** `connecta.emit(
|
|
744
|
+
**M1.** `connecta.emit(result)` accepts a rich result from this program's
|
|
745
|
+
`connecta.call` and forwards its original native content blocks, including
|
|
746
|
+
resources, resource links, annotations and `_meta`. `connecta.emit(block)` also
|
|
747
|
+
accepts individual entries of that result's `content`. The trusted guest
|
|
748
|
+
prelude maps these objects to opaque request-local references; the host checks
|
|
749
|
+
those references and emits owned deep snapshots of retained native blocks taken
|
|
750
|
+
before result paging can yield. Oversized structured data returns its paging
|
|
751
|
+
handle before native presentation is inspected. Presentation traversal stops at
|
|
752
|
+
64 levels, 32,768 values, or the larger of the default and configured emission
|
|
753
|
+
byte budgets. Only envelopes within the 1 MiB inline cap retain block snapshots.
|
|
754
|
+
Cycles, non-JSON values, and traversal limits refuse presentation with an
|
|
755
|
+
unavailable-paging notice; structured data remains usable. That notice has no
|
|
756
|
+
result ID and reports `totalBytes: 0` because traversal could not measure a
|
|
757
|
+
complete JSON value.
|
|
758
|
+
Connector mutations after retention cannot change guest output, accepted blocks,
|
|
759
|
+
or their byte and text charges, including nested resource fields and metadata.
|
|
760
|
+
Copies and guest-authored blocks keep the strict validation below. No program
|
|
761
|
+
can mint a native URI.
|
|
762
|
+
|
|
763
|
+
Guest-authored `connecta.emit(block)` accepts exactly one block: `{ type: "text",
|
|
679
764
|
text }` or `{ type: "image" | "audio", data /* base64 */, mimeType }`, every
|
|
680
765
|
field a string, no extra fields, no `annotations`, no `_meta`, no sugar forms.
|
|
681
766
|
An invalid block throws catchably and nothing is accepted — rejected, not
|
|
@@ -692,6 +777,8 @@ presentation, not a second data channel.
|
|
|
692
777
|
serialized block size reduces the return budget, and oversized text fails with
|
|
693
778
|
`result_too_large`. Image/audio blocks use the separate transport budget and
|
|
694
779
|
reach the model as real MCP media content, including when `emit` is not awaited.
|
|
780
|
+
Native embedded resource text also shares the result cap; resource blobs count
|
|
781
|
+
against the serialized-byte emission budget.
|
|
695
782
|
The trusted runner waits for emission acknowledgments before returning success.
|
|
696
783
|
An unobserved emission failure fails the run; an awaited failure remains catchable.
|
|
697
784
|
Rejections propagated through `then` or `finally` can be caught later in that
|
|
@@ -703,7 +790,8 @@ chain. A separate unhandled branch still fails the run.
|
|
|
703
790
|
**M5.** Two budgets (`ConnectaConfig.execute.maxEmittedBytes` /
|
|
704
791
|
`.maxEmittedBlocks`, defaults 4,000,000 serialized bytes and 32 blocks) fail
|
|
705
792
|
loudly at the `emit` call, naming the budget and the room remaining; nothing is
|
|
706
|
-
partially accepted and prior blocks stand.
|
|
793
|
+
partially accepted and prior blocks stand. Forwarding a whole native result
|
|
794
|
+
checks every block before accepting any of them. Accepted and rejected emission attempts
|
|
707
795
|
also have a terminal limit of four times the configured block cap (at least 128),
|
|
708
796
|
which bounds retained host failures and guest acknowledgement state without
|
|
709
797
|
discarding an older error identity. No result stash for emitted blocks: the program
|
|
@@ -712,14 +800,15 @@ bound, not a context bound — emitted media reaches the model as media, not
|
|
|
712
800
|
base64 text.
|
|
713
801
|
|
|
714
802
|
**M6.** No provenance is claimed: every emitted block is program output, trusted
|
|
715
|
-
exactly as much as the return value.
|
|
716
|
-
downstream block,
|
|
803
|
+
exactly as much as the return value. Native forwarding preserves the raw
|
|
804
|
+
downstream block through a host-issued reference, within `S5`, `L6` and `M5`.
|
|
717
805
|
|
|
718
806
|
**M7.** `emit` alone spends no host-call budget (`L4`); `search`, `describe`,
|
|
719
807
|
`call`, `read`, `result`, and `skill` share it. Text also observes `R2`.
|
|
720
808
|
|
|
721
|
-
**M8.** `emit` is a provider function
|
|
722
|
-
|
|
809
|
+
**M8.** `emit` is a provider function. Guest-authored blocks cross as arguments;
|
|
810
|
+
native blocks cross once as call output and emissions send only their references.
|
|
811
|
+
Native call output uses the same bounded stash transfers as `L6`. `ExecuteResult` remains compatible with upstream codemode's types;
|
|
723
812
|
construction requires the Worker adapter or explicit custom opt-in. Any executor
|
|
724
813
|
that bridges provider calls gets emission for free.
|
|
725
814
|
|
|
@@ -834,13 +923,34 @@ the Dynamic Worker inherits the platform isolate's limits (`X2`). A third
|
|
|
834
923
|
executor must bound all three somehow — this is the clause that makes untrusted
|
|
835
924
|
code safe to run at all.
|
|
836
925
|
|
|
837
|
-
**L6.**
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
926
|
+
**L6.** QuickJS bounds each serialized host-call message at 256 KiB. Full guest
|
|
927
|
+
returns cross bounded 65,536-character IPC chunks, with a 64 MiB aggregate
|
|
928
|
+
transport ceiling. The parent retains the completed value until it can apply
|
|
929
|
+
the result stash policy; the 1 MiB per-message IPC ceiling stays in force. Oversized
|
|
930
|
+
`connecta.call` results use the existing direct-call stash before crossing that
|
|
931
|
+
bridge. The trusted guest initializer reconstructs values up to 1 MiB from
|
|
932
|
+
bounded pages, retaining JSON versus text format and every payload code point,
|
|
933
|
+
including U+FEFF at page starts. Larger values return a
|
|
934
|
+
`{ format: "paged", valueFormat, resultId, totalBytes, truncated: true, hint }`
|
|
935
|
+
handle. Pass the handle or its `resultId` to `connecta.result` and reduce the
|
|
936
|
+
pages before returning them. Automatic transfers spend no additional host-call
|
|
937
|
+
budget; explicit paging does. This policy is shared by QuickJS, Worker and custom
|
|
938
|
+
executors that run provider preludes.
|
|
939
|
+
Oversized raw text containing unpaired UTF-16 surrogates returns a handle without
|
|
940
|
+
`resultId`, with a notice that it cannot be paged as text. This preserves the
|
|
941
|
+
UTF-8 byte-offset contract without silently replacing code units. The completed
|
|
942
|
+
call stays successful, including write accounting; JSON-wrapped strings still
|
|
943
|
+
round-trip losslessly.
|
|
944
|
+
|
|
945
|
+
Stashes retain their existing bindings, 15-minute expiry, per-connector page
|
|
946
|
+
caps and aggregate capacity charges on memory, SQLite and D1. Capacity exhaustion
|
|
947
|
+
or a storage failure returns a successful notice without a `resultId`. A failed
|
|
948
|
+
automatic reconstruction retains the handle. Neither result path reissues the
|
|
949
|
+
call or changes a completed write into a failed or unknown write. Guest returns use the same store when they exceed the presentation cap (`R2`–`R4`).
|
|
950
|
+
|
|
951
|
+
Over-bound arguments and other unpaged bridge results still fail catchably with
|
|
952
|
+
executor-owned text. An over-bound result names the called address; an argument
|
|
953
|
+
payload is refused before parsing and names no address.
|
|
844
954
|
|
|
845
955
|
**L7.** Executions are admitted, not queued indefinitely: bounded concurrency
|
|
846
956
|
plus a bounded queue with a wait timeout. Overload is a retryable
|
|
@@ -948,6 +1058,15 @@ transport failure leaves the outcome unknown.
|
|
|
948
1058
|
addition to the host-call budget. It is checked after argument validation and
|
|
949
1059
|
before admission, so an over-budget write spends no permit.
|
|
950
1060
|
|
|
1061
|
+
Program `uncertainCall` and `uncertainCalls` use the same schema-filtered argument
|
|
1062
|
+
snapshots as direct calls, even when guest code catches the failure. `argsRedacted: true`
|
|
1063
|
+
means sensitive fields were omitted or the entire echo was withheld because
|
|
1064
|
+
sensitivity could not be resolved. `argsOmitted: true` means no `args` is present,
|
|
1065
|
+
including echoes above the byte budget. These fields identify targets for
|
|
1066
|
+
reconciliation. Any new call must use the original arguments when its echo is
|
|
1067
|
+
partial or absent. A returned `writes` count cannot make a run safe to repeat.
|
|
1068
|
+
See [argument echo rules](./meta-tools.md#echo-budgets) for supported schema shapes.
|
|
1069
|
+
|
|
951
1070
|
**W12.** `trusted` endpoints annotate `execute_code` as a write and permit
|
|
952
1071
|
program writes. `read-only` endpoints annotate it as read-only and refuse
|
|
953
1072
|
program writes before validation, with `call_destructive_tool` as the recovery.
|
|
@@ -1025,7 +1144,7 @@ reasonable demand on a platform sandbox.
|
|
|
1025
1144
|
values through a tagged envelope, so a `Uint8Array` may survive there. `P3` is
|
|
1026
1145
|
the contract: JSON-serializable values, or the program is Workers-only.
|
|
1027
1146
|
|
|
1028
|
-
**X8. Unknown properties.** The guest namespace exposes only the
|
|
1147
|
+
**X8. Unknown properties.** The guest namespace exposes only the seven documented
|
|
1029
1148
|
functions. Unknown and inherited members are absent on both executors; calling
|
|
1030
1149
|
one is a guest `TypeError` under `E6`. Engine message text is not contract.
|
|
1031
1150
|
|
|
@@ -1037,13 +1156,11 @@ Normalizing that would spend real CPU on every program to improve the error
|
|
|
1037
1156
|
message of a program that is already wrong. `P3` is the contract: neither
|
|
1038
1157
|
behavior returns the value.
|
|
1039
1158
|
|
|
1040
|
-
**X10. Per-host-call payload bound.** `L6`'s 256 KiB
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
one tool call therefore fails on Node and may succeed on Workers — reduce inside
|
|
1046
|
-
the program either way (`R1`).
|
|
1159
|
+
**X10. Per-host-call payload bound.** QuickJS enforces `L6`'s 256 KiB message
|
|
1160
|
+
ceiling at its IPC boundary. The Dynamic Worker uses Workers RPC limits.
|
|
1161
|
+
Connecta's shared program result policy keeps call results and result pages
|
|
1162
|
+
within the QuickJS message ceiling on every executor. It does not raise the
|
|
1163
|
+
argument limit or the guest's heap, CPU, execution, or returned-result limits.
|
|
1047
1164
|
|
|
1048
1165
|
**X12** described a paused sandbox and left with pausing
|
|
1049
1166
|
([#672](https://github.com/zackbart/connecta/issues/672)); the id stays retired.
|
|
@@ -1076,49 +1193,49 @@ Titles name clauses; executor-independent clauses run in both arms.
|
|
|
1076
1193
|
`test/codemode-compat.test.ts` pins upstream shape compatibility, minified upstream
|
|
1077
1194
|
rejection, and branded adapter acceptance across module copies.
|
|
1078
1195
|
|
|
1079
|
-
| Clauses
|
|
1080
|
-
|
|
|
1081
|
-
| `P1`, `P5`
|
|
1082
|
-
| `P2`, `X5`
|
|
1083
|
-
| `P3`, `X9`
|
|
1084
|
-
| `P4`
|
|
1085
|
-
| `A1`, `A2`
|
|
1086
|
-
| `S1`, `S1a`, `S2`
|
|
1087
|
-
| `S3`
|
|
1088
|
-
| `S4`
|
|
1089
|
-
| `S5`, `S6`
|
|
1090
|
-
| `S7`
|
|
1091
|
-
| `S8`, `E1`, `X11`
|
|
1092
|
-
| `S9`
|
|
1093
|
-
| `S10`
|
|
1094
|
-
| `E2`, `E8`
|
|
1095
|
-
| `E3`, `E4`
|
|
1096
|
-
| `E5`
|
|
1097
|
-
| `E6`, `X8`
|
|
1098
|
-
| `E7`
|
|
1099
|
-
| `R1`, `R2`, `R3`
|
|
1100
|
-
| `
|
|
1101
|
-
| `R5`
|
|
1102
|
-
| `R6`–`R8`
|
|
1103
|
-
| `Y1`, `Y2`, `Y3`
|
|
1104
|
-
| `Y4`
|
|
1105
|
-
| `L1`, `L2`
|
|
1106
|
-
| `L3`, `X1`
|
|
1107
|
-
| `L4`, `L8`
|
|
1108
|
-
| `L5`, `L7`, `X2`
|
|
1109
|
-
| `L6`, `X10`
|
|
1110
|
-
| `V1`–`V4`
|
|
1111
|
-
| `V5`, `W9`
|
|
1112
|
-
| `W10`, `W12`
|
|
1113
|
-
| `M1`
|
|
1114
|
-
| `M2`, `M3`
|
|
1115
|
-
| `M4`
|
|
1116
|
-
| `M5`, `M7`
|
|
1117
|
-
| `M8`
|
|
1118
|
-
| `M10`
|
|
1119
|
-
| `X4`
|
|
1120
|
-
| `X3`, `X6`
|
|
1121
|
-
| `X7`
|
|
1196
|
+
| Clauses | Test |
|
|
1197
|
+
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
1198
|
+
| `P1`, `P5` | both guest-contract executors (TypeScript syntax, trailing terminators, wrapper recovery), `test/program-source.test.ts` (which semicolons and wrappers are recovered), `test/quickjs-executor.node.test.ts` (`normalizeCode`) |
|
|
1199
|
+
| `P2`, `X5` | `test/guest-api-contract.test.ts` (Dynamic globals plus loader-only filesystem, HTTP, environment, egress, DNS, and local `data:` boundaries), `test/guest-api-contract-quickjs.node.test.ts` (exact absent globals and blocked imports), `test/quickjs-child-stderr.node.test.ts` (a child-process environment holding only `TZ=UTC`), `test/deployment-shapes.node.test.ts` (loader-only Worker construction) |
|
|
1200
|
+
| `P3`, `X9` | `test/guest-api-contract.test.ts`, `test/execute.test.ts` |
|
|
1201
|
+
| `P4` | `test/guest-api-contract.test.ts` (no cross-run leakage), `test/execute.test.ts` (one catalog load per connector per execution) |
|
|
1202
|
+
| `A1`, `A2` | `test/guest-api-contract.test.ts`, `test/execute.test.ts` (canonical addressing), `test/server.test.ts` (bounded live connector inventory) |
|
|
1203
|
+
| `S1`, `S1a`, `S2` | `test/guest-api-contract.test.ts` (flat page, connector guides, schema keys, unfiltered browse), `test/execute.test.ts` (guide pagination/partial/no-match behavior and `$ref`/`allOf`), `test/meta-tools-search.test.ts` (mixed complete/partial ranking, stable pagination, the two safety classes), `test/typescript-signatures.test.ts` (the TypeScript format over provider and pathological schemas, search/describe parity, observed labeling), `test/typescript-signatures-parse.node.test.ts` (every rendering parses) |
|
|
1204
|
+
| `S3` | `test/guest-api-contract.test.ts` (typed uncaught bound), `test/execute.test.ts` (count limits, fan-out bound) |
|
|
1205
|
+
| `S4` | both guest-contract executors (ordered mixed describe results with unknown-address, unknown-tool suggestion, and catalog-failure details), `test/meta-tools-search.test.ts` (top-level routing, no-suggestion, catalog-failure, and hostile-input bounds) |
|
|
1206
|
+
| `S5`, `S6` | `test/guest-api-contract.test.ts`, `test/execute.test.ts` (`unwrapMcpResult`, fail-closed annotations, activity parity) |
|
|
1207
|
+
| `S7` | `test/guest-api-contract.test.ts`, `test/execute.test.ts` (parallel calls and shared admission) |
|
|
1208
|
+
| `S8`, `E1`, `X11` | both guest-contract executors (caught call, discovery, utility, removed-function, and forgery cases; typed promise rejections), `test/quickjs-executor.node.test.ts` (oversized messages, private transport, forged outcomes) |
|
|
1209
|
+
| `S9` | `test/result-shapes.test.ts` (value exclusion, bounds, merging, LRU and time expiry, runtime isolation, read-only admission, declared precedence, definition invalidation, unwrapped MCP results, discovery provenance, copy isolation, failure isolation) |
|
|
1210
|
+
| `S10` | `test/resource-read.test.ts` (qualified routing, whole-connector grants, personal credentials, redaction, admission, timeout, cancellation and downstream MCP reads), both guest-contract executors (successful resource reads and caught/uncaught typed failures) |
|
|
1211
|
+
| `E2`, `E8` | `test/guest-api-contract.test.ts` (code → `retryable`, caught, parallel, and uncaught validation recovery, a conflict's bounded `current`), `test/meta-tools-call.test.ts` (direct, destructive, provider fallback), `test/validate.test.ts` (bounded payload-free findings), `test/errors.test.ts` |
|
|
1212
|
+
| `E3`, `E4` | `test/guest-api-contract.test.ts`, `test/execute.test.ts` (`auth_required`, destructive reroute), `test/program-writes.test.ts` (the refusal's `nextAction`, nothing sent, a caught refusal) |
|
|
1213
|
+
| `E5` | `test/guest-api-contract.test.ts` (execution-failure channel, in-flight `cancelled`), `test/execute.test.ts` (admission), `test/executor-admission.test.ts`, `test/quickjs-executor.node.test.ts` (mid-run shutdown) |
|
|
1214
|
+
| `E6`, `X8` | `test/guest-api-contract.test.ts` (unknown and inherited members, retained error identities), `test/quickjs-executor.node.test.ts` |
|
|
1215
|
+
| `E7` | `test/guest-api-contract.test.ts` (refusals about a `503`-named connector), `test/errors.test.ts` |
|
|
1216
|
+
| `R1`, `R2`, `R3`, `R4` | `test/guest-api-contract.test.ts` and `test/guest-api-contract-quickjs.node.test.ts` (small pass-through, shared return paging and unavailable fallback, no repeated writes, live authority), `test/program-result-cases.ts` (reconstruction, redaction, notice survives a 2,000-character spill) |
|
|
1217
|
+
| `M6`, `M9` | verdicts; `R2`'s guard, `M1`'s strict typing, and `M2`'s collect-then-deliver are their enforcement |
|
|
1218
|
+
| `R5` | `test/guest-api-contract.test.ts`, `test/quickjs-log-limits.node.test.ts` |
|
|
1219
|
+
| `R6`–`R8` | `test/guest-api-contract.test.ts` (normal result keys), `test/execute.test.ts` (opt-in operation aggregates, failure paths, payload exclusion) |
|
|
1220
|
+
| `Y1`, `Y2`, `Y3` | `test/guest-api-contract.test.ts` (one attempt per call, retryable flags by code) |
|
|
1221
|
+
| `Y4` | `test/meta-tools-call.test.ts`, `test/call-admission.test.ts` (one attempt, retry hints, caller reissue) |
|
|
1222
|
+
| `L1`, `L2` | `test/guest-api-contract.test.ts` (in-flight call fails `cancelled`), `test/execute.test.ts` (cancels outstanding host calls, discovery included, and refuses discovery after the run; a cancelled wedged executor, or one whose `acquire()` ignores the signal, returns promptly and releases its lease) |
|
|
1223
|
+
| `L3`, `X1` | `test/guest-api-contract.test.ts` (short-deadline executors), `test/execute.test.ts` (the watchdog ends a never-settling executor, frees the default pool, spares a slow run, and falls back from an unusable value) |
|
|
1224
|
+
| `L4`, `L8` | `test/guest-api-contract.test.ts`, `test/execute.test.ts` (shared discovery/call budgets and terminal catch-and-continue loops and queued-write cancellation on both executors), `test/worker-budget-response.node.test.ts` (native handle disposal and admission recovery across completed HTTP responses) |
|
|
1225
|
+
| `L5`, `L7`, `X2` | `test/quickjs-executor.node.test.ts` (CPU, heap), `test/execute.test.ts` and `test/executor-admission.test.ts` (bounded admission and queue) |
|
|
1226
|
+
| `L6`, `X10` | `test/guest-api-contract-quickjs.node.test.ts` and `test/guest-api-contract.test.ts` (whole oversized reads and one-write pageable handles), `test/sqlite-storage.node.test.ts` and `test/d1-storage.node.test.ts` (shared stash transfers), `test/quickjs-executor.node.test.ts` (bridge and IPC bounds for arguments and result; the address in the over-bound message), `test/quickjs-child-stderr.node.test.ts` (outer reply serialization failure settles the call) |
|
|
1227
|
+
| `V1`–`V4` | `test/guest-api-contract.test.ts` (dispatched calls, every refusal class including an address no connector owns, the friction each derives, no event for the execution itself), `test/activity.test.ts` (the shared code → friction table, the identity clamp, the one-attempt floor), `test/operator-view.test.ts`, `test/sql-storage-contract.ts`, run by `test/d1-storage.node.test.ts` and `test/sqlite-storage.node.test.ts` (historical pause and approval rows still render and round-trip) |
|
|
1228
|
+
| `V5`, `W9` | `test/program-writes.test.ts` (an unawaited trusted-pool write finished and recorded, its unknown outcome reported, counts on a failed program, the classification table), `test/invocation-pipeline.test.ts` (the gate after validation, an unrecorded refusal) |
|
|
1229
|
+
| `W10`, `W12` | `test/program-writes.test.ts` (a trusted-pool write runs and every other write keeps `E4`, the write budget, pool trust and override precedence, `call_tool` still refusing, search and describe verdicts, construction refusals), `test/operator-ui-model.test.ts`, `test/browser/operator-ui.spec.ts` (the badge) |
|
|
1230
|
+
| `M1` | `test/guest-api-contract.test.ts` (invalid emits throw catchably, accept nothing), `test/execute-emit.test.ts` (rejected shapes, bounded native snapshots, paging before metadata traversal, and cyclic presentation refusal) |
|
|
1231
|
+
| `M2`, `M3` | `test/guest-api-contract.test.ts` (delivery order, truncated return plus delivered blocks), `test/execute-emit.test.ts` (envelope, `structuredContent`, byte-for-byte no-emit path) |
|
|
1232
|
+
| `M4` | `test/guest-api-contract.test.ts` (discard is visible), `test/execute-emit.test.ts` (structured and plain paths), `test/quickjs-executor.node.test.ts` (mid-run shutdown) |
|
|
1233
|
+
| `M5`, `M7` | `test/execute-emit.test.ts` (both budgets fail the crossing block; host-call budget untouched) |
|
|
1234
|
+
| `M8` | two arms passing one case table, `test/codemode-compat.test.ts` |
|
|
1235
|
+
| `M10` | `test/execute-emit.test.ts` (aggregate present, numbers only, absent when nothing emitted) |
|
|
1236
|
+
| `X4` | `test/guest-api-contract.test.ts` (string logs only), `test/quickjs-executor.node.test.ts` (logs before cancellation), `test/quickjs-child-stderr.node.test.ts` (crash, shutdown, deadline, IPC failure, bounded parent retention), `test/quickjs-log-limits.node.test.ts` (unchanged successful logs) |
|
|
1237
|
+
| `X3`, `X6` | `test/quickjs-executor.node.test.ts` (cancels a running child, never-settling await), `test/execute.test.ts` (a wedged executor stops being awaited) |
|
|
1238
|
+
| `X7` | `P3`'s tests; the Workers superset is deliberately unused |
|
|
1122
1239
|
|
|
1123
1240
|
The surface itself is checked by `test/server.test.ts` (the exact six-tool list),
|
|
1124
1241
|
`test/code-first-surface.test.ts` (construction, executor, removed tools, copy, and size),
|