@kindgi/capabilities 0.1.2 → 0.1.4-rc.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.
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Counts each model call's HTTP attempts, retries included, without
3
+ * taking over the vendor SDK's retry policy (its `Retry-After` handling,
4
+ * its backoff). An adapter gives its SDK client `fetch`, and runs each
5
+ * call inside `count`: every request the SDK sends for that call, the
6
+ * first and each retry, goes through `fetch` and is counted for it.
7
+ * Calls running at the same time are counted apart.
8
+ *
9
+ * A call that throws throws its own error, unchanged (callers may check
10
+ * its type or status); the attempts it took are `attemptsOf(error)`.
11
+ *
12
+ * Node only (`AsyncLocalStorage`): it's the `@kindgi/capabilities/attempts`
13
+ * entry, apart from the package's runtime-neutral main entry.
14
+ */
15
+ export interface AttemptCounter {
16
+ /** The `fetch` the SDK client sends with: counts, then sends with `inner`. */
17
+ readonly fetch: typeof globalThis.fetch;
18
+ /** Run one call; its result, and the HTTP attempts it took. */
19
+ count<T>(call: () => PromiseLike<T>): Promise<{
20
+ readonly value: T;
21
+ readonly attempts: number;
22
+ }>;
23
+ }
24
+ /**
25
+ * An `AttemptCounter` over `inner`. Without one, it sends with the global
26
+ * `fetch` as it is at each request, so a `fetch` patched after the
27
+ * provider was built (a test's mock, a tracer) still sees the requests.
28
+ */
29
+ export declare function createAttemptCounter(inner?: typeof globalThis.fetch): AttemptCounter;
30
+ /**
31
+ * The HTTP attempts a counted call took before it threw `error`;
32
+ * `undefined` when it wasn't counted, or sent nothing.
33
+ */
34
+ export declare function attemptsOf(error: unknown): number | undefined;
35
+ //# sourceMappingURL=attempts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attempts.d.ts","sourceRoot":"","sources":["../src/attempts.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,cAAc;IAC7B,8EAA8E;IAC9E,QAAQ,CAAC,KAAK,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IACxC,+DAA+D;IAC/D,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;QAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;QAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjG;AAKD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,GAAG,cAAc,CAwBpF;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAE7D"}
@@ -0,0 +1,45 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+ import { AsyncLocalStorage } from 'node:async_hooks';
4
+ /** The attempts of counted calls that threw, by their error (`attemptsOf`). */
5
+ const failedAttempts = new WeakMap();
6
+ /**
7
+ * An `AttemptCounter` over `inner`. Without one, it sends with the global
8
+ * `fetch` as it is at each request, so a `fetch` patched after the
9
+ * provider was built (a test's mock, a tracer) still sees the requests.
10
+ */
11
+ export function createAttemptCounter(inner) {
12
+ const calls = new AsyncLocalStorage();
13
+ return {
14
+ fetch: (input, init) => {
15
+ const call = calls.getStore();
16
+ if (call !== undefined)
17
+ call.attempts += 1;
18
+ return (inner ?? globalThis.fetch)(input, init);
19
+ },
20
+ async count(call) {
21
+ const state = { attempts: 0 };
22
+ try {
23
+ // Awaited inside the store: an SDK's promise can be lazy (OpenAI's
24
+ // `APIPromise` sends, and retries a body that stalls, only when
25
+ // it's awaited), and those requests are this call's too.
26
+ const value = await calls.run(state, async () => await call());
27
+ return { value, attempts: state.attempts };
28
+ }
29
+ catch (error) {
30
+ if (typeof error === 'object' && error !== null && state.attempts > 0) {
31
+ failedAttempts.set(error, state.attempts);
32
+ }
33
+ throw error;
34
+ }
35
+ },
36
+ };
37
+ }
38
+ /**
39
+ * The HTTP attempts a counted call took before it threw `error`;
40
+ * `undefined` when it wasn't counted, or sent nothing.
41
+ */
42
+ export function attemptsOf(error) {
43
+ return typeof error === 'object' && error !== null ? failedAttempts.get(error) : undefined;
44
+ }
45
+ //# sourceMappingURL=attempts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attempts.js","sourceRoot":"","sources":["../src/attempts.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAEjC,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAuBrD,+EAA+E;AAC/E,MAAM,cAAc,GAAG,IAAI,OAAO,EAAkB,CAAC;AAErD;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAA+B;IAClE,MAAM,KAAK,GAAG,IAAI,iBAAiB,EAAwB,CAAC;IAC5D,OAAO;QACL,KAAK,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;YACrB,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;YAC9B,IAAI,IAAI,KAAK,SAAS;gBAAE,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC;YAC3C,OAAO,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAClD,CAAC;QACD,KAAK,CAAC,KAAK,CAAC,IAAI;YACd,MAAM,KAAK,GAAG,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;YAC9B,IAAI,CAAC;gBACH,mEAAmE;gBACnE,gEAAgE;gBAChE,yDAAyD;gBACzD,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;gBAC/D,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;YAC7C,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;oBACtE,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;gBAC5C,CAAC;gBACD,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7F,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,10 +1,13 @@
1
1
  export { createAdapterFactoryRegistry } from './adapter-factory.js';
2
2
  export type { AdapterConfig, AdapterFactory, AdapterFactoryEntry, AdapterFactoryInput, AdapterFactoryRegistry, PrepareEvent, } from './adapter-factory.js';
3
3
  export { CAPABILITY_SCHEMA_URI, defineCapability } from './define.js';
4
+ export { PROVIDER_LABEL_KEY, PROVIDER_LABEL_MANAGED_BY, PROVIDER_LABEL_VALUE_MAX_LENGTH, PROVIDER_LABELS_MAX_KEYS, validateProviderLabels, } from './provider-labels.js';
4
5
  export { createProviderRegistry } from './registry.js';
5
6
  export { matchTuples, route } from './router.js';
6
7
  export type { RouteInput } from './router.js';
