@cleocode/contracts 2026.6.13 → 2026.6.14
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/dist/__tests__/operation-def.test.js +4 -1
- package/dist/__tests__/operation-def.test.js.map +1 -1
- package/dist/__tests__/provider-def.test.d.ts +12 -0
- package/dist/__tests__/provider-def.test.d.ts.map +1 -0
- package/dist/__tests__/provider-def.test.js +84 -0
- package/dist/__tests__/provider-def.test.js.map +1 -0
- package/dist/__tests__/service-provider.test.d.ts +17 -0
- package/dist/__tests__/service-provider.test.d.ts.map +1 -0
- package/dist/__tests__/service-provider.test.js +108 -0
- package/dist/__tests__/service-provider.test.js.map +1 -0
- package/dist/boundary.d.ts +52 -0
- package/dist/boundary.d.ts.map +1 -1
- package/dist/boundary.js +23 -0
- package/dist/boundary.js.map +1 -1
- package/dist/conduit.d.ts +171 -0
- package/dist/conduit.d.ts.map +1 -1
- package/dist/config/index.d.ts +23 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +22 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config.d.ts +2 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/dispatch/__tests__/tasks-gateway-crud-ops.test.d.ts +21 -0
- package/dist/dispatch/__tests__/tasks-gateway-crud-ops.test.d.ts.map +1 -0
- package/dist/dispatch/__tests__/tasks-gateway-crud-ops.test.js +84 -0
- package/dist/dispatch/__tests__/tasks-gateway-crud-ops.test.js.map +1 -0
- package/dist/dispatch/identity.d.ts +1 -1
- package/dist/dispatch/identity.d.ts.map +1 -1
- package/dist/dispatch/identity.js +20 -0
- package/dist/dispatch/identity.js.map +1 -1
- package/dist/dispatch/operation-def.d.ts +20 -0
- package/dist/dispatch/operation-def.d.ts.map +1 -1
- package/dist/dispatch/operations-registry.d.ts.map +1 -1
- package/dist/dispatch/operations-registry.js +1030 -46
- package/dist/dispatch/operations-registry.js.map +1 -1
- package/dist/index.d.ts +15 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -2
- package/dist/index.js.map +1 -1
- package/dist/lease-ipc/__tests__/freeze.test.js +92 -0
- package/dist/lease-ipc/__tests__/freeze.test.js.map +1 -1
- package/dist/lease-ipc/index.d.ts +2 -2
- package/dist/lease-ipc/index.d.ts.map +1 -1
- package/dist/lease-ipc/index.js +1 -1
- package/dist/lease-ipc/index.js.map +1 -1
- package/dist/lease-ipc/messages.d.ts +167 -3
- package/dist/lease-ipc/messages.d.ts.map +1 -1
- package/dist/lease-ipc/messages.js +93 -0
- package/dist/lease-ipc/messages.js.map +1 -1
- package/dist/llm/catalog-schema.d.ts +242 -0
- package/dist/llm/catalog-schema.d.ts.map +1 -0
- package/dist/llm/catalog-schema.js +153 -0
- package/dist/llm/catalog-schema.js.map +1 -0
- package/dist/llm/catalog-schema.json +139 -0
- package/dist/llm/index.d.ts +15 -0
- package/dist/llm/index.d.ts.map +1 -0
- package/dist/llm/index.js +14 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/llm/oauth.d.ts +16 -2
- package/dist/llm/oauth.d.ts.map +1 -1
- package/dist/llm/onboarding.d.ts +126 -0
- package/dist/llm/onboarding.d.ts.map +1 -0
- package/dist/llm/onboarding.js +34 -0
- package/dist/llm/onboarding.js.map +1 -0
- package/dist/llm/provider-def.d.ts +254 -0
- package/dist/llm/provider-def.d.ts.map +1 -0
- package/dist/llm/provider-def.js +93 -0
- package/dist/llm/provider-def.js.map +1 -0
- package/dist/llm/system-resolver.d.ts +42 -0
- package/dist/llm/system-resolver.d.ts.map +1 -1
- package/dist/operations/admin.d.ts +124 -1
- package/dist/operations/admin.d.ts.map +1 -1
- package/dist/operations/entities.d.ts +110 -0
- package/dist/operations/entities.d.ts.map +1 -0
- package/dist/operations/entities.js +695 -0
- package/dist/operations/entities.js.map +1 -0
- package/dist/operations/llm.d.ts +15 -0
- package/dist/operations/llm.d.ts.map +1 -1
- package/dist/operations/output-contracts-data.d.ts.map +1 -1
- package/dist/operations/output-contracts-data.js +230 -0
- package/dist/operations/output-contracts-data.js.map +1 -1
- package/dist/operations/service.d.ts +68 -0
- package/dist/operations/service.d.ts.map +1 -0
- package/dist/operations/service.js +336 -0
- package/dist/operations/service.js.map +1 -0
- package/dist/operations/tasks.d.ts +109 -0
- package/dist/operations/tasks.d.ts.map +1 -1
- package/dist/operations/tasks.js.map +1 -1
- package/dist/playbook.d.ts +56 -0
- package/dist/playbook.d.ts.map +1 -1
- package/dist/release/plan.d.ts +5 -5
- package/dist/vault/service-provider.d.ts +343 -0
- package/dist/vault/service-provider.d.ts.map +1 -0
- package/dist/vault/service-provider.js +857 -0
- package/dist/vault/service-provider.js.map +1 -0
- package/dist/workgraph.d.ts +12 -12
- package/package.json +10 -2
- package/src/__tests__/__snapshots__/operations-registry.test.ts.snap +1 -1
- package/src/__tests__/operation-def.test.ts +6 -1
- package/src/__tests__/provider-def.test.ts +93 -0
- package/src/__tests__/service-provider.test.ts +129 -0
- package/src/boundary.ts +69 -0
- package/src/conduit.ts +200 -0
- package/src/config/index.ts +35 -0
- package/src/config.ts +2 -1
- package/src/dispatch/__tests__/tasks-gateway-crud-ops.test.ts +99 -0
- package/src/dispatch/identity.ts +20 -0
- package/src/dispatch/operation-def.ts +21 -0
- package/src/dispatch/operations-registry.ts +1062 -36
- package/src/index.ts +137 -1
- package/src/lease-ipc/__tests__/freeze.test.ts +96 -0
- package/src/lease-ipc/index.ts +12 -0
- package/src/lease-ipc/messages.ts +117 -0
- package/src/llm/catalog-schema.json +139 -0
- package/src/llm/catalog-schema.ts +184 -0
- package/src/llm/index.ts +29 -0
- package/src/llm/oauth.ts +16 -2
- package/src/llm/onboarding.ts +131 -0
- package/src/llm/provider-def.ts +291 -0
- package/src/llm/system-resolver.ts +45 -0
- package/src/operations/admin.ts +144 -0
- package/src/operations/entities.ts +758 -0
- package/src/operations/llm.ts +15 -0
- package/src/operations/output-contracts-data.ts +264 -0
- package/src/operations/service.ts +360 -0
- package/src/operations/tasks.ts +119 -0
- package/src/playbook.ts +56 -0
- package/src/vault/service-provider.ts +1137 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://cleocode.dev/schemas/llm/curated-catalog.json",
|
|
4
|
+
"title": "Curated Models Catalog",
|
|
5
|
+
"description": "The shipped, offline-first provider+model catalog seed (E8 · T11731). One self-contained snapshot of the models.dev wire shape that seeds the global `models_catalog` table and backs offline/degraded reads. NO network access is implied by this file — it is the build-time committed mirror.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": ["version", "lastUpdated", "providers", "models"],
|
|
8
|
+
"additionalProperties": false,
|
|
9
|
+
"properties": {
|
|
10
|
+
"$schema": { "type": "string" },
|
|
11
|
+
"version": {
|
|
12
|
+
"type": "string",
|
|
13
|
+
"pattern": "^\\d+\\.\\d+\\.\\d+$",
|
|
14
|
+
"description": "Semver version of this catalog snapshot. Bumped on every regeneration; drives the seeder skip/re-seed decision."
|
|
15
|
+
},
|
|
16
|
+
"lastUpdated": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
|
|
19
|
+
"description": "ISO date (YYYY-MM-DD) the snapshot was generated."
|
|
20
|
+
},
|
|
21
|
+
"providers": {
|
|
22
|
+
"type": "object",
|
|
23
|
+
"description": "Provider records keyed by models.dev provider id (e.g. `anthropic`, `openai`, `google`).",
|
|
24
|
+
"additionalProperties": {
|
|
25
|
+
"type": "object",
|
|
26
|
+
"required": ["id", "endpoint", "authTypes"],
|
|
27
|
+
"additionalProperties": false,
|
|
28
|
+
"properties": {
|
|
29
|
+
"id": { "type": "string", "description": "Provider id (matches the map key)." },
|
|
30
|
+
"endpoint": {
|
|
31
|
+
"type": "string",
|
|
32
|
+
"description": "Provider API base URL (e.g. `https://api.anthropic.com`)."
|
|
33
|
+
},
|
|
34
|
+
"authTypes": {
|
|
35
|
+
"type": "array",
|
|
36
|
+
"description": "Supported auth mechanisms keyed by provider id.",
|
|
37
|
+
"items": { "type": "string", "enum": ["api_key", "oauth", "bedrock", "vertex"] },
|
|
38
|
+
"minItems": 1
|
|
39
|
+
},
|
|
40
|
+
"npm": {
|
|
41
|
+
"type": "string",
|
|
42
|
+
"description": "Provider SDK npm package, when applicable (e.g. `@anthropic-ai/sdk`)."
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"models": {
|
|
48
|
+
"type": "object",
|
|
49
|
+
"description": "Model entries keyed by provider id; each value is a map of model-id → model entry.",
|
|
50
|
+
"additionalProperties": {
|
|
51
|
+
"type": "object",
|
|
52
|
+
"additionalProperties": {
|
|
53
|
+
"$ref": "#/$defs/modelEntry"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"$defs": {
|
|
59
|
+
"modelEntry": {
|
|
60
|
+
"type": "object",
|
|
61
|
+
"description": "Full models.dev wire capability set for a single model.",
|
|
62
|
+
"required": [
|
|
63
|
+
"id",
|
|
64
|
+
"name",
|
|
65
|
+
"family",
|
|
66
|
+
"attachment",
|
|
67
|
+
"reasoning",
|
|
68
|
+
"temperature",
|
|
69
|
+
"interleaved",
|
|
70
|
+
"tool_call",
|
|
71
|
+
"modalities",
|
|
72
|
+
"cost",
|
|
73
|
+
"limit",
|
|
74
|
+
"status",
|
|
75
|
+
"release_date",
|
|
76
|
+
"provider"
|
|
77
|
+
],
|
|
78
|
+
"additionalProperties": false,
|
|
79
|
+
"properties": {
|
|
80
|
+
"id": { "type": "string", "description": "Model identifier (e.g. `claude-haiku-4-5`)." },
|
|
81
|
+
"name": { "type": "string", "description": "Human-readable display name." },
|
|
82
|
+
"family": { "type": "string", "description": "Model family (e.g. `claude`, `gpt`, `gemini`)." },
|
|
83
|
+
"attachment": { "type": "boolean", "description": "Supports file/image attachments." },
|
|
84
|
+
"reasoning": { "type": "boolean", "description": "Supports extended reasoning / thinking." },
|
|
85
|
+
"temperature": { "type": "boolean", "description": "Honours a temperature parameter." },
|
|
86
|
+
"interleaved": { "type": "boolean", "description": "Supports interleaved thinking blocks." },
|
|
87
|
+
"tool_call": { "type": "boolean", "description": "Supports tool/function calling." },
|
|
88
|
+
"modalities": {
|
|
89
|
+
"type": "object",
|
|
90
|
+
"required": ["input", "output"],
|
|
91
|
+
"additionalProperties": false,
|
|
92
|
+
"properties": {
|
|
93
|
+
"input": { "type": "array", "items": { "type": "string" } },
|
|
94
|
+
"output": { "type": "array", "items": { "type": "string" } }
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
"cost": {
|
|
98
|
+
"type": "object",
|
|
99
|
+
"additionalProperties": false,
|
|
100
|
+
"properties": {
|
|
101
|
+
"input": { "type": "number" },
|
|
102
|
+
"output": { "type": "number" },
|
|
103
|
+
"cache_read": { "type": "number" },
|
|
104
|
+
"cache_write": { "type": "number" },
|
|
105
|
+
"context_over_200k": { "type": "number" }
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
"limit": {
|
|
109
|
+
"type": "object",
|
|
110
|
+
"required": ["context", "output"],
|
|
111
|
+
"additionalProperties": false,
|
|
112
|
+
"properties": {
|
|
113
|
+
"context": { "type": "number", "description": "Max context window (tokens)." },
|
|
114
|
+
"output": { "type": "number", "description": "Max output tokens." }
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
"status": {
|
|
118
|
+
"type": "string",
|
|
119
|
+
"enum": ["stable", "beta", "preview", "deprecated", "retired"],
|
|
120
|
+
"description": "Availability lifecycle of the model."
|
|
121
|
+
},
|
|
122
|
+
"release_date": {
|
|
123
|
+
"type": "string",
|
|
124
|
+
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
|
|
125
|
+
"description": "ISO release date (YYYY-MM-DD). The SSoT sort key — latest wins."
|
|
126
|
+
},
|
|
127
|
+
"provider": {
|
|
128
|
+
"type": "object",
|
|
129
|
+
"required": ["npm", "api"],
|
|
130
|
+
"additionalProperties": false,
|
|
131
|
+
"properties": {
|
|
132
|
+
"npm": { "type": "string" },
|
|
133
|
+
"api": { "type": "string" }
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zod mirror + TypeScript types for the curated models catalog (E8 · T11731).
|
|
3
|
+
*
|
|
4
|
+
* This is the type+validation SSoT for the **shipped, offline-first** provider+model
|
|
5
|
+
* catalog seed that populates the global `models_catalog` table (T11733) and backs
|
|
6
|
+
* offline/degraded catalog reads (T11737). It mirrors the JSON Schema in the sibling
|
|
7
|
+
* `catalog-schema.json` (draft 2020-12) one-to-one.
|
|
8
|
+
*
|
|
9
|
+
* ## Offline-first — NO network is implied by these types
|
|
10
|
+
*
|
|
11
|
+
* The {@link CuratedCatalog} shape describes a committed, build-time snapshot of the
|
|
12
|
+
* models.dev wire shape. Nothing here fetches; the network refresh op
|
|
13
|
+
* (`cleo llm refresh-catalog`) is a SEPARATE leaf. The seeder reads the bundled
|
|
14
|
+
* `curated-catalog.json` (validated against {@link curatedCatalogSchema}) and upserts
|
|
15
|
+
* every row offline.
|
|
16
|
+
*
|
|
17
|
+
* ## models_catalog row parity (AC4)
|
|
18
|
+
*
|
|
19
|
+
* {@link modelsCatalogRowSelectSchema} / {@link modelsCatalogRowInsertSchema} describe the
|
|
20
|
+
* FLATTENED per-row shape persisted in the `models_catalog` DB table — the json/cost/
|
|
21
|
+
* modalities sub-objects serialize to TEXT columns, booleans to `integer({mode:'boolean'})`.
|
|
22
|
+
* {@link flattenCatalogToRows} (in core) maps a {@link CuratedCatalog} → these rows.
|
|
23
|
+
*
|
|
24
|
+
* Contracts-purity (Gate 10): this module exports ONLY zod schemas (values) and
|
|
25
|
+
* `z.infer` types — no bodied runtime helpers. The flatten/seed logic lives in core.
|
|
26
|
+
*
|
|
27
|
+
* @module llm/catalog-schema
|
|
28
|
+
* @task T11731
|
|
29
|
+
* @epic T11694 (E8-CATALOG-CURATION)
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
import { z } from 'zod';
|
|
33
|
+
|
|
34
|
+
/** Legal `models_catalog.status` availability-lifecycle values. */
|
|
35
|
+
export const CATALOG_MODEL_STATUSES = [
|
|
36
|
+
'stable',
|
|
37
|
+
'beta',
|
|
38
|
+
'preview',
|
|
39
|
+
'deprecated',
|
|
40
|
+
'retired',
|
|
41
|
+
] as const;
|
|
42
|
+
|
|
43
|
+
/** TypeScript union of {@link CATALOG_MODEL_STATUSES}. */
|
|
44
|
+
export type CatalogModelStatus = (typeof CATALOG_MODEL_STATUSES)[number];
|
|
45
|
+
|
|
46
|
+
/** Legal provider auth mechanisms carried in a catalog provider entry. */
|
|
47
|
+
export const CATALOG_AUTH_TYPES = ['api_key', 'oauth', 'bedrock', 'vertex'] as const;
|
|
48
|
+
|
|
49
|
+
/** TypeScript union of {@link CATALOG_AUTH_TYPES}. */
|
|
50
|
+
export type CatalogAuthType = (typeof CATALOG_AUTH_TYPES)[number];
|
|
51
|
+
|
|
52
|
+
/** ISO date `YYYY-MM-DD` matcher (the catalog sort/version key shape). */
|
|
53
|
+
const isoDate = z.string().regex(/^\d{4}-\d{2}-\d{2}$/, 'must be an ISO date (YYYY-MM-DD)');
|
|
54
|
+
|
|
55
|
+
/** Semver `MAJOR.MINOR.PATCH` matcher for the catalog snapshot version. */
|
|
56
|
+
const semver = z.string().regex(/^\d+\.\d+\.\d+$/, 'must be semver (MAJOR.MINOR.PATCH)');
|
|
57
|
+
|
|
58
|
+
/** Input/output modality lists for a model. */
|
|
59
|
+
export const catalogModalitiesSchema = z
|
|
60
|
+
.object({
|
|
61
|
+
input: z.array(z.string()),
|
|
62
|
+
output: z.array(z.string()),
|
|
63
|
+
})
|
|
64
|
+
.strict();
|
|
65
|
+
|
|
66
|
+
/** Per-1M-token cost facets for a model (all optional — providers vary). */
|
|
67
|
+
export const catalogCostSchema = z
|
|
68
|
+
.object({
|
|
69
|
+
input: z.number().optional(),
|
|
70
|
+
output: z.number().optional(),
|
|
71
|
+
cache_read: z.number().optional(),
|
|
72
|
+
cache_write: z.number().optional(),
|
|
73
|
+
context_over_200k: z.number().optional(),
|
|
74
|
+
})
|
|
75
|
+
.strict();
|
|
76
|
+
|
|
77
|
+
/** Context/output token-window limits for a model. */
|
|
78
|
+
export const catalogLimitSchema = z
|
|
79
|
+
.object({
|
|
80
|
+
context: z.number(),
|
|
81
|
+
output: z.number(),
|
|
82
|
+
})
|
|
83
|
+
.strict();
|
|
84
|
+
|
|
85
|
+
/** The provider-of-record (npm package + api protocol) for a model. */
|
|
86
|
+
export const catalogModelProviderSchema = z
|
|
87
|
+
.object({
|
|
88
|
+
npm: z.string(),
|
|
89
|
+
api: z.string(),
|
|
90
|
+
})
|
|
91
|
+
.strict();
|
|
92
|
+
|
|
93
|
+
/** Full models.dev wire capability set for a single model entry. */
|
|
94
|
+
export const catalogModelEntrySchema = z
|
|
95
|
+
.object({
|
|
96
|
+
id: z.string(),
|
|
97
|
+
name: z.string(),
|
|
98
|
+
family: z.string(),
|
|
99
|
+
attachment: z.boolean(),
|
|
100
|
+
reasoning: z.boolean(),
|
|
101
|
+
temperature: z.boolean(),
|
|
102
|
+
interleaved: z.boolean(),
|
|
103
|
+
tool_call: z.boolean(),
|
|
104
|
+
modalities: catalogModalitiesSchema,
|
|
105
|
+
cost: catalogCostSchema,
|
|
106
|
+
limit: catalogLimitSchema,
|
|
107
|
+
status: z.enum(CATALOG_MODEL_STATUSES),
|
|
108
|
+
release_date: isoDate,
|
|
109
|
+
provider: catalogModelProviderSchema,
|
|
110
|
+
})
|
|
111
|
+
.strict();
|
|
112
|
+
|
|
113
|
+
/** A provider record in the catalog envelope. */
|
|
114
|
+
export const catalogProviderSchema = z
|
|
115
|
+
.object({
|
|
116
|
+
id: z.string(),
|
|
117
|
+
endpoint: z.string(),
|
|
118
|
+
authTypes: z.array(z.enum(CATALOG_AUTH_TYPES)).min(1),
|
|
119
|
+
npm: z.string().optional(),
|
|
120
|
+
})
|
|
121
|
+
.strict();
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Top-level shape of the curated catalog seed (`curated-catalog.json`).
|
|
125
|
+
*
|
|
126
|
+
* `providers` is keyed by provider id; `models` is keyed by provider id → model id →
|
|
127
|
+
* {@link catalogModelEntrySchema}.
|
|
128
|
+
*/
|
|
129
|
+
export const curatedCatalogSchema = z
|
|
130
|
+
.object({
|
|
131
|
+
$schema: z.string().optional(),
|
|
132
|
+
version: semver,
|
|
133
|
+
lastUpdated: isoDate,
|
|
134
|
+
providers: z.record(z.string(), catalogProviderSchema),
|
|
135
|
+
models: z.record(z.string(), z.record(z.string(), catalogModelEntrySchema)),
|
|
136
|
+
})
|
|
137
|
+
.strict();
|
|
138
|
+
|
|
139
|
+
/** The validated curated catalog seed shape. */
|
|
140
|
+
export type CuratedCatalog = z.infer<typeof curatedCatalogSchema>;
|
|
141
|
+
/** A single model entry from the curated catalog. */
|
|
142
|
+
export type CatalogModelEntry = z.infer<typeof catalogModelEntrySchema>;
|
|
143
|
+
/** A single provider entry from the curated catalog. */
|
|
144
|
+
export type CatalogProvider = z.infer<typeof catalogProviderSchema>;
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* INSERT/UPSERT shape for one `models_catalog` row (the flattened persistence form).
|
|
148
|
+
*
|
|
149
|
+
* The catalog's nested `modalities` / `cost` sub-objects are JSON-serialized into the
|
|
150
|
+
* `modalities` / `cost` TEXT columns; booleans persist as `integer({mode:'boolean'})`.
|
|
151
|
+
* `provider_id` is the catalog key; `models_dev_id` mirrors the entry `id`.
|
|
152
|
+
*/
|
|
153
|
+
export const modelsCatalogRowInsertSchema = z
|
|
154
|
+
.object({
|
|
155
|
+
id: z.string(),
|
|
156
|
+
providerId: z.string(),
|
|
157
|
+
name: z.string(),
|
|
158
|
+
family: z.string(),
|
|
159
|
+
attachment: z.boolean(),
|
|
160
|
+
reasoning: z.boolean(),
|
|
161
|
+
temperature: z.boolean(),
|
|
162
|
+
interleaved: z.boolean(),
|
|
163
|
+
toolCall: z.boolean(),
|
|
164
|
+
modalities: z.string(),
|
|
165
|
+
cost: z.string(),
|
|
166
|
+
contextLimit: z.number().nullable().optional(),
|
|
167
|
+
outputLimit: z.number().nullable().optional(),
|
|
168
|
+
status: z.enum(CATALOG_MODEL_STATUSES),
|
|
169
|
+
releaseDate: isoDate,
|
|
170
|
+
modelsDevId: z.string(),
|
|
171
|
+
source: z.string(),
|
|
172
|
+
seededAt: z.string().optional(),
|
|
173
|
+
})
|
|
174
|
+
.strict();
|
|
175
|
+
|
|
176
|
+
/** SELECT shape for one `models_catalog` row (adds the always-present `seededAt`). */
|
|
177
|
+
export const modelsCatalogRowSelectSchema = modelsCatalogRowInsertSchema.extend({
|
|
178
|
+
seededAt: z.string(),
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
/** INSERT/UPSERT row type for `models_catalog`. */
|
|
182
|
+
export type ModelsCatalogRowInsert = z.infer<typeof modelsCatalogRowInsertSchema>;
|
|
183
|
+
/** SELECT row type for `models_catalog`. */
|
|
184
|
+
export type ModelsCatalogRowSelect = z.infer<typeof modelsCatalogRowSelectSchema>;
|
package/src/llm/index.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@cleocode/contracts/llm` — LLM contract subpath barrel.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports the declarative provider contracts so consumers can import from the
|
|
5
|
+
* `./llm` subpath (`@cleocode/contracts/llm`) in addition to the package root.
|
|
6
|
+
* Currently fronts the M3 Provider SSoT {@link ProviderDef} contract (T11702);
|
|
7
|
+
* other `llm/*` modules continue to export from the package root barrel.
|
|
8
|
+
*
|
|
9
|
+
* @module llm
|
|
10
|
+
* @task T11702
|
|
11
|
+
* @epic T11667
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export type {
|
|
15
|
+
AiSdkEndpoint,
|
|
16
|
+
AnthropicMessagesEndpoint,
|
|
17
|
+
OAuthFlowDef,
|
|
18
|
+
OpenAICompletionsEndpoint,
|
|
19
|
+
OpenAIResponsesEndpoint,
|
|
20
|
+
ProviderDef,
|
|
21
|
+
ProviderEndpoint,
|
|
22
|
+
ProviderTransport,
|
|
23
|
+
RequestQuirk,
|
|
24
|
+
RequestQuirkKind,
|
|
25
|
+
} from './provider-def.js';
|
|
26
|
+
export {
|
|
27
|
+
PROVIDER_TRANSPORTS,
|
|
28
|
+
REQUEST_QUIRK_KINDS,
|
|
29
|
+
} from './provider-def.js';
|
package/src/llm/oauth.ts
CHANGED
|
@@ -154,8 +154,22 @@ export interface ProviderOAuthConfig {
|
|
|
154
154
|
* `code_challenge`/`code_challenge_method`/`state`).
|
|
155
155
|
*
|
|
156
156
|
* Used by OpenAI/Codex (`id_token_add_organizations=true`,
|
|
157
|
-
* `codex_cli_simplified_flow=true`, `originator=codex_cli_rs`)
|
|
158
|
-
*
|
|
157
|
+
* `codex_cli_simplified_flow=true`, `originator=codex_cli_rs`) and Anthropic
|
|
158
|
+
* (`code=true` — makes the hosted callback page display the authorization
|
|
159
|
+
* code for manual paste-back). Kimi Code leaves this unset.
|
|
159
160
|
*/
|
|
160
161
|
extraAuthParams?: Readonly<Record<string, string>>;
|
|
162
|
+
/**
|
|
163
|
+
* Encoding of the token-endpoint request body (code exchange + refresh).
|
|
164
|
+
*
|
|
165
|
+
* - `'form'` (default) — RFC 6749 §4.1.3 `application/x-www-form-urlencoded`.
|
|
166
|
+
* Used by OpenAI/Codex and every spec-compliant authorization server.
|
|
167
|
+
* - `'json'` — non-standard `application/json` body. Anthropic's token
|
|
168
|
+
* endpoint (`platform.claude.com/v1/oauth/token`) expects JSON and
|
|
169
|
+
* additionally requires the authorize-time `state` echoed in the exchange
|
|
170
|
+
* body (the same wire shape pi-ai, OpenCode, and Claude Code use).
|
|
171
|
+
*
|
|
172
|
+
* @default 'form'
|
|
173
|
+
*/
|
|
174
|
+
tokenBodyFormat?: 'form' | 'json';
|
|
161
175
|
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Onboarding login engine — typed result envelope (T11724 · M3).
|
|
3
|
+
*
|
|
4
|
+
* The 3-step onboarding login flow (`runOnboardingLogin` in `@cleocode/core`)
|
|
5
|
+
* walks a provider from a cold start to a usable, validated profile binding:
|
|
6
|
+
*
|
|
7
|
+
* 1. **connect** — resolve the provider (alias → canonical) and land a
|
|
8
|
+
* credential (Account) in the multi-credential pool (OAuth token or API
|
|
9
|
+
* key). NO browser interaction in the engine itself: the owner-driven
|
|
10
|
+
* OAuth code/token is passed in, so the flow is non-interactive and
|
|
11
|
+
* testable.
|
|
12
|
+
* 2. **select** — pick a model from the catalog (latest by `release_date`,
|
|
13
|
+
* or an explicit override validated against the catalog).
|
|
14
|
+
* 3. **bind** — write the `llm.default` / `llm.roles[role]` config binding
|
|
15
|
+
* that ties the account + model together.
|
|
16
|
+
* 4. **validate** — round-trip the binding through `resolveLLMForSystem` and
|
|
17
|
+
* confirm the resolved provider/model are consistent. NOT a live LLM call:
|
|
18
|
+
* no token is materialized, only the resolution metadata is asserted.
|
|
19
|
+
*
|
|
20
|
+
* ## Security — NO secret fields (AC2)
|
|
21
|
+
*
|
|
22
|
+
* This module is **types-only** (Gate 10 contracts-purity). The result
|
|
23
|
+
* envelope carries ONLY non-secret identifiers — provider name, account label,
|
|
24
|
+
* model id, profile/role name, and per-step status. It NEVER carries an access
|
|
25
|
+
* token, API key, refresh token, or any token-derived value beyond a redacted
|
|
26
|
+
* preview. The plaintext secret is materialized only at the wire via the
|
|
27
|
+
* {@link SealedCredential} handle — never on this envelope.
|
|
28
|
+
*
|
|
29
|
+
* @module llm/onboarding
|
|
30
|
+
* @task T11724
|
|
31
|
+
* @epic T11671 (E6-ONBOARDING-FRONT-DOOR)
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
import type { ProviderId } from './provider-id.js';
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Discriminant naming each step of the onboarding login flow, in execution
|
|
38
|
+
* order. Surfaced on every {@link OnboardingStepResult} so a UI / CLI can
|
|
39
|
+
* render a deterministic 4-row progress checklist.
|
|
40
|
+
*
|
|
41
|
+
* @task T11724
|
|
42
|
+
*/
|
|
43
|
+
export type OnboardingStepName = 'connect' | 'select' | 'bind' | 'validate';
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Outcome of a single onboarding step.
|
|
47
|
+
*
|
|
48
|
+
* - `'ok'` — the step completed successfully.
|
|
49
|
+
* - `'failed'` — the step could not complete (e.g. missing credential,
|
|
50
|
+
* unknown model, config write error). The engine STOPS at the first
|
|
51
|
+
* `'failed'` step and returns the partial envelope; it does NOT throw.
|
|
52
|
+
* - `'skipped'` — the step was intentionally not run because an earlier step
|
|
53
|
+
* failed (downstream steps are short-circuited but still reported so the
|
|
54
|
+
* 4-row shape is stable).
|
|
55
|
+
*
|
|
56
|
+
* @task T11724
|
|
57
|
+
*/
|
|
58
|
+
export type OnboardingStepStatus = 'ok' | 'failed' | 'skipped';
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Result of one step in the onboarding login flow.
|
|
62
|
+
*
|
|
63
|
+
* `detail` is a short, human-readable, SECRET-FREE summary of what the step
|
|
64
|
+
* did (e.g. `"account 'work' connected (oauth)"`, `"model 'claude-…' selected
|
|
65
|
+
* from catalog"`). `code` carries a stable `E_*` error code on failure so a
|
|
66
|
+
* caller can branch programmatically without string-matching `detail`.
|
|
67
|
+
*
|
|
68
|
+
* @task T11724
|
|
69
|
+
*/
|
|
70
|
+
export interface OnboardingStepResult {
|
|
71
|
+
/** Which step this result describes. */
|
|
72
|
+
readonly step: OnboardingStepName;
|
|
73
|
+
/** Terminal status of the step. */
|
|
74
|
+
readonly status: OnboardingStepStatus;
|
|
75
|
+
/** Human-readable, secret-free summary of the step outcome. */
|
|
76
|
+
readonly detail: string;
|
|
77
|
+
/**
|
|
78
|
+
* Stable `E_*` error code when `status === 'failed'`; omitted otherwise.
|
|
79
|
+
* Never carries a token or other secret.
|
|
80
|
+
*/
|
|
81
|
+
readonly code?: string;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* The auth scheme by which the connect step landed a credential in the pool.
|
|
86
|
+
*
|
|
87
|
+
* - `'oauth'` — an OAuth access token (PKCE / device-code) was supplied.
|
|
88
|
+
* - `'api_key'` — a raw API key was supplied (OAuth-less providers fall
|
|
89
|
+
* through to this path — AC4).
|
|
90
|
+
*
|
|
91
|
+
* @task T11724
|
|
92
|
+
*/
|
|
93
|
+
export type OnboardingAuthMode = 'oauth' | 'api_key';
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Typed result envelope returned by `runOnboardingLogin` (AC2).
|
|
97
|
+
*
|
|
98
|
+
* Carries NO secret fields — only the per-step trace and the non-secret
|
|
99
|
+
* identifiers needed to render the result and confirm the binding. `validated`
|
|
100
|
+
* is the single boolean a caller checks to know the end-to-end flow succeeded
|
|
101
|
+
* (all four steps `'ok'` AND the round-trip resolution was consistent).
|
|
102
|
+
*
|
|
103
|
+
* @task T11724
|
|
104
|
+
*/
|
|
105
|
+
export interface OnboardingResult {
|
|
106
|
+
/** The 4 step traces, always length 4, in execution order. */
|
|
107
|
+
readonly steps: ReadonlyArray<OnboardingStepResult>;
|
|
108
|
+
/** Canonical provider id the flow resolved to (alias → canonical). */
|
|
109
|
+
readonly provider: ProviderId;
|
|
110
|
+
/**
|
|
111
|
+
* Human-readable account/credential label the connect step stored in the
|
|
112
|
+
* pool (e.g. `'oauth-login'`, `'work'`). Names *which* credential the
|
|
113
|
+
* binding points at — safe to log/serialize; NOT a secret.
|
|
114
|
+
*/
|
|
115
|
+
readonly accountLabel: string;
|
|
116
|
+
/** The auth scheme used by the connect step, or `null` when connect failed. */
|
|
117
|
+
readonly authMode: OnboardingAuthMode | null;
|
|
118
|
+
/** Catalog model id the select step chose, or `null` when select failed. */
|
|
119
|
+
readonly modelId: string | null;
|
|
120
|
+
/**
|
|
121
|
+
* The profile/role name the bind step wrote (e.g. `'default'` for the global
|
|
122
|
+
* binding or a {@link import('../config.js').RoleName} for a per-role
|
|
123
|
+
* binding), or `null` when bind failed.
|
|
124
|
+
*/
|
|
125
|
+
readonly profileName: string | null;
|
|
126
|
+
/**
|
|
127
|
+
* `true` only when all four steps succeeded AND the validate round-trip
|
|
128
|
+
* confirmed the binding resolves to the connected provider + selected model.
|
|
129
|
+
*/
|
|
130
|
+
readonly validated: boolean;
|
|
131
|
+
}
|