@zackbart/connecta 0.7.7 → 0.7.9

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.
Files changed (59) hide show
  1. package/CHANGELOG.md +88 -0
  2. package/dist/activity.d.ts +1 -1
  3. package/dist/activity.d.ts.map +1 -1
  4. package/dist/activity.js.map +1 -1
  5. package/dist/call-admission.d.ts +81 -0
  6. package/dist/call-admission.d.ts.map +1 -0
  7. package/dist/call-admission.js +339 -0
  8. package/dist/call-admission.js.map +1 -0
  9. package/dist/catalog.d.ts +5 -3
  10. package/dist/catalog.d.ts.map +1 -1
  11. package/dist/catalog.js +13 -4
  12. package/dist/catalog.js.map +1 -1
  13. package/dist/connectors/api.d.ts +3 -1
  14. package/dist/connectors/api.d.ts.map +1 -1
  15. package/dist/connectors/api.js +1 -0
  16. package/dist/connectors/api.js.map +1 -1
  17. package/dist/connectors/remote-mcp.d.ts +3 -1
  18. package/dist/connectors/remote-mcp.d.ts.map +1 -1
  19. package/dist/connectors/remote-mcp.js +1 -0
  20. package/dist/connectors/remote-mcp.js.map +1 -1
  21. package/dist/execute.d.ts.map +1 -1
  22. package/dist/execute.js +72 -30
  23. package/dist/execute.js.map +1 -1
  24. package/dist/index.d.ts +9 -2
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +2 -0
  27. package/dist/index.js.map +1 -1
  28. package/dist/meta-tools.d.ts +7 -4
  29. package/dist/meta-tools.d.ts.map +1 -1
  30. package/dist/meta-tools.js +212 -54
  31. package/dist/meta-tools.js.map +1 -1
  32. package/dist/registry.d.ts +37 -0
  33. package/dist/registry.d.ts.map +1 -1
  34. package/dist/registry.js +45 -2
  35. package/dist/registry.js.map +1 -1
  36. package/dist/server.d.ts.map +1 -1
  37. package/dist/server.js +5 -0
  38. package/dist/server.js.map +1 -1
  39. package/dist/types.d.ts +55 -0
  40. package/dist/types.d.ts.map +1 -1
  41. package/dist/ui.d.ts.map +1 -1
  42. package/dist/ui.js +8 -4
  43. package/dist/ui.js.map +1 -1
  44. package/dist/version.d.ts +1 -1
  45. package/dist/version.js +1 -1
  46. package/package.json +1 -1
  47. package/src/activity.ts +5 -1
  48. package/src/call-admission.ts +519 -0
  49. package/src/catalog.ts +24 -4
  50. package/src/connectors/api.ts +4 -0
  51. package/src/connectors/remote-mcp.ts +4 -0
  52. package/src/execute.ts +83 -35
  53. package/src/index.ts +14 -1
  54. package/src/meta-tools.ts +246 -70
  55. package/src/registry.ts +91 -1
  56. package/src/server.ts +5 -0
  57. package/src/types.ts +61 -0
  58. package/src/ui.ts +8 -4
  59. package/src/version.ts +1 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,94 @@
2
2
 
3
3
  All notable changes to this package are documented here.
4
4
 