8
+ export { recordModelUsage } from './usage.js';
9
+ export type { RecordModelUsageOptions } from './usage.js';
7
10
  export { BUILT_IN_CAPABILITY_KINDS, DEFAULT_CAPABILITY_KIND, FEATURES } from './types.js';
8
- export type { Budget, BuiltInCapabilityKind, Capability, CapabilityKind, ComparisonOp, Feature, ModelCallInput, ModelCallResult, ModelMessage, ModelInfo, ModelProvider, ModelToolCall, ModelToolDefinition, Preference, ProviderMetadata, ProviderModelPick, ProviderRegistry, RejectionReason, Requirement, RoutingDecision, StructuredOutputRequest, TenantPolicy, UpperBoundOp, UsageCounters, } from './types.js';
11
+ export type { Budget, BuiltInCapabilityKind, Capability, CapabilityKind, ComparisonOp, Feature, ModelCallInput, ModelUsageRecord, ModelCallResult, ModelMessage, ModelInfo, ModelProvider, ModelToolCall, ModelToolDefinition, Preference, ProviderMetadata, ProviderModelPick, ProviderRegistry, RejectionReason, Requirement, RoutingDecision, StructuredOutputRequest, TenantPolicy, UpperBoundOp, UsageCounters, UsageSink, } from './types.js';
9
12
  export type { BudgetExceededError, CapabilityError, CapabilityUnsatisfiableError, DuplicateProviderError, InvalidCapabilityError, InvalidProviderError, } from './errors.js';
10
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,4BAA4B,EAAE,MAAM,sBAAsB,CAAC;AACpE,YAAY,EACV,aAAa,EACb,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,EACtB,YAAY,GACb,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACjD,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,yBAAyB,EAAE,uBAAuB,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC1F,YAAY,EACV,MAAM,EACN,qBAAqB,EACrB,UAAU,EACV,cAAc,EACd,YAAY,EACZ,OAAO,EACP,cAAc,EACd,eAAe,EACf,YAAY,EACZ,SAAS,EACT,aAAa,EACb,aAAa,EACb,mBAAmB,EACnB,UAAU,EACV,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,eAAe,EACf,uBAAuB,EACvB,YAAY,EACZ,YAAY,EACZ,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,mBAAmB,EACnB,eAAe,EACf,4BAA4B,EAC5B,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,4BAA4B,EAAE,MAAM,sBAAsB,CAAC;AACpE,YAAY,EACV,aAAa,EACb,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,EACtB,YAAY,GACb,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EACL,kBAAkB,EAClB,yBAAyB,EACzB,+BAA+B,EAC/B,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACjD,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,YAAY,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,EAAE,yBAAyB,EAAE,uBAAuB,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC1F,YAAY,EACV,MAAM,EACN,qBAAqB,EACrB,UAAU,EACV,cAAc,EACd,YAAY,EACZ,OAAO,EACP,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,SAAS,EACT,aAAa,EACb,aAAa,EACb,mBAAmB,EACnB,UAAU,EACV,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,eAAe,EACf,uBAAuB,EACvB,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,SAAS,GACV,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,mBAAmB,EACnB,eAAe,EACf,4BAA4B,EAC5B,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,aAAa,CAAC"}
package/dist/index.js CHANGED
@@ -2,7 +2,9 @@
2
2
  // Copyright (C) 2026 Kindgi Inc.
3
3
  export { createAdapterFactoryRegistry } from './adapter-factory.js';
4
4
  export { CAPABILITY_SCHEMA_URI, defineCapability } from './define.js';
5
+ export { PROVIDER_LABEL_KEY, PROVIDER_LABEL_MANAGED_BY, PROVIDER_LABEL_VALUE_MAX_LENGTH, PROVIDER_LABELS_MAX_KEYS, validateProviderLabels, } from './provider-labels.js';
5
6
  export { createProviderRegistry } from './registry.js';
6
7
  export { matchTuples, route } from './router.js';
8
+ export { recordModelUsage } from './usage.js';
7
9
  export { BUILT_IN_CAPABILITY_KINDS, DEFAULT_CAPABILITY_KIND, FEATURES } from './types.js';
