ai-capability-framework 1.0.3 → 1.1.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 +42 -0
- package/README.md +38 -30
- package/ROADMAP.md +14 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +32 -1
- package/dist/discovery/bindings.d.ts +7 -0
- package/dist/discovery/bindings.d.ts.map +1 -0
- package/dist/discovery/bindings.js +24 -0
- package/dist/discovery/budget.d.ts +17 -0
- package/dist/discovery/budget.d.ts.map +1 -0
- package/dist/discovery/budget.js +77 -0
- package/dist/discovery/configuration.d.ts +10 -0
- package/dist/discovery/configuration.d.ts.map +1 -0
- package/dist/discovery/configuration.js +63 -0
- package/dist/discovery/corpus.d.ts +8 -0
- package/dist/discovery/corpus.d.ts.map +1 -0
- package/dist/discovery/corpus.js +64 -0
- package/dist/discovery/diagnostics.d.ts +15 -0
- package/dist/discovery/diagnostics.d.ts.map +1 -0
- package/dist/discovery/diagnostics.js +11 -0
- package/dist/discovery/discoverer.d.ts +23 -0
- package/dist/discovery/discoverer.d.ts.map +1 -0
- package/dist/discovery/discoverer.js +261 -0
- package/dist/discovery/embedding-configuration.d.ts +12 -0
- package/dist/discovery/embedding-configuration.d.ts.map +1 -0
- package/dist/discovery/embedding-configuration.js +81 -0
- package/dist/discovery/embedding-types.d.ts +75 -0
- package/dist/discovery/embedding-types.d.ts.map +1 -0
- package/dist/discovery/embedding-types.js +1 -0
- package/dist/discovery/embeddings.d.ts +38 -0
- package/dist/discovery/embeddings.d.ts.map +1 -0
- package/dist/discovery/embeddings.js +71 -0
- package/dist/discovery/evaluation-validation.d.ts +8 -0
- package/dist/discovery/evaluation-validation.d.ts.map +1 -0
- package/dist/discovery/evaluation-validation.js +19 -0
- package/dist/discovery/evaluation.d.ts +84 -0
- package/dist/discovery/evaluation.d.ts.map +1 -0
- package/dist/discovery/evaluation.js +310 -0
- package/dist/discovery/export.d.ts +14 -0
- package/dist/discovery/export.d.ts.map +1 -0
- package/dist/discovery/export.js +81 -0
- package/dist/discovery/facade.d.ts +82 -0
- package/dist/discovery/facade.d.ts.map +1 -0
- package/dist/discovery/facade.js +266 -0
- package/dist/discovery/fingerprint.d.ts +71 -0
- package/dist/discovery/fingerprint.d.ts.map +1 -0
- package/dist/discovery/fingerprint.js +67 -0
- package/dist/discovery/index-builder.d.ts +3 -0
- package/dist/discovery/index-builder.d.ts.map +1 -0
- package/dist/discovery/index-builder.js +129 -0
- package/dist/discovery/index-validation.d.ts +12 -0
- package/dist/discovery/index-validation.d.ts.map +1 -0
- package/dist/discovery/index-validation.js +117 -0
- package/dist/discovery/index.d.ts +32 -0
- package/dist/discovery/index.d.ts.map +1 -0
- package/dist/discovery/index.js +18 -0
- package/dist/discovery/json-snapshot.d.ts +3 -0
- package/dist/discovery/json-snapshot.d.ts.map +1 -0
- package/dist/discovery/json-snapshot.js +11 -0
- package/dist/discovery/lexical.d.ts +12 -0
- package/dist/discovery/lexical.d.ts.map +1 -0
- package/dist/discovery/lexical.js +26 -0
- package/dist/discovery/metadata.d.ts +4 -0
- package/dist/discovery/metadata.d.ts.map +1 -0
- package/dist/discovery/metadata.js +33 -0
- package/dist/discovery/ranking.d.ts +7 -0
- package/dist/discovery/ranking.d.ts.map +1 -0
- package/dist/discovery/ranking.js +68 -0
- package/dist/discovery/replay.d.ts +50 -0
- package/dist/discovery/replay.d.ts.map +1 -0
- package/dist/discovery/replay.js +175 -0
- package/dist/discovery/retrieval-policy.d.ts +5 -0
- package/dist/discovery/retrieval-policy.d.ts.map +1 -0
- package/dist/discovery/retrieval-policy.js +10 -0
- package/dist/discovery/router.d.ts +39 -0
- package/dist/discovery/router.d.ts.map +1 -0
- package/dist/discovery/router.js +98 -0
- package/dist/discovery/selection-attempt.d.ts +20 -0
- package/dist/discovery/selection-attempt.d.ts.map +1 -0
- package/dist/discovery/selection-attempt.js +39 -0
- package/dist/discovery/selection-cards.d.ts +12 -0
- package/dist/discovery/selection-cards.d.ts.map +1 -0
- package/dist/discovery/selection-cards.js +79 -0
- package/dist/discovery/selection-configuration.d.ts +18 -0
- package/dist/discovery/selection-configuration.d.ts.map +1 -0
- package/dist/discovery/selection-configuration.js +71 -0
- package/dist/discovery/selection-response.d.ts +13 -0
- package/dist/discovery/selection-response.d.ts.map +1 -0
- package/dist/discovery/selection-response.js +47 -0
- package/dist/discovery/selection-types.d.ts +18 -0
- package/dist/discovery/selection-types.d.ts.map +1 -0
- package/dist/discovery/selection-types.js +1 -0
- package/dist/discovery/selection.d.ts +6 -0
- package/dist/discovery/selection.d.ts.map +1 -0
- package/dist/discovery/selection.js +145 -0
- package/dist/discovery/types.d.ts +291 -0
- package/dist/discovery/types.d.ts.map +1 -0
- package/dist/discovery/types.js +1 -0
- package/dist/discovery/usage.d.ts +2 -0
- package/dist/discovery/usage.d.ts.map +1 -0
- package/dist/discovery/usage.js +1 -0
- package/dist/discovery/vectors.d.ts +5 -0
- package/dist/discovery/vectors.d.ts.map +1 -0
- package/dist/discovery/vectors.js +43 -0
- package/dist/discovery/versions.d.ts +37 -0
- package/dist/discovery/versions.d.ts.map +1 -0
- package/dist/discovery/versions.js +36 -0
- package/dist/evals-live/live-eval-runner.d.ts +1 -0
- package/dist/evals-live/live-eval-runner.d.ts.map +1 -1
- package/dist/evals-live/live-eval-runner.js +12 -1
- package/dist/evals-live/types.d.ts +3 -0
- package/dist/evals-live/types.d.ts.map +1 -1
- package/dist/generated/manifest-types.d.ts +3655 -0
- package/dist/generated/manifest-types.d.ts.map +1 -1
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +8 -0
- package/dist/mcp-server/server.d.ts.map +1 -1
- package/dist/mcp-server/server.js +11 -2
- package/dist/mcp-server/types.d.ts +4 -0
- package/dist/mcp-server/types.d.ts.map +1 -1
- package/dist/observability/redaction.d.ts.map +1 -1
- package/dist/observability/redaction.js +6 -2
- package/dist/observability/types.d.ts +1 -1
- package/dist/observability/types.d.ts.map +1 -1
- package/dist/openai/index.d.ts +2 -0
- package/dist/openai/index.d.ts.map +1 -1
- package/dist/openai/index.js +1 -0
- package/dist/openai/responses-runner.d.ts +1 -1
- package/dist/openai/responses-runner.d.ts.map +1 -1
- package/dist/openai/responses-runner.js +134 -7
- package/dist/openai/selection-client.d.ts +28 -0
- package/dist/openai/selection-client.d.ts.map +1 -0
- package/dist/openai/selection-client.js +95 -0
- package/dist/openai/tool-loop.js +1 -1
- package/dist/openai/types.d.ts +19 -2
- package/dist/openai/types.d.ts.map +1 -1
- package/dist/replay/discovery-snapshot.d.ts +10 -0
- package/dist/replay/discovery-snapshot.d.ts.map +1 -0
- package/dist/replay/discovery-snapshot.js +17 -0
- package/dist/replay/recorder.d.ts.map +1 -1
- package/dist/replay/recorder.js +4 -0
- package/dist/replay/redaction.js +5 -1
- package/dist/replay/replayer.d.ts.map +1 -1
- package/dist/replay/replayer.js +14 -1
- package/dist/replay/types.d.ts +3 -0
- package/dist/replay/types.d.ts.map +1 -1
- package/dist/replay/validation.d.ts.map +1 -1
- package/dist/replay/validation.js +6 -0
- package/dist/runtime/bounded-json.d.ts +4 -0
- package/dist/runtime/bounded-json.d.ts.map +1 -0
- package/dist/runtime/bounded-json.js +74 -0
- package/dist/runtime/eligibility.d.ts +4 -0
- package/dist/runtime/eligibility.d.ts.map +1 -0
- package/dist/runtime/eligibility.js +128 -0
- package/dist/runtime/index.d.ts +5 -1
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +2 -0
- package/dist/runtime/provider-attempt.d.ts +11 -0
- package/dist/runtime/provider-attempt.d.ts.map +1 -0
- package/dist/runtime/provider-attempt.js +221 -0
- package/dist/runtime/provider-run.d.ts +10 -0
- package/dist/runtime/provider-run.d.ts.map +1 -0
- package/dist/runtime/provider-run.js +123 -0
- package/dist/runtime/provider-stop.d.ts +9 -0
- package/dist/runtime/provider-stop.d.ts.map +1 -0
- package/dist/runtime/provider-stop.js +28 -0
- package/dist/runtime/provider-types.d.ts +189 -0
- package/dist/runtime/provider-types.d.ts.map +1 -0
- package/dist/runtime/provider-types.js +1 -0
- package/dist/runtime/provider-usage.d.ts +9 -0
- package/dist/runtime/provider-usage.d.ts.map +1 -0
- package/dist/runtime/provider-usage.js +69 -0
- package/dist/runtime/router.d.ts.map +1 -1
- package/dist/runtime/router.js +3 -118
- package/dist/runtime/types.d.ts +9 -0
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/validator.d.ts +3 -0
- package/dist/validator.d.ts.map +1 -1
- package/dist/validator.js +32 -0
- package/docs/api/public-api-policy.md +10 -0
- package/docs/api/stable-workflow.md +58 -0
- package/docs/api.md +7 -0
- package/docs/capability-manifests.md +24 -0
- package/docs/development.md +22 -0
- package/docs/discovery.md +186 -0
- package/docs/evals/discovery-live.md +199 -0
- package/docs/evals/discovery-qualification.md +158 -0
- package/docs/evals/overview.md +9 -0
- package/docs/getting-started/installation.md +11 -12
- package/docs/getting-started/openai-quickstart.md +16 -5
- package/docs/getting-started/provider-neutral-quickstart.md +247 -88
- package/docs/getting-started/quickstart.md +8 -30
- package/docs/index.md +10 -0
- package/docs/release.md +29 -5
- package/docs/runtime.md +27 -0
- package/docs/start-here.md +23 -134
- package/examples/12-capability-discovery-selection/README.md +346 -0
- package/examples/12-capability-discovery-selection/customer-cases.mjs +52 -0
- package/examples/12-capability-discovery-selection/customer-harness.mjs +91 -0
- package/examples/12-capability-discovery-selection/customer-request-example.mjs +320 -0
- package/examples/12-capability-discovery-selection/discovery-example.mjs +175 -0
- package/examples/12-capability-discovery-selection/discovery-fixtures/three-domains.suite.json +7887 -0
- package/examples/12-capability-discovery-selection/discovery-fixtures/three-domains.v2.suite.json +8167 -0
- package/examples/12-capability-discovery-selection/discovery-fixtures/three-domains.v3.suite.json +8342 -0
- package/examples/12-capability-discovery-selection/evaluation/application.mjs +305 -0
- package/examples/12-capability-discovery-selection/evaluation/campaign.mjs +248 -0
- package/examples/12-capability-discovery-selection/evaluation/clients.mjs +433 -0
- package/examples/12-capability-discovery-selection/evaluation/continuation.mjs +208 -0
- package/examples/12-capability-discovery-selection/evaluation/durable-budget.mjs +420 -0
- package/examples/12-capability-discovery-selection/evaluation/freeze.mjs +9 -0
- package/examples/12-capability-discovery-selection/evaluation/harness.mjs +618 -0
- package/examples/12-capability-discovery-selection/evaluation/mock-host.mjs +260 -0
- package/examples/12-capability-discovery-selection/evaluation/preflight.mjs +115 -0
- package/examples/12-capability-discovery-selection/evaluation/qualification-workflows.mjs +87 -0
- package/examples/12-capability-discovery-selection/evaluation/regrade.mjs +281 -0
- package/examples/12-capability-discovery-selection/evaluation/report.mjs +517 -0
- package/examples/12-capability-discovery-selection/evaluation/runner.mjs +613 -0
- package/examples/12-capability-discovery-selection/evaluation/saved-campaign.mjs +385 -0
- package/examples/12-capability-discovery-selection/evaluation/wording.mjs +115 -0
- package/examples/12-capability-discovery-selection/evaluation/workflow-application.mjs +378 -0
- package/examples/12-capability-discovery-selection/evaluation/workflow-cases.mjs +90 -0
- package/examples/12-capability-discovery-selection/evaluation-example.mjs +154 -0
- package/examples/12-capability-discovery-selection/hybrid-example.mjs +174 -0
- package/examples/12-capability-discovery-selection/mock-embeddings.mjs +101 -0
- package/examples/12-capability-discovery-selection/mock-selection.mjs +78 -0
- package/examples/12-capability-discovery-selection/pipeline-example.mjs +496 -0
- package/examples/12-capability-discovery-selection/retrieval-cases.mjs +31 -0
- package/examples/12-capability-discovery-selection/run-campaign-mock.mjs +40 -0
- package/examples/12-capability-discovery-selection/run-customer-mock.mjs +15 -0
- package/examples/12-capability-discovery-selection/run-evaluation-live.mjs +10 -0
- package/examples/12-capability-discovery-selection/run-evaluation-mock.mjs +3 -0
- package/examples/12-capability-discovery-selection/run-evaluation-regrade.mjs +71 -0
- package/examples/12-capability-discovery-selection/run-hybrid-mock.mjs +3 -0
- package/examples/12-capability-discovery-selection/run-mock.mjs +3 -0
- package/examples/12-capability-discovery-selection/run-pipeline-mock.mjs +2 -0
- package/examples/12-capability-discovery-selection/run-selector-mock.mjs +3 -0
- package/examples/12-capability-discovery-selection/selection-example.mjs +88 -0
- package/package.json +17 -4
- package/schemas/discovery/embedding-index.schema.json +71 -0
- package/schemas/discovery/eval-observations.schema.json +409 -0
- package/schemas/discovery/eval-suite.schema.json +375 -0
- package/schemas/discovery/metadata.schema.json +30 -0
- package/schemas/discovery/selection-response.schema.json +47 -0
- package/schemas/replay/discovery-snapshot.schema.json +335 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,48 @@ All notable public changes to AI Capability Framework are documented here.
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
## 1.1.0 - 2026-10-17
|
|
8
|
+
|
|
9
|
+
- Fixed the installed CLI's POSIX symlink entrypoint so `npx aicf` runs commands instead
|
|
10
|
+
of silently returning. Programmatic CLI imports remain side-effect-free.
|
|
11
|
+
|
|
12
|
+
- Stabilized the recommended lexical/native search-to-tool workflow and its named
|
|
13
|
+
runtime/provider contracts. Advanced APIs retain their documented maturity; hybrid
|
|
14
|
+
remains experimental and dedicated selection optional.
|
|
15
|
+
- Made installed-package onboarding primary, with a complete manifest and mock app
|
|
16
|
+
checked directly from the published documentation in fresh consumers.
|
|
17
|
+
- Corrected obsolete checkout-only guidance and a nonexistent registry-helper import.
|
|
18
|
+
Retrieval behavior, authorization, approval boundaries and model configuration are
|
|
19
|
+
unchanged. Frozen qualification evidence is reused without new live trials.
|
|
20
|
+
|
|
21
|
+
## 1.1.0-rc.1 - 2026-10-17
|
|
22
|
+
|
|
23
|
+
- Published discovery as release-candidate public, with lexical retrieval and ordinary
|
|
24
|
+
model tool selection as the recommended default. Dedicated selection is optional.
|
|
25
|
+
- Documented the tested synthetic configuration: both lexical modes qualify after a
|
|
26
|
+
separately versioned offline wording correction; hybrid remains experimental and
|
|
27
|
+
opt-in because its incremental-gain gate was not met. See the
|
|
28
|
+
[qualification report](docs/evals/discovery-qualification.md).
|
|
29
|
+
- Tightened registry-error handling and retained tag-only OIDC publication to next. No
|
|
30
|
+
model defaults, retrieval scoring or application deployment changed.
|
|
31
|
+
|
|
32
|
+
- Corrected the synthetic workflow app's planning, terminal dependency states and
|
|
33
|
+
response grading. Added versioned readiness fixtures, fresh qualification families,
|
|
34
|
+
and a remaining-budget continuation protocol. These offline changes preserve
|
|
35
|
+
historical live results and do not qualify a model or change framework defaults.
|
|
36
|
+
|
|
37
|
+
- Added scoped discovery evaluation reports, corrected versioned domain fixtures, and
|
|
38
|
+
opt-in live campaign tooling with durable budgets and independent per-mode gates.
|
|
39
|
+
Default invocation validates offline; synthetic campaign results do not qualify
|
|
40
|
+
models.
|
|
41
|
+
|
|
42
|
+
- Added the optional release-candidate discovery subpath with task search, reusable
|
|
43
|
+
task-bound routers, explicit hybrid retrieval and dedicated selection, shared-run
|
|
44
|
+
accounting, metadata tracing, and bounded replay. Default routing remains unchanged.
|
|
45
|
+
- Added portable no-key customer-request examples, public discovery schemas, and frozen
|
|
46
|
+
synthetic evaluation fixtures. Mock integration and offline metrics do not qualify
|
|
47
|
+
real-model retrieval or selection quality.
|
|
48
|
+
|
|
7
49
|
## 1.0.3 - 2026-09-07
|
|
8
50
|
|
|
9
51
|
- Updated the resolved `fast-uri` dependency to `3.1.7` to address the high-severity
|
package/README.md
CHANGED
|
@@ -110,40 +110,23 @@ In plain terms:
|
|
|
110
110
|
|
|
111
111
|
## Try It
|
|
112
112
|
|
|
113
|
-
|
|
113
|
+
Start in a new project:
|
|
114
114
|
|
|
115
|
-
```
|
|
116
|
-
npm
|
|
117
|
-
npm
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
Build the CLI and inspect the example registry:
|
|
121
|
-
|
|
122
|
-
```bash
|
|
123
|
-
npm run build
|
|
124
|
-
node dist/cli.js inspect examples
|
|
115
|
+
```sh
|
|
116
|
+
npm init -y
|
|
117
|
+
npm install ai-capability-framework
|
|
118
|
+
node node_modules/ai-capability-framework/examples/12-capability-discovery-selection/run-customer-mock.mjs
|
|
125
119
|
```
|
|
126
120
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
node dist/cli.js openai-tools examples --context examples/support/openai/context.support_agent.json
|
|
131
|
-
```
|
|
121
|
+
The mock flow reads a ticket, carries its order ID into refund preparation, and returns
|
|
122
|
+
a preview awaiting approval. It exposes no commit and makes no real provider calls. No
|
|
123
|
+
repository checkout, framework build or optional provider SDK is required.
|
|
132
124
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
Run deterministic evals:
|
|
140
|
-
|
|
141
|
-
```bash
|
|
142
|
-
node dist/cli.js eval examples --results examples/eval-results/public.results.passing.json
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
For expected output excerpts and what each command proves, use
|
|
146
|
-
[Start here](docs/start-here.md).
|
|
125
|
+
Follow the
|
|
126
|
+
[complete first-app walkthrough](docs/getting-started/provider-neutral-quickstart.md) to
|
|
127
|
+
author a capability, load a registry, register a handler and use the stable
|
|
128
|
+
lexical/native workflow. [Repository development](docs/development.md) has separate
|
|
129
|
+
build and validation commands.
|
|
147
130
|
|
|
148
131
|
## Documentation Map
|
|
149
132
|
|
|
@@ -297,3 +280,28 @@ certification is documented in
|
|
|
297
280
|
## License
|
|
298
281
|
|
|
299
282
|
MIT
|
|
283
|
+
|
|
284
|
+
## Find capabilities for a task
|
|
285
|
+
|
|
286
|
+
Install the stable framework:
|
|
287
|
+
|
|
288
|
+
```sh
|
|
289
|
+
npm install ai-capability-framework
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
Lexical retrieval with the ordinary model/tool loop is the recommended default. The
|
|
293
|
+
[qualification report](docs/evals/discovery-qualification.md) records the tested lexical
|
|
294
|
+
results and the unmet hybrid incremental-gain gate. Hybrid remains experimental and
|
|
295
|
+
opt-in; dedicated selection remains optional.
|
|
296
|
+
|
|
297
|
+
Use the [stable lexical/native workflow](docs/api/stable-workflow.md) and optional
|
|
298
|
+
[discovery API](docs/discovery.md) when your application AI decomposes a customer
|
|
299
|
+
request into tasks. Search each ready task and pass its result-bound router to the
|
|
300
|
+
ordinary model/tool loop. Lexical search needs only a registry, task IDs/text, and
|
|
301
|
+
existing runtime context. Hybrid retrieval and dedicated selection are optional and
|
|
302
|
+
require caller-supplied model access and budgets.
|
|
303
|
+
|
|
304
|
+
Run the
|
|
305
|
+
[complete customer-request example](examples/12-capability-discovery-selection/README.md)
|
|
306
|
+
with deterministic mocks and no provider key. Retrieval scores never authorize execution
|
|
307
|
+
or guarantee a suitable first candidate.
|
package/ROADMAP.md
CHANGED
|
@@ -24,3 +24,17 @@ signing implementation.
|
|
|
24
24
|
Future work should be driven by real adopter feedback and should preserve the same
|
|
25
25
|
architecture: AICF owns capability safety contracts and host applications own production
|
|
26
26
|
systems, credentials, side effects, and deployment.
|
|
27
|
+
|
|
28
|
+
## Capability Discovery
|
|
29
|
+
|
|
30
|
+
The stable lexical/native workflow supports application-produced tasks, eligible
|
|
31
|
+
shortlists, and ordinary model tool selection. Hybrid retrieval and dedicated selection
|
|
32
|
+
remain explicit. No-key examples, a frozen synthetic dataset, and packed consumer checks
|
|
33
|
+
cover integration. The tested synthetic configuration qualifies both lexical modes after
|
|
34
|
+
an offline wording correction. Lexical/native is recommended; hybrid remains
|
|
35
|
+
experimental because incremental benefit was not qualified. See the
|
|
36
|
+
[qualification report](docs/evals/discovery-qualification.md). Application-specific
|
|
37
|
+
qualification and adoption remain separate from framework publication. Normal npm
|
|
38
|
+
installation includes the stable workflow; advanced features retain their own maturity
|
|
39
|
+
labels. The active framework roadmap is complete when installed-package usability and
|
|
40
|
+
verified stable publication pass; application migrations are outside its scope.
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAwGA,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE;QAAE,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAC7C,MAAM,CAAC,EAAE;QAAE,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;CAC9C;AA4BD,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CA+SzF"}
|
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
3
|
+
import { realpathSync } from "node:fs";
|
|
3
4
|
import path from "node:path";
|
|
4
5
|
import { fileURLToPath } from "node:url";
|
|
5
6
|
import YAML from "yaml";
|
|
@@ -91,6 +92,31 @@ export async function runCli(argv, options = {}) {
|
|
|
91
92
|
const validation = validateManifests(loadResult.manifests);
|
|
92
93
|
const fixtureValidation = validatePublicFixtures(loadResult.fixtures);
|
|
93
94
|
const errors = [...loadResult.errors, ...validation.errors, ...fixtureValidation.errors];
|
|
95
|
+
if (!errors.length && loadResult.fixtures.some(fixture => fixture.kind === "discovery_eval_suite" || fixture.kind === "discovery_eval_observations")) {
|
|
96
|
+
const { validateDiscoveryEvaluationSuite, evaluateCapabilityDiscovery } = await import("./discovery/evaluation.js");
|
|
97
|
+
const suites = loadResult.fixtures.filter(fixture => fixture.kind === "discovery_eval_suite");
|
|
98
|
+
for (const fixture of suites) {
|
|
99
|
+
for (const diagnostic of validateDiscoveryEvaluationSuite(fixture.fixture)) {
|
|
100
|
+
errors.push({ code: "invalid_fixture", message: diagnostic.code, path: fixture.path, id: diagnostic.caseId });
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
for (const fixture of loadResult.fixtures.filter(fixture => fixture.kind === "discovery_eval_observations")) {
|
|
104
|
+
const observations = fixture.fixture;
|
|
105
|
+
const matches = suites.filter(candidate => candidate.fixture.id === observations.suite_id);
|
|
106
|
+
if (matches.length !== 1) {
|
|
107
|
+
errors.push({ code: "invalid_fixture", message: "discovery_evaluation_suite_required", path: fixture.path });
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
const suite = matches[0].fixture;
|
|
111
|
+
const registry = buildRegistry(suite.capabilities.map(manifest => ({ kind: "capability", manifest,
|
|
112
|
+
path: `synthetic/${manifest.id}.yaml`, absolutePath: `/synthetic/${manifest.id}.yaml` })));
|
|
113
|
+
const result = evaluateCapabilityDiscovery({ suite, registry, observations });
|
|
114
|
+
if (!result.valid)
|
|
115
|
+
for (const diagnostic of result.diagnostics) {
|
|
116
|
+
errors.push({ code: "invalid_fixture", message: diagnostic.code, path: fixture.path, id: diagnostic.caseId });
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
94
120
|
if (errors.length > 0) {
|
|
95
121
|
stderr.write(formatDiagnostics(errors));
|
|
96
122
|
return 1;
|
|
@@ -2140,5 +2166,10 @@ function isDirectCliRun() {
|
|
|
2140
2166
|
if (!invokedPath) {
|
|
2141
2167
|
return false;
|
|
2142
2168
|
}
|
|
2143
|
-
|
|
2169
|
+
try {
|
|
2170
|
+
return realpathSync(invokedPath) === realpathSync(fileURLToPath(import.meta.url));
|
|
2171
|
+
}
|
|
2172
|
+
catch {
|
|
2173
|
+
return false;
|
|
2174
|
+
}
|
|
2144
2175
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { CapabilityRouteRequest } from "../runtime/types.js";
|
|
2
|
+
export declare function captureEligibility(request: CapabilityRouteRequest): {
|
|
3
|
+
fingerprint: string;
|
|
4
|
+
eligible: import("../types.js").LoadedCapabilityManifest[];
|
|
5
|
+
excluded: import("../runtime/types.js").RuntimeCapabilitySlice["excluded"];
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=bindings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bindings.d.ts","sourceRoot":"","sources":["../../src/discovery/bindings.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAIlE,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,sBAAsB;;;;EAoBjE"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { filterEligibleCapabilities } from "../runtime/eligibility.js";
|
|
2
|
+
import { ordinalCompare } from "./corpus.js";
|
|
3
|
+
import { fingerprintDiscoveryValue } from "./fingerprint.js";
|
|
4
|
+
export function captureEligibility(request) {
|
|
5
|
+
const result = filterEligibleCapabilities(request);
|
|
6
|
+
const sorted = (values) => values === undefined ? null : [...new Set(values)].sort(ordinalCompare);
|
|
7
|
+
return {
|
|
8
|
+
...result,
|
|
9
|
+
fingerprint: fingerprintDiscoveryValue("eligibility", {
|
|
10
|
+
capabilities: result.eligible.map(({ manifest }) => ({
|
|
11
|
+
capabilityId: manifest.id, capabilityVersion: manifest.version,
|
|
12
|
+
exposedOperations: manifest.lifecycle.prepare ? ["select", "prepare"] : ["select"]
|
|
13
|
+
})).sort((left, right) => ordinalCompare(left.capabilityId, right.capabilityId)),
|
|
14
|
+
policy: {
|
|
15
|
+
allowedCapabilityTypes: sorted(request.allowedCapabilityTypes), allowedDomains: sorted(request.allowedDomains),
|
|
16
|
+
includeCapabilityIds: sorted(request.includeCapabilityIds), excludeCapabilityIds: sorted(request.excludeCapabilityIds),
|
|
17
|
+
maxRiskTier: request.maxRiskTier ?? request.builtContext.runtimeContext.autonomy.maxRiskTier,
|
|
18
|
+
includeRestricted: request.includeRestricted ?? false, includeDraft: request.includeDraft ?? false,
|
|
19
|
+
includeExperimental: request.includeExperimental ?? false, includeDeprecated: request.includeDeprecated ?? false,
|
|
20
|
+
includeDisabledForTests: request.includeDisabledForTests ?? false
|
|
21
|
+
}
|
|
22
|
+
})
|
|
23
|
+
};
|
|
24
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { BudgetPolicy } from "../controls/types.js";
|
|
2
|
+
import type { DiscoveryBudgetLedger } from "./types.js";
|
|
3
|
+
/** A host may supply its own ledger and existing budget policy instead. */
|
|
4
|
+
export interface DiscoveryBudgetScope {
|
|
5
|
+
ledger: DiscoveryBudgetLedger;
|
|
6
|
+
policy: BudgetPolicy;
|
|
7
|
+
}
|
|
8
|
+
export interface InMemoryDiscoveryBudgetOptions {
|
|
9
|
+
runId: string;
|
|
10
|
+
maxProviderCalls: number;
|
|
11
|
+
maxInputTokens: number;
|
|
12
|
+
maxEstimatedCost?: number;
|
|
13
|
+
maxOutputTokens?: number;
|
|
14
|
+
}
|
|
15
|
+
/** Single-process, single-run accounting. Outstanding and unknown consumption retain allowance. */
|
|
16
|
+
export declare function createInMemoryDiscoveryBudget(options: InMemoryDiscoveryBudgetOptions): DiscoveryBudgetScope;
|
|
17
|
+
//# sourceMappingURL=budget.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"budget.d.ts","sourceRoot":"","sources":["../../src/discovery/budget.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAe,MAAM,sBAAsB,CAAC;AAKtE,OAAO,KAAK,EAAE,qBAAqB,EAA6B,MAAM,YAAY,CAAC;AAGnF,2EAA2E;AAC3E,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,qBAAqB,CAAC;IAC9B,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,MAAM,WAAW,8BAA8B;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,mGAAmG;AACnG,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,8BAA8B,GAAG,oBAAoB,CAmE3G"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { hasOnlyKeys, isRecord, nonblank } from "./configuration.js";
|
|
2
|
+
import { DiscoveryError } from "./diagnostics.js";
|
|
3
|
+
import { nonnegative, positiveInteger } from "./embedding-configuration.js";
|
|
4
|
+
import { stopReason } from "./embeddings.js";
|
|
5
|
+
import { knownUsage } from "./usage.js";
|
|
6
|
+
/** Single-process, single-run accounting. Outstanding and unknown consumption retain allowance. */
|
|
7
|
+
export function createInMemoryDiscoveryBudget(options) {
|
|
8
|
+
if (!isRecord(options) || !hasOnlyKeys(options, ["runId", "maxProviderCalls", "maxInputTokens", "maxOutputTokens", "maxEstimatedCost"])
|
|
9
|
+
|| !nonblank(options.runId) || !positiveInteger(options.maxProviderCalls) || !positiveInteger(options.maxInputTokens)
|
|
10
|
+
|| options.maxOutputTokens !== undefined && !positiveInteger(options.maxOutputTokens)
|
|
11
|
+
|| options.maxEstimatedCost !== undefined && !nonnegative(options.maxEstimatedCost)) {
|
|
12
|
+
throw new DiscoveryError({ code: "invalid_configuration", message: "An in-memory budget requires a run ID and positive finite call and input-token limits." });
|
|
13
|
+
}
|
|
14
|
+
const runId = options.runId;
|
|
15
|
+
const policy = Object.freeze({
|
|
16
|
+
id: "discovery.in-memory.v1", scope: Object.freeze({ type: "global" }), mode: "hard",
|
|
17
|
+
maxProviderCallsPerRun: options.maxProviderCalls, maxInputTokensPerRun: options.maxInputTokens,
|
|
18
|
+
...(options.maxOutputTokens === undefined ? {} : { maxOutputTokensPerRun: options.maxOutputTokens }),
|
|
19
|
+
...(options.maxEstimatedCost === undefined ? {} : { maxEstimatedCostPerRun: options.maxEstimatedCost })
|
|
20
|
+
});
|
|
21
|
+
const pending = new Map();
|
|
22
|
+
const charged = { providerCalls: 0, inputTokens: 0, outputTokens: 0, estimatedCost: 0 };
|
|
23
|
+
const held = { providerCalls: 0, inputTokens: 0, outputTokens: 0, estimatedCost: 0 };
|
|
24
|
+
let sequence = 0;
|
|
25
|
+
const ledger = {
|
|
26
|
+
async reserve(input) {
|
|
27
|
+
const denied = () => ({ status: "denied", diagnostic: {
|
|
28
|
+
code: "budget_denied", message: "The in-memory run budget denied this reservation."
|
|
29
|
+
} });
|
|
30
|
+
const usage = input.requestedUsage;
|
|
31
|
+
if (input.runId !== runId || !nonblank(input.requestId) || !Number.isFinite(input.deadlineAt)
|
|
32
|
+
|| stopReason(input) || !isRecord(usage) || !positiveInteger(usage.providerCalls)
|
|
33
|
+
|| !positiveInteger(usage.inputTokens)
|
|
34
|
+
|| usage.outputTokens !== undefined && (typeof usage.outputTokens !== "number" || !Number.isSafeInteger(usage.outputTokens) || usage.outputTokens < 0)
|
|
35
|
+
|| policy.maxOutputTokensPerRun !== undefined && !["embedding_build", "query_embedding"].includes(input.stage) && !positiveInteger(usage.outputTokens)
|
|
36
|
+
|| usage.estimatedCost !== undefined && !nonnegative(usage.estimatedCost)
|
|
37
|
+
|| policy.maxEstimatedCostPerRun !== undefined && usage.estimatedCost === undefined)
|
|
38
|
+
return denied();
|
|
39
|
+
const amounts = { providerCalls: usage.providerCalls, inputTokens: usage.inputTokens, outputTokens: usage.outputTokens ?? 0, estimatedCost: usage.estimatedCost ?? 0 };
|
|
40
|
+
if (charged.providerCalls + held.providerCalls + amounts.providerCalls > policy.maxProviderCallsPerRun
|
|
41
|
+
|| charged.inputTokens + held.inputTokens + amounts.inputTokens > policy.maxInputTokensPerRun
|
|
42
|
+
|| policy.maxOutputTokensPerRun !== undefined && charged.outputTokens + held.outputTokens + amounts.outputTokens > policy.maxOutputTokensPerRun
|
|
43
|
+
|| policy.maxEstimatedCostPerRun !== undefined
|
|
44
|
+
&& charged.estimatedCost + held.estimatedCost + amounts.estimatedCost > policy.maxEstimatedCostPerRun)
|
|
45
|
+
return denied();
|
|
46
|
+
// No await between checking capacity and recording the reservation.
|
|
47
|
+
const id = "discovery-reservation-" + ++sequence;
|
|
48
|
+
pending.set(id, amounts);
|
|
49
|
+
for (const key of ["providerCalls", "inputTokens", "outputTokens", "estimatedCost"])
|
|
50
|
+
held[key] += amounts[key];
|
|
51
|
+
return { status: "reserved", reservationId: id };
|
|
52
|
+
},
|
|
53
|
+
async settle(id, result) {
|
|
54
|
+
const reserved = pending.get(id);
|
|
55
|
+
if (!reserved || !isRecord(result) || !Number.isSafeInteger(result.providerAttempts) || result.providerAttempts < 0
|
|
56
|
+
|| !Number.isSafeInteger(result.completedResponses) || result.completedResponses < 0
|
|
57
|
+
|| !["completed", "failed", "cancelled", "discarded"].includes(result.outcome)) {
|
|
58
|
+
throw new DiscoveryError({ code: "accounting_unavailable", message: "The budget settlement is invalid or its reservation was already settled." });
|
|
59
|
+
}
|
|
60
|
+
const usage = knownUsage(result.usage);
|
|
61
|
+
// A completed response establishes an attempt even if a malformed client reports zero.
|
|
62
|
+
const attempts = Math.max(result.providerAttempts, result.completedResponses);
|
|
63
|
+
const actual = {
|
|
64
|
+
providerCalls: attempts,
|
|
65
|
+
inputTokens: usage.inputTokens ?? (attempts ? reserved.inputTokens : 0),
|
|
66
|
+
outputTokens: usage.outputTokens ?? (attempts ? reserved.outputTokens : 0),
|
|
67
|
+
estimatedCost: usage.estimatedCost ?? (attempts ? reserved.estimatedCost : 0)
|
|
68
|
+
};
|
|
69
|
+
pending.delete(id);
|
|
70
|
+
for (const key of ["providerCalls", "inputTokens", "outputTokens", "estimatedCost"]) {
|
|
71
|
+
held[key] = Math.max(0, held[key] - reserved[key]);
|
|
72
|
+
charged[key] += actual[key];
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
return Object.freeze({ ledger: Object.freeze(ledger), policy });
|
|
77
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { DiscoveryConfiguration, ResolvedDiscoveryConfiguration, ResolvedLexicalDiscoveryConfiguration } from "./types.js";
|
|
2
|
+
export declare const HYBRID_WEIGHT_TOLERANCE = 1e-12;
|
|
3
|
+
export declare function resolveDiscoveryConfiguration(value: DiscoveryConfiguration): ResolvedDiscoveryConfiguration;
|
|
4
|
+
export declare function lexicalConfiguration(value: ResolvedDiscoveryConfiguration): ResolvedLexicalDiscoveryConfiguration;
|
|
5
|
+
export declare function isRecord(value: unknown): value is Record<string, unknown>;
|
|
6
|
+
export declare function hasOnlyKeys(value: Record<string, unknown>, keys: readonly string[]): boolean;
|
|
7
|
+
export declare function nonblank(value: unknown): value is string;
|
|
8
|
+
export declare function unitScore(value: unknown): value is number;
|
|
9
|
+
export declare function resolveLexicalConfiguration(value: DiscoveryConfiguration): ResolvedLexicalDiscoveryConfiguration;
|
|
10
|
+
//# sourceMappingURL=configuration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configuration.d.ts","sourceRoot":"","sources":["../../src/discovery/configuration.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,8BAA8B,EAAE,qCAAqC,EAAE,MAAM,YAAY,CAAC;AAEhI,eAAO,MAAM,uBAAuB,QAAQ,CAAC;AAE7C,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,sBAAsB,GAAG,8BAA8B,CAgB3G;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,8BAA8B,GAAG,qCAAqC,CAGjH;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAGzE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAE5F;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAExD;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAEzD;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,sBAAsB,GAAG,qCAAqC,CAsBhH"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { DiscoveryError } from "./diagnostics.js";
|
|
2
|
+
import { DISCOVERY_DEFAULT_LIMITS, DISCOVERY_HARD_LIMITS } from "./versions.js";
|
|
3
|
+
export const HYBRID_WEIGHT_TOLERANCE = 1e-12;
|
|
4
|
+
export function resolveDiscoveryConfiguration(value) {
|
|
5
|
+
if (isRecord(value) && value.mode === "hybrid") {
|
|
6
|
+
if (!hasOnlyKeys(value, ["mode", "policyVersion", "limits", "aliasWeight", "minRetrievalScore", "weights", "failurePolicy"])
|
|
7
|
+
|| !isRecord(value.weights) || !hasOnlyKeys(value.weights, ["semantic", "lexical"])
|
|
8
|
+
|| !unitScore(value.weights.semantic) || !unitScore(value.weights.lexical)
|
|
9
|
+
|| Math.abs(value.weights.semantic + value.weights.lexical - 1) > HYBRID_WEIGHT_TOLERANCE
|
|
10
|
+
|| value.failurePolicy !== "unavailable" && value.failurePolicy !== "lexical_fallback") {
|
|
11
|
+
throw new DiscoveryError({ code: "invalid_configuration", message: "Hybrid discovery requires explicit unit weights and a failure policy." });
|
|
12
|
+
}
|
|
13
|
+
const lexical = resolveLexicalConfiguration({
|
|
14
|
+
mode: "lexical", policyVersion: value.policyVersion,
|
|
15
|
+
limits: value.limits, aliasWeight: value.aliasWeight, minRetrievalScore: value.minRetrievalScore
|
|
16
|
+
});
|
|
17
|
+
return Object.freeze({ ...lexical, mode: "hybrid", weights: Object.freeze({ ...value.weights }), failurePolicy: value.failurePolicy });
|
|
18
|
+
}
|
|
19
|
+
return resolveLexicalConfiguration(value);
|
|
20
|
+
}
|
|
21
|
+
export function lexicalConfiguration(value) {
|
|
22
|
+
return Object.freeze({ mode: "lexical", policyVersion: value.policyVersion, limits: value.limits,
|
|
23
|
+
aliasWeight: value.aliasWeight, minRetrievalScore: value.minRetrievalScore });
|
|
24
|
+
}
|
|
25
|
+
export function isRecord(value) {
|
|
26
|
+
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
27
|
+
&& (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null);
|
|
28
|
+
}
|
|
29
|
+
export function hasOnlyKeys(value, keys) {
|
|
30
|
+
return Reflect.ownKeys(value).every((key) => typeof key === "string" && keys.includes(key));
|
|
31
|
+
}
|
|
32
|
+
export function nonblank(value) {
|
|
33
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
34
|
+
}
|
|
35
|
+
export function unitScore(value) {
|
|
36
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 && value <= 1;
|
|
37
|
+
}
|
|
38
|
+
export function resolveLexicalConfiguration(value) {
|
|
39
|
+
const invalid = () => new DiscoveryError({
|
|
40
|
+
code: "invalid_configuration", message: "Discovery requires a valid, explicit lexical configuration."
|
|
41
|
+
});
|
|
42
|
+
if (!isRecord(value) || !hasOnlyKeys(value, ["mode", "policyVersion", "limits", "aliasWeight", "minRetrievalScore"])
|
|
43
|
+
|| value.mode !== "lexical" || !nonblank(value.policyVersion))
|
|
44
|
+
throw invalid();
|
|
45
|
+
if (value.limits !== undefined && (!isRecord(value.limits)
|
|
46
|
+
|| !hasOnlyKeys(value.limits, Object.keys(DISCOVERY_DEFAULT_LIMITS))))
|
|
47
|
+
throw invalid();
|
|
48
|
+
const limits = { ...DISCOVERY_DEFAULT_LIMITS, ...value.limits };
|
|
49
|
+
for (const key of Object.keys(limits)) {
|
|
50
|
+
const minimum = key === "aliasDiversitySlots" ? 0 : 1;
|
|
51
|
+
if (!Number.isInteger(limits[key]) || limits[key] < minimum || limits[key] > DISCOVERY_HARD_LIMITS[key]) {
|
|
52
|
+
throw invalid();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (limits.aliasDiversitySlots >= limits.maxCandidates
|
|
56
|
+
|| (value.aliasWeight !== undefined && !unitScore(value.aliasWeight))
|
|
57
|
+
|| (value.minRetrievalScore !== undefined && !unitScore(value.minRetrievalScore)))
|
|
58
|
+
throw invalid();
|
|
59
|
+
return Object.freeze({
|
|
60
|
+
mode: "lexical", policyVersion: value.policyVersion, limits: Object.freeze(limits),
|
|
61
|
+
aliasWeight: value.aliasWeight ?? 0, minRetrievalScore: value.minRetrievalScore ?? 0
|
|
62
|
+
});
|
|
63
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ManifestRegistry } from "../types.js";
|
|
2
|
+
import type { CapabilitySearchCorpus } from "./types.js";
|
|
3
|
+
export declare const CAPABILITY_CORPUS_PROJECTION_VERSION = "approved-retrieval-fields.v1";
|
|
4
|
+
/** Rechecks definitions and map/list consistency without projecting another corpus. */
|
|
5
|
+
export declare function registrySourceFingerprint(registry: ManifestRegistry): string;
|
|
6
|
+
export declare function buildCapabilitySearchCorpus(registry: ManifestRegistry): CapabilitySearchCorpus;
|
|
7
|
+
export declare function ordinalCompare(left: string, right: string): number;
|
|
8
|
+
//# sourceMappingURL=corpus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"corpus.d.ts","sourceRoot":"","sources":["../../src/discovery/corpus.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAMpD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEzD,eAAO,MAAM,oCAAoC,iCAAiC,CAAC;AAEnF,uFAAuF;AACvF,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CAmB5E;AAED,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,gBAAgB,GAAG,sBAAsB,CA0B9F;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAElE"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { validateManifests } from "../validator.js";
|
|
2
|
+
import { DiscoveryError } from "./diagnostics.js";
|
|
3
|
+
import { fingerprintDiscoveryValue, hashDiscoveryContent } from "./fingerprint.js";
|
|
4
|
+
import { tokenizeDiscoveryText, LEXICAL_TOKENIZER_VERSION } from "./lexical.js";
|
|
5
|
+
import { resolveDiscoveryMetadata } from "./metadata.js";
|
|
6
|
+
export const CAPABILITY_CORPUS_PROJECTION_VERSION = "approved-retrieval-fields.v1";
|
|
7
|
+
/** Rechecks definitions and map/list consistency without projecting another corpus. */
|
|
8
|
+
export function registrySourceFingerprint(registry) {
|
|
9
|
+
try {
|
|
10
|
+
const ids = new Set();
|
|
11
|
+
for (const entry of registry.capabilities) {
|
|
12
|
+
const id = entry.manifest.id;
|
|
13
|
+
if (entry.kind !== "capability" || ids.has(id) || registry.capabilityById.get(id) !== entry)
|
|
14
|
+
throw invalidRegistry();
|
|
15
|
+
ids.add(id);
|
|
16
|
+
}
|
|
17
|
+
if (registry.capabilityById.size !== ids.size)
|
|
18
|
+
throw invalidRegistry();
|
|
19
|
+
const validation = validateManifests([...registry.capabilities, ...registry.entities, ...registry.evals]);
|
|
20
|
+
if (!validation.valid)
|
|
21
|
+
throw invalidRegistry();
|
|
22
|
+
return fingerprintDiscoveryValue("registry_source", {
|
|
23
|
+
capabilities: registry.capabilities.map(({ manifest }) => ({
|
|
24
|
+
capabilityId: manifest.id, capabilityVersion: manifest.version, sourceContentHash: hashDiscoveryContent(manifest)
|
|
25
|
+
})).sort((left, right) => ordinalCompare(left.capabilityId, right.capabilityId))
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
throw invalidRegistry();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export function buildCapabilitySearchCorpus(registry) {
|
|
33
|
+
const source = registrySourceFingerprint(registry);
|
|
34
|
+
const documents = registry.capabilities.map(({ manifest }) => {
|
|
35
|
+
const metadata = resolveDiscoveryMetadata(manifest);
|
|
36
|
+
const content = {
|
|
37
|
+
capabilityId: manifest.id, capabilityVersion: manifest.version, riskTier: manifest.risk_tier,
|
|
38
|
+
name: manifest.name, summary: metadata.summary, aliases: [...metadata.aliases]
|
|
39
|
+
};
|
|
40
|
+
const fields = [content.capabilityId, content.name, content.summary, ...content.aliases];
|
|
41
|
+
return Object.freeze({
|
|
42
|
+
...content, aliases: Object.freeze(content.aliases), text: fields.join("\n"),
|
|
43
|
+
tokens: Object.freeze([...new Set(fields.flatMap(tokenizeDiscoveryText))]),
|
|
44
|
+
documentHash: hashDiscoveryContent(content)
|
|
45
|
+
});
|
|
46
|
+
}).sort((left, right) => ordinalCompare(left.capabilityId, right.capabilityId));
|
|
47
|
+
return Object.freeze({
|
|
48
|
+
schemaVersion: "1.0", projectionVersion: CAPABILITY_CORPUS_PROJECTION_VERSION,
|
|
49
|
+
registrySourceFingerprint: source, documents: Object.freeze(documents),
|
|
50
|
+
corpusFingerprint: fingerprintDiscoveryValue("corpus", {
|
|
51
|
+
registrySourceFingerprint: source, projectionVersion: CAPABILITY_CORPUS_PROJECTION_VERSION,
|
|
52
|
+
projectionConfiguration: { tokenizerVersion: LEXICAL_TOKENIZER_VERSION },
|
|
53
|
+
documents: documents.map(({ capabilityId, capabilityVersion, documentHash }) => ({
|
|
54
|
+
capabilityId, capabilityVersion, documentHash
|
|
55
|
+
}))
|
|
56
|
+
})
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
export function ordinalCompare(left, right) {
|
|
60
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
61
|
+
}
|
|
62
|
+
function invalidRegistry() {
|
|
63
|
+
return new DiscoveryError({ code: "invalid_input", message: "Discovery requires a valid, consistent capability registry." });
|
|
64
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type DiscoveryDiagnosticCode = "invalid_configuration" | "invalid_metadata" | "invalid_input" | "input_limit_exceeded" | "empty_query" | "no_eligible_capabilities" | "no_matching_candidates" | "invalid_ranker_output" | "invalid_index" | "embedding_configuration_mismatch" | "invalid_embedding" | "provider_unavailable" | "invalid_selection_output" | "invalid_selection_input" | "selection_configuration_mismatch" | "stale_binding" | "budget_denied" | "control_denied" | "accounting_unavailable" | "deadline_exceeded" | "cancelled" | "lexical_fallback" | "invalid_fingerprint_payload" | "replay_inputs_unavailable";
|
|
2
|
+
export interface DiscoveryDiagnostic {
|
|
3
|
+
code: DiscoveryDiagnosticCode;
|
|
4
|
+
message: string;
|
|
5
|
+
queryId?: string;
|
|
6
|
+
capabilityId?: string;
|
|
7
|
+
path?: string;
|
|
8
|
+
}
|
|
9
|
+
/** Configuration/contract errors only; operational outcomes use result statuses. */
|
|
10
|
+
export declare class DiscoveryError extends Error {
|
|
11
|
+
readonly code: DiscoveryDiagnosticCode;
|
|
12
|
+
readonly diagnostic: Readonly<DiscoveryDiagnostic>;
|
|
13
|
+
constructor(diagnostic: DiscoveryDiagnostic);
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=diagnostics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../src/discovery/diagnostics.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,uBAAuB,GAC/B,uBAAuB,GACvB,kBAAkB,GAClB,eAAe,GACf,sBAAsB,GACtB,aAAa,GACb,0BAA0B,GAC1B,wBAAwB,GACxB,uBAAuB,GACvB,eAAe,GACf,kCAAkC,GAClC,mBAAmB,GACnB,sBAAsB,GACtB,0BAA0B,GAC1B,yBAAyB,GACzB,kCAAkC,GAClC,eAAe,GACf,eAAe,GACf,gBAAgB,GAChB,wBAAwB,GACxB,mBAAmB,GACnB,WAAW,GACX,kBAAkB,GAClB,6BAA6B,GAC7B,2BAA2B,CAAC;AAEhC,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,uBAAuB,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,oFAAoF;AACpF,qBAAa,cAAe,SAAQ,KAAK;IACvC,QAAQ,CAAC,IAAI,EAAE,uBAAuB,CAAC;IACvC,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,mBAAmB,CAAC,CAAC;gBAEvC,UAAU,EAAE,mBAAmB;CAM5C"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Configuration/contract errors only; operational outcomes use result statuses. */
|
|
2
|
+
export class DiscoveryError extends Error {
|
|
3
|
+
code;
|
|
4
|
+
diagnostic;
|
|
5
|
+
constructor(diagnostic) {
|
|
6
|
+
super(diagnostic.message);
|
|
7
|
+
this.name = "DiscoveryError";
|
|
8
|
+
this.code = diagnostic.code;
|
|
9
|
+
this.diagnostic = Object.freeze({ ...diagnostic });
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type DiscoveryDiagnosticCode } from "./diagnostics.js";
|
|
2
|
+
import type { HybridDiscoveryDependencies } from "./embedding-types.js";
|
|
3
|
+
import type { CapabilityDiscoveryRequest, CapabilityDiscoveryResult, CapabilityLexicalRanker, DiscoveryConfiguration, DiscoveryQuery, DiscoveryUsage, ResolvedDiscoveryConfiguration } from "./types.js";
|
|
4
|
+
export { HYBRID_RANKER_VERSION, QUERY_EMBEDDING_PROJECTION_VERSION } from "./retrieval-policy.js";
|
|
5
|
+
export interface CapabilityDiscovererOptions {
|
|
6
|
+
ranker?: CapabilityLexicalRanker;
|
|
7
|
+
embedding?: HybridDiscoveryDependencies;
|
|
8
|
+
}
|
|
9
|
+
export declare class CapabilityDiscoverer {
|
|
10
|
+
readonly configuration: ResolvedDiscoveryConfiguration;
|
|
11
|
+
private readonly ranker?;
|
|
12
|
+
private readonly embedding?;
|
|
13
|
+
constructor(configuration: DiscoveryConfiguration, options?: CapabilityDiscovererOptions);
|
|
14
|
+
discover(request: CapabilityDiscoveryRequest): Promise<readonly CapabilityDiscoveryResult[]>;
|
|
15
|
+
private invocationConfiguration;
|
|
16
|
+
}
|
|
17
|
+
export declare function validateQueries(request: Pick<CapabilityDiscoveryRequest, "queries">, configuration: ResolvedDiscoveryConfiguration): readonly DiscoveryQuery[];
|
|
18
|
+
export declare function discoveryStopReason(request: {
|
|
19
|
+
signal?: AbortSignal;
|
|
20
|
+
deadlineAt?: number;
|
|
21
|
+
}): DiscoveryDiagnosticCode | undefined;
|
|
22
|
+
export declare function zeroDiscoveryUsage(elapsedMs: number): DiscoveryUsage;
|
|
23
|
+
//# sourceMappingURL=discoverer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discoverer.d.ts","sourceRoot":"","sources":["../../src/discovery/discoverer.ts"],"names":[],"mappings":"AAMA,OAAO,EAAkB,KAAK,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAIhF,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AAMxE,OAAO,KAAK,EACV,0BAA0B,EAAE,yBAAyB,EAAE,uBAAuB,EAAE,sBAAsB,EACtG,cAAc,EAAE,cAAc,EAAE,8BAA8B,EAC/D,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,qBAAqB,EAAE,kCAAkC,EAAE,MAAM,uBAAuB,CAAC;AAClG,MAAM,WAAW,2BAA2B;IAC1C,MAAM,CAAC,EAAE,uBAAuB,CAAC;IACjC,SAAS,CAAC,EAAE,2BAA2B,CAAC;CACzC;AAED,qBAAa,oBAAoB;IAC/B,QAAQ,CAAC,aAAa,EAAE,8BAA8B,CAAC;IACvD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAA0B;IAClD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAEzB;gBAEU,aAAa,EAAE,sBAAsB,EAAE,OAAO,GAAE,2BAAgC;IA0BtF,QAAQ,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,SAAS,yBAAyB,EAAE,CAAC;IAsHlG,OAAO,CAAC,uBAAuB;CAchC;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,IAAI,CAAC,0BAA0B,EAAE,SAAS,CAAC,EAAE,aAAa,EAAE,8BAA8B,GAAG,SAAS,cAAc,EAAE,CAqB9J;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE;IAAE,MAAM,CAAC,EAAE,WAAW,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,uBAAuB,GAAG,SAAS,CAE/H;AAED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,CAEpE"}
|