ai-capability-framework 1.0.2 → 1.1.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -0
- package/README.md +24 -0
- package/ROADMAP.md +11 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +25 -0
- 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 +7 -0
- package/docs/api.md +7 -0
- package/docs/capability-manifests.md +24 -0
- package/docs/discovery.md +191 -0
- package/docs/evals/discovery-live.md +199 -0
- package/docs/evals/discovery-qualification.md +153 -0
- package/docs/evals/overview.md +9 -0
- package/docs/index.md +9 -0
- package/docs/release.md +25 -5
- package/docs/runtime.md +22 -0
- package/examples/12-capability-discovery-selection/README.md +345 -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,42 @@ All notable public changes to AI Capability Framework are documented here.
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
## 1.1.0-rc.1 - 2026-10-17
|
|
8
|
+
|
|
9
|
+
- Published discovery as release-candidate public, with lexical retrieval and ordinary
|
|
10
|
+
model tool selection as the recommended default. Dedicated selection is optional.
|
|
11
|
+
- Documented the tested synthetic configuration: both lexical modes qualify after a
|
|
12
|
+
separately versioned offline wording correction; hybrid remains experimental and
|
|
13
|
+
opt-in because its incremental-gain gate was not met. See the
|
|
14
|
+
[qualification report](docs/evals/discovery-qualification.md).
|
|
15
|
+
- Tightened registry-error handling and retained tag-only OIDC publication to next. No
|
|
16
|
+
model defaults, retrieval scoring or application deployment changed.
|
|
17
|
+
|
|
18
|
+
- Corrected the synthetic workflow app's planning, terminal dependency states and
|
|
19
|
+
response grading. Added versioned readiness fixtures, fresh qualification families,
|
|
20
|
+
and a remaining-budget continuation protocol. These offline changes preserve
|
|
21
|
+
historical live results and do not qualify a model or change framework defaults.
|
|
22
|
+
|
|
23
|
+
- Added scoped discovery evaluation reports, corrected versioned domain fixtures, and
|
|
24
|
+
opt-in live campaign tooling with durable budgets and independent per-mode gates.
|
|
25
|
+
Default invocation validates offline; synthetic campaign results do not qualify
|
|
26
|
+
models.
|
|
27
|
+
|
|
28
|
+
- Added the optional release-candidate discovery subpath with task search, reusable
|
|
29
|
+
task-bound routers, explicit hybrid retrieval and dedicated selection, shared-run
|
|
30
|
+
accounting, metadata tracing, and bounded replay. Default routing remains unchanged.
|
|
31
|
+
- Added portable no-key customer-request examples, public discovery schemas, and frozen
|
|
32
|
+
synthetic evaluation fixtures. Mock integration and offline metrics do not qualify
|
|
33
|
+
real-model retrieval or selection quality.
|
|
34
|
+
|
|
35
|
+
## 1.0.3 - 2026-09-07
|
|
36
|
+
|
|
37
|
+
- Updated the resolved `fast-uri` dependency to `3.1.7` to address the high-severity
|
|
38
|
+
host-confusion and server-side request forgery advisories reported by the scheduled
|
|
39
|
+
production dependency audit.
|
|
40
|
+
- Kept `ai-capability-framework`, `@aicf/agent-skills`, and Codex plugin metadata
|
|
41
|
+
aligned under the coordinated `1.0.3` patch release.
|
|
42
|
+
|
|
7
43
|
## 1.0.2 - 2026-08-10
|
|
8
44
|
|
|
9
45
|
- Updated the resolved `fast-uri` dependency to `3.1.5` to address
|
package/README.md
CHANGED
|
@@ -297,3 +297,27 @@ certification is documented in
|
|
|
297
297
|
## License
|
|
298
298
|
|
|
299
299
|
MIT
|
|
300
|
+
|
|
301
|
+
## Find capabilities for a task
|
|
302
|
+
|
|
303
|
+
Install the discovery prerelease explicitly:
|
|
304
|
+
|
|
305
|
+
```sh
|
|
306
|
+
npm install ai-capability-framework@1.1.0-rc.1
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
Lexical retrieval with the ordinary model/tool loop is the recommended default. The
|
|
310
|
+
[qualification report](docs/evals/discovery-qualification.md) records the tested lexical
|
|
311
|
+
results and the unmet hybrid incremental-gain gate. Hybrid remains experimental and
|
|
312
|
+
opt-in; dedicated selection remains optional.
|
|
313
|
+
|
|
314
|
+
Use the optional release-candidate [discovery API](docs/discovery.md) when your
|
|
315
|
+
application AI decomposes a customer request into tasks. Search each ready task and pass
|
|
316
|
+
its result-bound router to the ordinary model/tool loop. Lexical search needs only a
|
|
317
|
+
registry, task IDs/text, and existing runtime context. Hybrid retrieval and dedicated
|
|
318
|
+
selection are optional and require caller-supplied model access and budgets.
|
|
319
|
+
|
|
320
|
+
Run the
|
|
321
|
+
[complete customer-request example](examples/12-capability-discovery-selection/README.md)
|
|
322
|
+
with deterministic mocks and no provider key. Retrieval scores never authorize execution
|
|
323
|
+
or guarantee a suitable first candidate.
|
package/ROADMAP.md
CHANGED
|
@@ -24,3 +24,14 @@ 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 optional release-candidate discovery API supports application-produced tasks,
|
|
31
|
+
eligible shortlists, and ordinary model tool selection. Hybrid retrieval and dedicated
|
|
32
|
+
selection remain explicit. No-key examples, a frozen synthetic dataset, and packed
|
|
33
|
+
consumer checks cover integration. The tested synthetic configuration qualifies both
|
|
34
|
+
lexical modes after an offline wording correction. Lexical/native is recommended; hybrid
|
|
35
|
+
remains 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 prerelease publication.
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAuGA,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,
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAuGA,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
|
@@ -91,6 +91,31 @@ export async function runCli(argv, options = {}) {
|
|
|
91
91
|
const validation = validateManifests(loadResult.manifests);
|
|
92
92
|
const fixtureValidation = validatePublicFixtures(loadResult.fixtures);
|
|
93
93
|
const errors = [...loadResult.errors, ...validation.errors, ...fixtureValidation.errors];
|
|
94
|
+
if (!errors.length && loadResult.fixtures.some(fixture => fixture.kind === "discovery_eval_suite" || fixture.kind === "discovery_eval_observations")) {
|
|
95
|
+
const { validateDiscoveryEvaluationSuite, evaluateCapabilityDiscovery } = await import("./discovery/evaluation.js");
|
|
96
|
+
const suites = loadResult.fixtures.filter(fixture => fixture.kind === "discovery_eval_suite");
|
|
97
|
+
for (const fixture of suites) {
|
|
98
|
+
for (const diagnostic of validateDiscoveryEvaluationSuite(fixture.fixture)) {
|
|
99
|
+
errors.push({ code: "invalid_fixture", message: diagnostic.code, path: fixture.path, id: diagnostic.caseId });
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
for (const fixture of loadResult.fixtures.filter(fixture => fixture.kind === "discovery_eval_observations")) {
|
|
103
|
+
const observations = fixture.fixture;
|
|
104
|
+
const matches = suites.filter(candidate => candidate.fixture.id === observations.suite_id);
|
|
105
|
+
if (matches.length !== 1) {
|
|
106
|
+
errors.push({ code: "invalid_fixture", message: "discovery_evaluation_suite_required", path: fixture.path });
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
const suite = matches[0].fixture;
|
|
110
|
+
const registry = buildRegistry(suite.capabilities.map(manifest => ({ kind: "capability", manifest,
|
|
111
|
+
path: `synthetic/${manifest.id}.yaml`, absolutePath: `/synthetic/${manifest.id}.yaml` })));
|
|
112
|
+
const result = evaluateCapabilityDiscovery({ suite, registry, observations });
|
|
113
|
+
if (!result.valid)
|
|
114
|
+
for (const diagnostic of result.diagnostics) {
|
|
115
|
+
errors.push({ code: "invalid_fixture", message: diagnostic.code, path: fixture.path, id: diagnostic.caseId });
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
94
119
|
if (errors.length > 0) {
|
|
95
120
|
stderr.write(formatDiagnostics(errors));
|
|
96
121
|
return 1;
|
|
@@ -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"}
|