8
10
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAEjC,OAAO,EAAE,4BAA4B,EAAE,MAAM,sBAAsB,CAAC;AASpE,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,EAAE,yBAAyB,EAAE,uBAAuB,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAEjC,OAAO,EAAE,4BAA4B,EAAE,MAAM,sBAAsB,CAAC;AASpE,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EACL,kBAAkB,EAClB,yBAAyB,EACzB,+BAA+B,EAC/B,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EAAE,yBAAyB,EAAE,uBAAuB,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * `ProviderMetadata.labels`: string keys to string values, for whoever
3
+ * manages a provider to record that it does. The router ignores them.
4
+ *
5
+ * One validator, used where a provider is registered in-process
6
+ * (`createProviderRegistry`) and over the wire (`POST /v1/providers`),
7
+ * so the two accept the same labels.
8
+ */
9
+ /** The convention key for who manages a provider: `kindgi-dev`, `kindgi-dev:<pack id>`, `kindgi-deploy:<environment>`. */
10
+ export declare const PROVIDER_LABEL_MANAGED_BY = "kindgi.com/managed-by";
11
+ export declare const PROVIDER_LABELS_MAX_KEYS = 32;
12
+ export declare const PROVIDER_LABEL_VALUE_MAX_LENGTH = 256;
13
+ /** 1–63 characters: lowercase letters and digits, with `.`, `-`, `_` or `/` inside. */
14
+ export declare const PROVIDER_LABEL_KEY: RegExp;
15
+ /**
16
+ * `undefined` when `labels` is absent or well formed; otherwise why not,
17
+ * as the `invalid-provider` error's `message` and `reason`.
18
+ */
19
+ export declare function validateProviderLabels(providerId: string, labels: unknown): {
20
+ readonly message: string;
21
+ readonly reason: 'invalid-labels';
22
+ } | undefined;
23
+ //# sourceMappingURL=provider-labels.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-labels.d.ts","sourceRoot":"","sources":["../src/provider-labels.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AAEH,0HAA0H;AAC1H,eAAO,MAAM,yBAAyB,0BAA0B,CAAC;AAEjE,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAC3C,eAAO,MAAM,+BAA+B,MAAM,CAAC;AAEnD,uFAAuF;AACvF,eAAO,MAAM,kBAAkB,QAA4C,CAAC;AAE5E;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,OAAO,GACd;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,GAAG,SAAS,CA6B7E"}
@@ -0,0 +1,48 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+ /**
4
+ * `ProviderMetadata.labels`: string keys to string values, for whoever
5
+ * manages a provider to record that it does. The router ignores them.
6
+ *
7
+ * One validator, used where a provider is registered in-process
8
+ * (`createProviderRegistry`) and over the wire (`POST /v1/providers`),
9
+ * so the two accept the same labels.
10
+ */
11
+ /** The convention key for who manages a provider: `kindgi-dev`, `kindgi-dev:<pack id>`, `kindgi-deploy:<environment>`. */
12
+ export const PROVIDER_LABEL_MANAGED_BY = 'kindgi.com/managed-by';
13
+ export const PROVIDER_LABELS_MAX_KEYS = 32;
14
+ export const PROVIDER_LABEL_VALUE_MAX_LENGTH = 256;
15
+ /** 1–63 characters: lowercase letters and digits, with `.`, `-`, `_` or `/` inside. */
16
+ export const PROVIDER_LABEL_KEY = /^[a-z0-9]([a-z0-9._/-]{0,61}[a-z0-9])?$/;
17
+ /**
18
+ * `undefined` when `labels` is absent or well formed; otherwise why not,
19
+ * as the `invalid-provider` error's `message` and `reason`.
20
+ */
21
+ export function validateProviderLabels(providerId, labels) {
22
+ if (labels === undefined)
23
+ return undefined;
24
+ const invalid = (detail) => ({
25
+ message: `provider "${providerId}" labels ${detail}`,
26
+ reason: 'invalid-labels',
27
+ });
28
+ if (typeof labels !== 'object' || labels === null || Array.isArray(labels)) {
29
+ return invalid('must be an object of string keys to string values');
30
+ }
31
+ const entries = Object.entries(labels);
32
+ if (entries.length > PROVIDER_LABELS_MAX_KEYS) {
33
+ return invalid(`may have at most ${PROVIDER_LABELS_MAX_KEYS} keys (got ${entries.length})`);
34
+ }
35
+ for (const [key, value] of entries) {
36
+ if (!PROVIDER_LABEL_KEY.test(key)) {
37
+ return invalid(`key "${key}" must be 1-63 lowercase letters and digits, with ".", "-", "_" or "/" inside`);
38
+ }
39
+ if (typeof value !== 'string') {
40
+ return invalid(`value of "${key}" must be a string`);
41
+ }
42
+ if (value.length > PROVIDER_LABEL_VALUE_MAX_LENGTH) {
43
+ return invalid(`value of "${key}" may be at most ${PROVIDER_LABEL_VALUE_MAX_LENGTH} characters (got ${value.length})`);
44
+ }
45
+ }
46
+ return undefined;
47
+ }
48
+ //# sourceMappingURL=provider-labels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-labels.js","sourceRoot":"","sources":["../src/provider-labels.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAEjC;;;;;;;GAOG;AAEH,0HAA0H;AAC1H,MAAM,CAAC,MAAM,yBAAyB,GAAG,uBAAuB,CAAC;AAEjE,MAAM,CAAC,MAAM,wBAAwB,GAAG,EAAE,CAAC;AAC3C,MAAM,CAAC,MAAM,+BAA+B,GAAG,GAAG,CAAC;AAEnD,uFAAuF;AACvF,MAAM,CAAC,MAAM,kBAAkB,GAAG,yCAAyC,CAAC;AAE5E;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CACpC,UAAkB,EAClB,MAAe;IAEf,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC3C,MAAM,OAAO,GAAG,CAAC,MAAc,EAAE,EAAE,CAAC,CAAC;QACnC,OAAO,EAAE,aAAa,UAAU,YAAY,MAAM,EAAE;QACpD,MAAM,EAAE,gBAAyB;KAClC,CAAC,CAAC;IACH,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3E,OAAO,OAAO,CAAC,mDAAmD,CAAC,CAAC;IACtE,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACvC,IAAI,OAAO,CAAC,MAAM,GAAG,wBAAwB,EAAE,CAAC;QAC9C,OAAO,OAAO,CAAC,oBAAoB,wBAAwB,cAAc,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;IAC9F,CAAC;IACD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,OAAO,EAAE,CAAC;QACnC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAClC,OAAO,OAAO,CACZ,QAAQ,GAAG,+EAA+E,CAC3F,CAAC;QACJ,CAAC;QACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO,OAAO,CAAC,aAAa,GAAG,oBAAoB,CAAC,CAAC;QACvD,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,GAAG,+BAA+B,EAAE,CAAC;YACnD,OAAO,OAAO,CACZ,aAAa,GAAG,oBAAoB,+BAA+B,oBAAoB,KAAK,CAAC,MAAM,GAAG,CACvG,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -11,7 +11,8 @@ import type { ModelProvider, ProviderRegistry } from './types.js';
11
11
  * non-empty; `models[]` non-empty with unique `name` per entry;
12
12
  * per-model `contextWindow` positive integer; per-model `cost`
13
13
  * non-negative; optional per-model `p95LatencyMs` / `maxOutputTokens`
14
- * well-shaped; `invoke` is a function. Duplicate ids within a tenant
14
+ * well-shaped; `labels` within their limits (`provider-labels.ts`);
15
+ * `invoke` is a function. Duplicate ids within a tenant
15
16
  * are refused — accidental clobber of a running provider would be
16
17
  * catastrophic under a live workload. The same `providerId` may be
