@illuminis/comprism 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.
- package/LICENSE +15 -0
- package/README.md +281 -0
- package/out/agent/command.d.ts +86 -0
- package/out/agent/command.js +259 -0
- package/out/agent/render.d.ts +97 -0
- package/out/agent/render.js +255 -0
- package/out/agent/session.d.ts +175 -0
- package/out/agent/session.js +573 -0
- package/out/commands/ask.d.ts +1 -0
- package/out/commands/ask.js +146 -0
- package/out/commands/codemap.d.ts +2 -0
- package/out/commands/codemap.js +151 -0
- package/out/commands/commands-thin.d.ts +39 -0
- package/out/commands/commands-thin.js +182 -0
- package/out/commands/install.d.ts +163 -0
- package/out/commands/install.js +543 -0
- package/out/commands/keys.d.ts +55 -0
- package/out/commands/keys.js +344 -0
- package/out/commands/login.d.ts +9 -0
- package/out/commands/login.js +384 -0
- package/out/commands/repl.d.ts +1 -0
- package/out/commands/repl.js +752 -0
- package/out/commands/settings.d.ts +21 -0
- package/out/commands/settings.js +244 -0
- package/out/commands/welcome.d.ts +1 -0
- package/out/commands/welcome.js +196 -0
- package/out/executor/documents.d.ts +40 -0
- package/out/executor/documents.js +170 -0
- package/out/executor/files.d.ts +2 -0
- package/out/executor/files.js +360 -0
- package/out/executor/git.d.ts +48 -0
- package/out/executor/git.js +132 -0
- package/out/executor/hooks.d.ts +67 -0
- package/out/executor/hooks.js +247 -0
- package/out/executor/index.d.ts +29 -0
- package/out/executor/index.js +221 -0
- package/out/executor/notebook.d.ts +2 -0
- package/out/executor/notebook.js +147 -0
- package/out/executor/paths.d.ts +15 -0
- package/out/executor/paths.js +126 -0
- package/out/executor/shell.d.ts +41 -0
- package/out/executor/shell.js +336 -0
- package/out/graph/build.d.ts +45 -0
- package/out/graph/build.js +91 -0
- package/out/graph/facts.d.ts +47 -0
- package/out/graph/facts.js +12 -0
- package/out/graph/files.d.ts +45 -0
- package/out/graph/files.js +207 -0
- package/out/graph/read-locales.d.ts +29 -0
- package/out/graph/read-locales.js +246 -0
- package/out/graph/read-python.d.ts +11 -0
- package/out/graph/read-python.js +115 -0
- package/out/graph/read-typescript.d.ts +16 -0
- package/out/graph/read-typescript.js +292 -0
- package/out/graph/sync.d.ts +66 -0
- package/out/graph/sync.js +242 -0
- package/out/lib/attach.d.ts +62 -0
- package/out/lib/attach.js +228 -0
- package/out/lib/config.d.ts +93 -0
- package/out/lib/config.js +198 -0
- package/out/lib/connection.d.ts +73 -0
- package/out/lib/connection.js +188 -0
- package/out/lib/gateway.d.ts +239 -0
- package/out/lib/gateway.js +171 -0
- package/out/lib/prompt.d.ts +34 -0
- package/out/lib/prompt.js +108 -0
- package/out/lib/types.d.ts +417 -0
- package/out/lib/types.js +21 -0
- package/out/lib/ui.d.ts +114 -0
- package/out/lib/ui.js +265 -0
- package/out/lib/version.d.ts +24 -0
- package/out/lib/version.js +27 -0
- package/out/lib/voice.d.ts +50 -0
- package/out/lib/voice.js +218 -0
- package/out/postinstall.d.ts +2 -0
- package/out/postinstall.js +92 -0
- package/out/thin.d.ts +2 -0
- package/out/thin.js +259 -0
- package/package.json +101 -0
- package/scripts/read_python.py +270 -0
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for the CompletionPrism Companion. No logic lives here.
|
|
3
|
+
*
|
|
4
|
+
* Frozen build spec Part C, section 0.5, extended with the v3.2 schema
|
|
5
|
+
* additions the kickoff brief names: `ExecutedArm`, `LedgerRowV32`,
|
|
6
|
+
* `DecisionSnapshotV32`, `ProvenanceMeta`, `PersistedTurn`, `ShadowDecision`.
|
|
7
|
+
*
|
|
8
|
+
* Three rules shape almost every field below, and they are worth stating once
|
|
9
|
+
* rather than repeating in forty comments:
|
|
10
|
+
*
|
|
11
|
+
* 1. Append-only. Nothing here is ever mutated in place. A correction is a
|
|
12
|
+
* new row carrying `supersedes`. `DecisionSnapshot` is stricter still and
|
|
13
|
+
* carries no `supersedes` field at all, because it never has one.
|
|
14
|
+
* 2. Provenance on every derived field. A number says whether it was
|
|
15
|
+
* observed, inferred or estimated, and anything inferred says by what
|
|
16
|
+
* method.
|
|
17
|
+
* 3. Content-blind by default. The record carries a fingerprint of a request
|
|
18
|
+
* and never the request. Response text is a character count, not text.
|
|
19
|
+
*/
|
|
20
|
+
import type { TaskRepresentation } from '../internal/representation';
|
|
21
|
+
export type Provider = 'anthropic' | 'openai';
|
|
22
|
+
/** Coarse structural bands. Never the model's lookup key on its own. */
|
|
23
|
+
export type Tier = 'simple' | 'standard' | 'complex';
|
|
24
|
+
export type ContextState = 'fresh' | 'warm';
|
|
25
|
+
/** How a number came to exist. Rule 2 of the frozen spec's ground rules. */
|
|
26
|
+
export type Derivation = 'observed' | 'inferred' | 'estimated';
|
|
27
|
+
/**
|
|
28
|
+
* Where a record came from, which decides what it is allowed to influence.
|
|
29
|
+
*
|
|
30
|
+
* `imported` rows - provider exports, log scans, anything reconstructed after
|
|
31
|
+
* the fact - can be reported on and can never reach an estimator. That
|
|
32
|
+
* separation is enforced by schema rather than by convention, which is why it
|
|
33
|
+
* is a field on every row and not a flag someone remembers to check.
|
|
34
|
+
*/
|
|
35
|
+
export type Provenance = 'first_party' | 'imported';
|
|
36
|
+
/** The surface a record entered through, in descending order of fidelity. */
|
|
37
|
+
export type SourceSurface = 'sdk' | 'cli' | 'proxy' | 'vscode' | 'mcp' | 'provider_export' | 'scan';
|
|
38
|
+
/**
|
|
39
|
+
* What a cost figure actually is.
|
|
40
|
+
*
|
|
41
|
+
* A cost the provider billed is not the same object as one we computed from the
|
|
42
|
+
* published catalog, and neither is the same as one a customer's export
|
|
43
|
+
* reported to us. Collapsing the three into a single `cost_usd` column is how a
|
|
44
|
+
* savings figure ends up indefensible.
|
|
45
|
+
*/
|
|
46
|
+
export type CostSemantic = 'billed_actual' | 'catalog_computed' | 'imported_reported' | 'unpriced';
|
|
47
|
+
/**
|
|
48
|
+
* How an unsuccessful attempt surfaced. The economics live here: a refusal
|
|
49
|
+
* costs seconds, a plausible wrong answer that survives review costs the most.
|
|
50
|
+
* Phase 2 measures these; Phase 1 records the raw material for them.
|
|
51
|
+
*/
|
|
52
|
+
export type FailureMode = 'refusal_or_error' | 'incomplete' | 'plausible_wrong' | 'latent' | 'unknown';
|
|
53
|
+
/** What the policy did at a decision point. */
|
|
54
|
+
export type PolicyAction = 'initial' | 'continue_same' | 'switch_model' | 'abandon_recommended';
|
|
55
|
+
/**
|
|
56
|
+
* Whether the Companion may alter dispatch.
|
|
57
|
+
*
|
|
58
|
+
* `monitor` is the only mode this release ships behavior for: the engine runs,
|
|
59
|
+
* records everything a decision would need, and changes nothing. `active`
|
|
60
|
+
* exists in the schema so a decision made later is permanently distinguishable
|
|
61
|
+
* from one made now. It is not a flag that turns selection on - there is no
|
|
62
|
+
* selection to turn on until the model program delivers tables.
|
|
63
|
+
*/
|
|
64
|
+
export type ExecutionMode = 'monitor' | 'active';
|
|
65
|
+
export interface ModelInfo {
|
|
66
|
+
id: string;
|
|
67
|
+
provider: Provider;
|
|
68
|
+
inPerMTok: number;
|
|
69
|
+
outPerMTok: number;
|
|
70
|
+
reportsReasoningTokens: boolean;
|
|
71
|
+
/** The structural band this model is the default candidate for. */
|
|
72
|
+
tier: Tier;
|
|
73
|
+
/** Human label for reports. */
|
|
74
|
+
label: string;
|
|
75
|
+
}
|
|
76
|
+
export interface Usage {
|
|
77
|
+
inputTokens: number | null;
|
|
78
|
+
outputTokens: number | null;
|
|
79
|
+
reasoningTokens?: number | null;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Provenance metadata carried alongside any derived figure (v3.2).
|
|
83
|
+
*
|
|
84
|
+
* `method` is required whenever `derivation` is `inferred`, and `confidence`
|
|
85
|
+
* whenever it is `estimated`. A derived number with neither cannot be restated
|
|
86
|
+
* later and so cannot serve as evidence.
|
|
87
|
+
*/
|
|
88
|
+
export interface ProvenanceMeta {
|
|
89
|
+
derivation: Derivation;
|
|
90
|
+
provenance: Provenance;
|
|
91
|
+
/** Required when derivation is 'inferred'. How the number was arrived at. */
|
|
92
|
+
method?: string;
|
|
93
|
+
/** Required when derivation is 'estimated'. 0..1. */
|
|
94
|
+
confidence?: number;
|
|
95
|
+
source_surface: SourceSurface;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* One persisted turn of a working conversation (v3.2), content-blind.
|
|
99
|
+
*
|
|
100
|
+
* The frozen spec's section 1.5 stores turn content in `sessions.json`. That
|
|
101
|
+
* conflicts with ground rule 6 and with the Phase 1 canary test that no request
|
|
102
|
+
* text reaches any file, so the persisted form carries the shape of a turn and
|
|
103
|
+
* not its words: role, fingerprint, size, and which model answered. `content`
|
|
104
|
+
* appears only when the tenant has explicitly turned text storage on.
|
|
105
|
+
*
|
|
106
|
+
* The consequence is deliberate and worth knowing: a session resumed in a new
|
|
107
|
+
* process cannot replay what was said unless text storage is enabled. Being
|
|
108
|
+
* content-blind has a cost, and paying it visibly is better than storing the
|
|
109
|
+
* text and describing the product as content-blind anyway.
|
|
110
|
+
*/
|
|
111
|
+
export interface PersistedTurn {
|
|
112
|
+
role: 'user' | 'assistant';
|
|
113
|
+
ts: string;
|
|
114
|
+
fingerprint: string;
|
|
115
|
+
chars: number;
|
|
116
|
+
approx_tokens: number;
|
|
117
|
+
model?: string;
|
|
118
|
+
provider?: Provider;
|
|
119
|
+
/** Present only when contentPolicy.storeText is true. Default: absent. */
|
|
120
|
+
content?: string;
|
|
121
|
+
}
|
|
122
|
+
export interface Session {
|
|
123
|
+
session_id: string;
|
|
124
|
+
title: string;
|
|
125
|
+
created: string;
|
|
126
|
+
updated: string;
|
|
127
|
+
source_surface: SourceSurface;
|
|
128
|
+
turns: PersistedTurn[];
|
|
129
|
+
}
|
|
130
|
+
/** An in-memory conversation turn. Never written to disk in this shape. */
|
|
131
|
+
export interface Message {
|
|
132
|
+
role: 'user' | 'assistant';
|
|
133
|
+
content: string;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* One row per provider call, or per imported usage record.
|
|
137
|
+
*
|
|
138
|
+
* Absent by design: prompt text, response text, API keys.
|
|
139
|
+
*
|
|
140
|
+
* Token counts and cost are nullable, and that is not laziness. A streamed
|
|
141
|
+
* response whose provider did not report usage has no token count, and writing
|
|
142
|
+
* a zero there would understate a real cost while looking like a measurement.
|
|
143
|
+
* `cost_semantic: 'unpriced'` says so out loud, and the report counts those
|
|
144
|
+
* calls on their own line rather than folding them silently into a total.
|
|
145
|
+
*/
|
|
146
|
+
export interface LedgerRowV32 {
|
|
147
|
+
event_id: string;
|
|
148
|
+
/** The DecisionSnapshot that caused this call. Always resolves. */
|
|
149
|
+
decision_id: string;
|
|
150
|
+
ts: string;
|
|
151
|
+
source_system: SourceSurface;
|
|
152
|
+
granularity: 'request' | 'daily_aggregate';
|
|
153
|
+
session_id: string;
|
|
154
|
+
turn_index: number;
|
|
155
|
+
user: string;
|
|
156
|
+
task_tier: Tier;
|
|
157
|
+
context_tokens: number;
|
|
158
|
+
prompt_tokens: number;
|
|
159
|
+
fresh_context: boolean;
|
|
160
|
+
provider: Provider;
|
|
161
|
+
model_dispatched: string;
|
|
162
|
+
attempt_index: number;
|
|
163
|
+
input_tokens: number | null;
|
|
164
|
+
output_tokens: number | null;
|
|
165
|
+
reasoning_tokens?: number | null;
|
|
166
|
+
finish_reason: string;
|
|
167
|
+
latency_ms: number;
|
|
168
|
+
cost_usd: number | null;
|
|
169
|
+
cost_semantic: CostSemantic;
|
|
170
|
+
/** sha256 of the normalized prompt. NOT the prompt. */
|
|
171
|
+
prompt_fingerprint: string;
|
|
172
|
+
/** Length only. */
|
|
173
|
+
response_chars: number;
|
|
174
|
+
catalog_version: string;
|
|
175
|
+
mode: ExecutionMode;
|
|
176
|
+
supersedes?: string;
|
|
177
|
+
meta: ProvenanceMeta;
|
|
178
|
+
comprism_version: string;
|
|
179
|
+
}
|
|
180
|
+
/** The frozen spec's Phase 1 name for the same object. */
|
|
181
|
+
export type LedgerRow = LedgerRowV32;
|
|
182
|
+
/**
|
|
183
|
+
* Per-candidate cost breakdown at decision time.
|
|
184
|
+
*
|
|
185
|
+
* Every figure is zero and `excludedReason` is set in this release: with no
|
|
186
|
+
* estimate tables there is nothing to break down, and inventing a number to
|
|
187
|
+
* fill the shape would be exactly the behavior this product exists to replace.
|
|
188
|
+
* The shape ships now so the record written today has the same schema as the
|
|
189
|
+
* record written the day tables arrive.
|
|
190
|
+
*/
|
|
191
|
+
export type EccBreakdown = Record<string, never>;
|
|
192
|
+
/**
|
|
193
|
+
* Why no recommendation was made. Recorded on every decision in this release.
|
|
194
|
+
*
|
|
195
|
+
* Recording the reason rather than a null is what lets a historical request be
|
|
196
|
+
* re-evaluated the day tables exist: we know exactly what was missing.
|
|
197
|
+
*/
|
|
198
|
+
export type WithheldReason = 'insufficient_evidence' | 'estimator_inert' | 'confidence_below_floor' | 'component_error' | 'no_decision';
|
|
199
|
+
/**
|
|
200
|
+
* What the system knew and chose at the moment of a decision.
|
|
201
|
+
*
|
|
202
|
+
* Written once. Never updated, never superseded, never backfilled. There is no
|
|
203
|
+
* `supersedes` field and no `chain_id`: chain membership is retrospective
|
|
204
|
+
* knowledge and lives in its own linkage record, because putting it here would
|
|
205
|
+
* either make this record mutable or make it a lie.
|
|
206
|
+
*
|
|
207
|
+
* That single property - this record means one thing forever - is worth a large
|
|
208
|
+
* fraction of the calibration, audit and evidence value of the whole system.
|
|
209
|
+
*/
|
|
210
|
+
export interface DecisionSnapshotV32 {
|
|
211
|
+
decision_id: string;
|
|
212
|
+
ts: string;
|
|
213
|
+
session_id: string;
|
|
214
|
+
turn_index: number;
|
|
215
|
+
attempt_index: number;
|
|
216
|
+
action: PolicyAction;
|
|
217
|
+
task_tier: Tier;
|
|
218
|
+
classifier_signals: string[];
|
|
219
|
+
classifier_version: string;
|
|
220
|
+
/**
|
|
221
|
+
* The full task representation as it stood at decision time: structural
|
|
222
|
+
* signals, the locally computed reduced vector, deployment context and the
|
|
223
|
+
* reporting labels, each with its own version.
|
|
224
|
+
*
|
|
225
|
+
* Optional only because records written before the representation shipped do
|
|
226
|
+
* not carry one, and a record is never rewritten to add a field it did not
|
|
227
|
+
* have. Everything written from now on has it.
|
|
228
|
+
*/
|
|
229
|
+
task_representation?: TaskRepresentation;
|
|
230
|
+
context_tokens: number;
|
|
231
|
+
fresh_context: boolean;
|
|
232
|
+
/** sha256 of the normalized prompt, never the prompt. */
|
|
233
|
+
prompt_fingerprint: string;
|
|
234
|
+
eligible_candidates: string[];
|
|
235
|
+
chosen_model: string;
|
|
236
|
+
chosen_by: 'policy' | 'caller_override';
|
|
237
|
+
ecc_breakdown: Record<string, EccBreakdown>;
|
|
238
|
+
/** Content hash of every estimate table consulted. Empty while inert. */
|
|
239
|
+
survival_table_hashes: Record<string, string>;
|
|
240
|
+
baseline_version: string | null;
|
|
241
|
+
policy_version: string;
|
|
242
|
+
/** Present on every decision in this release: why nothing was recommended. */
|
|
243
|
+
recommendation_withheld: WithheldReason | null;
|
|
244
|
+
recommendation_withheld_detail?: string;
|
|
245
|
+
fallback_used: boolean;
|
|
246
|
+
fallback_reason?: string;
|
|
247
|
+
mode: ExecutionMode;
|
|
248
|
+
meta: ProvenanceMeta;
|
|
249
|
+
comprism_version: string;
|
|
250
|
+
}
|
|
251
|
+
export type DecisionSnapshot = DecisionSnapshotV32;
|
|
252
|
+
/**
|
|
253
|
+
* What the policy would have done, recorded without acting on it (v3.2).
|
|
254
|
+
*
|
|
255
|
+
* The type ships now so the schema is fixed; the recorder that writes it is
|
|
256
|
+
* Phase 3 work. While the estimator is inert a shadow decision would carry no
|
|
257
|
+
* recommendation, which is why nothing writes one yet.
|
|
258
|
+
*/
|
|
259
|
+
export interface ShadowDecision {
|
|
260
|
+
shadow_id: string;
|
|
261
|
+
decision_id: string;
|
|
262
|
+
ts: string;
|
|
263
|
+
would_have_dispatched: string | null;
|
|
264
|
+
actually_dispatched: string;
|
|
265
|
+
ecc_breakdown: Record<string, EccBreakdown>;
|
|
266
|
+
recommendation_withheld: WithheldReason | null;
|
|
267
|
+
policy_version: string;
|
|
268
|
+
meta: ProvenanceMeta;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* One arm of a head-to-head observation (v3.2): a model that actually ran on a
|
|
272
|
+
* task, with what it cost and how it turned out.
|
|
273
|
+
*/
|
|
274
|
+
export interface ExecutedArm {
|
|
275
|
+
decision_id: string;
|
|
276
|
+
event_id: string;
|
|
277
|
+
model: string;
|
|
278
|
+
provider: Provider;
|
|
279
|
+
attempt_index: number;
|
|
280
|
+
input_tokens: number | null;
|
|
281
|
+
output_tokens: number | null;
|
|
282
|
+
cost_usd: number | null;
|
|
283
|
+
latency_ms: number;
|
|
284
|
+
finish_reason: string;
|
|
285
|
+
failure_mode: FailureMode | null;
|
|
286
|
+
response_chars: number;
|
|
287
|
+
}
|
|
288
|
+
export interface ProviderCall {
|
|
289
|
+
model: string;
|
|
290
|
+
messages: Message[];
|
|
291
|
+
maxTokens?: number;
|
|
292
|
+
}
|
|
293
|
+
export interface ProviderResult {
|
|
294
|
+
text: string;
|
|
295
|
+
usage: Usage;
|
|
296
|
+
finishReason: string;
|
|
297
|
+
latencyMs: number;
|
|
298
|
+
/** True when the provider itself reported the token counts. */
|
|
299
|
+
usageReported: boolean;
|
|
300
|
+
/**
|
|
301
|
+
* Present only on a failure. A status line or transport error - never a
|
|
302
|
+
* response body, because a provider's error body can echo the request back,
|
|
303
|
+
* and the request is the customer's content.
|
|
304
|
+
*/
|
|
305
|
+
errorMessage?: string;
|
|
306
|
+
}
|
|
307
|
+
export interface SendOptions {
|
|
308
|
+
sessionId?: string;
|
|
309
|
+
/** Dispatch this model regardless of the policy. Records a caller override. */
|
|
310
|
+
model?: string;
|
|
311
|
+
maxTokens?: number;
|
|
312
|
+
/** Which surface is calling. Defaults to 'sdk'. */
|
|
313
|
+
surface?: SourceSurface;
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* What a caller gets back. The receipt fields are returned here and rendered by
|
|
317
|
+
* the client, never appended to the message history: a caller holding a result
|
|
318
|
+
* object already has somewhere to put a receipt, so there is nothing to gain by
|
|
319
|
+
* writing one into the conversation.
|
|
320
|
+
*
|
|
321
|
+
* The proxy is the one surface where that is not true - the customer's client
|
|
322
|
+
* renders the message body and nothing else - so it injects a sentinel-wrapped
|
|
323
|
+
* footer and strips it back out of every later request. See `footer.ts`.
|
|
324
|
+
*/
|
|
325
|
+
export interface SendResult {
|
|
326
|
+
text: string;
|
|
327
|
+
model: string;
|
|
328
|
+
provider: Provider;
|
|
329
|
+
usage: Usage;
|
|
330
|
+
costUsd: number | null;
|
|
331
|
+
costSemantic: CostSemantic;
|
|
332
|
+
decisionId: string;
|
|
333
|
+
eventId: string;
|
|
334
|
+
sessionId: string;
|
|
335
|
+
attempts: number;
|
|
336
|
+
remediated: boolean;
|
|
337
|
+
taskTier: Tier;
|
|
338
|
+
classifierSignals: string[];
|
|
339
|
+
recommendationWithheld: WithheldReason | null;
|
|
340
|
+
latencyMs: number;
|
|
341
|
+
/** Every ledger row this send produced, in dispatch order. */
|
|
342
|
+
ledger: LedgerRowV32[];
|
|
343
|
+
}
|
|
344
|
+
/** Which of the shipped footer layouts the proxy renders. */
|
|
345
|
+
export type FooterTemplate =
|
|
346
|
+
/** The default: money, attempts and human time - the day-one promise. */
|
|
347
|
+
'completion'
|
|
348
|
+
/** The patent's four cost mechanics, itemized. For technical demos. */
|
|
349
|
+
| 'mechanics' | 'compact' | 'cumulative' | 'detailed';
|
|
350
|
+
/**
|
|
351
|
+
* A per-model price the tenant states themselves, layered over the catalog.
|
|
352
|
+
*
|
|
353
|
+
* It exists because published list price is not what a large customer pays, and
|
|
354
|
+
* a savings figure computed from a price the customer knows to be wrong is
|
|
355
|
+
* worse than no figure at all. Cache prices are optional: left out, they are
|
|
356
|
+
* derived from the input price by the provider's published multipliers.
|
|
357
|
+
*/
|
|
358
|
+
export interface FooterPriceOverride {
|
|
359
|
+
inPerMTok: number;
|
|
360
|
+
outPerMTok: number;
|
|
361
|
+
cacheReadPerMTok?: number;
|
|
362
|
+
cacheWritePerMTok?: number;
|
|
363
|
+
}
|
|
364
|
+
export interface FooterConfig {
|
|
365
|
+
/** Kill switch. Off means the proxy is byte-faithful in both directions. */
|
|
366
|
+
enabled: boolean;
|
|
367
|
+
template: FooterTemplate;
|
|
368
|
+
/**
|
|
369
|
+
* The model the saving is measured against: what the customer would have
|
|
370
|
+
* spent had the company mandated one capable model for everything. Named in
|
|
371
|
+
* the footer itself, because a saving is only meaningful against a stated
|
|
372
|
+
* alternative.
|
|
373
|
+
*/
|
|
374
|
+
baselineModel: string;
|
|
375
|
+
/** Model id to price. Empty means the catalog's published prices. */
|
|
376
|
+
pricing: Record<string, FooterPriceOverride>;
|
|
377
|
+
/**
|
|
378
|
+
* How the receipt is delimited.
|
|
379
|
+
*
|
|
380
|
+
* `comment` wraps it in an HTML comment, which renders as nothing. `visible`
|
|
381
|
+
* uses plain text markers instead - needed on any surface whose renderer
|
|
382
|
+
* strips comments before display, and the way to tell the two failures apart.
|
|
383
|
+
*/
|
|
384
|
+
marker?: 'comment' | 'visible' | 'none';
|
|
385
|
+
/**
|
|
386
|
+
* The tenant's own portal, linked at the end of every receipt.
|
|
387
|
+
*
|
|
388
|
+
* The receipt is two lines and can never carry the whole story, so it ends
|
|
389
|
+
* with where the whole story is: the tenant's stats, traceable to the records
|
|
390
|
+
* behind them. Empty means no link rather than a broken one.
|
|
391
|
+
*/
|
|
392
|
+
tenant?: string;
|
|
393
|
+
/**
|
|
394
|
+
* Let the model choose which model answers.
|
|
395
|
+
*
|
|
396
|
+
* Off means observe and report a counterfactual. On means the request is
|
|
397
|
+
* rewritten to the model with the lowest expected cost to complete, and the
|
|
398
|
+
* receipt describes what actually happened rather than what might have.
|
|
399
|
+
*/
|
|
400
|
+
route?: boolean;
|
|
401
|
+
/**
|
|
402
|
+
* Where the receipt's link points.
|
|
403
|
+
*
|
|
404
|
+
* Production is `{tenant}.{app}.illuminis.ai` - the tenant's own subdomain of
|
|
405
|
+
* the app's own subdomain of the company domain. In development it points at
|
|
406
|
+
* the app running on this machine instead, so the link is clickable rather
|
|
407
|
+
* than decorative.
|
|
408
|
+
*/
|
|
409
|
+
portal?: {
|
|
410
|
+
/** Set false to link at production. */
|
|
411
|
+
useDev?: boolean;
|
|
412
|
+
/** The app running locally, e.g. http://localhost:5182 */
|
|
413
|
+
devUrl?: string;
|
|
414
|
+
/** The production suffix after the tenant, e.g. completionprism.illuminis.ai */
|
|
415
|
+
domain?: string;
|
|
416
|
+
};
|
|
417
|
+
}
|
package/out/lib/types.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Shared types for the CompletionPrism Companion. No logic lives here.
|
|
4
|
+
*
|
|
5
|
+
* Frozen build spec Part C, section 0.5, extended with the v3.2 schema
|
|
6
|
+
* additions the kickoff brief names: `ExecutedArm`, `LedgerRowV32`,
|
|
7
|
+
* `DecisionSnapshotV32`, `ProvenanceMeta`, `PersistedTurn`, `ShadowDecision`.
|
|
8
|
+
*
|
|
9
|
+
* Three rules shape almost every field below, and they are worth stating once
|
|
10
|
+
* rather than repeating in forty comments:
|
|
11
|
+
*
|
|
12
|
+
* 1. Append-only. Nothing here is ever mutated in place. A correction is a
|
|
13
|
+
* new row carrying `supersedes`. `DecisionSnapshot` is stricter still and
|
|
14
|
+
* carries no `supersedes` field at all, because it never has one.
|
|
15
|
+
* 2. Provenance on every derived field. A number says whether it was
|
|
16
|
+
* observed, inferred or estimated, and anything inferred says by what
|
|
17
|
+
* method.
|
|
18
|
+
* 3. Content-blind by default. The record carries a fingerprint of a request
|
|
19
|
+
* and never the request. Response text is a character count, not text.
|
|
20
|
+
*/
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
package/out/lib/ui.d.ts
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal presentation.
|
|
3
|
+
*
|
|
4
|
+
* This is a developer product, so the terminal IS the interface, and it gets the
|
|
5
|
+
* same care a screen would. Three rules hold it together:
|
|
6
|
+
*
|
|
7
|
+
* 1. **The brand shows up here.** The prism spectrum and the illuminis palette
|
|
8
|
+
* are the same ones the portal and the documents use, rendered in 24-bit
|
|
9
|
+
* color where the terminal supports it.
|
|
10
|
+
* 2. **Color is never the only signal.** Every state that matters also has a
|
|
11
|
+
* glyph and a word, so the output survives `NO_COLOR`, a pipe, a CI log and
|
|
12
|
+
* a color-blind reader unchanged.
|
|
13
|
+
* 3. **Nothing here is decoration for its own sake.** Every panel answers a
|
|
14
|
+
* question the person actually has: what did that cost, what was wasted,
|
|
15
|
+
* and how sure are we of the number.
|
|
16
|
+
*/
|
|
17
|
+
export declare function width(): number;
|
|
18
|
+
export declare const c: {
|
|
19
|
+
blue: (s: string) => string;
|
|
20
|
+
deep: (s: string) => string;
|
|
21
|
+
purple: (s: string) => string;
|
|
22
|
+
green: (s: string) => string;
|
|
23
|
+
amber: (s: string) => string;
|
|
24
|
+
red: (s: string) => string;
|
|
25
|
+
muted: (s: string) => string;
|
|
26
|
+
text: (s: string) => string;
|
|
27
|
+
bold: (s: string) => string;
|
|
28
|
+
dim: (s: string) => string;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Any glyph, in one of the eight spectrum colors.
|
|
32
|
+
*
|
|
33
|
+
* Exported so the logo and the rule under it are drawn from the SAME eight
|
|
34
|
+
* values. Two hand-picked palettes in one product drift apart within a release,
|
|
35
|
+
* and the brand is the one thing a customer notices before the engine.
|
|
36
|
+
*/
|
|
37
|
+
export declare function spectrumAt(index: number, glyph: string): string;
|
|
38
|
+
export declare function prismRule(w?: number): string;
|
|
39
|
+
export declare function banner(subtitle?: string): string;
|
|
40
|
+
export declare function money(v: number | null): string;
|
|
41
|
+
/** Clip to a visible width, with an ellipsis, so a card never bleeds. */
|
|
42
|
+
export declare function clip(s: string, n: number): string;
|
|
43
|
+
export declare function pad(s: string, n: number): string;
|
|
44
|
+
export declare function padLeft(s: string, n: number): string;
|
|
45
|
+
export declare function stripAnsi(s: string): string;
|
|
46
|
+
/**
|
|
47
|
+
* A row of KPI cards - the same shape the portal's summary tab uses, so the two
|
|
48
|
+
* surfaces read as one product rather than two tools that happen to share a name.
|
|
49
|
+
*/
|
|
50
|
+
export declare function kpiCards(cards: {
|
|
51
|
+
label: string;
|
|
52
|
+
value: string;
|
|
53
|
+
note?: string;
|
|
54
|
+
tone?: 'good' | 'warn' | 'plain';
|
|
55
|
+
}[]): string;
|
|
56
|
+
/**
|
|
57
|
+
* A Pareto bar: sorted descending with a running cumulative share.
|
|
58
|
+
*
|
|
59
|
+
* Pareto rather than a plain bar chart because the question a spend screen has
|
|
60
|
+
* to answer is not "how much did each cost" but "how few of these carry most of
|
|
61
|
+
* the bill" - the answer is usually two or three, and that is the whole insight.
|
|
62
|
+
*/
|
|
63
|
+
export declare function paretoBars(rows: {
|
|
64
|
+
label: string;
|
|
65
|
+
value: number;
|
|
66
|
+
sub?: string;
|
|
67
|
+
}[], opts?: {
|
|
68
|
+
unit?: (v: number) => string;
|
|
69
|
+
barWidth?: number;
|
|
70
|
+
}): string;
|
|
71
|
+
export declare function table(headers: string[], rows: string[][]): string;
|
|
72
|
+
/**
|
|
73
|
+
* The thing that makes it visible that something is between the person and the
|
|
74
|
+
* provider.
|
|
75
|
+
*
|
|
76
|
+
* Without this, an instrumented session looks exactly like an uninstrumented
|
|
77
|
+
* one, and a product nobody can see is a product nobody renews. It shows the
|
|
78
|
+
* work as it happens - characterising, dispatching, recording - and then gets
|
|
79
|
+
* out of the way, leaving the answer and a one-line receipt.
|
|
80
|
+
*/
|
|
81
|
+
export declare class LiveIndicator {
|
|
82
|
+
private timer;
|
|
83
|
+
private frame;
|
|
84
|
+
private label;
|
|
85
|
+
private readonly frames;
|
|
86
|
+
start(label: string): void;
|
|
87
|
+
update(label: string): void;
|
|
88
|
+
stop(): void;
|
|
89
|
+
}
|
|
90
|
+
export interface ReceiptData {
|
|
91
|
+
model: string;
|
|
92
|
+
tier: string;
|
|
93
|
+
signals: string[];
|
|
94
|
+
inputTokens: number | null;
|
|
95
|
+
outputTokens: number | null;
|
|
96
|
+
costUsd: number | null;
|
|
97
|
+
latencyMs: number;
|
|
98
|
+
attempts: number;
|
|
99
|
+
remediated: boolean;
|
|
100
|
+
wastedUsd: number | null;
|
|
101
|
+
withheld: string | null;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* The receipt, rendered by the client and never injected into the conversation.
|
|
105
|
+
*
|
|
106
|
+
* Injected text is re-sent on every later turn, so a receipt in the message
|
|
107
|
+
* array is a line item the customer pays for again on every turn for the rest of
|
|
108
|
+
* the session. It belongs on the screen, not in the context window.
|
|
109
|
+
*/
|
|
110
|
+
export declare function receipt(r: ReceiptData): string;
|
|
111
|
+
export declare function ok(msg: string): string;
|
|
112
|
+
export declare function warn(msg: string): string;
|
|
113
|
+
export declare function fail(msg: string): string;
|
|
114
|
+
export declare function info(msg: string): string;
|