dialai 1.0.0 → 1.2.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/.claude/skills/dial-machine/SKILL.md +401 -0
- package/.claude/skills/dial-machine/references/api-reference.md +515 -0
- package/.claude/skills/dial-machine/references/patterns.md +628 -0
- package/.claude/skills/spec-for-ralph/SKILL.md +542 -0
- package/.claude/specs/llm-audit-log.md +280 -0
- package/LICENSE +1 -1
- package/README.md +1 -1
- package/dist/dialai/api.d.ts +2 -6
- package/dist/dialai/api.d.ts.map +1 -1
- package/dist/dialai/api.js +22 -6
- package/dist/dialai/api.js.map +1 -1
- package/dist/dialai/llm.d.ts +6 -4
- package/dist/dialai/llm.d.ts.map +1 -1
- package/dist/dialai/llm.js +96 -31
- package/dist/dialai/llm.js.map +1 -1
- package/dist/dialai/migrations/002-llm-audit-log.d.ts +8 -0
- package/dist/dialai/migrations/002-llm-audit-log.d.ts.map +1 -0
- package/dist/dialai/migrations/002-llm-audit-log.js +41 -0
- package/dist/dialai/migrations/002-llm-audit-log.js.map +1 -0
- package/dist/dialai/migrations/migrate.d.ts.map +1 -1
- package/dist/dialai/migrations/migrate.js +2 -0
- package/dist/dialai/migrations/migrate.js.map +1 -1
- package/dist/dialai/store-memory.d.ts.map +1 -1
- package/dist/dialai/store-memory.js +22 -0
- package/dist/dialai/store-memory.js.map +1 -1
- package/dist/dialai/store-postgres.d.ts.map +1 -1
- package/dist/dialai/store-postgres.js +54 -1
- package/dist/dialai/store-postgres.js.map +1 -1
- package/dist/dialai/store.d.ts +3 -1
- package/dist/dialai/store.d.ts.map +1 -1
- package/dist/dialai/store.js.map +1 -1
- package/dist/dialai/types.d.ts +54 -0
- package/dist/dialai/types.d.ts.map +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,515 @@
|
|
|
1
|
+
# DIAL API Reference
|
|
2
|
+
|
|
3
|
+
Complete API types and function signatures for the `dialai` library. All exports are available from the top-level `"dialai"` package.
|
|
4
|
+
|
|
5
|
+
## Core Types
|
|
6
|
+
|
|
7
|
+
### `MachineDefinition`
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
interface MachineDefinition {
|
|
11
|
+
machineName: string; // Unique identifier for this machine type
|
|
12
|
+
initialState: string; // State where sessions start
|
|
13
|
+
goalState: string; // Rest state where the session is headed
|
|
14
|
+
states: Record<string, StateDefinition>; // Map of state names to definitions
|
|
15
|
+
specialists?: SpecialistDefinition[]; // Optional machine-level specialists
|
|
16
|
+
consensusThreshold?: number; // Default consensus threshold (0-1)
|
|
17
|
+
}
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### `StateDefinition`
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
interface StateDefinition {
|
|
24
|
+
prompt?: string; // Decision prompt for this state
|
|
25
|
+
transitions?: Record<string, string>; // Map of transition names to target states
|
|
26
|
+
consensusThreshold?: number; // Override threshold for this state
|
|
27
|
+
specialists?: SpecialistDefinition[]; // Per-state specialist declarations
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### `Session`
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
interface Session {
|
|
35
|
+
sessionId: string; // UUID generated at creation
|
|
36
|
+
machineName: string; // Name of the machine being run
|
|
37
|
+
currentState: string; // Current state in the machine
|
|
38
|
+
currentRoundId: string; // ID of the current decision round
|
|
39
|
+
machine: MachineDefinition; // The full machine definition
|
|
40
|
+
history: TransitionRecord[]; // All executed transitions in order
|
|
41
|
+
createdAt: Date; // When the session was created
|
|
42
|
+
metaJson?: Record<string, unknown>; // Arbitrary session-level metadata
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### `TransitionRecord`
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
interface TransitionRecord {
|
|
50
|
+
transitionName: string; // Name of the transition taken
|
|
51
|
+
reasoning: string; // Why this transition was chosen
|
|
52
|
+
executionTimestamp: Date; // When the transition was executed
|
|
53
|
+
metaJson?: Record<string, unknown>; // Arbitrary metadata from the winning proposal
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Specialist Types
|
|
58
|
+
|
|
59
|
+
### `SpecialistDefinition`
|
|
60
|
+
|
|
61
|
+
Used in machine JSON for declaring specialists:
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
interface SpecialistDefinition {
|
|
65
|
+
role: "proposer" | "arbiter";
|
|
66
|
+
specialistId: string;
|
|
67
|
+
machineName?: string; // Defaults to the machine's machineName
|
|
68
|
+
isHuman?: boolean;
|
|
69
|
+
disabled?: boolean; // Per-state: registered but not solicited
|
|
70
|
+
strategyFn?: string;
|
|
71
|
+
strategyFnName?: string; // Built-in strategy name
|
|
72
|
+
strategyWebhookUrl?: string;
|
|
73
|
+
contextFn?: string;
|
|
74
|
+
contextWebhookUrl?: string;
|
|
75
|
+
modelId?: string;
|
|
76
|
+
webhookTokenName?: string;
|
|
77
|
+
threshold?: number;
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### `Proposer`
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
interface Proposer {
|
|
85
|
+
role: "proposer";
|
|
86
|
+
specialistId: string;
|
|
87
|
+
machineName: string;
|
|
88
|
+
isHuman?: boolean;
|
|
89
|
+
enabled?: boolean; // Default true
|
|
90
|
+
strategyFn?: (ctx: ProposerContext) => Promise<ProposerStrategyResult>;
|
|
91
|
+
strategyFnName?: string;
|
|
92
|
+
strategyWebhookUrl?: string;
|
|
93
|
+
contextFn?: (ctx: ProposerContext) => Promise<string>;
|
|
94
|
+
contextWebhookUrl?: string;
|
|
95
|
+
modelId?: string;
|
|
96
|
+
webhookTokenName?: string;
|
|
97
|
+
threshold?: number;
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### `Arbiter`
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
interface Arbiter {
|
|
105
|
+
role: "arbiter";
|
|
106
|
+
specialistId: string;
|
|
107
|
+
machineName: string;
|
|
108
|
+
enabled?: boolean; // Default true
|
|
109
|
+
strategyFn?: (ctx: ArbiterContext) => Promise<ArbiterStrategyResult>;
|
|
110
|
+
strategyFnName?: string;
|
|
111
|
+
strategyWebhookUrl?: string;
|
|
112
|
+
webhookTokenName?: string;
|
|
113
|
+
threshold?: number;
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### `ProposerStrategyResult`
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
interface ProposerStrategyResult {
|
|
121
|
+
transitionName: string;
|
|
122
|
+
toState: string;
|
|
123
|
+
reasoning: string;
|
|
124
|
+
costUSD?: number; // Cost in USD to generate this result
|
|
125
|
+
latencyMsec?: number; // Time in milliseconds to generate
|
|
126
|
+
numInputTokens?: number; // Input tokens used
|
|
127
|
+
numOutputTokens?: number; // Output tokens used
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
When returned from a strategy function, these optional metrics are merged into the resulting `Proposal`. Metrics passed via `SubmitProposalOptions` take precedence over strategy-returned values.
|
|
132
|
+
|
|
133
|
+
### `ArbiterStrategyResult`
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
interface ArbiterStrategyResult {
|
|
137
|
+
consensusReached: boolean;
|
|
138
|
+
winningProposalId?: string;
|
|
139
|
+
reasoning: string;
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Context Types
|
|
144
|
+
|
|
145
|
+
### `ProposerContext`
|
|
146
|
+
|
|
147
|
+
Provided to proposer strategy functions:
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
interface ProposerContext {
|
|
151
|
+
sessionId: string;
|
|
152
|
+
currentState: string;
|
|
153
|
+
prompt: string; // Decision prompt for this state
|
|
154
|
+
transitions: Record<string, string>; // Available transitions (name -> target)
|
|
155
|
+
history: TransitionRecord[]; // All previous transitions
|
|
156
|
+
metaJson?: Record<string, unknown>; // Session-level metadata
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### `ArbiterContext`
|
|
161
|
+
|
|
162
|
+
Provided to arbiter strategy functions:
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
interface ArbiterContext {
|
|
166
|
+
sessionId: string;
|
|
167
|
+
roundId: string;
|
|
168
|
+
currentState: string;
|
|
169
|
+
prompt: string;
|
|
170
|
+
machineName: string;
|
|
171
|
+
proposals: Proposal[]; // All proposals in this round
|
|
172
|
+
alignmentScores?: Record<string, number>; // Alignment scores by specialistId
|
|
173
|
+
humanGoldExamples?: HumanGoldExample[]; // Human gold examples
|
|
174
|
+
history: TransitionRecord[];
|
|
175
|
+
threshold?: number; // Configured threshold for this arbiter
|
|
176
|
+
metaJson?: Record<string, unknown>;
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Decision Types
|
|
181
|
+
|
|
182
|
+
### `Proposal`
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
interface Proposal {
|
|
186
|
+
proposalId: string; // UUID generated on creation
|
|
187
|
+
sessionId: string;
|
|
188
|
+
roundId: string;
|
|
189
|
+
specialistId: string; // Who submitted this proposal
|
|
190
|
+
isHuman: boolean;
|
|
191
|
+
transitionName: string; // The transition being proposed
|
|
192
|
+
toState: string; // Target state of the transition
|
|
193
|
+
reasoning: string;
|
|
194
|
+
metaJson?: Record<string, unknown>;
|
|
195
|
+
costUSD?: number; // Cost in USD to generate
|
|
196
|
+
latencyMsec?: number; // Time in milliseconds to generate
|
|
197
|
+
numInputTokens?: number;
|
|
198
|
+
numOutputTokens?: number;
|
|
199
|
+
createdAt: Date;
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### `ConsensusResult`
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
interface ConsensusResult {
|
|
207
|
+
consensusReached: boolean;
|
|
208
|
+
winningProposalId?: string; // Set if consensus reached
|
|
209
|
+
reasoning: string;
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### `ArbitrationResult`
|
|
214
|
+
|
|
215
|
+
Returned by `submitArbitration()`:
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
interface ArbitrationResult {
|
|
219
|
+
arbitrationId: string;
|
|
220
|
+
sessionId: string;
|
|
221
|
+
roundId: string;
|
|
222
|
+
specialistId?: string;
|
|
223
|
+
stale: boolean; // True if roundId doesn't match current
|
|
224
|
+
guardsPass: boolean; // True if all guards passed
|
|
225
|
+
guardReason: string; // Explanation if guards failed
|
|
226
|
+
winningProposalId?: string;
|
|
227
|
+
transitionName?: string;
|
|
228
|
+
toState?: string;
|
|
229
|
+
reasoning?: string;
|
|
230
|
+
executed: boolean; // Whether transition was executed
|
|
231
|
+
isHuman: boolean; // Whether this was a human-forced decision
|
|
232
|
+
metaJson?: Record<string, unknown>;
|
|
233
|
+
costUSD?: number;
|
|
234
|
+
latencyMsec?: number;
|
|
235
|
+
numInputTokens?: number;
|
|
236
|
+
numOutputTokens?: number;
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Registration Options
|
|
241
|
+
|
|
242
|
+
### `RegisterProposerOptions`
|
|
243
|
+
|
|
244
|
+
Exactly one execution mode is required. Forbidden combinations are validated at registration time.
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
interface RegisterProposerOptions {
|
|
248
|
+
specialistId: string; // Required: unique identifier
|
|
249
|
+
machineName: string; // Required: which machine
|
|
250
|
+
|
|
251
|
+
isHuman?: boolean;
|
|
252
|
+
|
|
253
|
+
// Execution mode (exactly one required):
|
|
254
|
+
strategyFn?: (ctx: ProposerContext) => Promise<ProposerStrategyResult>;
|
|
255
|
+
strategyFnName?: string; // Built-in strategy name
|
|
256
|
+
strategyWebhookUrl?: string; // External webhook URL
|
|
257
|
+
|
|
258
|
+
// LLM-based modes:
|
|
259
|
+
modelId?: string; // Required with contextFn or contextWebhookUrl
|
|
260
|
+
contextFn?: (ctx: ProposerContext) => Promise<string>;
|
|
261
|
+
contextWebhookUrl?: string;
|
|
262
|
+
|
|
263
|
+
webhookTokenName?: string; // Required with webhook URLs
|
|
264
|
+
threshold?: number; // Strategy-specific threshold
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
**Five execution modes:**
|
|
269
|
+
1. `strategyFn` — local async function that returns `ProposerStrategyResult`
|
|
270
|
+
2. `strategyFnName` — name of a built-in strategy (`firstAvailable`, `lastAvailable`, `random`)
|
|
271
|
+
3. `strategyWebhookUrl` + `webhookTokenName` — external HTTP endpoint
|
|
272
|
+
4. `contextFn` + `modelId` — local function provides context string, DIAL calls the LLM
|
|
273
|
+
5. `contextWebhookUrl` + `modelId` + `webhookTokenName` — webhook provides context, DIAL calls the LLM
|
|
274
|
+
|
|
275
|
+
### `RegisterArbiterOptions`
|
|
276
|
+
|
|
277
|
+
```typescript
|
|
278
|
+
interface RegisterArbiterOptions {
|
|
279
|
+
specialistId: string; // Required: unique identifier
|
|
280
|
+
machineName: string; // Required: which machine
|
|
281
|
+
|
|
282
|
+
// Execution mode (exactly one required):
|
|
283
|
+
strategyFn?: (ctx: ArbiterContext) => Promise<ArbiterStrategyResult>;
|
|
284
|
+
strategyFnName?: string; // Built-in strategy name
|
|
285
|
+
strategyWebhookUrl?: string; // External webhook URL
|
|
286
|
+
|
|
287
|
+
webhookTokenName?: string; // Required with webhook URLs
|
|
288
|
+
threshold?: number; // Strategy-specific threshold
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
**Three execution modes:**
|
|
293
|
+
1. `strategyFn` — local async function
|
|
294
|
+
2. `strategyFnName` — name of a built-in strategy (`firstProposal`, `alignmentMargin`)
|
|
295
|
+
3. `strategyWebhookUrl` + `webhookTokenName` — external HTTP endpoint
|
|
296
|
+
|
|
297
|
+
### `SubmitProposalOptions`
|
|
298
|
+
|
|
299
|
+
```typescript
|
|
300
|
+
interface SubmitProposalOptions {
|
|
301
|
+
sessionId: string; // Required
|
|
302
|
+
specialistId: string; // Required
|
|
303
|
+
roundId?: string; // Defaults to session's currentRoundId
|
|
304
|
+
transitionName?: string; // If omitted, invokes registered strategy
|
|
305
|
+
reasoning?: string;
|
|
306
|
+
metaJson?: Record<string, unknown>;
|
|
307
|
+
costUSD?: number;
|
|
308
|
+
latencyMsec?: number;
|
|
309
|
+
numInputTokens?: number;
|
|
310
|
+
numOutputTokens?: number;
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### `SubmitArbitrationOptions`
|
|
315
|
+
|
|
316
|
+
```typescript
|
|
317
|
+
interface SubmitArbitrationOptions {
|
|
318
|
+
sessionId: string; // Required
|
|
319
|
+
roundId?: string; // Defaults to session's currentRoundId
|
|
320
|
+
specialistId?: string; // Who is calling
|
|
321
|
+
transitionName?: string; // Force this transition (human only)
|
|
322
|
+
reasoning?: string;
|
|
323
|
+
metaJson?: Record<string, unknown>;
|
|
324
|
+
costUSD?: number;
|
|
325
|
+
latencyMsec?: number;
|
|
326
|
+
numInputTokens?: number;
|
|
327
|
+
numOutputTokens?: number;
|
|
328
|
+
}
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
## Function Signatures
|
|
332
|
+
|
|
333
|
+
### Session Management
|
|
334
|
+
|
|
335
|
+
```typescript
|
|
336
|
+
// Create a new session from a machine definition
|
|
337
|
+
async function createSession(
|
|
338
|
+
machine: MachineDefinition,
|
|
339
|
+
metaJson?: Record<string, unknown>
|
|
340
|
+
): Promise<Session>;
|
|
341
|
+
|
|
342
|
+
// Get a session by ID (throws if not found)
|
|
343
|
+
async function getSession(sessionId: string): Promise<Session>;
|
|
344
|
+
|
|
345
|
+
// Get all sessions
|
|
346
|
+
async function getSessions(): Promise<Session[]>;
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### Specialist Registration
|
|
350
|
+
|
|
351
|
+
```typescript
|
|
352
|
+
// Register a proposer (throws if specialistId already exists)
|
|
353
|
+
async function registerProposer(opts: RegisterProposerOptions): Promise<Proposer>;
|
|
354
|
+
|
|
355
|
+
// Register an arbiter (throws if specialistId already exists)
|
|
356
|
+
async function registerArbiter(opts: RegisterArbiterOptions): Promise<Arbiter>;
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### Decision Cycle
|
|
360
|
+
|
|
361
|
+
```typescript
|
|
362
|
+
// Submit a proposal (invokes strategy if transitionName omitted)
|
|
363
|
+
async function submitProposal(opts: SubmitProposalOptions): Promise<Proposal>;
|
|
364
|
+
|
|
365
|
+
// Evaluate consensus (read-only, does not execute transitions)
|
|
366
|
+
async function evaluateConsensus(sessionId: string): Promise<ConsensusResult>;
|
|
367
|
+
|
|
368
|
+
// Evaluate consensus and execute transition if reached
|
|
369
|
+
async function submitArbitration(opts: SubmitArbitrationOptions): Promise<ArbitrationResult>;
|
|
370
|
+
|
|
371
|
+
// Execute a state transition directly
|
|
372
|
+
async function executeTransition(
|
|
373
|
+
sessionId: string,
|
|
374
|
+
transitionName: string,
|
|
375
|
+
toState: string,
|
|
376
|
+
reasoning?: string
|
|
377
|
+
): Promise<Session>;
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
### Engine
|
|
381
|
+
|
|
382
|
+
```typescript
|
|
383
|
+
// Run a machine to completion (creates session, registers defaults, loops tick)
|
|
384
|
+
async function runSession(machine: MachineDefinition): Promise<Session>;
|
|
385
|
+
|
|
386
|
+
// Global heartbeat: one atomic step per active session
|
|
387
|
+
async function tick(): Promise<TickResult[]>;
|
|
388
|
+
|
|
389
|
+
// Select the highest-alignment proposer above threshold
|
|
390
|
+
async function selectChampion(
|
|
391
|
+
machineName: string,
|
|
392
|
+
threshold: number,
|
|
393
|
+
proposers?: Proposer[],
|
|
394
|
+
state?: string
|
|
395
|
+
): Promise<string | undefined>;
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
### Store
|
|
399
|
+
|
|
400
|
+
```typescript
|
|
401
|
+
// Reset all state (sessions, specialists, proposals, alignment records, etc.)
|
|
402
|
+
async function clear(): Promise<void>;
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
### Monitoring
|
|
406
|
+
|
|
407
|
+
```typescript
|
|
408
|
+
// Compute collapse metrics for a machine
|
|
409
|
+
async function getCollapseMetrics(
|
|
410
|
+
machineName: string,
|
|
411
|
+
state?: string
|
|
412
|
+
): Promise<CollapseMetrics>;
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
## Built-in Strategies
|
|
416
|
+
|
|
417
|
+
### Proposer Strategies
|
|
418
|
+
|
|
419
|
+
| Name | Behavior |
|
|
420
|
+
|---|---|
|
|
421
|
+
| `firstAvailable` | Returns the first transition in `ctx.transitions` |
|
|
422
|
+
| `lastAvailable` | Returns the last transition in `ctx.transitions` |
|
|
423
|
+
| `random` | Returns a randomly selected transition |
|
|
424
|
+
|
|
425
|
+
All throw if no transitions are available.
|
|
426
|
+
|
|
427
|
+
### Arbiter Strategies
|
|
428
|
+
|
|
429
|
+
| Name | Behavior |
|
|
430
|
+
|---|---|
|
|
431
|
+
| `firstProposal` | Accepts the first proposal by creation timestamp |
|
|
432
|
+
| `alignmentMargin` | Alignment-weighted margin consensus |
|
|
433
|
+
|
|
434
|
+
**`alignmentMargin` details:**
|
|
435
|
+
- Single proposal with `threshold <= 1`: auto-approves
|
|
436
|
+
- Multiple proposals: groups by `transitionName`, scores each group by summing proposer alignment scores
|
|
437
|
+
- `margin = (leaderScore - runnerUpScore) / totalAlignment`
|
|
438
|
+
- Consensus when `margin >= threshold` (default threshold = 1, requiring unanimity)
|
|
439
|
+
- Cold start (all alignment scores = 0): no consensus, human input required
|
|
440
|
+
- Winner: highest-alignment proposer in the winning transition group
|
|
441
|
+
|
|
442
|
+
## Monitoring Types
|
|
443
|
+
|
|
444
|
+
### `CollapseMetrics`
|
|
445
|
+
|
|
446
|
+
```typescript
|
|
447
|
+
interface CollapseMetrics {
|
|
448
|
+
machineName: string;
|
|
449
|
+
totalDecisions: number;
|
|
450
|
+
humanDecisions: number;
|
|
451
|
+
aiDecisions: number;
|
|
452
|
+
collapseRatio: number; // aiDecisions / totalDecisions
|
|
453
|
+
recentCollapseRatio: number; // Collapse ratio for recent decisions
|
|
454
|
+
averageConsensusMargin: number;
|
|
455
|
+
alignmentScores: Record<string, number>;
|
|
456
|
+
specialists: SpecialistMetrics[];
|
|
457
|
+
signals: Signal[]; // Actionable signals (info/warning/action)
|
|
458
|
+
}
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
### `AlignmentRecord`
|
|
462
|
+
|
|
463
|
+
```typescript
|
|
464
|
+
interface AlignmentRecord {
|
|
465
|
+
specialistId: string;
|
|
466
|
+
machineName: string;
|
|
467
|
+
state?: string; // When present, alignment is per-state
|
|
468
|
+
matchingChoices: number;
|
|
469
|
+
totalComparisons: number;
|
|
470
|
+
alignmentScore: number; // Wilson score lower bound
|
|
471
|
+
lastUpdated: Date;
|
|
472
|
+
}
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
### `Exemplar`
|
|
476
|
+
|
|
477
|
+
```typescript
|
|
478
|
+
interface Exemplar {
|
|
479
|
+
exemplarId: string;
|
|
480
|
+
machineName: string;
|
|
481
|
+
state: string;
|
|
482
|
+
context: ProposerContext; // Session context at decision time
|
|
483
|
+
humanTransitionName: string;
|
|
484
|
+
humanToState: string;
|
|
485
|
+
proposals: Proposal[]; // All proposals that were available
|
|
486
|
+
createdAt: Date;
|
|
487
|
+
}
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
### `TickResult`
|
|
491
|
+
|
|
492
|
+
```typescript
|
|
493
|
+
type TickStatus = "solicited" | "advanced" | "needs_human";
|
|
494
|
+
|
|
495
|
+
interface TickResult {
|
|
496
|
+
sessionId: string;
|
|
497
|
+
machineName: string;
|
|
498
|
+
status: TickStatus;
|
|
499
|
+
currentState: string;
|
|
500
|
+
specialistId?: string; // Set when status === "solicited"
|
|
501
|
+
previousState?: string; // Set when status === "advanced"
|
|
502
|
+
transitionName?: string; // Set when status === "advanced"
|
|
503
|
+
reasoning?: string; // Set when status === "advanced"
|
|
504
|
+
}
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
## Environment Variables
|
|
508
|
+
|
|
509
|
+
| Variable | Default | Description |
|
|
510
|
+
|---|---|---|
|
|
511
|
+
| `DIALAI_BASE_URL` | `""` | Remote DIAL server URL (proxy mode) |
|
|
512
|
+
| `DIALAI_PORT` | — | Port for HTTP server mode |
|
|
513
|
+
| `DIALAI_API_TOKEN` | `""` | Bearer token for HTTP server and proxy mode |
|
|
514
|
+
| `DIALAI_LLM_BASE_URL` | `"https://openrouter.ai/api/v1"` | OpenAI-compatible LLM endpoint |
|
|
515
|
+
| `OPENROUTER_API_TOKEN` | `""` | API token for OpenRouter or compatible provider |
|