17
18
  * registered under different tenants (that's the whole point).
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEtD,OAAO,KAAK,EAAE,eAAe,EAAgD,MAAM,aAAa,CAAC;AACjG,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAElE;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,GAAE,SAAS;IAAE,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAA;CAAE,EAAO,GACtF;IACD,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,GAAG,MAAM,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;CACtF,CAsJA"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEtD,OAAO,KAAK,EAAE,eAAe,EAAgD,MAAM,aAAa,CAAC;AAEjG,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAElE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,GAAE,SAAS;IAAE,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAA;CAAE,EAAO,GACtF;IACD,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,GAAG,MAAM,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;CACtF,CAwJA"}
package/dist/registry.js CHANGED
@@ -1,5 +1,6 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  // Copyright (C) 2026 Kindgi Inc.
3
+ import { validateProviderLabels } from './provider-labels.js';
3
4
  /**
4
5
  * Create an in-memory registry of model providers. Tenant-scoped:
5
6
  * each tenant owns its own `providerId → ModelProvider` map. The
@@ -10,7 +11,8 @@
10
11
  * non-empty; `models[]` non-empty with unique `name` per entry;
11
12
  * per-model `contextWindow` positive integer; per-model `cost`
12
13
  * non-negative; optional per-model `p95LatencyMs` / `maxOutputTokens`
13
- * well-shaped; `invoke` is a function. Duplicate ids within a tenant
14
+ * well-shaped; `labels` within their limits (`provider-labels.ts`);
15
+ * `invoke` is a function. Duplicate ids within a tenant
14
16
  * are refused — accidental clobber of a running provider would be
15
17
  * catastrophic under a live workload. The same `providerId` may be
16
18
  * registered under different tenants (that's the whole point).
@@ -102,6 +104,9 @@ export function createProviderRegistry(seed = []) {
102
104
  };
103
105
  }
104
106
  }
107
+ const badLabels = validateProviderLabels(p.metadata.id, p.metadata.labels);
108
+ if (badLabels !== undefined)
109
+ return { code: 'invalid-provider', ...badLabels };
105
110
  if (typeof p.invoke !== 'function') {
106
111
  return {
107
112
  code: 'invalid-provider',
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { TenantId } from '@kindgi/types';
1
+ import type { ProjectId, RunId, TenantId } from '@kindgi/types';
2
2
  /**
3
3
  * The closed set of feature flags an agent can require. Matches
4
4
  * `@kindgi/specs/capability.schema.json` FeatureRequirement enum. Providers self-
@@ -281,6 +281,12 @@ export interface ProviderMetadata {
281
281
  * to one says so (`RoutingDecision.fallback`).
282
282
  */
283
283
  readonly fallback?: boolean;
284
+ /**
285
+ * Bookkeeping, such as who manages the provider: string keys to
286
+ * string values. The router ignores them. The limits and the
287
+ * convention key (`kindgi.com/managed-by`) are in `provider-labels.ts`.
288
+ */
289
+ readonly labels?: Readonly<Record<string, string>>;
284
290
  }
285
291
  /**
286
292
  * A single message in a model call. Standardised wire shape — provider
@@ -351,12 +357,27 @@ export interface ModelCallInput {
351
357
  /** Cooperative cancellation. Handlers should observe. */
352
358
  readonly abortSignal?: AbortSignal;
353
359
  }
354
- /** Usage counters — used by the cost meter. */
360
+ /**
361
+ * A model call's token counts. `promptTokens` and `completionTokens` are
362
+ * the totals; the optional counts are parts of them, there when the
363
+ * provider reports them (a reported 0 is 0; a part it doesn't report is
364
+ * absent):
365
+ * - `cacheReadTokens` and `cacheWriteTokens` are part of `promptTokens`;
366
+ * - `reasoningTokens` are part of `completionTokens`.
367
+ * Nothing is folded away: the provider's own counts are in
368
+ * `ModelCallResult.rawUsage`.
369
+ */
355
370
  export interface UsageCounters {
371
+ /** Every input token, cache reads and writes included. */
356
372
  readonly promptTokens: number;
373
+ /** Every output token, reasoning included. */
357
374
  readonly completionTokens: number;
358
- /** Some providers report cached tokens separately. Optional. */
359
- readonly cachedTokens?: number;
375
+ /** Prompt tokens read from the provider's prompt cache. */
376
+ readonly cacheReadTokens?: number;
377
+ /** Prompt tokens written to the provider's prompt cache. */
378
+ readonly cacheWriteTokens?: number;
379
+ /** Completion tokens the model spent reasoning ("thinking"). */
380
+ readonly reasoningTokens?: number;
360
381
  }
