taias 0.8.0 → 0.9.1
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 +1 -1
- package/README.md +30 -3
- package/dist/index.cjs +227 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +84 -1
- package/dist/index.d.ts +84 -1
- package/dist/index.js +226 -9
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/LICENSE
CHANGED
|
@@ -186,7 +186,7 @@ Apache License
|
|
|
186
186
|
same "printed page" as the copyright notice for easier
|
|
187
187
|
identification within third-party archives.
|
|
188
188
|
|
|
189
|
-
Copyright 2025 Taias (github.com/taias-
|
|
189
|
+
Copyright 2025 Taias (github.com/taias-xyz)
|
|
190
190
|
|
|
191
191
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
192
|
you may not use this file except in compliance with the License.
|
package/README.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
|
|
3
3
|
<picture>
|
|
4
|
-
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/taias-
|
|
5
|
-
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/taias-
|
|
6
|
-
<img width="300" alt="Taias logo" src="https://raw.githubusercontent.com/taias-
|
|
4
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/taias-xyz/taias/main/static/taias_dark.png">
|
|
5
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/taias-xyz/taias/main/static/taias_light.png">
|
|
6
|
+
<img width="300" alt="Taias logo" src="https://raw.githubusercontent.com/taias-xyz/taias/main/static/taias_light.png">
|
|
7
7
|
</picture>
|
|
8
8
|
|
|
9
9
|
<br/>
|
|
@@ -120,6 +120,8 @@ const taias = createTaias({
|
|
|
120
120
|
**Options:**
|
|
121
121
|
- `flow` - A `FlowDefinition` created by `defineFlow`
|
|
122
122
|
- `devMode` (optional) - Enable development mode checks
|
|
123
|
+
- `debug` (optional) - `true` or `{ format, logger }` -- enable built-in debug output
|
|
124
|
+
- `tracing` (optional) - `"summary"` (default) or `"detailed"` -- controls trace depth
|
|
123
125
|
- `onMissingStep` (optional) - Callback invoked when no step matches
|
|
124
126
|
|
|
125
127
|
**Returns:** `Taias` instance
|
|
@@ -150,6 +152,31 @@ const affordances = await taias.resolve({
|
|
|
150
152
|
|
|
151
153
|
See the [full documentation](https://taias.xyz/docs) for complete API reference and types.
|
|
152
154
|
|
|
155
|
+
## Observability
|
|
156
|
+
|
|
157
|
+
Enable debug output with a single option:
|
|
158
|
+
|
|
159
|
+
```ts
|
|
160
|
+
const taias = createTaias({ flow, debug: true });
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Every `resolve()` call prints a formatted breakdown to the console -- what went in, how the decision was reached, and what was produced.
|
|
164
|
+
|
|
165
|
+
For compact single-line output:
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
const taias = createTaias({ flow, debug: { format: "compact" } });
|
|
169
|
+
// [Taias] scan_repo → nextTool=configure_app (indexed, step 0, 1 evaluated)
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Enable detailed tracing for per-step evaluation breakdowns (verbose -- best used when debugging specific resolve calls):
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
const taias = createTaias({ flow, debug: true, tracing: "detailed" });
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
For programmatic access to resolve events, use the event emitter API (`taias.on` / `taias.off`). See the [full documentation](https://taias.xyz/docs) for details.
|
|
179
|
+
|
|
153
180
|
## Dev Mode
|
|
154
181
|
|
|
155
182
|
<details>
|
package/dist/index.cjs
CHANGED
|
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
createDebugSubscriber: () => createDebugSubscriber,
|
|
23
24
|
createTaias: () => createTaias,
|
|
24
25
|
defineAffordances: () => defineAffordances,
|
|
25
26
|
defineFlow: () => defineFlow,
|
|
@@ -106,6 +107,88 @@ function selectUiAffordances(decision, index, opts = {}) {
|
|
|
106
107
|
return selections;
|
|
107
108
|
}
|
|
108
109
|
|
|
110
|
+
// src/debugSubscriber.ts
|
|
111
|
+
function formatContext(context) {
|
|
112
|
+
const parts = [];
|
|
113
|
+
if (context.toolName) parts.push(`toolName=${context.toolName}`);
|
|
114
|
+
if (context.params) parts.push(`params=${JSON.stringify(context.params)}`);
|
|
115
|
+
if (context.result) parts.push(`result=${JSON.stringify(context.result)}`);
|
|
116
|
+
return parts.length > 0 ? parts.join(", ") : "(empty)";
|
|
117
|
+
}
|
|
118
|
+
function formatContextLabel(context) {
|
|
119
|
+
if (context.toolName) return context.toolName;
|
|
120
|
+
if (context.params) return `params:${JSON.stringify(context.params)}`;
|
|
121
|
+
if (context.result) return `result:${JSON.stringify(context.result)}`;
|
|
122
|
+
return "(empty)";
|
|
123
|
+
}
|
|
124
|
+
function createDebugSubscriber(options) {
|
|
125
|
+
const format = options?.format ?? "default";
|
|
126
|
+
const log = options?.logger ?? console.log;
|
|
127
|
+
if (format === "compact") {
|
|
128
|
+
return (event) => {
|
|
129
|
+
const { trace, context } = event;
|
|
130
|
+
const label = formatContextLabel(context);
|
|
131
|
+
if (!trace.matched) {
|
|
132
|
+
log(`[Taias] ${label} \u2192 no match (${trace.candidatesEvaluated} evaluated)`);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const decisionSummary = event.decision ? Object.entries(event.decision).map(([k, v]) => `${k}=${v}`).join(", ") : "null";
|
|
136
|
+
log(
|
|
137
|
+
`[Taias] ${label} \u2192 ${decisionSummary} (${trace.phase}, step ${trace.matchedStepIndex}, ${trace.candidatesEvaluated} evaluated)`
|
|
138
|
+
);
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
return (event) => {
|
|
142
|
+
const { trace, context } = event;
|
|
143
|
+
const lines = [];
|
|
144
|
+
lines.push("\u250C\u2500 Taias Resolve \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
145
|
+
lines.push(`\u2502 Flow: ${event.flowId}`);
|
|
146
|
+
lines.push(`\u2502 Context: ${formatContext(context)}`);
|
|
147
|
+
lines.push("\u2502");
|
|
148
|
+
if (!trace.matched) {
|
|
149
|
+
lines.push("\u2502 Result: NO MATCH");
|
|
150
|
+
lines.push(`\u2502 Candidates evaluated: ${trace.candidatesEvaluated}`);
|
|
151
|
+
} else {
|
|
152
|
+
lines.push(`\u2502 Matched: step ${trace.matchedStepIndex} (${trace.matchedStepKind})`);
|
|
153
|
+
lines.push(`\u2502 Phase: ${trace.phase}`);
|
|
154
|
+
if (trace.resolutionPath.length > 0) {
|
|
155
|
+
lines.push(`\u2502 Resolution path: ${trace.resolutionPath.join(" \u2192 ")}`);
|
|
156
|
+
}
|
|
157
|
+
lines.push(`\u2502 Candidates evaluated: ${trace.candidatesEvaluated}`);
|
|
158
|
+
if (trace.matchedStepMatch) {
|
|
159
|
+
lines.push(`\u2502 Match condition: ${JSON.stringify(trace.matchedStepMatch)}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
lines.push("\u2502");
|
|
163
|
+
if (event.decision) {
|
|
164
|
+
const fields = Object.entries(event.decision).map(([k, v]) => `${k}=${v}`).join(", ");
|
|
165
|
+
lines.push(`\u2502 Decision: ${fields}`);
|
|
166
|
+
} else {
|
|
167
|
+
lines.push("\u2502 Decision: null");
|
|
168
|
+
}
|
|
169
|
+
if (event.affordances) {
|
|
170
|
+
lines.push(`\u2502 Advice: ${event.affordances.advice.slice(0, 80)}${event.affordances.advice.length > 80 ? "..." : ""}`);
|
|
171
|
+
}
|
|
172
|
+
lines.push(`\u2502 Duration: ${event.durationMs.toFixed(2)}ms`);
|
|
173
|
+
if (trace.evaluations) {
|
|
174
|
+
lines.push("\u2502");
|
|
175
|
+
lines.push("\u2502 Detailed evaluations:");
|
|
176
|
+
for (const evaluation of trace.evaluations) {
|
|
177
|
+
const icon = evaluation.result === "matched" ? "\u2713" : "\u2717";
|
|
178
|
+
lines.push(`\u2502 ${icon} step ${evaluation.stepIndex}: ${evaluation.result}`);
|
|
179
|
+
if (evaluation.fieldResults) {
|
|
180
|
+
for (const [field, fr] of Object.entries(evaluation.fieldResults)) {
|
|
181
|
+
const fieldIcon = fr.passed ? "\u2713" : "\u2717";
|
|
182
|
+
lines.push(`\u2502 ${fieldIcon} ${field}: ${JSON.stringify(fr.condition)} vs ${JSON.stringify(fr.actual)}`);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
lines.push("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
188
|
+
log(lines.join("\n"));
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
109
192
|
// src/createTaias.ts
|
|
110
193
|
function generateAdvice(nextTool) {
|
|
111
194
|
return `FOR THE BEST USER EXPERIENCE, TELL THE USER TO USE THE ${nextTool} TOOL NEXT!!!!!`;
|
|
@@ -131,6 +214,47 @@ function evaluateMatch(match, ctx) {
|
|
|
131
214
|
}
|
|
132
215
|
return true;
|
|
133
216
|
}
|
|
217
|
+
function evaluateMatchDetailed(match, ctx) {
|
|
218
|
+
const fieldResults = {};
|
|
219
|
+
let allPassed = true;
|
|
220
|
+
if (match.toolName) {
|
|
221
|
+
const actual = ctx.toolName;
|
|
222
|
+
const passed = evaluateCondition(match.toolName, actual);
|
|
223
|
+
fieldResults["toolName"] = { condition: match.toolName, actual, passed };
|
|
224
|
+
if (!passed) allPassed = false;
|
|
225
|
+
}
|
|
226
|
+
if (match.params) {
|
|
227
|
+
if (!ctx.params) {
|
|
228
|
+
for (const [key, condition] of Object.entries(match.params)) {
|
|
229
|
+
fieldResults[`params.${key}`] = { condition, actual: void 0, passed: false };
|
|
230
|
+
}
|
|
231
|
+
allPassed = false;
|
|
232
|
+
} else {
|
|
233
|
+
for (const [key, condition] of Object.entries(match.params)) {
|
|
234
|
+
const actual = ctx.params[key];
|
|
235
|
+
const passed = evaluateCondition(condition, actual);
|
|
236
|
+
fieldResults[`params.${key}`] = { condition, actual, passed };
|
|
237
|
+
if (!passed) allPassed = false;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
if (match.result) {
|
|
242
|
+
if (!ctx.result) {
|
|
243
|
+
for (const [key, condition] of Object.entries(match.result)) {
|
|
244
|
+
fieldResults[`result.${key}`] = { condition, actual: void 0, passed: false };
|
|
245
|
+
}
|
|
246
|
+
allPassed = false;
|
|
247
|
+
} else {
|
|
248
|
+
for (const [key, condition] of Object.entries(match.result)) {
|
|
249
|
+
const actual = ctx.result[key];
|
|
250
|
+
const passed = evaluateCondition(condition, actual);
|
|
251
|
+
fieldResults[`result.${key}`] = { condition, actual, passed };
|
|
252
|
+
if (!passed) allPassed = false;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return { passed: allPassed, fieldResults };
|
|
257
|
+
}
|
|
134
258
|
function extractIsConditions(match) {
|
|
135
259
|
const conditions = [];
|
|
136
260
|
if (match.toolName && "is" in match.toolName) {
|
|
@@ -171,10 +295,13 @@ function createTaias(options) {
|
|
|
171
295
|
flow,
|
|
172
296
|
affordances,
|
|
173
297
|
devMode = false,
|
|
298
|
+
debug = false,
|
|
299
|
+
tracing = "summary",
|
|
174
300
|
onMissingStep,
|
|
175
301
|
onWarn
|
|
176
302
|
} = options;
|
|
177
303
|
const warn = onWarn ?? ((msg) => console.warn(msg));
|
|
304
|
+
const detailed = tracing === "detailed";
|
|
178
305
|
if (devMode) {
|
|
179
306
|
const seenKeys = /* @__PURE__ */ new Set();
|
|
180
307
|
for (const step of flow.steps) {
|
|
@@ -221,9 +348,54 @@ function createTaias(options) {
|
|
|
221
348
|
}
|
|
222
349
|
const hasBroadSteps = broadStepIndices.length > 0;
|
|
223
350
|
const registryIndex = buildRegistryIndex(affordances);
|
|
351
|
+
const listeners = /* @__PURE__ */ new Map();
|
|
352
|
+
function emit(event, data) {
|
|
353
|
+
const handlers = listeners.get(event);
|
|
354
|
+
if (handlers) {
|
|
355
|
+
for (const handler of handlers) handler(data);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
function on(event, handler) {
|
|
359
|
+
let set = listeners.get(event);
|
|
360
|
+
if (!set) {
|
|
361
|
+
set = /* @__PURE__ */ new Set();
|
|
362
|
+
listeners.set(event, set);
|
|
363
|
+
}
|
|
364
|
+
set.add(handler);
|
|
365
|
+
}
|
|
366
|
+
function off(event, handler) {
|
|
367
|
+
listeners.get(event)?.delete(handler);
|
|
368
|
+
}
|
|
369
|
+
if (debug) {
|
|
370
|
+
const debugOpts = typeof debug === "object" ? debug : void 0;
|
|
371
|
+
on("resolve", createDebugSubscriber(debugOpts));
|
|
372
|
+
}
|
|
224
373
|
return {
|
|
225
374
|
async resolve(ctx) {
|
|
375
|
+
const startTime = performance.now();
|
|
376
|
+
const timestamp = Date.now();
|
|
226
377
|
let matchedStep;
|
|
378
|
+
let matchedStepIndex = null;
|
|
379
|
+
let matchPhase = null;
|
|
380
|
+
const resolutionPath = [];
|
|
381
|
+
let candidatesEvaluated = 0;
|
|
382
|
+
const evaluations = detailed ? [] : void 0;
|
|
383
|
+
function tryMatch(idx) {
|
|
384
|
+
candidatesEvaluated++;
|
|
385
|
+
const step = flow.steps[idx];
|
|
386
|
+
const match = getMatch(step);
|
|
387
|
+
if (detailed) {
|
|
388
|
+
const { passed, fieldResults } = evaluateMatchDetailed(match, ctx);
|
|
389
|
+
evaluations.push({
|
|
390
|
+
stepIndex: idx,
|
|
391
|
+
match,
|
|
392
|
+
result: passed ? "matched" : "no-match",
|
|
393
|
+
fieldResults
|
|
394
|
+
});
|
|
395
|
+
return passed;
|
|
396
|
+
}
|
|
397
|
+
return evaluateMatch(match, ctx);
|
|
398
|
+
}
|
|
227
399
|
const applicableFieldPaths = [];
|
|
228
400
|
for (const fieldPath of fieldIndexes.keys()) {
|
|
229
401
|
const ctxValue = getContextValue(ctx, fieldPath);
|
|
@@ -231,6 +403,7 @@ function createTaias(options) {
|
|
|
231
403
|
applicableFieldPaths.push(fieldPath);
|
|
232
404
|
}
|
|
233
405
|
}
|
|
406
|
+
resolutionPath.push(...applicableFieldPaths);
|
|
234
407
|
if (applicableFieldPaths.length > 0) {
|
|
235
408
|
let candidates = null;
|
|
236
409
|
for (const fieldPath of applicableFieldPaths) {
|
|
@@ -255,30 +428,55 @@ function createTaias(options) {
|
|
|
255
428
|
if (candidates && candidates.size > 0) {
|
|
256
429
|
const sorted = [...candidates].sort((a, b) => a - b);
|
|
257
430
|
for (const idx of sorted) {
|
|
258
|
-
if (
|
|
431
|
+
if (tryMatch(idx)) {
|
|
259
432
|
matchedStep = flow.steps[idx];
|
|
433
|
+
matchedStepIndex = idx;
|
|
434
|
+
matchPhase = "indexed";
|
|
260
435
|
break;
|
|
261
436
|
}
|
|
262
437
|
}
|
|
263
438
|
}
|
|
264
439
|
} else if (indexableStepIndices.length > 0) {
|
|
265
440
|
for (const idx of indexableStepIndices) {
|
|
266
|
-
if (
|
|
441
|
+
if (tryMatch(idx)) {
|
|
267
442
|
matchedStep = flow.steps[idx];
|
|
443
|
+
matchedStepIndex = idx;
|
|
444
|
+
matchPhase = "indexed";
|
|
268
445
|
break;
|
|
269
446
|
}
|
|
270
447
|
}
|
|
271
448
|
}
|
|
272
449
|
if (!matchedStep && hasBroadSteps) {
|
|
273
450
|
for (const idx of broadStepIndices) {
|
|
274
|
-
if (
|
|
451
|
+
if (tryMatch(idx)) {
|
|
275
452
|
matchedStep = flow.steps[idx];
|
|
453
|
+
matchedStepIndex = idx;
|
|
454
|
+
matchPhase = "broad";
|
|
276
455
|
break;
|
|
277
456
|
}
|
|
278
457
|
}
|
|
279
458
|
}
|
|
459
|
+
const trace = {
|
|
460
|
+
matched: !!matchedStep,
|
|
461
|
+
matchedStepIndex,
|
|
462
|
+
matchedStepKind: matchedStep?.kind ?? null,
|
|
463
|
+
matchedStepMatch: matchedStep ? getMatch(matchedStep) : null,
|
|
464
|
+
phase: matchPhase,
|
|
465
|
+
resolutionPath,
|
|
466
|
+
candidatesEvaluated,
|
|
467
|
+
...evaluations !== void 0 ? { evaluations } : {}
|
|
468
|
+
};
|
|
280
469
|
if (!matchedStep) {
|
|
281
470
|
onMissingStep?.(ctx);
|
|
471
|
+
emit("resolve", {
|
|
472
|
+
flowId: flow.id,
|
|
473
|
+
timestamp,
|
|
474
|
+
durationMs: performance.now() - startTime,
|
|
475
|
+
context: ctx,
|
|
476
|
+
trace,
|
|
477
|
+
decision: null,
|
|
478
|
+
affordances: null
|
|
479
|
+
});
|
|
282
480
|
return null;
|
|
283
481
|
}
|
|
284
482
|
let result;
|
|
@@ -287,7 +485,18 @@ function createTaias(options) {
|
|
|
287
485
|
} else {
|
|
288
486
|
result = await matchedStep.handler(ctx);
|
|
289
487
|
}
|
|
290
|
-
if (!result)
|
|
488
|
+
if (!result) {
|
|
489
|
+
emit("resolve", {
|
|
490
|
+
flowId: flow.id,
|
|
491
|
+
timestamp,
|
|
492
|
+
durationMs: performance.now() - startTime,
|
|
493
|
+
context: ctx,
|
|
494
|
+
trace,
|
|
495
|
+
decision: null,
|
|
496
|
+
affordances: null
|
|
497
|
+
});
|
|
498
|
+
return null;
|
|
499
|
+
}
|
|
291
500
|
if (devMode && result.nextTool === "") {
|
|
292
501
|
warn(`Taias: nextTool for tool '${ctx.toolName}' is empty.`);
|
|
293
502
|
}
|
|
@@ -296,12 +505,20 @@ function createTaias(options) {
|
|
|
296
505
|
devMode,
|
|
297
506
|
onWarn: warn
|
|
298
507
|
});
|
|
299
|
-
|
|
300
|
-
|
|
508
|
+
const advice = generateAdvice(result.nextTool);
|
|
509
|
+
emit("resolve", {
|
|
510
|
+
flowId: flow.id,
|
|
511
|
+
timestamp,
|
|
512
|
+
durationMs: performance.now() - startTime,
|
|
513
|
+
context: ctx,
|
|
514
|
+
trace,
|
|
301
515
|
decision,
|
|
302
|
-
selections
|
|
303
|
-
};
|
|
304
|
-
|
|
516
|
+
affordances: { advice, selections }
|
|
517
|
+
});
|
|
518
|
+
return { advice, decision, selections };
|
|
519
|
+
},
|
|
520
|
+
on,
|
|
521
|
+
off
|
|
305
522
|
};
|
|
306
523
|
}
|
|
307
524
|
|
|
@@ -352,6 +569,7 @@ function mergeAffordances(registries, opts = {}) {
|
|
|
352
569
|
}
|
|
353
570
|
// Annotate the CommonJS export names for ESM import in node:
|
|
354
571
|
0 && (module.exports = {
|
|
572
|
+
createDebugSubscriber,
|
|
355
573
|
createTaias,
|
|
356
574
|
defineAffordances,
|
|
357
575
|
defineFlow,
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/flow.ts","../src/uiAffordances/types.ts","../src/uiAffordances/indexing.ts","../src/uiAffordances/select.ts","../src/createTaias.ts","../src/uiAffordances/defineAffordances.ts","../src/uiAffordances/mergeAffordances.ts"],"sourcesContent":["// Main exports\nexport { defineFlow } from \"./flow\";\nexport { createTaias } from \"./createTaias\";\n\n// UI affordances exports\nexport { defineAffordances } from \"./uiAffordances/defineAffordances\";\nexport { mergeAffordances } from \"./uiAffordances/mergeAffordances\";\nexport type { AffordanceRegistrar } from \"./uiAffordances/defineAffordances\";\nexport type {\n DefaultSlots,\n CanonicalSlot,\n Binding,\n BindingInput,\n HandleRegistration,\n Selection,\n UiSelections,\n AffordanceRegistry,\n} from \"./uiAffordances/types\";\n\n// Core + flow type exports\nexport type {\n Condition,\n Decision,\n TaiasContext,\n StepDecision,\n Affordances,\n StepHandler,\n StepInput,\n MatchCondition,\n LogicStatement,\n FlowStep,\n FlowDefinition,\n FlowBuilder,\n TaiasOptions,\n Taias,\n} from \"./types\";\n","import type { FlowBuilder, FlowDefinition, FlowStep, MatchCondition, StepInput } from \"./types\";\n\n/**\n * Define a flow with its steps.\n *\n * @param flowId - Unique identifier for the flow\n * @param builder - Callback that receives a FlowBuilder to define steps\n * @returns A FlowDefinition object\n *\n * @example Logic statement matching on toolName\n * ```ts\n * const onboardRepoFlow = defineFlow(\"onboard_repo\", (flow) => {\n * flow.step({ toolName: { is: \"scan_repo\" } }, { nextTool: \"configure_app\" });\n * });\n * ```\n *\n * @example Matching on params and result\n * ```ts\n * flow.step(\n * { toolName: { is: \"scan_repo\" }, params: { language: { is: \"python\" } } },\n * { nextTool: \"configure_python\" },\n * );\n * flow.step(\n * { result: { hasConfig: { is: true } } },\n * { nextTool: \"review_config\" },\n * );\n * ```\n *\n * @example isNot operator\n * ```ts\n * flow.step({ toolName: { isNot: \"abort_session\" } }, { nextTool: \"continue_flow\" });\n * ```\n */\nexport function defineFlow(\n flowId: string,\n builder: (flow: FlowBuilder) => void\n): FlowDefinition {\n const steps: FlowStep[] = [];\n\n const flowBuilder: FlowBuilder = {\n step(match: MatchCondition, input: StepInput): void {\n if (typeof input === \"function\") {\n steps.push({ kind: \"handler\", match, handler: input });\n } else {\n steps.push({\n kind: \"logic\",\n statement: {\n match,\n decision: input,\n },\n });\n }\n },\n };\n\n builder(flowBuilder);\n\n return {\n id: flowId,\n steps,\n };\n}\n","/**\n * Default slots for backwards compatibility.\n * Users can define custom slots by passing a type parameter.\n */\nexport type DefaultSlots = \"primaryCta\" | \"secondaryCta\" | \"widgetVariant\";\n\n/**\n * Alias for backwards compatibility in exports.\n * @deprecated Use DefaultSlots or define your own slot type\n */\nexport type CanonicalSlot = DefaultSlots;\n\nexport type Binding = {\n key: string;\n value: string;\n};\n\n/**\n * Input format for registering affordance bindings.\n * - { toolName } is shorthand for { key: \"nextTool\", value: toolName }\n * - { key, value } is the generalized form for custom bindings\n */\nexport type BindingInput = { toolName: string } | { key: string; value: string };\n\n/**\n * A registered UI affordance handle.\n * Generic over slot type S for custom slot support.\n */\nexport type HandleRegistration<S extends string = DefaultSlots> = {\n slot: S;\n handleId: string;\n bindsTo: Binding;\n};\n\nexport type Selection = {\n handleId: string;\n bindsTo: Binding;\n};\n\n/**\n * UI selections keyed by slot name.\n * Generic over slot type S for custom slot support.\n */\nexport type UiSelections<S extends string = DefaultSlots> = Partial<Record<S, Selection>>;\n\n/**\n * Collection of registered handles.\n * Generic over slot type S for custom slot support.\n */\nexport type AffordanceRegistry<S extends string = DefaultSlots> = {\n handles: HandleRegistration<S>[];\n};\n\nexport function normalizeBinding(input: BindingInput): Binding {\n if (\"toolName\" in input) return { key: \"nextTool\", value: input.toolName };\n return { key: input.key, value: input.value };\n}\n\n/**\n * Creates a binding key for indexing.\n * Accepts any string for slot to support custom slots.\n */\nexport function makeBindingKey(slot: string, binding: Binding): string {\n return `${slot}::${binding.key}::${binding.value}`;\n}\n","import type { AffordanceRegistry, DefaultSlots, HandleRegistration } from \"./types\";\nimport { makeBindingKey } from \"./types\";\n\n/**\n * Index structure for efficient affordance lookup.\n * Generic over slot type S for custom slot support.\n */\nexport type RegistryIndex<S extends string = DefaultSlots> = {\n byBindingKey: Map<string, HandleRegistration<S>>;\n slots: Set<S>;\n /** Inferred decision field for each slot, derived from handle bindings. */\n slotKeyMap: Map<S, string>;\n};\n\n/**\n * Build an index from a registry for efficient lookup during selection.\n * Tracks which slots have registered handles and infers the decision field\n * for each slot from its handle bindings.\n *\n * @throws Error if handles for the same slot bind to different keys\n */\nexport function buildRegistryIndex<S extends string = DefaultSlots>(\n registry?: AffordanceRegistry<S>\n): RegistryIndex<S> {\n const byBindingKey = new Map<string, HandleRegistration<S>>();\n const slots = new Set<S>();\n const slotKeyMap = new Map<S, string>();\n\n if (!registry) return { byBindingKey, slots, slotKeyMap };\n\n for (const h of registry.handles) {\n slots.add(h.slot);\n\n // Infer and validate slot key\n const existingKey = slotKeyMap.get(h.slot);\n if (existingKey && existingKey !== h.bindsTo.key) {\n throw new Error(\n `[Taias] Slot \"${h.slot}\" has handles bound to different keys: \"${existingKey}\" and \"${h.bindsTo.key}\". ` +\n `All handles for a slot must use the same decision field.`\n );\n }\n slotKeyMap.set(h.slot, h.bindsTo.key);\n\n byBindingKey.set(makeBindingKey(h.slot, h.bindsTo), h);\n }\n\n return { byBindingKey, slots, slotKeyMap };\n}\n","import type { Decision } from \"../types\";\nimport type { DefaultSlots, UiSelections } from \"./types\";\nimport type { RegistryIndex } from \"./indexing\";\nimport { makeBindingKey } from \"./types\";\n\nexport type SelectOptions = {\n devMode?: boolean;\n onWarn?: (msg: string) => void;\n};\n\n/**\n * Select UI affordances based on flow decision.\n * Uses the inferred decision field for each slot from the registry index.\n */\nexport function selectUiAffordances<S extends string = DefaultSlots>(\n decision: Decision,\n index: RegistryIndex<S>,\n opts: SelectOptions = {}\n): UiSelections<S> {\n const devMode = !!opts.devMode;\n const warn = opts.onWarn ?? (() => {});\n\n const selections: UiSelections<S> = {};\n\n for (const slot of index.slots) {\n // Use inferred key from handle bindings\n const field = index.slotKeyMap.get(slot);\n if (!field) continue;\n\n const value = decision[field];\n if (!value) continue;\n\n const k = makeBindingKey(slot, { key: field, value });\n const handle = index.byBindingKey.get(k);\n\n if (!handle) {\n if (devMode) warn(`[Taias] No affordance for slot \"${slot}\" when ${field}=\"${value}\"`);\n continue;\n }\n\n (selections as Record<string, unknown>)[slot] = {\n handleId: handle.handleId,\n bindsTo: handle.bindsTo,\n };\n }\n\n return selections;\n}\n","import type { Affordances, Condition, FlowStep, MatchCondition, StepDecision, Taias, TaiasContext, TaiasOptions, Decision } from \"./types\";\nimport type { DefaultSlots } from \"./uiAffordances/types\";\nimport { buildRegistryIndex } from \"./uiAffordances/indexing\";\nimport { selectUiAffordances } from \"./uiAffordances/select\";\n\n/**\n * Generate advice text for a given next tool.\n */\nfunction generateAdvice(nextTool: string): string {\n return `FOR THE BEST USER EXPERIENCE, TELL THE USER TO USE THE ${nextTool} TOOL NEXT!!!!!`;\n}\n\n// ---------------------------------------------------------------------------\n// Condition evaluation\n// ---------------------------------------------------------------------------\n\n/**\n * Evaluate a single Condition against a value using strict equality.\n */\nfunction evaluateCondition(condition: Condition, value: unknown): boolean {\n if (\"is\" in condition) return value === condition.is;\n if (\"isNot\" in condition) return value !== condition.isNot;\n return false;\n}\n\n/**\n * Evaluate a full MatchCondition against a TaiasContext.\n * All present conditions must be satisfied (logical AND).\n *\n * - toolName: compared directly against ctx.toolName\n * - params: subset match -- each specified key is checked against ctx.params\n * - result: subset match -- each specified key is checked against ctx.result\n *\n * If a step specifies params/result conditions but the context doesn't\n * include params/result, the step does not match.\n */\nfunction evaluateMatch(match: MatchCondition, ctx: TaiasContext): boolean {\n if (match.toolName && !evaluateCondition(match.toolName, ctx.toolName)) return false;\n\n if (match.params) {\n if (!ctx.params) return false;\n for (const [key, condition] of Object.entries(match.params)) {\n if (!evaluateCondition(condition, ctx.params[key])) return false;\n }\n }\n\n if (match.result) {\n if (!ctx.result) return false;\n for (const [key, condition] of Object.entries(match.result)) {\n if (!evaluateCondition(condition, ctx.result[key])) return false;\n }\n }\n\n return true;\n}\n\n// ---------------------------------------------------------------------------\n// Per-field indexing\n// ---------------------------------------------------------------------------\n\ninterface FieldIndex {\n valueMap: Map<unknown, number[]>;\n unconstrained: number[];\n}\n\n/**\n * Extract all `is` conditions from a match condition as field-path / value pairs.\n */\nfunction extractIsConditions(match: MatchCondition): Array<{ path: string; value: unknown }> {\n const conditions: Array<{ path: string; value: unknown }> = [];\n if (match.toolName && \"is\" in match.toolName) {\n conditions.push({ path: \"toolName\", value: match.toolName.is });\n }\n if (match.params) {\n for (const [key, cond] of Object.entries(match.params)) {\n if (\"is\" in cond) conditions.push({ path: `params.${key}`, value: cond.is });\n }\n }\n if (match.result) {\n for (const [key, cond] of Object.entries(match.result)) {\n if (\"is\" in cond) conditions.push({ path: `result.${key}`, value: cond.is });\n }\n }\n return conditions;\n}\n\n/**\n * Check whether a match condition has a condition on a given field path.\n */\nfunction hasConditionOnField(match: MatchCondition, path: string): boolean {\n if (path === \"toolName\") return !!match.toolName;\n if (path.startsWith(\"params.\")) return !!match.params?.[path.slice(7)];\n if (path.startsWith(\"result.\")) return !!match.result?.[path.slice(7)];\n return false;\n}\n\n/**\n * Get the value from a TaiasContext for a given field path.\n */\nfunction getContextValue(ctx: TaiasContext, path: string): unknown {\n if (path === \"toolName\") return ctx.toolName;\n if (path.startsWith(\"params.\")) return ctx.params?.[path.slice(7)];\n if (path.startsWith(\"result.\")) return ctx.result?.[path.slice(7)];\n return undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Step access helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Get the match condition from a FlowStep.\n *\n * - Logic-based steps: match comes from statement.match\n * - Handler-based steps (backwards compatibility): match is stored directly on the step\n */\nfunction getMatch(step: FlowStep): MatchCondition {\n return step.kind === \"logic\" ? step.statement.match : step.match;\n}\n\n/**\n * Serialize a MatchCondition into a stable string for duplicate detection.\n */\nfunction serializeMatch(match: MatchCondition): string {\n return JSON.stringify(match);\n}\n\n/**\n * createTaias constructs a decision engine.\n *\n * Taias resolves context into a generalized Decision object,\n * and then manifests that decision into concrete affordances:\n *\n * - LLM guidance (advice)\n * - UI affordance selections\n *\n * Flow logic is expressed as logic statements -- structured data that\n * Taias understands. (Handler functions remain as a backwards-compatible\n * escape hatch.)\n *\n * Flow logic determines *what should happen next*.\n * UI affordances determine *how that decision appears in the interface*.\n *\n * This file is the boundary where:\n *\n * Inputs -> Decision -> Manifestations\n *\n * are unified into a single resolve() call.\n *\n * @example\n * ```ts\n * const taias = createTaias({ flow, affordances });\n * ```\n */\nexport function createTaias<S extends string = DefaultSlots>(\n options: TaiasOptions<S>\n): Taias<S> {\n const {\n flow,\n affordances,\n devMode = false,\n onMissingStep,\n onWarn,\n } = options;\n\n const warn = onWarn ?? ((msg: string) => console.warn(msg));\n\n // Dev mode: Check for duplicate match conditions.\n if (devMode) {\n const seenKeys = new Set<string>();\n for (const step of flow.steps) {\n const key = serializeMatch(getMatch(step));\n if (seenKeys.has(key)) {\n throw new Error(\n `Taias: Duplicate match condition in flow '${flow.id}'. Each step must have a unique match condition. Duplicate: ${key}`\n );\n }\n seenKeys.add(key);\n }\n }\n\n // -----------------------------------------------------------------------\n // Build per-field indexes\n // -----------------------------------------------------------------------\n\n const fieldIndexes = new Map<string, FieldIndex>();\n const indexableStepIndices: number[] = [];\n const broadStepIndices: number[] = [];\n\n for (let i = 0; i < flow.steps.length; i++) {\n const match = getMatch(flow.steps[i]);\n const isConditions = extractIsConditions(match);\n\n if (isConditions.length === 0) {\n broadStepIndices.push(i);\n continue;\n }\n\n indexableStepIndices.push(i);\n\n for (const { path, value } of isConditions) {\n let fieldIndex = fieldIndexes.get(path);\n if (!fieldIndex) {\n fieldIndex = { valueMap: new Map(), unconstrained: [] };\n fieldIndexes.set(path, fieldIndex);\n }\n let stepList = fieldIndex.valueMap.get(value);\n if (!stepList) {\n stepList = [];\n fieldIndex.valueMap.set(value, stepList);\n }\n stepList.push(i);\n }\n }\n\n // Build unconstrained sets: for each field index, find indexable steps\n // that don't have a condition on that field.\n for (const [fieldPath, fieldIndex] of fieldIndexes) {\n for (const i of indexableStepIndices) {\n if (!hasConditionOnField(getMatch(flow.steps[i]), fieldPath)) {\n fieldIndex.unconstrained.push(i);\n }\n }\n }\n\n const hasBroadSteps = broadStepIndices.length > 0;\n\n // Build affordance index once (if provided)\n const registryIndex = buildRegistryIndex<S>(affordances);\n\n return {\n async resolve(ctx: TaiasContext): Promise<Affordances<S> | null> {\n let matchedStep: FlowStep | undefined;\n\n // Phase 1: Find candidates from per-field indexes via intersection\n const applicableFieldPaths: string[] = [];\n for (const fieldPath of fieldIndexes.keys()) {\n const ctxValue = getContextValue(ctx, fieldPath);\n if (ctxValue !== undefined) {\n applicableFieldPaths.push(fieldPath);\n }\n }\n\n if (applicableFieldPaths.length > 0) {\n // Build candidate sets for each applicable field and intersect\n let candidates: Set<number> | null = null;\n\n for (const fieldPath of applicableFieldPaths) {\n const fieldIndex = fieldIndexes.get(fieldPath)!;\n const ctxValue = getContextValue(ctx, fieldPath);\n\n const fieldCandidates = new Set<number>();\n\n // Indexed matches for this field's value\n const indexed = fieldIndex.valueMap.get(ctxValue);\n if (indexed) {\n for (const idx of indexed) fieldCandidates.add(idx);\n }\n\n // Unconstrained steps (don't care about this field)\n for (const idx of fieldIndex.unconstrained) {\n fieldCandidates.add(idx);\n }\n\n if (candidates === null) {\n candidates = fieldCandidates;\n } else {\n // Intersect\n for (const idx of candidates) {\n if (!fieldCandidates.has(idx)) candidates.delete(idx);\n }\n }\n }\n\n // Evaluate full conditions on narrowed candidates (definition order)\n if (candidates && candidates.size > 0) {\n const sorted = [...candidates].sort((a, b) => a - b);\n for (const idx of sorted) {\n if (evaluateMatch(getMatch(flow.steps[idx]), ctx)) {\n matchedStep = flow.steps[idx];\n break;\n }\n }\n }\n } else if (indexableStepIndices.length > 0) {\n // Context has no fields that match any index -- evaluate all\n // indexable steps that are unconstrained on everything\n // (i.e., steps with is conditions on fields not present in context).\n // evaluateMatch handles this correctly.\n for (const idx of indexableStepIndices) {\n if (evaluateMatch(getMatch(flow.steps[idx]), ctx)) {\n matchedStep = flow.steps[idx];\n break;\n }\n }\n }\n\n // Phase 2: If no indexed match, evaluate broad steps\n if (!matchedStep && hasBroadSteps) {\n for (const idx of broadStepIndices) {\n if (evaluateMatch(getMatch(flow.steps[idx]), ctx)) {\n matchedStep = flow.steps[idx];\n break;\n }\n }\n }\n\n if (!matchedStep) {\n onMissingStep?.(ctx);\n return null;\n }\n\n // Evaluate the step based on its kind\n let result: StepDecision | null;\n\n if (matchedStep.kind === \"logic\") {\n result = matchedStep.statement.decision;\n } else {\n result = await matchedStep.handler(ctx);\n }\n\n if (!result) return null;\n\n if (devMode && result.nextTool === \"\") {\n warn(`Taias: nextTool for tool '${ctx.toolName}' is empty.`);\n }\n\n const decision: Decision = { ...result };\n\n const selections = selectUiAffordances<S>(decision, registryIndex, {\n devMode,\n onWarn: warn,\n });\n\n return {\n advice: generateAdvice(result.nextTool),\n decision,\n selections,\n };\n },\n };\n}\n","import type {\n AffordanceRegistry,\n BindingInput,\n DefaultSlots,\n HandleRegistration,\n} from \"./types\";\nimport { normalizeBinding } from \"./types\";\n\n/**\n * Mapped type that creates a registration method for each slot in S.\n * This enables fully typed custom slots via generics.\n */\nexport type AffordanceRegistrar<S extends string = DefaultSlots> = {\n [K in S]: (handleId: string, bindsTo: BindingInput) => void;\n};\n\n/**\n * Define UI affordances for a widget using a builder pattern.\n *\n * @example Default slots (backwards compatible)\n * ```ts\n * const affordances = defineAffordances((r) => {\n * r.primaryCta(\"cta.recommend\", { toolName: \"get_recommendations\" });\n * r.widgetVariant(\"variant.discovery\", { toolName: \"get_recommendations\" });\n * });\n * ```\n *\n * @example Custom slots (fully type-safe)\n * ```ts\n * type MySlots = \"primaryCta\" | \"contentArea\" | \"headerStyle\";\n * const affordances = defineAffordances<MySlots>((r) => {\n * r.primaryCta(\"cta.create\", { toolName: \"createUser\" });\n * r.contentArea(\"content.form\", { key: \"contentArea\", value: \"email-form\" });\n * r.headerStyle(\"header.progress\", { key: \"headerStyle\", value: \"step-1\" });\n * });\n * ```\n */\nexport function defineAffordances<S extends string = DefaultSlots>(\n builder: (r: AffordanceRegistrar<S>) => void\n): AffordanceRegistry<S> {\n const handles: HandleRegistration<S>[] = [];\n\n // Proxy creates methods on-the-fly for any slot name.\n // TypeScript ensures only valid slot names (from S) are called.\n const registrar = new Proxy({} as AffordanceRegistrar<S>, {\n get(_, slot: string) {\n return (handleId: string, bindsTo: BindingInput) => {\n handles.push({\n slot: slot as S,\n handleId,\n bindsTo: normalizeBinding(bindsTo),\n });\n };\n },\n });\n\n builder(registrar);\n return { handles };\n}\n","import type { AffordanceRegistry, DefaultSlots } from \"./types\";\nimport { makeBindingKey } from \"./types\";\n\nexport type MergeAffordancesOptions = {\n devMode?: boolean;\n onWarn?: (msg: string) => void;\n};\n\n/**\n * Merge multiple affordance registries into one.\n * Generic over slot type S for custom slot support.\n *\n * @example Default slots\n * ```ts\n * const merged = mergeAffordances([widgetA, widgetB]);\n * ```\n *\n * @example Custom slots\n * ```ts\n * type MySlots = \"primaryCta\" | \"contentArea\";\n * const merged = mergeAffordances<MySlots>([widgetA, widgetB]);\n * ```\n */\nexport function mergeAffordances<S extends string = DefaultSlots>(\n registries: AffordanceRegistry<S>[],\n opts: MergeAffordancesOptions = {}\n): AffordanceRegistry<S> {\n const devMode = !!opts.devMode;\n const warn = opts.onWarn ?? (() => {});\n\n const merged: AffordanceRegistry<S> = { handles: registries.flatMap((r) => r.handles) };\n\n if (!devMode) return merged;\n\n // Check for duplicate handleIds\n const seenHandleIds = new Set<string>();\n for (const h of merged.handles) {\n if (seenHandleIds.has(h.handleId)) {\n throw new Error(`[Taias] Duplicate handleId \"${h.handleId}\"`);\n }\n seenHandleIds.add(h.handleId);\n }\n\n // Check for ambiguous bindings (same slot + key + value)\n const seenTriples = new Set<string>();\n for (const h of merged.handles) {\n const k = makeBindingKey(h.slot, h.bindsTo);\n if (seenTriples.has(k)) {\n throw new Error(\n `[Taias] Ambiguous affordance: slot \"${h.slot}\" has multiple handles bound to (${h.bindsTo.key}=\"${h.bindsTo.value}\")`\n );\n }\n seenTriples.add(k);\n }\n\n warn(`[Taias] Loaded ${merged.handles.length} UI affordance handles`);\n return merged;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/flow.ts","../src/uiAffordances/types.ts","../src/uiAffordances/indexing.ts","../src/uiAffordances/select.ts","../src/debugSubscriber.ts","../src/createTaias.ts","../src/uiAffordances/defineAffordances.ts","../src/uiAffordances/mergeAffordances.ts"],"sourcesContent":["// Main exports\nexport { defineFlow } from \"./flow\";\nexport { createTaias } from \"./createTaias\";\n\n// Observability exports\nexport { createDebugSubscriber } from \"./debugSubscriber\";\n\n// UI affordances exports\nexport { defineAffordances } from \"./uiAffordances/defineAffordances\";\nexport { mergeAffordances } from \"./uiAffordances/mergeAffordances\";\nexport type { AffordanceRegistrar } from \"./uiAffordances/defineAffordances\";\nexport type {\n DefaultSlots,\n CanonicalSlot,\n Binding,\n BindingInput,\n HandleRegistration,\n Selection,\n UiSelections,\n AffordanceRegistry,\n} from \"./uiAffordances/types\";\n\n// Core + flow type exports\nexport type {\n Condition,\n Decision,\n TaiasContext,\n StepDecision,\n Affordances,\n StepHandler,\n StepInput,\n MatchCondition,\n LogicStatement,\n FlowStep,\n FlowDefinition,\n FlowBuilder,\n TaiasOptions,\n Taias,\n DebugOptions,\n ResolveEvent,\n ResolveTrace,\n StepEvaluation,\n TaiasEventMap,\n} from \"./types\";\n","import type { FlowBuilder, FlowDefinition, FlowStep, MatchCondition, StepInput } from \"./types\";\n\n/**\n * Define a flow with its steps.\n *\n * @param flowId - Unique identifier for the flow\n * @param builder - Callback that receives a FlowBuilder to define steps\n * @returns A FlowDefinition object\n *\n * @example Logic statement matching on toolName\n * ```ts\n * const onboardRepoFlow = defineFlow(\"onboard_repo\", (flow) => {\n * flow.step({ toolName: { is: \"scan_repo\" } }, { nextTool: \"configure_app\" });\n * });\n * ```\n *\n * @example Matching on params and result\n * ```ts\n * flow.step(\n * { toolName: { is: \"scan_repo\" }, params: { language: { is: \"python\" } } },\n * { nextTool: \"configure_python\" },\n * );\n * flow.step(\n * { result: { hasConfig: { is: true } } },\n * { nextTool: \"review_config\" },\n * );\n * ```\n *\n * @example isNot operator\n * ```ts\n * flow.step({ toolName: { isNot: \"abort_session\" } }, { nextTool: \"continue_flow\" });\n * ```\n */\nexport function defineFlow(\n flowId: string,\n builder: (flow: FlowBuilder) => void\n): FlowDefinition {\n const steps: FlowStep[] = [];\n\n const flowBuilder: FlowBuilder = {\n step(match: MatchCondition, input: StepInput): void {\n if (typeof input === \"function\") {\n steps.push({ kind: \"handler\", match, handler: input });\n } else {\n steps.push({\n kind: \"logic\",\n statement: {\n match,\n decision: input,\n },\n });\n }\n },\n };\n\n builder(flowBuilder);\n\n return {\n id: flowId,\n steps,\n };\n}\n","/**\n * Default slots for backwards compatibility.\n * Users can define custom slots by passing a type parameter.\n */\nexport type DefaultSlots = \"primaryCta\" | \"secondaryCta\" | \"widgetVariant\";\n\n/**\n * Alias for backwards compatibility in exports.\n * @deprecated Use DefaultSlots or define your own slot type\n */\nexport type CanonicalSlot = DefaultSlots;\n\nexport type Binding = {\n key: string;\n value: string;\n};\n\n/**\n * Input format for registering affordance bindings.\n * - { toolName } is shorthand for { key: \"nextTool\", value: toolName }\n * - { key, value } is the generalized form for custom bindings\n */\nexport type BindingInput = { toolName: string } | { key: string; value: string };\n\n/**\n * A registered UI affordance handle.\n * Generic over slot type S for custom slot support.\n */\nexport type HandleRegistration<S extends string = DefaultSlots> = {\n slot: S;\n handleId: string;\n bindsTo: Binding;\n};\n\nexport type Selection = {\n handleId: string;\n bindsTo: Binding;\n};\n\n/**\n * UI selections keyed by slot name.\n * Generic over slot type S for custom slot support.\n */\nexport type UiSelections<S extends string = DefaultSlots> = Partial<Record<S, Selection>>;\n\n/**\n * Collection of registered handles.\n * Generic over slot type S for custom slot support.\n */\nexport type AffordanceRegistry<S extends string = DefaultSlots> = {\n handles: HandleRegistration<S>[];\n};\n\nexport function normalizeBinding(input: BindingInput): Binding {\n if (\"toolName\" in input) return { key: \"nextTool\", value: input.toolName };\n return { key: input.key, value: input.value };\n}\n\n/**\n * Creates a binding key for indexing.\n * Accepts any string for slot to support custom slots.\n */\nexport function makeBindingKey(slot: string, binding: Binding): string {\n return `${slot}::${binding.key}::${binding.value}`;\n}\n","import type { AffordanceRegistry, DefaultSlots, HandleRegistration } from \"./types\";\nimport { makeBindingKey } from \"./types\";\n\n/**\n * Index structure for efficient affordance lookup.\n * Generic over slot type S for custom slot support.\n */\nexport type RegistryIndex<S extends string = DefaultSlots> = {\n byBindingKey: Map<string, HandleRegistration<S>>;\n slots: Set<S>;\n /** Inferred decision field for each slot, derived from handle bindings. */\n slotKeyMap: Map<S, string>;\n};\n\n/**\n * Build an index from a registry for efficient lookup during selection.\n * Tracks which slots have registered handles and infers the decision field\n * for each slot from its handle bindings.\n *\n * @throws Error if handles for the same slot bind to different keys\n */\nexport function buildRegistryIndex<S extends string = DefaultSlots>(\n registry?: AffordanceRegistry<S>\n): RegistryIndex<S> {\n const byBindingKey = new Map<string, HandleRegistration<S>>();\n const slots = new Set<S>();\n const slotKeyMap = new Map<S, string>();\n\n if (!registry) return { byBindingKey, slots, slotKeyMap };\n\n for (const h of registry.handles) {\n slots.add(h.slot);\n\n // Infer and validate slot key\n const existingKey = slotKeyMap.get(h.slot);\n if (existingKey && existingKey !== h.bindsTo.key) {\n throw new Error(\n `[Taias] Slot \"${h.slot}\" has handles bound to different keys: \"${existingKey}\" and \"${h.bindsTo.key}\". ` +\n `All handles for a slot must use the same decision field.`\n );\n }\n slotKeyMap.set(h.slot, h.bindsTo.key);\n\n byBindingKey.set(makeBindingKey(h.slot, h.bindsTo), h);\n }\n\n return { byBindingKey, slots, slotKeyMap };\n}\n","import type { Decision } from \"../types\";\nimport type { DefaultSlots, UiSelections } from \"./types\";\nimport type { RegistryIndex } from \"./indexing\";\nimport { makeBindingKey } from \"./types\";\n\nexport type SelectOptions = {\n devMode?: boolean;\n onWarn?: (msg: string) => void;\n};\n\n/**\n * Select UI affordances based on flow decision.\n * Uses the inferred decision field for each slot from the registry index.\n */\nexport function selectUiAffordances<S extends string = DefaultSlots>(\n decision: Decision,\n index: RegistryIndex<S>,\n opts: SelectOptions = {}\n): UiSelections<S> {\n const devMode = !!opts.devMode;\n const warn = opts.onWarn ?? (() => {});\n\n const selections: UiSelections<S> = {};\n\n for (const slot of index.slots) {\n // Use inferred key from handle bindings\n const field = index.slotKeyMap.get(slot);\n if (!field) continue;\n\n const value = decision[field];\n if (!value) continue;\n\n const k = makeBindingKey(slot, { key: field, value });\n const handle = index.byBindingKey.get(k);\n\n if (!handle) {\n if (devMode) warn(`[Taias] No affordance for slot \"${slot}\" when ${field}=\"${value}\"`);\n continue;\n }\n\n (selections as Record<string, unknown>)[slot] = {\n handleId: handle.handleId,\n bindsTo: handle.bindsTo,\n };\n }\n\n return selections;\n}\n","import type { ResolveEvent, TaiasContext, DebugOptions } from \"./types\";\n\nexport type DebugSubscriberOptions = DebugOptions;\n\nfunction formatContext(context: TaiasContext): string {\n const parts: string[] = [];\n if (context.toolName) parts.push(`toolName=${context.toolName}`);\n if (context.params) parts.push(`params=${JSON.stringify(context.params)}`);\n if (context.result) parts.push(`result=${JSON.stringify(context.result)}`);\n return parts.length > 0 ? parts.join(\", \") : \"(empty)\";\n}\n\nfunction formatContextLabel(context: TaiasContext): string {\n if (context.toolName) return context.toolName;\n if (context.params) return `params:${JSON.stringify(context.params)}`;\n if (context.result) return `result:${JSON.stringify(context.result)}`;\n return \"(empty)\";\n}\n\n/**\n * Create a debug subscriber for Taias resolve events.\n *\n * Returns a handler function suitable for `taias.on(\"resolve\", handler)`.\n *\n * - \"default\" format: multi-line breakdown of context, trace, decision, and affordances.\n * - \"compact\" format: single line per resolve call.\n */\nexport function createDebugSubscriber(\n options?: DebugSubscriberOptions\n): (event: ResolveEvent) => void {\n const format = options?.format ?? \"default\";\n const log = options?.logger ?? console.log;\n\n if (format === \"compact\") {\n return (event: ResolveEvent) => {\n const { trace, context } = event;\n const label = formatContextLabel(context);\n\n if (!trace.matched) {\n log(`[Taias] ${label} → no match (${trace.candidatesEvaluated} evaluated)`);\n return;\n }\n\n const decisionSummary = event.decision\n ? Object.entries(event.decision).map(([k, v]) => `${k}=${v}`).join(\", \")\n : \"null\";\n\n log(\n `[Taias] ${label} → ${decisionSummary} (${trace.phase}, step ${trace.matchedStepIndex}, ${trace.candidatesEvaluated} evaluated)`\n );\n };\n }\n\n return (event: ResolveEvent) => {\n const { trace, context } = event;\n const lines: string[] = [];\n\n lines.push(\"┌─ Taias Resolve ─────────────────────────────\");\n lines.push(`│ Flow: ${event.flowId}`);\n lines.push(`│ Context: ${formatContext(context)}`);\n\n lines.push(\"│\");\n\n if (!trace.matched) {\n lines.push(\"│ Result: NO MATCH\");\n lines.push(`│ Candidates evaluated: ${trace.candidatesEvaluated}`);\n } else {\n lines.push(`│ Matched: step ${trace.matchedStepIndex} (${trace.matchedStepKind})`);\n lines.push(`│ Phase: ${trace.phase}`);\n\n if (trace.resolutionPath.length > 0) {\n lines.push(`│ Resolution path: ${trace.resolutionPath.join(\" → \")}`);\n }\n\n lines.push(`│ Candidates evaluated: ${trace.candidatesEvaluated}`);\n\n if (trace.matchedStepMatch) {\n lines.push(`│ Match condition: ${JSON.stringify(trace.matchedStepMatch)}`);\n }\n }\n\n lines.push(\"│\");\n\n if (event.decision) {\n const fields = Object.entries(event.decision).map(([k, v]) => `${k}=${v}`).join(\", \");\n lines.push(`│ Decision: ${fields}`);\n } else {\n lines.push(\"│ Decision: null\");\n }\n\n if (event.affordances) {\n lines.push(`│ Advice: ${event.affordances.advice.slice(0, 80)}${event.affordances.advice.length > 80 ? \"...\" : \"\"}`);\n }\n\n lines.push(`│ Duration: ${event.durationMs.toFixed(2)}ms`);\n\n if (trace.evaluations) {\n lines.push(\"│\");\n lines.push(\"│ Detailed evaluations:\");\n for (const evaluation of trace.evaluations) {\n const icon = evaluation.result === \"matched\" ? \"✓\" : \"✗\";\n lines.push(`│ ${icon} step ${evaluation.stepIndex}: ${evaluation.result}`);\n\n if (evaluation.fieldResults) {\n for (const [field, fr] of Object.entries(evaluation.fieldResults)) {\n const fieldIcon = fr.passed ? \"✓\" : \"✗\";\n lines.push(`│ ${fieldIcon} ${field}: ${JSON.stringify(fr.condition)} vs ${JSON.stringify(fr.actual)}`);\n }\n }\n }\n }\n\n lines.push(\"└──────────────────────────────────────────────\");\n\n log(lines.join(\"\\n\"));\n };\n}\n","import type { Affordances, Condition, FlowStep, MatchCondition, StepDecision, Taias, TaiasContext, TaiasOptions, Decision, ResolveEvent, ResolveTrace, StepEvaluation } from \"./types\";\nimport type { DefaultSlots } from \"./uiAffordances/types\";\nimport { buildRegistryIndex } from \"./uiAffordances/indexing\";\nimport { selectUiAffordances } from \"./uiAffordances/select\";\nimport { createDebugSubscriber } from \"./debugSubscriber\";\n\n/**\n * Generate advice text for a given next tool.\n */\nfunction generateAdvice(nextTool: string): string {\n return `FOR THE BEST USER EXPERIENCE, TELL THE USER TO USE THE ${nextTool} TOOL NEXT!!!!!`;\n}\n\n// ---------------------------------------------------------------------------\n// Condition evaluation\n// ---------------------------------------------------------------------------\n\n/**\n * Evaluate a single Condition against a value using strict equality.\n */\nfunction evaluateCondition(condition: Condition, value: unknown): boolean {\n if (\"is\" in condition) return value === condition.is;\n if (\"isNot\" in condition) return value !== condition.isNot;\n return false;\n}\n\n/**\n * Evaluate a full MatchCondition against a TaiasContext.\n * All present conditions must be satisfied (logical AND).\n *\n * - toolName: compared directly against ctx.toolName\n * - params: subset match -- each specified key is checked against ctx.params\n * - result: subset match -- each specified key is checked against ctx.result\n *\n * If a step specifies params/result conditions but the context doesn't\n * include params/result, the step does not match.\n */\nfunction evaluateMatch(match: MatchCondition, ctx: TaiasContext): boolean {\n if (match.toolName && !evaluateCondition(match.toolName, ctx.toolName)) return false;\n\n if (match.params) {\n if (!ctx.params) return false;\n for (const [key, condition] of Object.entries(match.params)) {\n if (!evaluateCondition(condition, ctx.params[key])) return false;\n }\n }\n\n if (match.result) {\n if (!ctx.result) return false;\n for (const [key, condition] of Object.entries(match.result)) {\n if (!evaluateCondition(condition, ctx.result[key])) return false;\n }\n }\n\n return true;\n}\n\n/**\n * Evaluate a full MatchCondition and return per-field breakdown.\n * Used when detailed tracing is enabled.\n */\nfunction evaluateMatchDetailed(match: MatchCondition, ctx: TaiasContext): {\n passed: boolean;\n fieldResults: Record<string, { condition: Condition; actual: unknown; passed: boolean }>;\n} {\n const fieldResults: Record<string, { condition: Condition; actual: unknown; passed: boolean }> = {};\n let allPassed = true;\n\n if (match.toolName) {\n const actual = ctx.toolName;\n const passed = evaluateCondition(match.toolName, actual);\n fieldResults[\"toolName\"] = { condition: match.toolName, actual, passed };\n if (!passed) allPassed = false;\n }\n\n if (match.params) {\n if (!ctx.params) {\n for (const [key, condition] of Object.entries(match.params)) {\n fieldResults[`params.${key}`] = { condition, actual: undefined, passed: false };\n }\n allPassed = false;\n } else {\n for (const [key, condition] of Object.entries(match.params)) {\n const actual = ctx.params[key];\n const passed = evaluateCondition(condition, actual);\n fieldResults[`params.${key}`] = { condition, actual, passed };\n if (!passed) allPassed = false;\n }\n }\n }\n\n if (match.result) {\n if (!ctx.result) {\n for (const [key, condition] of Object.entries(match.result)) {\n fieldResults[`result.${key}`] = { condition, actual: undefined, passed: false };\n }\n allPassed = false;\n } else {\n for (const [key, condition] of Object.entries(match.result)) {\n const actual = ctx.result[key];\n const passed = evaluateCondition(condition, actual);\n fieldResults[`result.${key}`] = { condition, actual, passed };\n if (!passed) allPassed = false;\n }\n }\n }\n\n return { passed: allPassed, fieldResults };\n}\n\n// ---------------------------------------------------------------------------\n// Per-field indexing\n// ---------------------------------------------------------------------------\n\ninterface FieldIndex {\n valueMap: Map<unknown, number[]>;\n unconstrained: number[];\n}\n\n/**\n * Extract all `is` conditions from a match condition as field-path / value pairs.\n */\nfunction extractIsConditions(match: MatchCondition): Array<{ path: string; value: unknown }> {\n const conditions: Array<{ path: string; value: unknown }> = [];\n if (match.toolName && \"is\" in match.toolName) {\n conditions.push({ path: \"toolName\", value: match.toolName.is });\n }\n if (match.params) {\n for (const [key, cond] of Object.entries(match.params)) {\n if (\"is\" in cond) conditions.push({ path: `params.${key}`, value: cond.is });\n }\n }\n if (match.result) {\n for (const [key, cond] of Object.entries(match.result)) {\n if (\"is\" in cond) conditions.push({ path: `result.${key}`, value: cond.is });\n }\n }\n return conditions;\n}\n\n/**\n * Check whether a match condition has a condition on a given field path.\n */\nfunction hasConditionOnField(match: MatchCondition, path: string): boolean {\n if (path === \"toolName\") return !!match.toolName;\n if (path.startsWith(\"params.\")) return !!match.params?.[path.slice(7)];\n if (path.startsWith(\"result.\")) return !!match.result?.[path.slice(7)];\n return false;\n}\n\n/**\n * Get the value from a TaiasContext for a given field path.\n */\nfunction getContextValue(ctx: TaiasContext, path: string): unknown {\n if (path === \"toolName\") return ctx.toolName;\n if (path.startsWith(\"params.\")) return ctx.params?.[path.slice(7)];\n if (path.startsWith(\"result.\")) return ctx.result?.[path.slice(7)];\n return undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Step access helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Get the match condition from a FlowStep.\n *\n * - Logic-based steps: match comes from statement.match\n * - Handler-based steps (backwards compatibility): match is stored directly on the step\n */\nfunction getMatch(step: FlowStep): MatchCondition {\n return step.kind === \"logic\" ? step.statement.match : step.match;\n}\n\n/**\n * Serialize a MatchCondition into a stable string for duplicate detection.\n */\nfunction serializeMatch(match: MatchCondition): string {\n return JSON.stringify(match);\n}\n\n/**\n * createTaias constructs a decision engine.\n *\n * Taias resolves context into a generalized Decision object,\n * and then manifests that decision into concrete affordances:\n *\n * - LLM guidance (advice)\n * - UI affordance selections\n *\n * Flow logic is expressed as logic statements -- structured data that\n * Taias understands. (Handler functions remain as a backwards-compatible\n * escape hatch.)\n *\n * Flow logic determines *what should happen next*.\n * UI affordances determine *how that decision appears in the interface*.\n *\n * This file is the boundary where:\n *\n * Inputs -> Decision -> Manifestations\n *\n * are unified into a single resolve() call.\n *\n * @example\n * ```ts\n * const taias = createTaias({ flow, affordances });\n * ```\n */\nexport function createTaias<S extends string = DefaultSlots>(\n options: TaiasOptions<S>\n): Taias<S> {\n const {\n flow,\n affordances,\n devMode = false,\n debug = false,\n tracing = \"summary\",\n onMissingStep,\n onWarn,\n } = options;\n\n const warn = onWarn ?? ((msg: string) => console.warn(msg));\n const detailed = tracing === \"detailed\";\n\n // Dev mode: Check for duplicate match conditions.\n if (devMode) {\n const seenKeys = new Set<string>();\n for (const step of flow.steps) {\n const key = serializeMatch(getMatch(step));\n if (seenKeys.has(key)) {\n throw new Error(\n `Taias: Duplicate match condition in flow '${flow.id}'. Each step must have a unique match condition. Duplicate: ${key}`\n );\n }\n seenKeys.add(key);\n }\n }\n\n // -----------------------------------------------------------------------\n // Build per-field indexes\n // -----------------------------------------------------------------------\n\n const fieldIndexes = new Map<string, FieldIndex>();\n const indexableStepIndices: number[] = [];\n const broadStepIndices: number[] = [];\n\n for (let i = 0; i < flow.steps.length; i++) {\n const match = getMatch(flow.steps[i]);\n const isConditions = extractIsConditions(match);\n\n if (isConditions.length === 0) {\n broadStepIndices.push(i);\n continue;\n }\n\n indexableStepIndices.push(i);\n\n for (const { path, value } of isConditions) {\n let fieldIndex = fieldIndexes.get(path);\n if (!fieldIndex) {\n fieldIndex = { valueMap: new Map(), unconstrained: [] };\n fieldIndexes.set(path, fieldIndex);\n }\n let stepList = fieldIndex.valueMap.get(value);\n if (!stepList) {\n stepList = [];\n fieldIndex.valueMap.set(value, stepList);\n }\n stepList.push(i);\n }\n }\n\n // Build unconstrained sets: for each field index, find indexable steps\n // that don't have a condition on that field.\n for (const [fieldPath, fieldIndex] of fieldIndexes) {\n for (const i of indexableStepIndices) {\n if (!hasConditionOnField(getMatch(flow.steps[i]), fieldPath)) {\n fieldIndex.unconstrained.push(i);\n }\n }\n }\n\n const hasBroadSteps = broadStepIndices.length > 0;\n\n // Build affordance index once (if provided)\n const registryIndex = buildRegistryIndex<S>(affordances);\n\n // -----------------------------------------------------------------------\n // Event emitter\n // -----------------------------------------------------------------------\n\n const listeners = new Map<string, Set<Function>>();\n\n function emit<E extends string>(event: E, data: unknown): void {\n const handlers = listeners.get(event);\n if (handlers) {\n for (const handler of handlers) handler(data);\n }\n }\n\n function on(event: string, handler: Function): void {\n let set = listeners.get(event);\n if (!set) {\n set = new Set();\n listeners.set(event, set);\n }\n set.add(handler);\n }\n\n function off(event: string, handler: Function): void {\n listeners.get(event)?.delete(handler);\n }\n\n if (debug) {\n const debugOpts = typeof debug === \"object\" ? debug : undefined;\n on(\"resolve\", createDebugSubscriber(debugOpts));\n }\n\n return {\n async resolve(ctx: TaiasContext): Promise<Affordances<S> | null> {\n const startTime = performance.now();\n const timestamp = Date.now();\n\n let matchedStep: FlowStep | undefined;\n let matchedStepIndex: number | null = null;\n let matchPhase: \"indexed\" | \"broad\" | null = null;\n const resolutionPath: string[] = [];\n let candidatesEvaluated = 0;\n const evaluations: StepEvaluation[] | undefined = detailed ? [] : undefined;\n\n // Evaluate a candidate step and track it for tracing.\n // In detailed mode, uses evaluateMatchDetailed to capture per-field\n // outcomes; in summary mode, uses the cheaper evaluateMatch.\n function tryMatch(idx: number): boolean {\n candidatesEvaluated++;\n const step = flow.steps[idx];\n const match = getMatch(step);\n\n if (detailed) {\n const { passed, fieldResults } = evaluateMatchDetailed(match, ctx);\n evaluations!.push({\n stepIndex: idx,\n match,\n result: passed ? \"matched\" : \"no-match\",\n fieldResults,\n });\n return passed;\n }\n\n return evaluateMatch(match, ctx);\n }\n\n // Phase 1: Find candidates from per-field indexes via intersection\n const applicableFieldPaths: string[] = [];\n for (const fieldPath of fieldIndexes.keys()) {\n const ctxValue = getContextValue(ctx, fieldPath);\n if (ctxValue !== undefined) {\n applicableFieldPaths.push(fieldPath);\n }\n }\n\n resolutionPath.push(...applicableFieldPaths);\n\n if (applicableFieldPaths.length > 0) {\n // Build candidate sets for each applicable field and intersect\n let candidates: Set<number> | null = null;\n\n for (const fieldPath of applicableFieldPaths) {\n const fieldIndex = fieldIndexes.get(fieldPath)!;\n const ctxValue = getContextValue(ctx, fieldPath);\n\n const fieldCandidates = new Set<number>();\n\n // Indexed matches for this field's value\n const indexed = fieldIndex.valueMap.get(ctxValue);\n if (indexed) {\n for (const idx of indexed) fieldCandidates.add(idx);\n }\n\n // Unconstrained steps (don't care about this field)\n for (const idx of fieldIndex.unconstrained) {\n fieldCandidates.add(idx);\n }\n\n if (candidates === null) {\n candidates = fieldCandidates;\n } else {\n // Intersect\n for (const idx of candidates) {\n if (!fieldCandidates.has(idx)) candidates.delete(idx);\n }\n }\n }\n\n // Evaluate full conditions on narrowed candidates (definition order)\n if (candidates && candidates.size > 0) {\n const sorted = [...candidates].sort((a, b) => a - b);\n for (const idx of sorted) {\n if (tryMatch(idx)) {\n matchedStep = flow.steps[idx];\n matchedStepIndex = idx;\n matchPhase = \"indexed\";\n break;\n }\n }\n }\n } else if (indexableStepIndices.length > 0) {\n // Context has no fields that match any index -- evaluate all\n // indexable steps that are unconstrained on everything\n // (i.e., steps with is conditions on fields not present in context).\n // evaluateMatch handles this correctly.\n for (const idx of indexableStepIndices) {\n if (tryMatch(idx)) {\n matchedStep = flow.steps[idx];\n matchedStepIndex = idx;\n matchPhase = \"indexed\";\n break;\n }\n }\n }\n\n // Phase 2: If no indexed match, evaluate broad steps\n if (!matchedStep && hasBroadSteps) {\n for (const idx of broadStepIndices) {\n if (tryMatch(idx)) {\n matchedStep = flow.steps[idx];\n matchedStepIndex = idx;\n matchPhase = \"broad\";\n break;\n }\n }\n }\n\n // Construct the trace and emit event on every exit path (no-match,\n // handler-returns-null, and successful match). Subscribers always\n // get complete visibility into every resolve() call.\n const trace: ResolveTrace = {\n matched: !!matchedStep,\n matchedStepIndex,\n matchedStepKind: matchedStep?.kind ?? null,\n matchedStepMatch: matchedStep ? getMatch(matchedStep) : null,\n phase: matchPhase,\n resolutionPath,\n candidatesEvaluated,\n ...(evaluations !== undefined ? { evaluations } : {}),\n };\n\n if (!matchedStep) {\n onMissingStep?.(ctx);\n\n emit(\"resolve\", {\n flowId: flow.id,\n timestamp,\n durationMs: performance.now() - startTime,\n context: ctx,\n trace,\n decision: null,\n affordances: null,\n } satisfies ResolveEvent<S>);\n\n return null;\n }\n\n // Evaluate the step based on its kind\n let result: StepDecision | null;\n\n if (matchedStep.kind === \"logic\") {\n result = matchedStep.statement.decision;\n } else {\n result = await matchedStep.handler(ctx);\n }\n\n if (!result) {\n emit(\"resolve\", {\n flowId: flow.id,\n timestamp,\n durationMs: performance.now() - startTime,\n context: ctx,\n trace,\n decision: null,\n affordances: null,\n } satisfies ResolveEvent<S>);\n\n return null;\n }\n\n if (devMode && result.nextTool === \"\") {\n warn(`Taias: nextTool for tool '${ctx.toolName}' is empty.`);\n }\n\n const decision: Decision = { ...result };\n\n const selections = selectUiAffordances<S>(decision, registryIndex, {\n devMode,\n onWarn: warn,\n });\n\n const advice = generateAdvice(result.nextTool);\n\n emit(\"resolve\", {\n flowId: flow.id,\n timestamp,\n durationMs: performance.now() - startTime,\n context: ctx,\n trace,\n decision,\n affordances: { advice, selections },\n } satisfies ResolveEvent<S>);\n\n return { advice, decision, selections };\n },\n\n on: on as Taias<S>[\"on\"],\n off: off as Taias<S>[\"off\"],\n };\n}\n","import type {\n AffordanceRegistry,\n BindingInput,\n DefaultSlots,\n HandleRegistration,\n} from \"./types\";\nimport { normalizeBinding } from \"./types\";\n\n/**\n * Mapped type that creates a registration method for each slot in S.\n * This enables fully typed custom slots via generics.\n */\nexport type AffordanceRegistrar<S extends string = DefaultSlots> = {\n [K in S]: (handleId: string, bindsTo: BindingInput) => void;\n};\n\n/**\n * Define UI affordances for a widget using a builder pattern.\n *\n * @example Default slots (backwards compatible)\n * ```ts\n * const affordances = defineAffordances((r) => {\n * r.primaryCta(\"cta.recommend\", { toolName: \"get_recommendations\" });\n * r.widgetVariant(\"variant.discovery\", { toolName: \"get_recommendations\" });\n * });\n * ```\n *\n * @example Custom slots (fully type-safe)\n * ```ts\n * type MySlots = \"primaryCta\" | \"contentArea\" | \"headerStyle\";\n * const affordances = defineAffordances<MySlots>((r) => {\n * r.primaryCta(\"cta.create\", { toolName: \"createUser\" });\n * r.contentArea(\"content.form\", { key: \"contentArea\", value: \"email-form\" });\n * r.headerStyle(\"header.progress\", { key: \"headerStyle\", value: \"step-1\" });\n * });\n * ```\n */\nexport function defineAffordances<S extends string = DefaultSlots>(\n builder: (r: AffordanceRegistrar<S>) => void\n): AffordanceRegistry<S> {\n const handles: HandleRegistration<S>[] = [];\n\n // Proxy creates methods on-the-fly for any slot name.\n // TypeScript ensures only valid slot names (from S) are called.\n const registrar = new Proxy({} as AffordanceRegistrar<S>, {\n get(_, slot: string) {\n return (handleId: string, bindsTo: BindingInput) => {\n handles.push({\n slot: slot as S,\n handleId,\n bindsTo: normalizeBinding(bindsTo),\n });\n };\n },\n });\n\n builder(registrar);\n return { handles };\n}\n","import type { AffordanceRegistry, DefaultSlots } from \"./types\";\nimport { makeBindingKey } from \"./types\";\n\nexport type MergeAffordancesOptions = {\n devMode?: boolean;\n onWarn?: (msg: string) => void;\n};\n\n/**\n * Merge multiple affordance registries into one.\n * Generic over slot type S for custom slot support.\n *\n * @example Default slots\n * ```ts\n * const merged = mergeAffordances([widgetA, widgetB]);\n * ```\n *\n * @example Custom slots\n * ```ts\n * type MySlots = \"primaryCta\" | \"contentArea\";\n * const merged = mergeAffordances<MySlots>([widgetA, widgetB]);\n * ```\n */\nexport function mergeAffordances<S extends string = DefaultSlots>(\n registries: AffordanceRegistry<S>[],\n opts: MergeAffordancesOptions = {}\n): AffordanceRegistry<S> {\n const devMode = !!opts.devMode;\n const warn = opts.onWarn ?? (() => {});\n\n const merged: AffordanceRegistry<S> = { handles: registries.flatMap((r) => r.handles) };\n\n if (!devMode) return merged;\n\n // Check for duplicate handleIds\n const seenHandleIds = new Set<string>();\n for (const h of merged.handles) {\n if (seenHandleIds.has(h.handleId)) {\n throw new Error(`[Taias] Duplicate handleId \"${h.handleId}\"`);\n }\n seenHandleIds.add(h.handleId);\n }\n\n // Check for ambiguous bindings (same slot + key + value)\n const seenTriples = new Set<string>();\n for (const h of merged.handles) {\n const k = makeBindingKey(h.slot, h.bindsTo);\n if (seenTriples.has(k)) {\n throw new Error(\n `[Taias] Ambiguous affordance: slot \"${h.slot}\" has multiple handles bound to (${h.bindsTo.key}=\"${h.bindsTo.value}\")`\n );\n }\n seenTriples.add(k);\n }\n\n warn(`[Taias] Loaded ${merged.handles.length} UI affordance handles`);\n return merged;\n}\n"],"mappings":"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","names":[]}
|