@kindgi/capabilities 0.0.0-bootstrap.0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,498 @@
1
+ import type { TenantId } from '@kindgi/types';
2
+ /**
3
+ * The closed set of feature flags an agent can require. Matches
4
+ * `@kindgi/specs/capability.schema.json` FeatureRequirement enum. Providers self-
5
+ * report which of these they satisfy.
6
+ */
7
+ export declare const FEATURES: readonly ["structured-output", "vision", "audio-input", "audio-output", "tool-use", "parallel-tool-use", "thinking", "long-context", "code-execution", "web-search", "file-search", "streaming", "batch"];
8
+ export type Feature = (typeof FEATURES)[number];
9
+ /** Comparison operator used by numeric requirements (context, cost, latency). */
10
+ export type ComparisonOp = '>=' | '>' | '=' | '<=' | '<';
11
+ /** Numeric-comparison-only operators (latency can only bound from above). */
12
+ export type UpperBoundOp = '<=' | '<';
13
+ /**
14
+ * One member of the Requirement union — hard constraints that MUST hold.
15
+ *
16
+ * `providers` filters on `ProviderMetadata.id` (vendor connection);
17
+ * `models` filters on `ModelInfo.name` (specific model within a
18
+ * connection). Both may appear in the same capability declaration —
19
+ * "any provider EXCEPT anthropic, and any model EXCEPT haiku."
20
+ */
21
+ export type Requirement = {
22
+ readonly feature: Feature;
23
+ } | {
24
+ readonly contextWindow: {
25
+ readonly op: ComparisonOp;
26
+ readonly value: number;
27
+ };
28
+ } | {
29
+ readonly costPerCall: {
30
+ readonly op: ComparisonOp;
31
+ readonly usd: number;
32
+ };
33
+ } | {
34
+ readonly region: string;
35
+ } | {
36
+ readonly p95LatencyMs: {
37
+ readonly op: UpperBoundOp;
38
+ readonly value: number;
39
+ };
40
+ } | {
41
+ readonly providers: {
42
+ readonly allow?: readonly string[];
43
+ readonly deny?: readonly string[];
44
+ };
45
+ } | {
46
+ readonly models: {
47
+ readonly allow?: readonly string[];
48
+ readonly deny?: readonly string[];
49
+ };
50
+ };
51
+ /**
52
+ * A soft preference. Router filters by `needs` first, then ranks the
53
+ * survivors by summed weights of matched preferences.
54
+ *
55
+ * `feature` may be a canonical Feature name (e.g. `'thinking'`) or a
56
+ * soft attribute the provider self-reports (`'lower-cost'`,
57
+ * `'lower-latency'`, `'higher-accuracy'`, `'local'`, etc.). Weight can be
58
+ * negative (deprioritize).
59
+ */
60
+ export interface Preference {
61
+ readonly feature: string;
62
+ readonly weight: number;
63
+ }
64
+ /**
65
+ * Per-invocation budget. Declarative: carried with the declaration but not
66
+ * enforced by the runtime (per-turn spend is capped by the agent's
67
+ * `budget.maxCostUsd`).
68
+ */
69
+ export interface Budget {
70
+ readonly maxCostUsd?: number;
71
+ readonly maxTokens?: number;
72
+ readonly maxDurationMs?: number;
73
+ }
74
+ /**
75
+ * A capability declaration. Every agent (or every model-invoking node)
76
+ * declares one; the router uses it to pick a provider.
77
+ *
78
+ * `kind` discriminates the resource type being requested. An absent
79
+ * value is equivalent to `'llm-inference'`. Non-LLM kinds (`embedding`, `gpu-compute`,
80
+ * `sandbox-exec`, `browser-session`) are declared here as strings so
81
+ * adapter packages can register providers of that kind without a
82
+ * schema break. The router filters providers by
83
+ * `metadata.capabilityKind === capability.kind`.
84
+ */
85
+ export interface Capability {
86
+ readonly kind?: CapabilityKind;
87
+ readonly needs: readonly Requirement[];
88
+ readonly prefer?: readonly Preference[];
89
+ readonly budget?: Budget;
90
+ }
91
+ /**
92
+ * Open string discriminating capability kinds. Well-known values
93
+ * enumerated in `BUILT_IN_CAPABILITY_KINDS`. Adapters register
94
+ * providers of other kinds by declaring their own strings; the router
95
+ * matches strictly on equality.
96
+ */
97
+ export type CapabilityKind = string;
98
+ /** Well-known capability kinds — for enums, schema validation, docs. */
99
+ export declare const BUILT_IN_CAPABILITY_KINDS: readonly ["llm-inference", "embedding", "gpu-compute", "sandbox-exec", "browser-session"];
100
+ export type BuiltInCapabilityKind = (typeof BUILT_IN_CAPABILITY_KINDS)[number];
101
+ /** Default kind used when Capability.kind is omitted. */
102
+ export declare const DEFAULT_CAPABILITY_KIND: CapabilityKind;
103
+ /**
104
+ * Structured rejection reason surfaced when a provider fails a
105
+ * requirement. Each variant carries `code` (for programmatic
106
+ * matching) and `message` (for logs). Downstream callers can
107
+ * `switch (r.code)` to route on specific failure modes without
108
+ * string-parsing.
109
+ *
110
+ * The router's requirement checks return this discriminated union
111
+ * (rather than a bare string) so consumers of
112
+ * `CapabilityUnsatisfiableError.reasons[].rejectingProviders[].reason`
113
+ * can inspect programmatically.
114
+ */
115
+ export type RejectionReason = {
116
+ readonly code: 'missing-feature';
117
+ readonly message: string;
118
+ readonly feature: string;
119
+ } | {
120
+ readonly code: 'context-window-mismatch';
121
+ readonly message: string;
122
+ readonly observed: number;
123
+ readonly op: ComparisonOp;
124
+ readonly wanted: number;
125
+ } | {
126
+ readonly code: 'cost-exceeds-cap';
127
+ readonly message: string;
128
+ readonly observedUsdPer1k: number;
129
+ readonly op: ComparisonOp;
130
+ readonly wantedUsd: number;
131
+ } | {
132
+ readonly code: 'region-mismatch';
133
+ readonly message: string;
134
+ readonly observed: string;
135
+ readonly wanted: string;
136
+ } | {
137
+ readonly code: 'p95-latency-unknown';
138
+ readonly message: string;
139
+ } | {
140
+ readonly code: 'p95-latency-exceeds';
141
+ readonly message: string;
142
+ readonly observedMs: number;
143
+ readonly op: UpperBoundOp;
144
+ readonly wantedMs: number;
145
+ } | {
146
+ readonly code: 'provider-on-denylist';
147
+ readonly message: string;
148
+ readonly providerId: string;
149
+ } | {
150
+ readonly code: 'provider-not-in-allowlist';
151
+ readonly message: string;
152
+ readonly providerId: string;
153
+ readonly allow: readonly string[];
154
+ } | {
155
+ readonly code: 'model-on-denylist';
156
+ readonly message: string;
157
+ readonly modelName: string;
158
+ } | {
159
+ readonly code: 'model-not-in-allowlist';
160
+ readonly message: string;
161
+ readonly modelName: string;
162
+ readonly allow: readonly string[];
163
+ } | {
164
+ readonly code: 'tenant-denied';
165
+ readonly message: string;
166
+ readonly providerId: string;
167
+ } | {
168
+ readonly code: 'tenant-not-allowed';
169
+ readonly message: string;
170
+ readonly providerId: string;
171
+ } | {
172
+ readonly code: 'tenant-model-denied';
173
+ readonly message: string;
174
+ readonly modelName: string;
175
+ } | {
176
+ readonly code: 'tenant-model-not-allowed';
177
+ readonly message: string;
178
+ readonly modelName: string;
179
+ } | {
180
+ readonly code: 'tenant-region-not-allowed';
181
+ readonly message: string;
182
+ readonly observed: string;
183
+ readonly allow: readonly string[];
184
+ } | {
185
+ readonly code: 'tenant-cost-cap-exceeded';
186
+ readonly message: string;
187
+ readonly observedUsd: number;
188
+ readonly capUsd: number;
189
+ } | {
190
+ readonly code: 'capability-kind-mismatch';
191
+ readonly message: string;
192
+ readonly observed: CapabilityKind;
193
+ readonly wanted: CapabilityKind;
194
+ } | {
195
+ readonly code: 'unknown-requirement';
196
+ readonly message: string;
197
+ };
198
+ /**
199
+ * Per-model metadata. A provider row exposes one or more models (e.g.
200
+ * Anthropic exposing Sonnet + Opus + Haiku under one API key); each
201
+ * `ModelInfo` describes one entry the router can select. The router
202
+ * picks a `(provider, model)` tuple per invocation, and the caller
203
+ * threads `ModelCallInput.model = <ModelInfo.name>` so the adapter
204
+ * knows which model to invoke.
205
+ *
206
+ * Adapters may widen `cost` via intersection types when they need
207
+ * vendor-specific fields (e.g. Anthropic prompt-cache multipliers) —
208
+ * the framework declares the mandatory shape, adapters extend.
209
+ */
210
+ export interface ModelInfo {
211
+ /** Vendor-facing model id passed to the SDK (e.g. `claude-sonnet-4-6`). */
212
+ readonly name: string;
213
+ /** Context window in tokens. */
214
+ readonly contextWindow: number;
215
+ /** Features this model supports (tool-use, thinking, structured-output, ...). */
216
+ readonly features: readonly Feature[];
217
+ /**
218
+ * Cost per 1K tokens. Prompt + completion billed separately; both
219
+ * required. Denominated in USD.
220
+ */
221
+ readonly cost: {
222
+ readonly promptUsdPer1kTokens: number;
223
+ readonly completionUsdPer1kTokens: number;
224
+ };
225
+ /** Best-effort p95 latency estimate in ms — varies by model. */
226
+ readonly p95LatencyMs?: number;
227
+ /**
228
+ * Fallback cap on output tokens. Adapters that require max_tokens on
229
+ * every request (e.g. Anthropic) use this when
230
+ * `ModelCallInput.maxOutputTokens` is unset.
231
+ */
232
+ readonly maxOutputTokens?: number;
233
+ /** Short per-model description surfaced in logs. */
234
+ readonly description?: string;
235
+ }
236
+ /**
237
+ * What a `ModelProvider` reports about itself so the router can match
238
+ * capabilities against it without invoking. Static metadata — no side
239
+ * effects, no network. Every field is provider-declared and the router
240
+ * trusts it; misrepresentation is a provider bug.
241
+ *
242
+ * Provider-level fields (`id`, `region`, `attributes`) describe the
243
+ * connection; per-model fields (context window, cost, features) live
244
+ * under `models[]` so one connection can expose multiple models. The
245
+ * router picks a `(provider, model)` tuple per invocation.
246
+ */
247
+ export interface ProviderMetadata {
248
+ readonly id: string;
249
+ /**
250
+ * Region the connection routes to. All models on this provider share
251
+ * the region (Vertex-AI-Anthropic vs Bedrock-Anthropic vs
252
+ * Anthropic-direct are separate provider rows, one per region).
253
+ * `'unspecified'` if not region-scoped.
254
+ */
255
+ readonly region: string;
256
+ /**
257
+ * Models this connection exposes. Non-empty — a provider with zero
258
+ * models is unusable and rejected at registration. `models[i].name`
259
+ * must be unique within the list.
260
+ */
261
+ readonly models: readonly ModelInfo[];
262
+ /**
263
+ * Soft attributes the provider self-reports for preference-ranking.
264
+ * Examples: `'local'`, `'lower-cost'`, `'higher-accuracy'`. Opaque to
265
+ * the router — matched by string equality against `Preference.feature`.
266
+ */
267
+ readonly attributes?: readonly string[];
268
+ /** Short human description of the connection surfaced in logs + errors. */
269
+ readonly description?: string;
270
+ /**
271
+ * Kind of resource this provider fulfils. Optional — an absent value
272
+ * defaults to `'llm-inference'`. Adapters for non-LLM kinds
273
+ * (embedding, GPU compute, sandboxes, ...) set this explicitly. The router filters providers by
274
+ * `metadata.capabilityKind === capability.kind`.
275
+ */
276
+ readonly capabilityKind?: CapabilityKind;
277
+ /**
278
+ * A fallback serves a capability only when no other provider
279
+ * satisfies it — e.g. `kindgi dev`'s scripted `dev-echo`, which keeps
280
+ * agent turns runnable until a real model is registered. A turn routed
281
+ * to one says so (`RoutingDecision.fallback`).
282
+ */
283
+ readonly fallback?: boolean;
284
+ }
285
+ /**
286
+ * A single message in a model call. Standardised wire shape — provider
287
+ * adapters translate to/from their vendor SDK format.
288
+ */
289
+ export interface ModelMessage {
290
+ readonly role: 'system' | 'user' | 'assistant' | 'tool';
291
+ /** Text content. Tool-use payloads carry their own fields; text may be empty. */
292
+ readonly content: string;
293
+ /** For role='tool': the tool call id being responded to. */
294
+ readonly toolCallId?: string;
295
+ /** For role='assistant': tool calls the model wants executed. */
296
+ readonly toolCalls?: readonly ModelToolCall[];
297
+ }
298
+ export interface ModelToolCall {
299
+ readonly id: string;
300
+ readonly name: string;
301
+ /** JSON arguments as parsed object. */
302
+ readonly arguments: Readonly<Record<string, unknown>>;
303
+ /**
304
+ * An opaque token the provider attached to this call and needs back
305
+ * when the conversation continues — Gemini's thought signature, for
306
+ * example. Callers keep it with the call, unchanged; only the adapter
307
+ * that produced it reads it.
308
+ */
309
+ readonly signature?: string;
310
+ }
311
+ /** Tool definition passed to a model call — JSON-Schema-shaped, provider-neutral. */
312
+ export interface ModelToolDefinition {
313
+ readonly name: string;
314
+ readonly description: string;
315
+ readonly inputSchema: Readonly<Record<string, unknown>>;
316
+ }
317
+ /**
318
+ * Structured-output request — the model returns JSON matching this
319
+ * schema. Shape aligns with OpenAI's `response_format.json_schema`.
320
+ *
321
+ * Adapter coverage:
322
+ * - `@kindgi/adapter-model-openai-compat` — translates to
323
+ * `response_format: { type: "json_schema", json_schema: { name,
324
+ * schema, strict: true } }`.
325
+ * - `@kindgi/adapter-model-anthropic` — ignores it (see that
326
+ * package's README).
327
+ */
328
+ export interface StructuredOutputRequest {
329
+ readonly name: string;
330
+ readonly schema: Readonly<Record<string, unknown>>;
331
+ }
332
+ /**
333
+ * The input to a model invocation. All fields provider-agnostic; each
334
+ * adapter translates to its vendor SDK format.
335
+ */
336
+ export interface ModelCallInput {
337
+ /**
338
+ * Which model to invoke. Must match one of the receiving provider's
339
+ * `metadata.models[i].name`. Set by the caller from
340
+ * `RoutingDecision.model.name` (typical path) or hand-picked when
341
+ * the caller has a specific pin in mind. Adapters that don't
342
+ * recognize the name reject with an `unknown-model` error.
343
+ */
344
+ readonly model: string;
345
+ readonly messages: readonly ModelMessage[];
346
+ readonly tools?: readonly ModelToolDefinition[];
347
+ readonly structuredOutput?: StructuredOutputRequest;
348
+ /** Sampling controls — providers translate to their equivalent. */
349
+ readonly temperature?: number;
350
+ readonly maxOutputTokens?: number;
351
+ /** Cooperative cancellation. Handlers should observe. */
352
+ readonly abortSignal?: AbortSignal;
353
+ }
354
+ /** Usage counters — used by the cost meter. */
355
+ export interface UsageCounters {
356
+ readonly promptTokens: number;
357
+ readonly completionTokens: number;
358
+ /** Some providers report cached tokens separately. Optional. */
359
+ readonly cachedTokens?: number;
360
+ }
361
+ /**
362
+ * The result of a model invocation. `finishReason` matches OpenAI-style
363
+ * conventions; adapters normalize to this set.
364
+ */
365
+ export interface ModelCallResult {
366
+ readonly message: ModelMessage;
367
+ readonly finishReason: 'stop' | 'length' | 'tool-use' | 'content-filter' | 'error';
368
+ readonly usage: UsageCounters;
369
+ /**
370
+ * Denominated in USD. Provider computes this from the actual token
371
+ * usage against its cost table. Cost meter uses it directly rather
372
+ * than re-computing (in case pricing changes between adapter
373
+ * versions).
374
+ */
375
+ readonly costUsd: number;
376
+ readonly durationMs: number;
377
+ /** Provider + model actually invoked (in case the router picked a variant). */
378
+ readonly provider: {
379
+ readonly id: string;
380
+ readonly model: string;
381
+ };
382
+ }
383
+ /**
384
+ * A registered provider — metadata + invoke function. Registered once at
385
+ * pack init; invoked many times by the router.
386
+ */
387
+ export interface ModelProvider {
388
+ readonly metadata: ProviderMetadata;
389
+ invoke(input: ModelCallInput): Promise<ModelCallResult>;
390
+ }
391
+ /**
392
+ * Registry the router consults. Tenant-scoped: each tenant owns its
393
+ * own set of registered providers, and the router only sees a
394
+ * tenant's slice.
395
+ *
396
+ * Isolation model:
397
+ * - Isolation across tenants is enforced here (not by after-the-fact
398
+ * policy filtering).
399
+ * - A deployment either (a) runs one Kindgi instance per tenant
400
+ * with its own set of registered providers, or (b) runs a shared
401
+ * instance where the framework registers per-tenant provider
402
+ * entries — same adapter binary, different keys per tenant (each
403
+ * provider closes over that tenant's secrets).
404
+ * - `TenantPolicy` still narrows the visible set at routing time
405
+ * (allow/deny lists, cost caps, region gates) — that stays
406
+ * orthogonal to tenant isolation.
407
+ *
408
+ * This aligns with the storage-side `ProviderRegistryBinding` (in
409
+ * `@kindgi/api`), whose methods all take `tenantId`. A registry backed
410
+ * by that storage reads persisted provider metadata and instantiates
411
+ * providers through an `AdapterFactoryRegistry`.
412
+ */
413
+ export interface ProviderRegistry {
414
+ register(tenantId: TenantId, provider: ModelProvider): void;
415
+ get(tenantId: TenantId, id: string): ModelProvider | undefined;
416
+ list(tenantId: TenantId): readonly ModelProvider[];
417
+ has(tenantId: TenantId, id: string): boolean;
418
+ /**
419
+ * Optional async warm-up. Storage-backed implementations
420
+ * hydrate their per-tenant instance cache from the persistent
421
+ * `ProviderRegistryBinding` on the first call for a given tenant;
422
+ * the agent runtime awaits this before the sync `list(tenantId)` call
423
+ * so the router sees the full set. In-memory implementations that
424
+ * hold their state eagerly leave this undefined, and callers skip it.
425
+ *
426
+ * Idempotent: hydrating an already-hydrated tenant returns
427
+ * immediately.
428
+ */
429
+ hydrate?(tenantId: TenantId): Promise<void>;
430
+ /**
431
+ * Optional cache invalidation. Storage-backed implementations call
432
+ * this from the provider write path (register, unregister) so the
433
+ * next `hydrate(tenantId)` re-reads from the persistent store.
434
+ * Without it, a provider registered after boot is persisted but the
435
+ * cache keeps serving the providers loaded at boot. In-memory
436
+ * implementations leave it undefined — no cache to invalidate.
437
+ */
438
+ invalidate?(tenantId: TenantId): void;
439
+ }
440
+ /**
441
+ * Per-tenant policy the router honors on top of the capability
442
+ * declaration. Every field optional; empty policy = "no additional
443
+ * constraints."
444
+ *
445
+ * `providers.allow` is a positive list of provider ids; if present,
446
+ * only listed providers are eligible — an empty list allows none.
447
+ * `providers.deny` excludes. `models.allow` / `models.deny` do the same
448
+ * at the model level (e.g. "tenant may use anthropic but not opus").
449
+ * Deny wins over allow where the two overlap at either level.
450
+ *
451
+ * `regionAllow` narrows to specific provider regions; an empty list
452
+ * allows none.
453
+ * `maxCostPerCallUsd` caps per-invocation cost using the picked
454
+ * model's `promptUsdPer1kTokens` as the cheap proxy.
455
+ * `maxTokensPerCall` caps the picked model's context window.
456
+ */
457
+ export interface TenantPolicy {
458
+ readonly tenantId: TenantId;
459
+ readonly providers?: {
460
+ readonly allow?: readonly string[];
461
+ readonly deny?: readonly string[];
462
+ };
463
+ readonly models?: {
464
+ readonly allow?: readonly string[];
465
+ readonly deny?: readonly string[];
466
+ };
467
+ readonly regionAllow?: readonly string[];
468
+ readonly maxCostPerCallUsd?: number;
469
+ readonly maxTokensPerCall?: number;
470
+ }
471
+ /** A `(provider, model)` tuple as picked by the router. */
472
+ export interface ProviderModelPick {
473
+ readonly provider: ModelProvider;
474
+ readonly model: ModelInfo;
475
+ }
476
+ /**
477
+ * The router's decision output. Returns a `(provider, model)` tuple —
478
+ * the picked connection AND the picked model within it. Callers thread
479
+ * `ModelCallInput.model = decision.model.name` when invoking
480
+ * `provider.invoke`.
481
+ */
482
+ export interface RoutingDecision {
483
+ readonly provider: ModelProvider;
484
+ readonly model: ModelInfo;
485
+ readonly reason: string;
486
+ /**
487
+ * Alternate tuples in ranked order. Useful for failover — if the top
488
+ * pick throws or hits a rate limit, the caller can retry with the
489
+ * next.
490
+ */
491
+ readonly alternates: readonly ProviderModelPick[];
492
+ /**
493
+ * `true` when only fallback providers (`ProviderMetadata.fallback`)
494
+ * satisfy the capability, so the pick is one of them.
495
+ */
496
+ readonly fallback: boolean;
497
+ }
498
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,33 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+ /**
4
+ * The closed set of feature flags an agent can require. Matches
5
+ * `@kindgi/specs/capability.schema.json` FeatureRequirement enum. Providers self-
6
+ * report which of these they satisfy.
7
+ */
8
+ export const FEATURES = [
9
+ 'structured-output',
10
+ 'vision',
11
+ 'audio-input',
12
+ 'audio-output',
13
+ 'tool-use',
14
+ 'parallel-tool-use',
15
+ 'thinking',
16
+ 'long-context',
17
+ 'code-execution',
18
+ 'web-search',
19
+ 'file-search',
20
+ 'streaming',
21
+ 'batch',
22
+ ];
23
+ /** Well-known capability kinds — for enums, schema validation, docs. */
24
+ export const BUILT_IN_CAPABILITY_KINDS = [
25
+ 'llm-inference',
26
+ 'embedding',
27
+ 'gpu-compute',
28
+ 'sandbox-exec',
29
+ 'browser-session',
30
+ ];
31
+ /** Default kind used when Capability.kind is omitted. */
32
+ export const DEFAULT_CAPABILITY_KIND = 'llm-inference';
33
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAIjC;;;;GAIG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,mBAAmB;IACnB,QAAQ;IACR,aAAa;IACb,cAAc;IACd,UAAU;IACV,mBAAmB;IACnB,UAAU;IACV,cAAc;IACd,gBAAgB;IAChB,YAAY;IACZ,aAAa;IACb,WAAW;IACX,OAAO;CACC,CAAC;AAkFX,wEAAwE;AACxE,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,eAAe;IACf,WAAW;IACX,aAAa;IACb,cAAc;IACd,iBAAiB;CACT,CAAC;AAGX,yDAAyD;AACzD,MAAM,CAAC,MAAM,uBAAuB,GAAmB,eAAe,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,55 @@
1
1
  {
2
2
  "name": "@kindgi/capabilities",
3
- "version": "0.0.0-bootstrap.0",
4
- "description": "Placeholder so a trusted publisher can be attached. Releases are published from https://github.com/kindgi/kindgi-sdk with provenance; use 0.1.0 or later.",
3
+ "version": "0.1.0",
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
- "repository": { "type": "git", "url": "git+https://github.com/kindgi/kindgi-sdk.git" }
7
- }
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/kindgi/kindgi-sdk.git",
9
+ "directory": "packages/capabilities"
10
+ },
11
+ "homepage": "https://github.com/kindgi/kindgi-sdk/tree/main/packages/capabilities#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/kindgi/kindgi-sdk/issues"
14
+ },
15
+ "type": "module",
16
+ "main": "./dist/index.js",
17
+ "types": "./dist/index.d.ts",
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "import": "./dist/index.js"
22
+ }
23
+ },
24
+ "files": [
25
+ "dist",
26
+ "src",
27
+ "README.md",
28
+ "SPEC.md",
29
+ "type-manifest.json"
30
+ ],
31
+ "dependencies": {
32
+ "@kindgi/platform": "0.1.0",
33
+ "@kindgi/schema": "0.1.0",
34
+ "@kindgi/types": "0.1.0"
35
+ },
36
+ "devDependencies": {
37
+ "@kindgi/specs": "0.1.0",
38
+ "@types/node": "^22.10.5",
39
+ "typescript": "^5.7.3",
40
+ "vitest": "^2.1.8"
41
+ },
42
+ "engines": {
43
+ "node": ">=22.0.0"
44
+ },
45
+ "publishConfig": {
46
+ "access": "public",
47
+ "provenance": true
48
+ },
49
+ "scripts": {
50
+ "build": "tsc -p tsconfig.build.json",
51
+ "typecheck": "tsc --noEmit",
52
+ "test": "vitest run",
53
+ "clean": "rm -rf dist *.tsbuildinfo"
54
+ }
55
+ }