361
382
  /**
362
383
  * The result of a model invocation. `finishReason` matches OpenAI-style
@@ -379,6 +400,79 @@ export interface ModelCallResult {
379
400
  readonly id: string;
380
401
  readonly model: string;
381
402
  };
403
+ /**
404
+ * The exact model version the vendor says answered. Vendors alias: a
405
+ * `…-pro` request can be served by `…-pro-001`.
406
+ */
407
+ readonly servedModel?: string;
408
+ /** The vendor's id for the request: Anthropic's `request-id`, OpenAI's `x-request-id`, Gemini's `responseId`. */
409
+ readonly providerRequestId?: string;
410
+ /** HTTP attempts the call took, its client's own retries included. */
411
+ readonly attempts?: number;
412
+ /** The vendor's usage object, exactly as it reported it. */
413
+ readonly rawUsage?: Readonly<Record<string, unknown>>;
414
+ }
415
+ /**
416
+ * One model call, as a usage sink records it: who made it (tenant,
417
+ * project, run, agent, step), which provider and model answered, and what
418
+ * the call used. Never the messages.
419
+ */
420
+ export interface ModelUsageRecord {
421
+ /** The call's id, unique per call; its provenance node carries it too. */
422
+ readonly callId: string;
423
+ readonly tenantId: TenantId;
424
+ readonly projectId?: ProjectId;
425
+ readonly runId?: RunId;
426
+ readonly agentId?: string;
427
+ readonly agentVersion?: string;
428
+ readonly conversationId?: string;
429
+ /** The step of the run that made the call (`model-call`, `evaluate-guardrails`). */
430
+ readonly nodeId?: string;
431
+ /** The turn's step: its loop iteration. */
432
+ readonly step?: number;
433
+ /**
434
+ * What the call was for, when it isn't the turn's own model step:
435
+ * `guardrail-judge:<guardrail id>`.
436
+ */
437
+ readonly purpose?: string;
438
+ readonly providerId: string;
439
+ /** The model of the provider invoked. */
440
+ readonly model: string;
441
+ /** The router picked a fallback provider (`ProviderMetadata.fallback`). */
442
+ readonly fallback?: boolean;
443
+ /** When the call ended (ISO 8601). */
444
+ readonly occurredAt: string;
445
+ /** `ok`: the provider answered. `failed`: the call threw. */
446
+ readonly status: 'ok' | 'failed';
447
+ /** What the answer used, and what the vendor said about it (`ok`). */
448
+ readonly result?: Omit<ModelCallResult, 'message'>;
449
+ /**
450
+ * Why the call failed (`failed`), and the HTTP attempts it took before
451
+ * it did, when they were counted (`attemptsOf`).
452
+ */
453
+ readonly error?: {
454
+ readonly message: string;
455
+ readonly attempts?: number;
456
+ };
457
+ /** How long the call took, failed or not. */
458
+ readonly durationMs: number;
459
+ /**
460
+ * Set on a replay turn's calls: the past run it re-runs (`of`) and the
461
+ * eval run it's for, so eval spend can be told apart from production.
462
+ */
463
+ readonly replay?: {
464
+ readonly of: string;
465
+ readonly evalRunId: string;
466
+ };
467
+ }
468
+ /**
469
+ * Where model calls are recorded: the runtime's cost ledger. The caller
470
+ * awaits `record` before it goes on with the answer, and a `record` that
471
+ * throws fails the caller: a model call isn't left unrecorded. Recording
472
+ * the same `callId` again changes nothing.
473
+ */
474
+ export interface UsageSink {
475
+ record(call: ModelUsageRecord): Promise<void>;
382
476
  }
383
477
  /**
384
478
  * A registered provider — metadata + invoke function. Registered once at
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { Result } from '@kindgi/types';
2
+ import type { ModelUsageRecord, UsageSink } from './types.js';
3
+ /** How `recordModelUsage` tries a sink that fails. */
4
+ export interface RecordModelUsageOptions {
5
+ /** Tries in all, the first included. Default 3. */
6
+ readonly tries?: number;
7
+ /** The wait before the second try; each later wait is 4× the one before. Default 50 ms. */
8
+ readonly backoffMs?: number;
9
+ }
10
+ /**
11
+ * Record one model call in `sink`, trying again when the sink fails: a
12
+ * record is idempotent by `callId`, so a retry can't count a call twice.
13
+ * `err` carries the last failure when every try failed; the caller
14
+ * decides what that means for its step.
15
+ */
16
+ export declare function recordModelUsage(sink: UsageSink, call: ModelUsageRecord, options?: RecordModelUsageOptions): Promise<Result<void, unknown>>;
17
+ //# sourceMappingURL=usage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage.d.ts","sourceRoot":"","sources":["../src/usage.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE9D,sDAAsD;AACtD,MAAM,WAAW,uBAAuB;IACtC,mDAAmD;IACnD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,2FAA2F;IAC3F,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,gBAAgB,EACtB,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAiBhC"}
package/dist/usage.js ADDED
@@ -0,0 +1,28 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+ /**
4
+ * Record one model call in `sink`, trying again when the sink fails: a
5
+ * record is idempotent by `callId`, so a retry can't count a call twice.
6
+ * `err` carries the last failure when every try failed; the caller
7
+ * decides what that means for its step.
8
+ */
9
+ export async function recordModelUsage(sink, call, options = {}) {
10
+ const tries = Math.max(1, options.tries ?? 3);
11
+ let wait = options.backoffMs ?? 50;
12
+ let last;
13
+ for (let attempt = 1; attempt <= tries; attempt += 1) {
14
+ try {
15
+ await sink.record(call);
16
+ return { kind: 'ok', value: undefined };
17
+ }
18
+ catch (error) {
19
+ last = error;
20
+ if (attempt < tries) {
21
+ await new Promise((resolve) => setTimeout(resolve, wait));
22
+ wait *= 4;
23
+ }
24
+ }
25
+ }
26
+ return { kind: 'err', error: last };
27
+ }
28
+ //# sourceMappingURL=usage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage.js","sourceRoot":"","sources":["../src/usage.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAcjC;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAAe,EACf,IAAsB,EACtB,UAAmC,EAAE;IAErC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;IAC9C,IAAI,IAAI,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC;IACnC,IAAI,IAAa,CAAC;IAClB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,KAAK,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC;QACrD,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACxB,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;QAC1C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,GAAG,KAAK,CAAC;YACb,IAAI,OAAO,GAAG,KAAK,EAAE,CAAC;gBACpB,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;gBAC1D,IAAI,IAAI,CAAC,CAAC;YACZ,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACtC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kindgi/capabilities",
3
- "version": "0.1.2",
3
+ "version": "0.1.4-rc.0",
4
4
  "description": "Capability declarations + provider router for Kindgi™. Agents declare what they need from a model (features such as structured-output or tool-use, context window, cost, region, latency, provider and model allow/deny lists) and what they prefer; the router picks a registered (provider, model) pair that satisfies every hard constraint plus tenant policy, ranked by soft preferences, and reports per requirement which candidates it rejected when none qualify. Also the provider-neutral ModelProvider contract, a tenant-scoped provider registry, and an adapter-factory registry. Capability kinds are open strings matched by equality; llm-inference is the default.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -20,6 +20,11 @@
20
20
  "types": "./dist/index.d.ts",
21
21
  "import": "./dist/index.js",
22
22
  "default": "./dist/index.js"
