@substrat-run/vertical-host 0.92.1 → 0.95.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.
- package/README.md +7 -0
- package/dist/model.d.ts +124 -0
- package/dist/model.d.ts.map +1 -0
- package/dist/model.js +129 -0
- package/dist/model.js.map +1 -0
- package/package.json +11 -4
package/README.md
CHANGED
|
@@ -63,3 +63,10 @@ neither `adapter-cloudflare` nor any concrete host.
|
|
|
63
63
|
|
|
64
64
|
A vertical that never calls `mountPlatformSurface` has no `/internal/provision` and fails
|
|
65
65
|
to provision on first deploy and in its scenario test — louder than any lint.
|
|
66
|
+
|
|
67
|
+
## `createModelHost` — `@substrat-run/vertical-host/model`
|
|
68
|
+
|
|
69
|
+
Governance around a language-model call, provider-neutral: resolve `provider:model` against
|
|
70
|
+
platform-held credentials, consult the host's `guard`, run, and hand one `ModelUsageLine`
|
|
71
|
+
(reported tokens, rate-card list price, five fixed attribution keys) to the host's `record`.
|
|
72
|
+
Lives around operations, never inside a scope's transaction. See the reference page.
|
package/dist/model.d.ts
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The platform's model host — governance around a model call, provider-neutral.
|
|
3
|
+
*
|
|
4
|
+
* D-18 splits the AI capability in two: the model is an adapter (any row of
|
|
5
|
+
* `@substrat-run/model-providers`), the governance is the kernel's. This is the
|
|
6
|
+
* governance, at the host layer, wrapped around one call:
|
|
7
|
+
*
|
|
8
|
+
* 1. resolve `provider:model` against PLATFORM-held credentials (the worker's own
|
|
9
|
+
* bindings — never a per-install token, that is what made ticket0's assistant
|
|
10
|
+
* bring-your-own-account, #1054);
|
|
11
|
+
* 2. ask the host's `guard` whether this call may run at all (a tenant budget, a
|
|
12
|
+
* plan that does not include this model) — policy, enforced before the bytes go out;
|
|
13
|
+
* 3. run it;
|
|
14
|
+
* 4. turn the AI SDK's usage into one `ModelUsageLine`, priced from the rate card on
|
|
15
|
+
* OUR side, attributed with the five fixed keys, and hand it to `record`.
|
|
16
|
+
*
|
|
17
|
+
* It lives HERE, around operations, and not on `OperationContext`: a model call is a
|
|
18
|
+
* multi-second network round-trip, and holding a scope's transaction open across it
|
|
19
|
+
* would be exactly the "no network in module code" rule broken from the inside. A
|
|
20
|
+
* vertical calls this from its harness — the way ticket0's assistant already runs —
|
|
21
|
+
* and records the result through its own operations.
|
|
22
|
+
*
|
|
23
|
+
* Nothing in this file names a provider. Cloudflare's gateway extras (per-request
|
|
24
|
+
* metadata, spend limits) are layered on that row by the provider package when the
|
|
25
|
+
* host asks for them; the line this produces is the same for every row.
|
|
26
|
+
*/
|
|
27
|
+
import { type LanguageModelUsage } from 'ai';
|
|
28
|
+
import { ProviderError, type CredentialEnv, type DirectFactories, type HostingInfo, type StepTokens } from '@substrat-run/model-providers';
|
|
29
|
+
import { type ModelAttribution, type ModelUsageLine } from '@substrat-run/contracts';
|
|
30
|
+
export type { HostingInfo, ModelAttribution, ModelUsageLine };
|
|
31
|
+
export { ProviderError };
|
|
32
|
+
/** What the guard sees before anything is sent: which model, on whose behalf. */
|
|
33
|
+
export interface ModelIntent {
|
|
34
|
+
readonly spec: string;
|
|
35
|
+
readonly attribution: ModelAttribution;
|
|
36
|
+
}
|
|
37
|
+
export interface ModelRequest extends ModelIntent {
|
|
38
|
+
readonly system?: string;
|
|
39
|
+
readonly prompt: string;
|
|
40
|
+
readonly maxOutputTokens?: number;
|
|
41
|
+
readonly temperature?: number;
|
|
42
|
+
}
|
|
43
|
+
export interface ModelRun {
|
|
44
|
+
readonly text: string;
|
|
45
|
+
readonly finishReason: string;
|
|
46
|
+
/** `provider/modelId` — what a turn record shows. */
|
|
47
|
+
readonly label: string;
|
|
48
|
+
/** The one governance fact this call produced; already handed to `record`. */
|
|
49
|
+
readonly line: ModelUsageLine;
|
|
50
|
+
}
|
|
51
|
+
/** What a settings screen shows for a spec before anyone runs it. */
|
|
52
|
+
export interface ModelStatus {
|
|
53
|
+
readonly spec: string;
|
|
54
|
+
readonly label: string;
|
|
55
|
+
readonly provider: string;
|
|
56
|
+
readonly modelId: string;
|
|
57
|
+
/** The platform holds what this row needs. */
|
|
58
|
+
readonly configured: boolean;
|
|
59
|
+
/** The env vars it is missing, when not. */
|
|
60
|
+
readonly missing: readonly string[];
|
|
61
|
+
/** Where inference runs and what is sent there — the disclosure a settings screen shows. */
|
|
62
|
+
readonly hosting: HostingInfo;
|
|
63
|
+
}
|
|
64
|
+
export interface ModelHostOptions {
|
|
65
|
+
/** Platform-held credentials — the worker's own bindings. Only the row's own variables are read. */
|
|
66
|
+
readonly env: CredentialEnv;
|
|
67
|
+
/**
|
|
68
|
+
* Provider factories this bundle statically carries (`{ anthropic: createAnthropic }`),
|
|
69
|
+
* and — for a row that declares a binding transport — the binding itself, already
|
|
70
|
+
* wrapped. `aiBinding` below is the sanctioned way to supply the Workers AI one.
|
|
71
|
+
*/
|
|
72
|
+
readonly factories?: DirectFactories;
|
|
73
|
+
/**
|
|
74
|
+
* The Workers AI binding (`env.AI`), when the runtime has one.
|
|
75
|
+
*
|
|
76
|
+
* This is the transport we WANT for Cloudflare models: the runtime grants a capability,
|
|
77
|
+
* the account that owns the script is billed, and no credential exists on the script to
|
|
78
|
+
* be read, leaked or rotated. Supplying it makes the `cloudflare` row runnable with no
|
|
79
|
+
* `CLOUDFLARE_AI_*` set at all.
|
|
80
|
+
*
|
|
81
|
+
* Typed `unknown` on purpose — `@substrat-run/vertical-host` must not depend on
|
|
82
|
+
* `@cloudflare/workers-types` to describe an optional binding, and `workers-ai-provider`
|
|
83
|
+
* validates what it is handed.
|
|
84
|
+
*/
|
|
85
|
+
readonly aiBinding?: unknown;
|
|
86
|
+
/**
|
|
87
|
+
* The host's clock — stamped on every line.
|
|
88
|
+
*
|
|
89
|
+
* NOT `ctx.now()`, and it cannot be: a model call runs OUTSIDE any operation (D-59 —
|
|
90
|
+
* no scope transaction may span a multi-second round-trip), so there is no `ctx` in
|
|
91
|
+
* scope when this fires. The line's `at` is when the provider answered; the meter
|
|
92
|
+
* entry the vertical writes afterwards carries `ctx.now()`, and the two are different
|
|
93
|
+
* facts about different moments rather than one fact from two clocks. Injectable so a
|
|
94
|
+
* scenario can freeze it — which is what R6 is really protecting.
|
|
95
|
+
*/
|
|
96
|
+
readonly now?: () => Date;
|
|
97
|
+
/** What this host sends to a model, for the disclosure: 'Customer messages and the excerpts they match'. */
|
|
98
|
+
readonly sent?: string;
|
|
99
|
+
/**
|
|
100
|
+
* Policy, before the call. Throw to refuse: the model never runs, nothing is
|
|
101
|
+
* recorded, and the caller sees the throw. A budget lives here.
|
|
102
|
+
*/
|
|
103
|
+
readonly guard?: (intent: ModelIntent) => void | Promise<void>;
|
|
104
|
+
/**
|
|
105
|
+
* The ledger writes, after every successful call. A throw here fails the run —
|
|
106
|
+
* a call that cannot be recorded must not look like one that was.
|
|
107
|
+
*/
|
|
108
|
+
readonly record?: (line: ModelUsageLine) => void | Promise<void>;
|
|
109
|
+
}
|
|
110
|
+
export interface ModelHost {
|
|
111
|
+
status(spec: string): ModelStatus;
|
|
112
|
+
run(request: ModelRequest): Promise<ModelRun>;
|
|
113
|
+
}
|
|
114
|
+
/** The AI SDK's usage shape → the rate card's, with "reported" kept honest. */
|
|
115
|
+
export interface ReportedTokens extends StepTokens {
|
|
116
|
+
readonly reported: boolean;
|
|
117
|
+
readonly inputTokens: number;
|
|
118
|
+
readonly outputTokens: number;
|
|
119
|
+
readonly cachedInputTokens: number;
|
|
120
|
+
readonly cacheWriteTokens: number;
|
|
121
|
+
}
|
|
122
|
+
export declare function stepTokensOf(usage: LanguageModelUsage | undefined): ReportedTokens;
|
|
123
|
+
export declare function createModelHost(options: ModelHostOptions): ModelHost;
|
|
124
|
+
//# sourceMappingURL=model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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"}
|
package/dist/model.js
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The platform's model host — governance around a model call, provider-neutral.
|
|
3
|
+
*
|
|
4
|
+
* D-18 splits the AI capability in two: the model is an adapter (any row of
|
|
5
|
+
* `@substrat-run/model-providers`), the governance is the kernel's. This is the
|
|
6
|
+
* governance, at the host layer, wrapped around one call:
|
|
7
|
+
*
|
|
8
|
+
* 1. resolve `provider:model` against PLATFORM-held credentials (the worker's own
|
|
9
|
+
* bindings — never a per-install token, that is what made ticket0's assistant
|
|
10
|
+
* bring-your-own-account, #1054);
|
|
11
|
+
* 2. ask the host's `guard` whether this call may run at all (a tenant budget, a
|
|
12
|
+
* plan that does not include this model) — policy, enforced before the bytes go out;
|
|
13
|
+
* 3. run it;
|
|
14
|
+
* 4. turn the AI SDK's usage into one `ModelUsageLine`, priced from the rate card on
|
|
15
|
+
* OUR side, attributed with the five fixed keys, and hand it to `record`.
|
|
16
|
+
*
|
|
17
|
+
* It lives HERE, around operations, and not on `OperationContext`: a model call is a
|
|
18
|
+
* multi-second network round-trip, and holding a scope's transaction open across it
|
|
19
|
+
* would be exactly the "no network in module code" rule broken from the inside. A
|
|
20
|
+
* vertical calls this from its harness — the way ticket0's assistant already runs —
|
|
21
|
+
* and records the result through its own operations.
|
|
22
|
+
*
|
|
23
|
+
* Nothing in this file names a provider. Cloudflare's gateway extras (per-request
|
|
24
|
+
* metadata, spend limits) are layered on that row by the provider package when the
|
|
25
|
+
* host asks for them; the line this produces is the same for every row.
|
|
26
|
+
*/
|
|
27
|
+
import { generateText } from 'ai';
|
|
28
|
+
import { createModel, credentialsFrom, hostingInfo, providerRow, listCostOfSteps, normalizeModelSpec, parseModelSpec, ProviderError, requestHeadersFor, } from '@substrat-run/model-providers';
|
|
29
|
+
import { createWorkersAI } from 'workers-ai-provider';
|
|
30
|
+
import { modelAttribution, modelUsageLine } from '@substrat-run/contracts';
|
|
31
|
+
export { ProviderError };
|
|
32
|
+
const DESCRIBE_MISSING = (envVar) => `${envVar} is not set on the platform`;
|
|
33
|
+
export function stepTokensOf(usage) {
|
|
34
|
+
const input = usage?.inputTokens;
|
|
35
|
+
const output = usage?.outputTokens;
|
|
36
|
+
return {
|
|
37
|
+
reported: typeof input === 'number' || typeof output === 'number',
|
|
38
|
+
inputTokens: input ?? 0,
|
|
39
|
+
outputTokens: output ?? 0,
|
|
40
|
+
cachedInputTokens: usage?.inputTokenDetails?.cacheReadTokens ?? 0,
|
|
41
|
+
cacheWriteTokens: usage?.inputTokenDetails?.cacheWriteTokens ?? 0,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export function createModelHost(options) {
|
|
45
|
+
const now = options.now ?? (() => new Date());
|
|
46
|
+
// One place decides which providers this host can build. The binding, when present,
|
|
47
|
+
// joins the same `factories` map the direct rows use — so `createModel` reaches it
|
|
48
|
+
// through the seam it already had rather than a Cloudflare-shaped special case.
|
|
49
|
+
const factories = {
|
|
50
|
+
...(options.factories ?? {}),
|
|
51
|
+
...(options.aiBinding
|
|
52
|
+
? { cloudflare: () => (modelId) => createWorkersAI({ binding: options.aiBinding })(modelId) }
|
|
53
|
+
: {}),
|
|
54
|
+
};
|
|
55
|
+
const status = (spec) => {
|
|
56
|
+
const { provider, modelId } = parseModelSpec(spec);
|
|
57
|
+
const creds = credentialsFrom(provider, options.env);
|
|
58
|
+
// Exactly `createModel`'s rule, not a looser one. Only a row that DECLARES a binding
|
|
59
|
+
// transport is credential-free; a `direct` row's factory (`createAnthropic`) is just
|
|
60
|
+
// the package, and it still needs its key. Reported any looser, a settings screen
|
|
61
|
+
// would call an Anthropic row 'configured' with no key set and the call would then
|
|
62
|
+
// fail — the status lying about the thing it exists to answer.
|
|
63
|
+
const row = providerRow(provider);
|
|
64
|
+
const bound = Boolean(row?.kind === 'compatible' && row.binding && factories[provider]);
|
|
65
|
+
return {
|
|
66
|
+
spec: normalizeModelSpec(spec),
|
|
67
|
+
label: `${provider}/${modelId}`,
|
|
68
|
+
provider,
|
|
69
|
+
modelId,
|
|
70
|
+
configured: bound || creds.missing.length === 0,
|
|
71
|
+
missing: bound ? [] : creds.missing,
|
|
72
|
+
hosting: hostingInfo(provider, options.env, options.sent ? { sent: options.sent } : {}),
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
const run = async (request) => {
|
|
76
|
+
// Parse the attribution FIRST — before the guard, and long before anything
|
|
77
|
+
// billable. It used to be validated only when the line was built, which is after
|
|
78
|
+
// `generateText` has returned: a sixth key therefore bought a model call and then
|
|
79
|
+
// threw, spending money that no ledger line accounted for. Parse, don't trust
|
|
80
|
+
// (and the five-key limit is the whole reason this schema is `.strict()`).
|
|
81
|
+
const attribution = modelAttribution.parse(request.attribution);
|
|
82
|
+
// Then resolve: an unknown provider or an unconfigured row is refused before the
|
|
83
|
+
// guard is consulted, so a budget is never charged for a call that could not have
|
|
84
|
+
// happened.
|
|
85
|
+
const resolved = createModel(request.spec, options.env, {
|
|
86
|
+
factories,
|
|
87
|
+
hosted: true,
|
|
88
|
+
describeMissing: DESCRIBE_MISSING,
|
|
89
|
+
});
|
|
90
|
+
// The guard sees the CANONICAL spec, never the caller's shorthand. `claude-opus-5`
|
|
91
|
+
// and `anthropic:claude-opus-5` resolve to one model, so a policy written against
|
|
92
|
+
// the canonical form would otherwise be bypassed by typing the short one.
|
|
93
|
+
const model = normalizeModelSpec(request.spec);
|
|
94
|
+
await options.guard?.({ spec: model, attribution });
|
|
95
|
+
// The row's per-request extras — for Cloudflare's gateway, the attribution as
|
|
96
|
+
// metadata and payload retention off; for every other row, nothing. The host does
|
|
97
|
+
// not know which.
|
|
98
|
+
const headers = requestHeadersFor(resolved.provider, { attribution: request.attribution, env: options.env });
|
|
99
|
+
const started = now();
|
|
100
|
+
const result = await generateText({
|
|
101
|
+
model: resolved.model,
|
|
102
|
+
...(Object.keys(headers).length ? { headers } : {}),
|
|
103
|
+
...(request.system ? { system: request.system } : {}),
|
|
104
|
+
prompt: request.prompt,
|
|
105
|
+
...(request.maxOutputTokens !== undefined ? { maxOutputTokens: request.maxOutputTokens } : {}),
|
|
106
|
+
...(request.temperature !== undefined ? { temperature: request.temperature } : {}),
|
|
107
|
+
});
|
|
108
|
+
const finished = now();
|
|
109
|
+
const tokens = stepTokensOf(result.totalUsage);
|
|
110
|
+
const line = modelUsageLine.parse({
|
|
111
|
+
attribution,
|
|
112
|
+
model,
|
|
113
|
+
provider: resolved.provider,
|
|
114
|
+
modelId: resolved.modelId,
|
|
115
|
+
reported: tokens.reported,
|
|
116
|
+
inputTokens: tokens.inputTokens,
|
|
117
|
+
outputTokens: tokens.outputTokens,
|
|
118
|
+
cachedInputTokens: tokens.cachedInputTokens,
|
|
119
|
+
cacheWriteTokens: tokens.cacheWriteTokens,
|
|
120
|
+
listUsd: tokens.reported ? listCostOfSteps(model, [tokens]) : null,
|
|
121
|
+
at: finished.toISOString(),
|
|
122
|
+
elapsedMs: Math.max(0, finished.getTime() - started.getTime()),
|
|
123
|
+
});
|
|
124
|
+
await options.record?.(line);
|
|
125
|
+
return { text: result.text, finishReason: result.finishReason, label: resolved.label, line };
|
|
126
|
+
};
|
|
127
|
+
return { status, run };
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@substrat-run/vertical-host",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.95.0",
|
|
4
4
|
"description": "The platform's /internal/* surface + error envelope, authored once — mount it in a vertical worker instead of re-copying the control-plane contract",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"repository": {
|
|
@@ -16,15 +16,22 @@
|
|
|
16
16
|
".": {
|
|
17
17
|
"types": "./dist/index.d.ts",
|
|
18
18
|
"default": "./dist/index.js"
|
|
19
|
+
},
|
|
20
|
+
"./model": {
|
|
21
|
+
"types": "./dist/model.d.ts",
|
|
22
|
+
"default": "./dist/model.js"
|
|
19
23
|
}
|
|
20
24
|
},
|
|
21
25
|
"files": [
|
|
22
26
|
"dist"
|
|
23
27
|
],
|
|
24
28
|
"dependencies": {
|
|
29
|
+
"ai": "7.0.62",
|
|
25
30
|
"hono": "^4.6.0",
|
|
26
|
-
"
|
|
27
|
-
"@substrat-run/
|
|
31
|
+
"workers-ai-provider": "^4.0.0",
|
|
32
|
+
"@substrat-run/contracts": "^0.95.0",
|
|
33
|
+
"@substrat-run/model-providers": "^0.3.1",
|
|
34
|
+
"@substrat-run/kernel": "^0.95.0"
|
|
28
35
|
},
|
|
29
36
|
"devDependencies": {
|
|
30
37
|
"typescript": "^7.0.0",
|
|
@@ -35,7 +42,7 @@
|
|
|
35
42
|
},
|
|
36
43
|
"scripts": {
|
|
37
44
|
"build": "tsc -p tsconfig.json",
|
|
38
|
-
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
45
|
+
"typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.test.json --noEmit",
|
|
39
46
|
"test": "vitest run"
|
|
40
47
|
}
|
|
41
48
|
}
|