@godspeedai/cognate-capabilities 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +127 -10
  2. package/package.json +4 -4
package/README.md CHANGED
@@ -1,12 +1,129 @@
1
1
  # @godspeedai/cognate-capabilities
2
2
 
3
- Two-phase capability selection (spec §3.6, §8.2, §17, §30): every `EligibilityRule` filters
4
- every candidate first, and every (provider, rule) result is recorded. Only the eligible set is
5
- exposed to an adaptive `Ranker`, which can narrow but never widen it — an unknown, ineligible,
6
- duplicated, or non-finite ranker entry is dropped, and a missing or throwing ranker falls back to
7
- deterministic `providerId` order.
8
-
9
- `recordSelection` / `recordOutcome` make selections and their outcomes durable facts on stream
10
- `selection-<id>`. `outcomeProjection()` derives a Laplace-smoothed success rate per
11
- `(capability, provider)`, and `createOutcomeRanker(store)` turns that into a `Ranker` so feedback
12
- only changes ranking after it is committed and projected (spec §15).
3
+ Deterministic-first capability selection and the model provider contract for Cognate
4
+ applications. Given a requirement and a set of candidate providers, it decides — explainably
5
+ and durably — which provider to use, and it defines the plain-TypeScript `ModelProvider`
6
+ interface that model integrations implement.
7
+
8
+ **When to use this package:** you choose between multiple providers for the same capability
9
+ (for example several models) and need eligibility rules that always apply, ranking that can
10
+ never override policy, and a recorded explanation of every decision. Implementors of model
11
+ providers also need it for the `ModelProvider`, `ModelRequest`/`ModelResponse`, and
12
+ `ModelProviderError` types.
13
+
14
+ ## Installation
15
+
16
+ ```sh
17
+ bun add @godspeedai/cognate-capabilities
18
+ ```
19
+
20
+ Requires [Bun](https://bun.sh) >= 1.4.0. Recording selections needs any
21
+ [`@godspeedai/cognate-events`](https://www.npmjs.com/package/@godspeedai/cognate-events)
22
+ store. The SDK ships Bun-native TypeScript source, so add `@types/bun` and `@types/node` as
23
+ dev dependencies when typechecking your project.
24
+
25
+ ## Quick start
26
+
27
+ ```ts
28
+ import { createMemoryStore } from "@godspeedai/cognate-store-memory";
29
+ import {
30
+ compatibilityRule,
31
+ createSelector,
32
+ recordSelection,
33
+ } from "@godspeedai/cognate-capabilities";
34
+
35
+ const store = createMemoryStore();
36
+
37
+ const selector = createSelector({
38
+ rules: [
39
+ compatibilityRule, // contract id, major version, and attributes must satisfy the requirement
40
+ {
41
+ id: "policy.no-cloud",
42
+ evaluate: (candidate) =>
43
+ candidate.contract.attributes?.hosting === "cloud"
44
+ ? { eligible: false, reason: "tenant forbids cloud models" }
45
+ : { eligible: true, reason: "hosting allowed" },
46
+ },
47
+ ],
48
+ // ranker: optional; without one, eligible providers are picked in provider-id order
49
+ });
50
+
51
+ const decision = await selector.select({
52
+ requirement: { capability: "model.generate", version: "1.0", attributes: { structured_output: true } },
53
+ candidates: [
54
+ { providerId: "cloud-a", contract: { id: "model.generate", version: "1.2.0", attributes: { structured_output: true, hosting: "cloud" } } },
55
+ { providerId: "local-b", contract: { id: "model.generate", version: "1.0.0", attributes: { structured_output: true } } },
56
+ ],
57
+ principal: { id: "alice", kind: "user" },
58
+ tenant: "tenant-a",
59
+ });
60
+
61
+ decision.eligible; // ["local-b"] — cloud-a failed the policy rule
62
+ decision.selected; // "local-b"
63
+ decision.filters; // every (provider, rule) result with its reason
64
+
65
+ // Make the decision a durable fact with its full explanation:
66
+ await recordSelection(store, decision, { tenant: "tenant-a", scopeId: "root", correlationId: "corr-1", runId: "run-1" });
67
+ ```
68
+
69
+ ## How selection works
70
+
71
+ 1. **Eligibility first.** Every `EligibilityRule` evaluates every candidate. Rules must be
72
+ pure and deterministic; a candidate is eligible only if all rules pass.
73
+ 2. **Ranking second — and contained.** The optional `Ranker` sees only the eligible set and
74
+ can narrow it, never widen it. Ranker entries that are unknown, ineligible, duplicated, or
75
+ non-finite are dropped. A missing or throwing ranker falls back to deterministic
76
+ provider-id order, recorded in `decision.fallback`. With no eligible candidate, `selected`
77
+ is `null` and the ranker is never called.
78
+ 3. **Durable feedback.** `recordSelection` appends a `capability.selected` event with the
79
+ full explanation; `recordOutcome` appends a `capability.outcome` for a recorded selection.
80
+ Run `outcomeProjection()` in your projection runner to derive per-capability success
81
+ counts, then pass `createOutcomeRanker(store)` as the selector's ranker: it scores
82
+ providers by an upper-confidence-bound rule over recorded outcomes, tries untried
83
+ providers first, and is deterministic — replaying the same outcomes yields the same
84
+ ranking. Feedback only influences ranking after it is committed and projected.
85
+
86
+ ## The model provider contract
87
+
88
+ The package also defines the model integration contract every provider implements:
89
+
90
+ - `ModelProvider` — `id`, `model`, declared `features` (streaming, tool use, structured
91
+ output, multimodal input, context limit), `generate(request)` and `stream(request)`.
92
+ - `ModelRequest` / `ModelResponse` / `ModelDelta` — messages, tools, `responseFormat`, and
93
+ the streamed delta shapes (`text`, `tool_call_start`, `tool_call_args`, `tool_call_end`,
94
+ `tool_call`, `done`).
95
+ - `ModelProviderError` — typed failure kinds: `unauthorized`, `rate_limited`,
96
+ `invalid_request`, `unavailable`, `cancelled`, `malformed_response`.
97
+ - `modelContract(provider)` — the `CapabilityContract` a provider publishes (capability id
98
+ `model.generate`, features as attributes, never credentials).
99
+
100
+ Ready-made providers:
101
+ [`@godspeedai/cognate-provider-local`](https://www.npmjs.com/package/@godspeedai/cognate-provider-local)
102
+ (deterministic, offline) and
103
+ [`@godspeedai/cognate-provider-openai-compatible`](https://www.npmjs.com/package/@godspeedai/cognate-provider-openai-compatible)
104
+ (any OpenAI-compatible HTTP endpoint).
105
+
106
+ ## Limitations
107
+
108
+ - Rules and rankers are yours to write; this package guarantees containment and honest
109
+ bookkeeping, not ranking quality.
110
+ - The built-in outcome ranker is a deterministic bandit heuristic over your own recorded
111
+ outcomes — not a trained model — and scores are only comparable within one capability.
112
+ - `recordSelection`/`recordOutcome` write to the store you give them; without a durable
113
+ store, feedback is lost on restart.
114
+
115
+ ## Related packages
116
+
117
+ - [`@godspeedai/cognate-kernel-api`](https://www.npmjs.com/package/@godspeedai/cognate-kernel-api) —
118
+ `Requirement`, `CapabilityContract`, and the compatibility check used by `compatibilityRule`.
119
+ - [`@godspeedai/cognate-events`](https://www.npmjs.com/package/@godspeedai/cognate-events) —
120
+ the store contract for recording selections and outcomes.
121
+ - [`@godspeedai/cognate-projections`](https://www.npmjs.com/package/@godspeedai/cognate-projections) —
122
+ the projection runner that applies `outcomeProjection()`.
123
+ - [`@godspeedai/cognate-runtime-bun`](https://www.npmjs.com/package/@godspeedai/cognate-runtime-bun) —
124
+ the reference runtime, which wires selection and providers together.
125
+ - [`@godspeedai/cognate`](https://www.npmjs.com/package/@godspeedai/cognate) — the SDK umbrella.
126
+
127
+ ## License
128
+
129
+ Apache-2.0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@godspeedai/cognate-capabilities",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Two-phase capability selection: deterministic eligibility, then contained adaptive ranking with durable explanations (spec §8.2, §17, §30).",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -22,9 +22,9 @@
22
22
  ".": "./src/index.ts"
23
23
  },
24
24
  "dependencies": {
25
- "@godspeedai/cognate-events": "^0.1.1",
26
- "@godspeedai/cognate-kernel-api": "^0.1.1",
27
- "@godspeedai/cognate-projections": "^0.1.1"
25
+ "@godspeedai/cognate-events": "^0.1.2",
26
+ "@godspeedai/cognate-kernel-api": "^0.1.2",
27
+ "@godspeedai/cognate-projections": "^0.1.2"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@godspeedai/cognate-store-memory": "workspace:*",