5
+ ## 0.7.9 — 2026-07-28
6
+
7
+ 0.7.9 adds opt-in, connector-scoped admission for downstream tool calls. Direct
8
+ calls, batch children, and code-mode host calls to the same connector now share
9
+ one per-runtime limiter, including through toolkit-scoped views. Connectors
10
+ without a `callAdmission` policy behave as before. Dependencies, storage
11
+ formats, and package entrypoints are unchanged.
12
+
13
+ The policy is exact within one Node process or Worker isolate. Concurrency
14
+ limits fully contain one request's fan-out; rolling budgets remain best-effort
15
+ across multiple isolates, replicas, or restarts. This release deliberately
16
+ does not add a distributed coordinator.
17
+
18
+ ### Added
19
+
20
+ - **Connector-scoped downstream admission** (issue #138, PR #143).
21
+ `api()`, `remoteMcp()`, and custom connectors accept a plural-ready
22
+ `callAdmission.rules` policy. The single rule supported today can bound
23
+ concurrency, queue size and wait, and rolling-window calls, optionally
24
+ partitioned by a bounded operator-derived key.
25
+ - **Payload-free admission telemetry.** `/health` reports connector aggregates
26
+ for live partitions, active and queued calls, admission outcomes, and queue
27
+ waits without exposing partition keys, arguments, or results.
28
+ - **Explicit cancelled Activity outcomes.** Caller cancellation is represented
29
+ separately from provider errors and timeouts in the public Activity event
30
+ union, the operator UI, and the Worker D1 example.
31
+
32
+ ### Changed
33
+
34
+ - **Retries reacquire admission per attempt.** Backoff does not retain a
35
+ concurrency permit, and each actual retry consumes a fresh rolling-budget
36
+ entry. Short proactive `rate_limited` windows continue to use the existing
37
+ safe retry contract.
38
+ - **Queue and connector deadlines are separate.** `queueTimeoutMs` bounds only
39
+ permit wait; the per-attempt tool deadline begins after admission.
40
+ `diagnostics: true` reports the phases separately as `admissionMs` and
41
+ `connectorMs`.
42
+
43
+ ### Fixed
44
+
45
+ - **Caller cancellation no longer retries an abandoned attempt or degrades
46
+ connector health.** A call already cancelled avoids connector dispatch.
47
+ Queued cancellation still releases its place without spending a
48
+ rolling-budget entry, while active cancellation releases its permit and
49
+ records a non-retryable `cancelled` result.
50
+
51
+ ## 0.7.8 — 2026-07-28
52
+
53
+ 0.7.8 makes dependency-free tool discovery recover from natural-language
54
+ queries that contain more related terms than one catalog entry covers, and
55
+ closes the aggregate result-size gap in `batch_call`. Small batches, exact and
56
+ all-term search ranking, empty-query browsing, dependencies, storage formats,
57
+ and package entrypoints are unchanged.
58
+
59
+ Existing deployments gain an independent 100,000-byte final batch-envelope
60
+ boundary. Set `calls.maxBatchResultBytes` to another whole positive byte count
61
+ when needed. When the boundary is crossed, successful payloads move behind the
62
+ existing `get_result` page handle while ordered success/failure outcomes and
63
+ bounded failure details remain inline.
64
+
65
+ ### Added
66
+
67
+ - **An independent aggregate batch-result cap** (issue #139, PR #141).
68
+ `calls.maxBatchResultBytes` defaults to 100,000 bytes, is validated with the
69
+ ordinary result-cap rules, and applies after every child's global or
70
+ connector-level guard. The exact serialized `{ results, durationMs }`
71
+ envelope is stashed in the existing toolkit-aware result store and pages with
72
+ the same byte offsets and UTF-8 invariants as ordinary guarded results.
73
+
74
+ ### Changed
75
+
76
+ - **Lexical tool search recovers from over-specified queries** (issue #137,
77
+ PR #140). Exact, prefix, and all-term ranking remains the first stage. Only
78
+ when an entire scoped search has no match does dependency-free fallback rank
79
+ partial matches by term coverage, tool-name coverage, and stable catalog
80
+ order, marking the response with `matchMode: "partial"`. The behavior is
81
+ shared by `search_tools` and code mode's `connecta.search`; no-overlap
82
+ searches remain empty.
83
+
84
+ ### Fixed
85
+
86
+ - **`batch_call` can no longer multiply the inline result boundary by child
87
+ count** (issue #139, PR #141). The complete final envelope is measured before
88
+ emission. Oversized batches return a compact ordered outcome summary plus a
89
+ `get_result` handle, with partial failures still visible inline and successful
90
+ data available through paging. Below-cap batches retain their prior response
91
+ shape.
92
+
5
93
  ## 0.7.7 — 2026-07-27
6
94
 
7
95
  0.7.7 gives operators explicit downstream OAuth lifecycle controls, makes
@@ -1,6 +1,6 @@
1
1
  import type { Logger } from "./types.js";
2
2
  export type ActivityCallSource = "call_tool" | "call_destructive_tool" | "batch_call" | "execute_code";
3
- export type ActivityOutcome = "success" | "error" | "timeout";
3
+ export type ActivityOutcome = "success" | "error" | "timeout" | "cancelled";
4
4
  /**
5
5
  * Authenticated identity attached to an activity event. `id` is intentionally
6
6
  * optional: open deployments and shared bearer tokens cannot honestly identify
@@ -1 +1 @@
1
- {"version":3,"file":"activity.d.ts","sourceRoot":"","sources":["../src/activity.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"activity.d.ts","sourceRoot":"","sources":["../src/activity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC,MAAM,MAAM,kBAAkB,GAC1B,WAAW,GACX,uBAAuB,GACvB,YAAY,GACZ,cAAc,CAAC;AAEnB,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,OAAO,GACP,SAAS,GACT,WAAW,CAAC;AAEhB;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,aAAa,EAAE,CAAC,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,aAAa,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,OAAO,EAAE,eAAe,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,qBAAqB,EAAE,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,0EAA0E;AAC1E,MAAM,WAAW,iBAAkB,SAAQ,aAAa;IACtD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,qBAAqB,EAAE,OAAO,CAAC,GAAG;IACrE,KAAK,EAAE,iBAAiB,CAAC;CAC1B,CAAC;AAEF,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,iFAAiF;AACjF,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,KAAK,EAAE,qBAAqB,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5D;AAED,uEAAuE;AACvE,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,OAAO,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CAC1E;AAED,MAAM,WAAW,aAAc,SAAQ,YAAY;IACjD,IAAI,CAAC,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;CAC/B;AAED,iFAAiF;AACjF,qBAAa,0BAA2B,SAAQ,KAAK;IAC1C,IAAI,SAAgC;;CAK9C;AAED,MAAM,MAAM,gBAAgB,GAAG,CAC7B,KAAK,EAAE,aAAa,KACjB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEhC,gFAAgF;AAChF,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,aAAa,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;IAC5C,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,kBAAkB,GAAG,IAAI,CACnC,qBAAqB,EACnB,aAAa,GACb,UAAU,GACV,SAAS,GACT,QAAQ,GACR,SAAS,GACT,YAAY,GACZ,UAAU,GACV,WAAW,CACd,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,sBAAsB,GAAG,SAAS,EAC3C,KAAK,EAAE,kBAAkB,GACxB,IAAI,CAmCN"}
@@ -1 +1 @@
1
- {"version":3,"file":"activity.js","sourceRoot":"","sources":["../src/activity.ts"],"names":[],"mappings":"AA2FA,iFAAiF;AACjF,MAAM,OAAO,0BAA2B,SAAQ,KAAK;IAC1C,IAAI,GAAG,4BAA4B,CAAC;IAE7C;QACE,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACnC,CAAC;CACF;AA+BD;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAA2C,EAC3C,KAAyB;IAEzB,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,MAAM,KAAK,GAA0B;QACnC,aAAa,EAAE,CAAC;QAChB,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;QACvB,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACpC,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACrD,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACjD,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1D,UAAU,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI;QACnC,aAAa,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO;QACzC,GAAG,CAAC,OAAO,CAAC,YAAY;YACtB,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE;YACxC,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC/D,CAAC;IACF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM,IAAI,OAAQ,MAA2B,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YACvE,OAAO;QACT,CAAC;QACD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YACtD,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QACH,IAAI,OAAO,CAAC,KAAK;YAAE,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC5C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC;IAClE,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"activity.js","sourceRoot":"","sources":["../src/activity.ts"],"names":[],"mappings":"AA+FA,iFAAiF;AACjF,MAAM,OAAO,0BAA2B,SAAQ,KAAK;IAC1C,IAAI,GAAG,4BAA4B,CAAC;IAE7C;QACE,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACnC,CAAC;CACF;AA+BD;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAA2C,EAC3C,KAAyB;IAEzB,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,MAAM,KAAK,GAA0B;QACnC,aAAa,EAAE,CAAC;QAChB,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;QACvB,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACpC,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACrD,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACjD,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1D,UAAU,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI;QACnC,aAAa,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO;QACzC,GAAG,CAAC,OAAO,CAAC,YAAY;YACtB,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE;YACxC,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC/D,CAAC;IACF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM,IAAI,OAAQ,MAA2B,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YACvE,OAAO;QACT,CAAC;QACD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YACtD,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QACH,IAAI,OAAO,CAAC,KAAK;YAAE,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC5C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC;IAClE,CAAC;AACH,CAAC"}
@@ -0,0 +1,81 @@
1
+ import { ConnectorCallError } from "./errors.js";
2
+ import type { ConnectorCallAdmissionInput, ConnectorCallAdmissionPolicy } from "./types.js";
3
+ export type CallAdmissionFailureKind = "concurrency" | "budget" | "cancelled" | "closed" | "partition";
4
+ /**
5
+ * A locally-produced connector-call failure. Extending ConnectorCallError
6
+ * preserves the public error envelope while letting call paths avoid recording
7
+ * a refusal as evidence that the downstream provider is unhealthy.
8
+ */
9
+ export declare class CallAdmissionError extends ConnectorCallError {
10
+ readonly admissionKind: CallAdmissionFailureKind;
11
+ constructor(admissionKind: CallAdmissionFailureKind, code: ConstructorParameters<typeof ConnectorCallError>[0], message: string, opts?: ConstructorParameters<typeof ConnectorCallError>[2]);
12
+ }
13
+ export declare function isCallAdmissionError(error: unknown): error is CallAdmissionError;
14
+ export interface CallAdmissionPermit {
15
+ /** Time spent in the concurrency queue. Zero for immediate admission. */
16
+ readonly waitMs: number;
17
+ /** Idempotent. */
18
+ release(): void;
19
+ }
20
+ export interface ConnectorCallAdmissionSnapshot {
21
+ rules: number;
22
+ partitions: number;
23
+ active: number;
24
+ queued: number;
25
+ closed: boolean;
26
+ totals: {
27
+ admitted: number;
28
+ queued: number;
29
+ rejected: number;
30
+ rateLimited: number;
31
+ cancelled: number;
32
+ };
33
+ queueWaitMs: {
34
+ count: number;
35
+ total: number;
36
+ max: number;
37
+ };
38
+ }
39
+ /**
40
+ * Per-runtime, per-connector call admission. State contains only bounded
41
+ * partition keys, counters, timestamps, signals, and promise continuations;
42
+ * tool arguments never enter the controller.
43
+ */
44
+ export declare class ConnectorCallAdmissionController {
45
+ readonly connectorId: string;
46
+ private readonly maxConcurrency;
47
+ private readonly maxQueueSize;
48
+ private readonly queueTimeoutMs;
49
+ private readonly retryAfterMs;
50
+ private readonly maxPartitions;
51
+ private readonly budget;
52
+ private readonly partitionKey;
53
+ private readonly partitions;
54
+ private closed;
55
+ private admittedTotal;
56
+ private queuedTotal;
57
+ private rejectedTotal;
58
+ private rateLimitedTotal;
59
+ private cancelledTotal;
60
+ private queueWaitCount;
61
+ private queueWaitTotalMs;
62
+ private queueWaitMaxMs;
63
+ constructor(connectorId: string, policy: ConnectorCallAdmissionPolicy);
64
+ acquire(input: Readonly<ConnectorCallAdmissionInput> & {
65
+ signal?: AbortSignal;
66
+ }): Promise<CallAdmissionPermit>;
67
+ snapshot(): ConnectorCallAdmissionSnapshot;
68
+ close(): void;
69
+ private admit;
70
+ private pump;
71
+ private pruneBudget;
72
+ private budgetRetryAfterMs;
73
+ private evictIdlePartitions;
74
+ private maybeDeletePartition;
75
+ private removeWaiter;
76
+ private cleanupWaiter;
77
+ private concurrencyLimited;
78
+ private budgetLimited;
79
+ private cancelled;
80
+ }
81
+ //# sourceMappingURL=call-admission.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"call-admission.d.ts","sourceRoot":"","sources":["../src/call-admission.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,339 @@
1
+ import { ConnectorCallError } from "./errors.js";
2
+ const DEFAULT_MAX_QUEUE_SIZE = 32;
3
+ const DEFAULT_QUEUE_TIMEOUT_MS = 5_000;
4
+ const DEFAULT_RETRY_AFTER_MS = 1_000;
5
+ const DEFAULT_MAX_PARTITIONS = 1_024;
6
+ const MAX_PARTITION_KEY_BYTES = 128;
7
+ const DEFAULT_PARTITION_KEY = "";
8
+ const enc = new TextEncoder();
9
+ /**
10
+ * A locally-produced connector-call failure. Extending ConnectorCallError
11
+ * preserves the public error envelope while letting call paths avoid recording
12
+ * a refusal as evidence that the downstream provider is unhealthy.
13
+ */
14
+ export class CallAdmissionError extends ConnectorCallError {
15
+ admissionKind;
16
+ constructor(admissionKind, code, message, opts = {}) {
17
+ super(code, message, opts);
18
+ this.admissionKind = admissionKind;
19
+ this.name = "CallAdmissionError";
20
+ }
21
+ }
22
+ export function isCallAdmissionError(error) {
23
+ return error instanceof CallAdmissionError;
24
+ }
25
+ function positiveWhole(value, name) {
26
+ if (!Number.isFinite(value) || !Number.isInteger(value) || value < 1) {
27
+ throw new TypeError(`${name} must be a positive whole number.`);
28
+ }
29
+ return value;
30
+ }
31
+ function nonNegativeWhole(value, name) {
32
+ if (!Number.isFinite(value) || !Number.isInteger(value) || value < 0) {
33
+ throw new TypeError(`${name} must be a non-negative whole number.`);
34
+ }
35
+ return value;
36
+ }
37
+ /**
38
+ * Per-runtime, per-connector call admission. State contains only bounded
39
+ * partition keys, counters, timestamps, signals, and promise continuations;
40
+ * tool arguments never enter the controller.
41
+ */
42
+ export class ConnectorCallAdmissionController {
43
+ connectorId;
44
+ maxConcurrency;
45
+ maxQueueSize;
46
+ queueTimeoutMs;
47
+ retryAfterMs;
48
+ maxPartitions;
49
+ budget;
50
+ partitionKey;
51
+ partitions = new Map();
52
+ closed = false;
53
+ admittedTotal = 0;
54
+ queuedTotal = 0;
55
+ rejectedTotal = 0;
56
+ rateLimitedTotal = 0;
57
+ cancelledTotal = 0;
58
+ queueWaitCount = 0;
59
+ queueWaitTotalMs = 0;
60
+ queueWaitMaxMs = 0;
61
+ constructor(connectorId, policy) {
62
+ this.connectorId = connectorId;
63
+ if (!Array.isArray(policy.rules) || policy.rules.length !== 1) {
64
+ throw new TypeError(`connector "${connectorId}" callAdmission.rules must contain exactly one rule in this release.`);
65
+ }
66
+ const rule = policy.rules[0];
67
+ if (rule.maxConcurrency === undefined &&
68
+ rule.budget === undefined) {
69
+ throw new TypeError(`connector "${connectorId}" callAdmission rule must declare maxConcurrency or budget.`);
70
+ }
71
+ this.maxConcurrency =
72
+ rule.maxConcurrency === undefined
73
+ ? undefined
74
+ : positiveWhole(rule.maxConcurrency, `connector "${connectorId}" callAdmission maxConcurrency`);
75
+ if (this.maxConcurrency === undefined &&
76
+ (rule.maxQueueSize !== undefined ||
77
+ rule.queueTimeoutMs !== undefined ||
78
+ rule.retryAfterMs !== undefined)) {
79
+ throw new TypeError(`connector "${connectorId}" callAdmission queue settings require maxConcurrency.`);
80
+ }
81
+ this.maxQueueSize = nonNegativeWhole(rule.maxQueueSize ?? DEFAULT_MAX_QUEUE_SIZE, `connector "${connectorId}" callAdmission maxQueueSize`);
82
+ this.queueTimeoutMs = positiveWhole(rule.queueTimeoutMs ?? DEFAULT_QUEUE_TIMEOUT_MS, `connector "${connectorId}" callAdmission queueTimeoutMs`);
83
+ this.retryAfterMs = nonNegativeWhole(rule.retryAfterMs ?? DEFAULT_RETRY_AFTER_MS, `connector "${connectorId}" callAdmission retryAfterMs`);
84
+ this.maxPartitions = positiveWhole(policy.maxPartitions ?? DEFAULT_MAX_PARTITIONS, `connector "${connectorId}" callAdmission maxPartitions`);
85
+ if (rule.budget) {
86
+ if (rule.budget.kind !== "rolling-window") {
87
+ throw new TypeError(`connector "${connectorId}" callAdmission budget kind must be "rolling-window".`);
88
+ }
89
+ const maxCalls = positiveWhole(rule.budget.maxCalls, `connector "${connectorId}" callAdmission budget.maxCalls`);
90
+ const windowMs = positiveWhole(rule.budget.windowMs, `connector "${connectorId}" callAdmission budget.windowMs`);
91
+ this.budget = { maxCalls, windowMs };
92
+ }
93
+ else {
94
+ this.budget = undefined;
95
+ }
96
+ this.partitionKey = rule.partitionKey;
97
+ }
98
+ acquire(input) {
99
+ // Copy the signal out before constructing any waiter closure. Referencing
100
+ // `input` from a queued callback would retain its `args`, defeating the
101
+ // limiter's payload-free state contract.
102
+ const signal = input.signal;
103
+ if (this.closed) {
104
+ return Promise.reject(new CallAdmissionError("closed", "unavailable", `Connector "${this.connectorId}" call admission is closed.`));
105
+ }
106
+ if (signal?.aborted) {
107
+ this.cancelledTotal++;
108
+ return Promise.reject(this.cancelled(signal));
109
+ }
110
+ let key;
111
+ try {
112
+ key = this.partitionKey
113
+ ? this.partitionKey({
114
+ toolName: input.toolName,
115
+ args: input.args,
116
+ })
117
+ : DEFAULT_PARTITION_KEY;
118
+ }
119
+ catch (cause) {
120
+ this.rejectedTotal++;
121
+ return Promise.reject(new CallAdmissionError("partition", "connector_call_failed", `Connector "${this.connectorId}" call-admission partitionKey threw.`, { cause }));
122
+ }
123
+ if (typeof key !== "string" ||
124
+ enc.encode(key).length > MAX_PARTITION_KEY_BYTES) {
125
+ this.rejectedTotal++;
126
+ return Promise.reject(new CallAdmissionError("partition", "connector_call_failed", `Connector "${this.connectorId}" call-admission partitionKey must return a string of at most ${MAX_PARTITION_KEY_BYTES} UTF-8 bytes.`));
127
+ }
128
+ // A partition callback is operator code and may synchronously abort the
129
+ // caller. Recheck after it returns so that cancellation cannot consume a
130
+ // budget entry or concurrency slot.
131
+ if (signal?.aborted) {
132
+ this.cancelledTotal++;
133
+ return Promise.reject(this.cancelled(signal));
134
+ }
135
+ const now = Date.now();
136
+ let state = this.partitions.get(key);
137
+ if (!state) {
138
+ this.evictIdlePartitions(now);
139
+ if (this.partitions.size >= this.maxPartitions) {
140
+ this.rejectedTotal++;
141
+ return Promise.reject(new CallAdmissionError("partition", "rate_limited", `Connector "${this.connectorId}" call-admission partition capacity is exhausted.`, { retryAfterMs: this.retryAfterMs }));
142
+ }
143
+ state = {
144
+ active: 0,
145
+ waiters: [],
146
+ admittedAt: [],
147
+ };
148
+ this.partitions.set(key, state);
149
+ }
150
+ this.pruneBudget(state, now);
151
+ const budgetRetryAfterMs = this.budgetRetryAfterMs(state, now);
152
+ if (budgetRetryAfterMs !== undefined) {
153
+ this.rateLimitedTotal++;
154
+ return Promise.reject(this.budgetLimited(budgetRetryAfterMs));
155
+ }
156
+ if (this.maxConcurrency === undefined ||
157
+ state.active < this.maxConcurrency) {
158
+ return Promise.resolve(this.admit(state, now, 0));
159
+ }
160
+ if (state.waiters.length >= this.maxQueueSize) {
161
+ this.rejectedTotal++;
162
+ return Promise.reject(this.concurrencyLimited("queue is full"));
163
+ }
164
+ return new Promise((resolve, reject) => {
165
+ const waiter = {
166
+ queuedAt: now,
167
+ resolve,
168
+ reject,
169
+ ...(signal ? { signal } : {}),
170
+ };
171
+ waiter.onAbort = () => {
172
+ if (!this.removeWaiter(state, waiter))
173
+ return;
174
+ this.cleanupWaiter(waiter);
175
+ this.cancelledTotal++;
176
+ reject(this.cancelled(signal));
177
+ this.maybeDeletePartition(key, state, Date.now());
178
+ };
179
+ waiter.timer = setTimeout(() => {
180
+ if (!this.removeWaiter(state, waiter))
181
+ return;
182
+ this.cleanupWaiter(waiter);
183
+ this.rejectedTotal++;
184
+ reject(this.concurrencyLimited(`queue wait exceeded ${this.queueTimeoutMs}ms`));
185
+ this.maybeDeletePartition(key, state, Date.now());
186
+ }, this.queueTimeoutMs);
187
+ state.waiters.push(waiter);
188
+ this.queuedTotal++;
189
+ signal?.addEventListener("abort", waiter.onAbort, { once: true });
190
+ // Close the check-to-listener race: an abort before registration is not
191
+ // replayed by AbortSignal, so inspect it once after the waiter is fully
192
+ // removable and its timer is installed.
193
+ if (signal?.aborted)
194
+ waiter.onAbort();
195
+ });
196
+ }
197
+ snapshot() {
198
+ let active = 0;
199
+ let queued = 0;
200
+ for (const state of this.partitions.values()) {
201
+ active += state.active;
202
+ queued += state.waiters.length;
203
+ }
204
+ return {
205
+ rules: 1,
206
+ partitions: this.partitions.size,
207
+ active,
208
+ queued,
209
+ closed: this.closed,
210
+ totals: {
211
+ admitted: this.admittedTotal,
212
+ queued: this.queuedTotal,
213
+ rejected: this.rejectedTotal,
214
+ rateLimited: this.rateLimitedTotal,
215
+ cancelled: this.cancelledTotal,
216
+ },
217
+ queueWaitMs: {
218
+ count: this.queueWaitCount,
219
+ total: this.queueWaitTotalMs,
220
+ max: this.queueWaitMaxMs,
221
+ },
222
+ };
223
+ }
224
+ close() {
225
+ if (this.closed)
226
+ return;
227
+ this.closed = true;
228
+ for (const state of this.partitions.values()) {
229
+ for (const waiter of state.waiters.splice(0)) {
230
+ this.cleanupWaiter(waiter);
231
+ waiter.reject(new CallAdmissionError("closed", "unavailable", `Connector "${this.connectorId}" call admission is closed.`));
232
+ }
233
+ }
234
+ }
235
+ admit(state, now, waitMs) {
236
+ state.active++;
237
+ if (this.budget)
238
+ state.admittedAt.push(now);
239
+ this.admittedTotal++;
240
+ if (waitMs > 0) {
241
+ this.queueWaitCount++;
242
+ this.queueWaitTotalMs += waitMs;
243
+ this.queueWaitMaxMs = Math.max(this.queueWaitMaxMs, waitMs);
244
+ }
245
+ let released = false;
246
+ return {
247
+ waitMs,
248
+ release: () => {
249
+ if (released)
250
+ return;
251
+ released = true;
252
+ if (state.active > 0)
253
+ state.active--;
254
+ this.pump(state);
255
+ },
256
+ };
257
+ }
258
+ pump(state) {
259
+ if (this.closed || this.maxConcurrency === undefined)
260
+ return;
261
+ while (state.active < this.maxConcurrency &&
262
+ state.waiters.length > 0) {
263
+ const waiter = state.waiters.shift();
264
+ this.cleanupWaiter(waiter);
265
+ if (waiter.signal?.aborted) {
266
+ this.cancelledTotal++;
267
+ waiter.reject(this.cancelled(waiter.signal));
268
+ continue;
269
+ }
270
+ const now = Date.now();
271
+ this.pruneBudget(state, now);
272
+ const retryAfterMs = this.budgetRetryAfterMs(state, now);
273
+ if (retryAfterMs !== undefined) {
274
+ this.rateLimitedTotal++;
275
+ waiter.reject(this.budgetLimited(retryAfterMs));
276
+ continue;
277
+ }
278
+ const waitMs = Math.max(0, now - waiter.queuedAt);
279
+ waiter.resolve(this.admit(state, now, waitMs));
280
+ }
281
+ }
282
+ pruneBudget(state, now) {
283
+ const budget = this.budget;
284
+ if (!budget || state.admittedAt.length === 0)
285
+ return;
286
+ let expired = 0;
287
+ while (expired < state.admittedAt.length &&
288
+ state.admittedAt[expired] + budget.windowMs <= now) {
289
+ expired++;
290
+ }
291
+ if (expired > 0)
292
+ state.admittedAt.splice(0, expired);
293
+ }
294
+ budgetRetryAfterMs(state, now) {
295
+ const budget = this.budget;
296
+ if (!budget || state.admittedAt.length < budget.maxCalls) {
297
+ return undefined;
298
+ }
299
+ return Math.max(0, state.admittedAt[0] + budget.windowMs - now);
300
+ }
301
+ evictIdlePartitions(now) {
302
+ for (const [key, state] of this.partitions) {
303
+ this.pruneBudget(state, now);
304
+ this.maybeDeletePartition(key, state, now);
305
+ }
306
+ }
307
+ maybeDeletePartition(key, state, now) {
308
+ this.pruneBudget(state, now);
309
+ if (state.active === 0 &&
310
+ state.waiters.length === 0 &&
311
+ state.admittedAt.length === 0) {
312
+ this.partitions.delete(key);
313
+ }
314
+ }
315
+ removeWaiter(state, waiter) {
316
+ const index = state.waiters.indexOf(waiter);
317
+ if (index < 0)
318
+ return false;
319
+ state.waiters.splice(index, 1);
320
+ return true;
321
+ }
322
+ cleanupWaiter(waiter) {
323
+ if (waiter.timer !== undefined)
324
+ clearTimeout(waiter.timer);
325
+ if (waiter.onAbort) {
326
+ waiter.signal?.removeEventListener("abort", waiter.onAbort);
327
+ }
328
+ }
329
+ concurrencyLimited(reason) {
330
+ return new CallAdmissionError("concurrency", "rate_limited", `Connector "${this.connectorId}" call concurrency ${reason}.`, { retryAfterMs: this.retryAfterMs });
331
+ }
332
+ budgetLimited(retryAfterMs) {
333
+ return new CallAdmissionError("budget", "rate_limited", `Connector "${this.connectorId}" rolling call budget is exhausted.`, { retryAfterMs });
334
+ }
335
+ cancelled(signal) {
336
+ return new CallAdmissionError("cancelled", "timeout", `Connector "${this.connectorId}" call was cancelled before admission.`, { cause: signal.reason });
337
+ }
338
+ }
339
+ //# sourceMappingURL=call-admission.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"call-admission.js","sourceRoot":"","sources":["../src/call-admission.ts"],"names":[],"mappings":"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"}
package/dist/catalog.d.ts CHANGED
@@ -1,11 +1,13 @@
1
1
  import type { JsonSchema, ToolDef } from "./types.js";
2
2
  export declare function summarizeDescription(text: string | undefined, full: boolean): string | undefined;
3
- /** Rank a connector's tools while caching its normalized plain-data index. */
4
- export declare function rankTools(tools: ToolDef[], query: string): Array<{
3
+ export type LexicalMatchMode = "all" | "partial";
4
+ export interface RankedTool {
5
5
  tool: ToolDef;
6
6
  score: number;
7
7
  order: number;
8
- }>;
8
+ }
9
+ /** Rank a connector's tools while caching its normalized plain-data index. */
10
+ export declare function rankTools(tools: ToolDef[], query: string, mode?: LexicalMatchMode): RankedTool[];
9
11
  /** Render and cache a compact TypeScript-like representation of JSON Schema. */
10
12
  export declare function compactSchema(schema: JsonSchema): string;
11
13
  //# sourceMappingURL=catalog.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAItD,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,IAAI,EAAE,OAAO,GACZ,MAAM,GAAG,SAAS,CAMpB;AAiDD,8EAA8E;AAC9E,wBAAgB,SAAS,CACvB,KAAK,EAAE,OAAO,EAAE,EAChB,KAAK,EAAE,MAAM,GACZ,KAAK,CAAC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CASxD;AAuID,gFAAgF;AAChF,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAexD"}
1
+ {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAItD,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,IAAI,EAAE,OAAO,GACZ,MAAM,GAAG,SAAS,CAMpB;AAYD,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,SAAS,CAAC;AAEjD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAkDD,8EAA8E;AAC9E,wBAAgB,SAAS,CACvB,KAAK,EAAE,OAAO,EAAE,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,gBAAwB,GAC7B,UAAU,EAAE,CASd;AAuID,gFAAgF;AAChF,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAexD"}
package/dist/catalog.js CHANGED
@@ -25,12 +25,21 @@ function documentsFor(tools) {
25
25
  }
26
26
  return docs;
27
27
  }
28
- function scoreDocument(doc, phrase, terms) {
28
+ function scoreDocument(doc, phrase, terms, mode) {
29
29
  if (!phrase)
30
30
  return 0;
31
31
  const haystack = `${doc.name} ${doc.description}`;
32
- if (!terms.every((term) => haystack.includes(term)))
32
+ const matchedTerms = terms.filter((term) => haystack.includes(term));
33
+ if (mode === "all" && matchedTerms.length !== terms.length)
33
34
  return null;
35
+ if (mode === "partial") {
36
+ if (matchedTerms.length === 0)
37
+ return null;
38
+ const nameMatches = matchedTerms.filter((term) => doc.name.includes(term)).length;
39
+ // Coverage wins first, then the number of those terms found in the tool
40
+ // name. Catalog order breaks the remaining ties at the caller.
41
+ return matchedTerms.length * 1_000 + nameMatches;
42
+ }
34
43
  let score = 0;
35
44
  if (doc.name === phrase)
36
45
  score += 1_000;
@@ -51,12 +60,12 @@ function scoreDocument(doc, phrase, terms) {
51
60
  return score;
52
61
  }
53
62
  /** Rank a connector's tools while caching its normalized plain-data index. */
54
- export function rankTools(tools, query) {
63
+ export function rankTools(tools, query, mode = "all") {
55
64
  const phrase = normalized(query);
56
65
  const terms = phrase.split(/\s+/).filter(Boolean);
57
66
  const ranked = [];
58
67
  documentsFor(tools).forEach((doc, order) => {
59
- const score = scoreDocument(doc, phrase, terms);
68
+ const score = scoreDocument(doc, phrase, terms, mode);
60
69
  if (score !== null)
61
70
  ranked.push({ tool: doc.tool, score, order });
62
71
  });