23
+ },
24
+ "./attempts": {
25
+ "types": "./dist/attempts.d.ts",
26
+ "import": "./dist/attempts.js",
27
+ "default": "./dist/attempts.js"
23
28
  }
24
29
  },
25
30
  "files": [
@@ -30,12 +35,12 @@
30
35
  "type-manifest.json"
31
36
  ],
32
37
  "dependencies": {
33
- "@kindgi/platform": "0.1.2",
34
- "@kindgi/schema": "0.1.2",
35
- "@kindgi/types": "0.1.2"
38
+ "@kindgi/platform": "0.1.4-rc.0",
39
+ "@kindgi/schema": "0.1.4-rc.0",
40
+ "@kindgi/types": "0.1.4-rc.0"
36
41
  },
37
42
  "devDependencies": {
38
- "@kindgi/specs": "0.1.2",
43
+ "@kindgi/specs": "0.1.4-rc.0",
39
44
  "@types/node": "^22.10.5",
40
45
  "typescript": "^5.7.3",
41
46
  "vitest": "^2.1.8"
@@ -0,0 +1,67 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+
4
+ import { AsyncLocalStorage } from 'node:async_hooks';
5
+
6
+ /**
7
+ * Counts each model call's HTTP attempts, retries included, without
8
+ * taking over the vendor SDK's retry policy (its `Retry-After` handling,
9
+ * its backoff). An adapter gives its SDK client `fetch`, and runs each
10
+ * call inside `count`: every request the SDK sends for that call, the
11
+ * first and each retry, goes through `fetch` and is counted for it.
12
+ * Calls running at the same time are counted apart.
13
+ *
14
+ * A call that throws throws its own error, unchanged (callers may check
15
+ * its type or status); the attempts it took are `attemptsOf(error)`.
16
+ *
17
+ * Node only (`AsyncLocalStorage`): it's the `@kindgi/capabilities/attempts`
18
+ * entry, apart from the package's runtime-neutral main entry.
19
+ */
20
+ export interface AttemptCounter {
21
+ /** The `fetch` the SDK client sends with: counts, then sends with `inner`. */
22
+ readonly fetch: typeof globalThis.fetch;
23
+ /** Run one call; its result, and the HTTP attempts it took. */
24
+ count<T>(call: () => PromiseLike<T>): Promise<{ readonly value: T; readonly attempts: number }>;
25
+ }
26
+
27
+ /** The attempts of counted calls that threw, by their error (`attemptsOf`). */
28
+ const failedAttempts = new WeakMap<object, number>();
29
+
30
+ /**
31
+ * An `AttemptCounter` over `inner`. Without one, it sends with the global
32
+ * `fetch` as it is at each request, so a `fetch` patched after the
33
+ * provider was built (a test's mock, a tracer) still sees the requests.
34
+ */
35
+ export function createAttemptCounter(inner?: typeof globalThis.fetch): AttemptCounter {
36
+ const calls = new AsyncLocalStorage<{ attempts: number }>();
37
+ return {
38
+ fetch: (input, init) => {
39
+ const call = calls.getStore();
40
+ if (call !== undefined) call.attempts += 1;
41
+ return (inner ?? globalThis.fetch)(input, init);
42
+ },
43
+ async count(call) {
44
+ const state = { attempts: 0 };
45
+ try {
46
+ // Awaited inside the store: an SDK's promise can be lazy (OpenAI's
47
+ // `APIPromise` sends, and retries a body that stalls, only when
48
+ // it's awaited), and those requests are this call's too.
49
+ const value = await calls.run(state, async () => await call());
50
+ return { value, attempts: state.attempts };
51
+ } catch (error) {
52
+ if (typeof error === 'object' && error !== null && state.attempts > 0) {
53
+ failedAttempts.set(error, state.attempts);
54
+ }
55
+ throw error;
56
+ }
57
+ },
58
+ };
59
+ }
60
+
61
+ /**
62
+ * The HTTP attempts a counted call took before it threw `error`;
63
+ * `undefined` when it wasn't counted, or sent nothing.
64
+ */
65
+ export function attemptsOf(error: unknown): number | undefined {
66
+ return typeof error === 'object' && error !== null ? failedAttempts.get(error) : undefined;
67
+ }
package/src/index.ts CHANGED
@@ -11,9 +11,18 @@ export type {
11
11
  PrepareEvent,
12
12
  } from './adapter-factory.js';
13
13
  export { CAPABILITY_SCHEMA_URI, defineCapability } from './define.js';
14
+ export {
15
+ PROVIDER_LABEL_KEY,
16
+ PROVIDER_LABEL_MANAGED_BY,
17
+ PROVIDER_LABEL_VALUE_MAX_LENGTH,
18
+ PROVIDER_LABELS_MAX_KEYS,
19
+ validateProviderLabels,
20
+ } from './provider-labels.js';
14
21
  export { createProviderRegistry } from './registry.js';
15
22
  export { matchTuples, route } from './router.js';
16
23
  export type { RouteInput } from './router.js';
24
+ export { recordModelUsage } from './usage.js';
25
+ export type { RecordModelUsageOptions } from './usage.js';
17
26
  export { BUILT_IN_CAPABILITY_KINDS, DEFAULT_CAPABILITY_KIND, FEATURES } from './types.js';
18
27
  export type {
19
28
  Budget,
@@ -23,6 +32,7 @@ export type {
23
32
  ComparisonOp,
24
33
  Feature,
25
34
  ModelCallInput,
35
+ ModelUsageRecord,
26
36
  ModelCallResult,
27
37
  ModelMessage,
28
38
  ModelInfo,
@@ -40,6 +50,7 @@ export type {
40
50
  TenantPolicy,
41
51
  UpperBoundOp,
42
52
  UsageCounters,
53
+ UsageSink,
43
54
  } from './types.js';
44
55
  export type {
45
56
  BudgetExceededError,
@@ -0,0 +1,58 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+
4
+ /**
5
+ * `ProviderMetadata.labels`: string keys to string values, for whoever
6
+ * manages a provider to record that it does. The router ignores them.
7
+ *
8
+ * One validator, used where a provider is registered in-process
9
+ * (`createProviderRegistry`) and over the wire (`POST /v1/providers`),
10
+ * so the two accept the same labels.
11
+ */
12
+
13
+ /** The convention key for who manages a provider: `kindgi-dev`, `kindgi-dev:<pack id>`, `kindgi-deploy:<environment>`. */
14
+ export const PROVIDER_LABEL_MANAGED_BY = 'kindgi.com/managed-by';
15
+
16
+ export const PROVIDER_LABELS_MAX_KEYS = 32;
17
+ export const PROVIDER_LABEL_VALUE_MAX_LENGTH = 256;
18
+
19
+ /** 1–63 characters: lowercase letters and digits, with `.`, `-`, `_` or `/` inside. */
20
+ export const PROVIDER_LABEL_KEY = /^[a-z0-9]([a-z0-9._/-]{0,61}[a-z0-9])?$/;
21
+
22
+ /**
23
+ * `undefined` when `labels` is absent or well formed; otherwise why not,
24
+ * as the `invalid-provider` error's `message` and `reason`.
25
+ */
26
+ export function validateProviderLabels(
27
+ providerId: string,
28
+ labels: unknown,
29
+ ): { readonly message: string; readonly reason: 'invalid-labels' } | undefined {
30
+ if (labels === undefined) return undefined;
31
+ const invalid = (detail: string) => ({
32
+ message: `provider "${providerId}" labels ${detail}`,
33
+ reason: 'invalid-labels' as const,
34
+ });
35
+ if (typeof labels !== 'object' || labels === null || Array.isArray(labels)) {
36
+ return invalid('must be an object of string keys to string values');
37
+ }
38
+ const entries = Object.entries(labels);
39
+ if (entries.length > PROVIDER_LABELS_MAX_KEYS) {
40
+ return invalid(`may have at most ${PROVIDER_LABELS_MAX_KEYS} keys (got ${entries.length})`);
41
+ }
42
+ for (const [key, value] of entries) {
43
+ if (!PROVIDER_LABEL_KEY.test(key)) {
44
+ return invalid(
45
+ `key "${key}" must be 1-63 lowercase letters and digits, with ".", "-", "_" or "/" inside`,
46
+ );
47
+ }
48
+ if (typeof value !== 'string') {
49
+ return invalid(`value of "${key}" must be a string`);
50
+ }
51
+ if (value.length > PROVIDER_LABEL_VALUE_MAX_LENGTH) {
52
+ return invalid(
53
+ `value of "${key}" may be at most ${PROVIDER_LABEL_VALUE_MAX_LENGTH} characters (got ${value.length})`,
54
+ );
55
+ }
56
+ }
57
+ return undefined;
58
+ }
package/src/registry.ts CHANGED
@@ -4,6 +4,7 @@
4
4
  import type { Result, TenantId } from '@kindgi/types';
5
5
 
6
6
  import type { CapabilityError, DuplicateProviderError, InvalidProviderError } from './errors.js';
7
+ import { validateProviderLabels } from './provider-labels.js';
7
8
  import type { ModelProvider, ProviderRegistry } from './types.js';
8
9
 
9
10
  /**
@@ -16,7 +17,8 @@ import type { ModelProvider, ProviderRegistry } from './types.js';
16
17
  * non-empty; `models[]` non-empty with unique `name` per entry;
17
18
  * per-model `contextWindow` positive integer; per-model `cost`
18
19
  * non-negative; optional per-model `p95LatencyMs` / `maxOutputTokens`
19
- * well-shaped; `invoke` is a function. Duplicate ids within a tenant
20
+ * well-shaped; `labels` within their limits (`provider-labels.ts`);
21
+ * `invoke` is a function. Duplicate ids within a tenant
20
22
  * are refused — accidental clobber of a running provider would be
21
23
  * catastrophic under a live workload. The same `providerId` may be
22
24
  * registered under different tenants (that's the whole point).
@@ -123,6 +125,8 @@ export function createProviderRegistry(
123
125
  };
124
126
  }
125
127
  }
128
+ const badLabels = validateProviderLabels(p.metadata.id, p.metadata.labels);
129
+ if (badLabels !== undefined) return { code: 'invalid-provider', ...badLabels };
126
130
  if (typeof p.invoke !== 'function') {
127
131
  return {
128
132
  code: 'invalid-provider',
package/src/types.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  // Copyright (C) 2026 Kindgi Inc.
3
3
 
4
- import type { TenantId } from '@kindgi/types';
4
+ import type { ProjectId, RunId, TenantId } from '@kindgi/types';
5
5
 
6
6
  /**
7
7
  * The closed set of feature flags an agent can require. Matches
@@ -308,6 +308,12 @@ export interface ProviderMetadata {
308
308
  * to one says so (`RoutingDecision.fallback`).
309
309
  */
310
310
  readonly fallback?: boolean;
311
+ /**
312
+ * Bookkeeping, such as who manages the provider: string keys to
313
+ * string values. The router ignores them. The limits and the
314
+ * convention key (`kindgi.com/managed-by`) are in `provider-labels.ts`.
315
+ */
316
+ readonly labels?: Readonly<Record<string, string>>;
311
317
  }
312
318
 
313
319
  /**
@@ -384,12 +390,27 @@ export interface ModelCallInput {
384
390
  readonly abortSignal?: AbortSignal;
385
391
  }
386
392
 
387
- /** Usage counters — used by the cost meter. */
393
+ /**
394
+ * A model call's token counts. `promptTokens` and `completionTokens` are
395
+ * the totals; the optional counts are parts of them, there when the
396
+ * provider reports them (a reported 0 is 0; a part it doesn't report is
397
+ * absent):
398
+ * - `cacheReadTokens` and `cacheWriteTokens` are part of `promptTokens`;
399
+ * - `reasoningTokens` are part of `completionTokens`.
400
+ * Nothing is folded away: the provider's own counts are in
401
+ * `ModelCallResult.rawUsage`.
402
+ */
388
403
  export interface UsageCounters {
404
+ /** Every input token, cache reads and writes included. */
389
405
  readonly promptTokens: number;
406
+ /** Every output token, reasoning included. */
390
407
  readonly completionTokens: number;
391
- /** Some providers report cached tokens separately. Optional. */
392
- readonly cachedTokens?: number;
408
+ /** Prompt tokens read from the provider's prompt cache. */
409
+ readonly cacheReadTokens?: number;
410
+ /** Prompt tokens written to the provider's prompt cache. */
411
+ readonly cacheWriteTokens?: number;
412
+ /** Completion tokens the model spent reasoning ("thinking"). */
413
+ readonly reasoningTokens?: number;
393
414
  }
394
415
 
395
416
  /**
@@ -410,6 +431,75 @@ export interface ModelCallResult {
410
431
  readonly durationMs: number;
411
432
  /** Provider + model actually invoked (in case the router picked a variant). */
412
433
  readonly provider: { readonly id: string; readonly model: string };
434
+ /**
435
+ * The exact model version the vendor says answered. Vendors alias: a
436
+ * `…-pro` request can be served by `…-pro-001`.
437
+ */
438
+ readonly servedModel?: string;
439
+ /** The vendor's id for the request: Anthropic's `request-id`, OpenAI's `x-request-id`, Gemini's `responseId`. */
440
+ readonly providerRequestId?: string;
441
+ /** HTTP attempts the call took, its client's own retries included. */
442
+ readonly attempts?: number;
443
+ /** The vendor's usage object, exactly as it reported it. */
444
+ readonly rawUsage?: Readonly<Record<string, unknown>>;
445
+ }
446
+
447
+ /**
448
+ * One model call, as a usage sink records it: who made it (tenant,
449
+ * project, run, agent, step), which provider and model answered, and what
450
+ * the call used. Never the messages.
451
+ */
452
+ export interface ModelUsageRecord {
453
+ /** The call's id, unique per call; its provenance node carries it too. */
454
+ readonly callId: string;
455
+ readonly tenantId: TenantId;
456
+ readonly projectId?: ProjectId;
457
+ readonly runId?: RunId;
458
+ readonly agentId?: string;
459
+ readonly agentVersion?: string;
460
+ readonly conversationId?: string;
461
+ /** The step of the run that made the call (`model-call`, `evaluate-guardrails`). */
462
+ readonly nodeId?: string;
463
+ /** The turn's step: its loop iteration. */
464
+ readonly step?: number;
465
+ /**
466
+ * What the call was for, when it isn't the turn's own model step:
467
+ * `guardrail-judge:<guardrail id>`.
468
+ */
469
+ readonly purpose?: string;
470
+ readonly providerId: string;
471
+ /** The model of the provider invoked. */
472
+ readonly model: string;
473
+ /** The router picked a fallback provider (`ProviderMetadata.fallback`). */
474
+ readonly fallback?: boolean;
475
+ /** When the call ended (ISO 8601). */
476
+ readonly occurredAt: string;
477
+ /** `ok`: the provider answered. `failed`: the call threw. */
478
+ readonly status: 'ok' | 'failed';
479
+ /** What the answer used, and what the vendor said about it (`ok`). */
480
+ readonly result?: Omit<ModelCallResult, 'message'>;
481
+ /**
482
+ * Why the call failed (`failed`), and the HTTP attempts it took before
483
+ * it did, when they were counted (`attemptsOf`).
484
+ */
485
+ readonly error?: { readonly message: string; readonly attempts?: number };
486
+ /** How long the call took, failed or not. */
487
+ readonly durationMs: number;
488
+ /**
489
+ * Set on a replay turn's calls: the past run it re-runs (`of`) and the
490
+ * eval run it's for, so eval spend can be told apart from production.
491
+ */
492
+ readonly replay?: { readonly of: string; readonly evalRunId: string };
493
+ }
494
+
495
+ /**
496
+ * Where model calls are recorded: the runtime's cost ledger. The caller
497
+ * awaits `record` before it goes on with the answer, and a `record` that
498
+ * throws fails the caller: a model call isn't left unrecorded. Recording
499
+ * the same `callId` again changes nothing.
500
+ */
501
+ export interface UsageSink {
502
+ record(call: ModelUsageRecord): Promise<void>;
413
503
  }
414
504
 
415
505
  /**
package/src/usage.ts ADDED
@@ -0,0 +1,43 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+
4
+ import type { Result } from '@kindgi/types';
5
+
6
+ import type { ModelUsageRecord, UsageSink } from './types.js';
7
+
8
+ /** How `recordModelUsage` tries a sink that fails. */
9
+ export interface RecordModelUsageOptions {
10
+ /** Tries in all, the first included. Default 3. */
11
+ readonly tries?: number;
12
+ /** The wait before the second try; each later wait is 4× the one before. Default 50 ms. */
13
+ readonly backoffMs?: number;
14
+ }
15
+
16
+ /**
17
+ * Record one model call in `sink`, trying again when the sink fails: a
18
+ * record is idempotent by `callId`, so a retry can't count a call twice.
19
+ * `err` carries the last failure when every try failed; the caller
20
+ * decides what that means for its step.
21
+ */
22
+ export async function recordModelUsage(
23
+ sink: UsageSink,
24
+ call: ModelUsageRecord,
25
+ options: RecordModelUsageOptions = {},
26
+ ): Promise<Result<void, unknown>> {
27
+ const tries = Math.max(1, options.tries ?? 3);
28
+ let wait = options.backoffMs ?? 50;
29
+ let last: unknown;
30
+ for (let attempt = 1; attempt <= tries; attempt += 1) {
31
+ try {
32
+ await sink.record(call);
33
+ return { kind: 'ok', value: undefined };
34
+ } catch (error) {
35
+ last = error;
36
+ if (attempt < tries) {
37
+ await new Promise((resolve) => setTimeout(resolve, wait));
38
+ wait *= 4;
39
+ }
40
+ }
41
+ }
42
+ return { kind: 'err', error: last };
43
+ }