poly-weaver 0.15.0 → 0.15.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/executors/types.d.ts +3 -1
- package/dist/agents/executors/types.d.ts.map +1 -1
- package/dist/agents/implementors/adapter.d.ts +2 -1
- package/dist/agents/implementors/adapter.d.ts.map +1 -1
- package/dist/agents/implementors/adapter.js +2 -2
- package/dist/agents/implementors/adapter.js.map +1 -1
- package/dist/agents/implementors/index.d.ts.map +1 -1
- package/dist/agents/implementors/index.js +1 -1
- package/dist/agents/implementors/index.js.map +1 -1
- package/dist/agents/implementors/prompts.d.ts.map +1 -1
- package/dist/agents/implementors/prompts.js +7 -3
- package/dist/agents/implementors/prompts.js.map +1 -1
- package/dist/agents/interviewers/adapter.d.ts +2 -1
- package/dist/agents/interviewers/adapter.d.ts.map +1 -1
- package/dist/agents/interviewers/adapter.js +2 -2
- package/dist/agents/interviewers/adapter.js.map +1 -1
- package/dist/agents/interviewers/index.d.ts.map +1 -1
- package/dist/agents/interviewers/index.js +1 -1
- package/dist/agents/interviewers/index.js.map +1 -1
- package/dist/agents/planners/adapter.d.ts +2 -1
- package/dist/agents/planners/adapter.d.ts.map +1 -1
- package/dist/agents/planners/adapter.js +2 -2
- package/dist/agents/planners/adapter.js.map +1 -1
- package/dist/agents/planners/index.d.ts.map +1 -1
- package/dist/agents/planners/index.js +1 -1
- package/dist/agents/planners/index.js.map +1 -1
- package/dist/agents/planners/prompts.d.ts.map +1 -1
- package/dist/agents/planners/prompts.js +3 -0
- package/dist/agents/planners/prompts.js.map +1 -1
- package/dist/agents/registry.d.ts +3 -0
- package/dist/agents/registry.d.ts.map +1 -1
- package/dist/agents/registry.js.map +1 -1
- package/dist/agents/reviewers/adapter.d.ts +2 -1
- package/dist/agents/reviewers/adapter.d.ts.map +1 -1
- package/dist/agents/reviewers/adapter.js +2 -2
- package/dist/agents/reviewers/adapter.js.map +1 -1
- package/dist/agents/reviewers/index.d.ts.map +1 -1
- package/dist/agents/reviewers/index.js +1 -1
- package/dist/agents/reviewers/index.js.map +1 -1
- package/dist/agents/runner.d.ts +8 -1
- package/dist/agents/runner.d.ts.map +1 -1
- package/dist/agents/runner.js +10 -2
- package/dist/agents/runner.js.map +1 -1
- package/dist/agents/simplifiers/adapter.d.ts +2 -1
- package/dist/agents/simplifiers/adapter.d.ts.map +1 -1
- package/dist/agents/simplifiers/adapter.js +2 -2
- package/dist/agents/simplifiers/adapter.js.map +1 -1
- package/dist/agents/simplifiers/index.d.ts.map +1 -1
- package/dist/agents/simplifiers/index.js +1 -1
- package/dist/agents/simplifiers/index.js.map +1 -1
- package/dist/config.d.ts +3 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/crosscheck/coordinator.d.ts.map +1 -1
- package/dist/crosscheck/coordinator.js +19 -7
- package/dist/crosscheck/coordinator.js.map +1 -1
- package/dist/flow/built-in/crosscheck-factory.d.ts.map +1 -1
- package/dist/flow/built-in/crosscheck-factory.js +8 -0
- package/dist/flow/built-in/crosscheck-factory.js.map +1 -1
- package/dist/flow/built-in/default-factory.d.ts.map +1 -1
- package/dist/flow/built-in/default-factory.js +8 -0
- package/dist/flow/built-in/default-factory.js.map +1 -1
- package/dist/flow/built-in/simplify-factory.d.ts.map +1 -1
- package/dist/flow/built-in/simplify-factory.js +6 -0
- package/dist/flow/built-in/simplify-factory.js.map +1 -1
- package/dist/flow/index.d.ts +2 -2
- package/dist/flow/index.d.ts.map +1 -1
- package/dist/flow/index.js +1 -1
- package/dist/flow/index.js.map +1 -1
- package/dist/flow/params.d.ts +14 -6
- package/dist/flow/params.d.ts.map +1 -1
- package/dist/flow/params.js +111 -8
- package/dist/flow/params.js.map +1 -1
- package/dist/flow/types.d.ts +13 -1
- package/dist/flow/types.d.ts.map +1 -1
- package/dist/flow/types.js.map +1 -1
- package/dist/flow-editor/tui.d.ts.map +1 -1
- package/dist/flow-editor/tui.js +4 -1
- package/dist/flow-editor/tui.js.map +1 -1
- package/dist/managed-spec.d.ts.map +1 -1
- package/dist/managed-spec.js +149 -29
- package/dist/managed-spec.js.map +1 -1
- package/dist/offscreen/resolve.d.ts.map +1 -1
- package/dist/offscreen/resolve.js +2 -0
- package/dist/offscreen/resolve.js.map +1 -1
- package/dist/orchestrator.d.ts.map +1 -1
- package/dist/orchestrator.js +15 -5
- package/dist/orchestrator.js.map +1 -1
- package/dist/preview-panel.d.ts +9 -2
- package/dist/preview-panel.d.ts.map +1 -1
- package/dist/preview-panel.js +329 -54
- package/dist/preview-panel.js.map +1 -1
- package/dist/providers/base-completion.d.ts.map +1 -1
- package/dist/providers/base-completion.js +41 -0
- package/dist/providers/base-completion.js.map +1 -1
- package/dist/providers/claude/strategy.d.ts.map +1 -1
- package/dist/providers/claude/strategy.js +24 -9
- package/dist/providers/claude/strategy.js.map +1 -1
- package/dist/providers/codex/strategy.d.ts +2 -0
- package/dist/providers/codex/strategy.d.ts.map +1 -1
- package/dist/providers/codex/strategy.js +48 -15
- package/dist/providers/codex/strategy.js.map +1 -1
- package/dist/providers/configuration-presentation.d.ts +16 -0
- package/dist/providers/configuration-presentation.d.ts.map +1 -0
- package/dist/providers/configuration-presentation.js +31 -0
- package/dist/providers/configuration-presentation.js.map +1 -0
- package/dist/providers/copilot/strategy.d.ts +2 -0
- package/dist/providers/copilot/strategy.d.ts.map +1 -1
- package/dist/providers/copilot/strategy.js +51 -21
- package/dist/providers/copilot/strategy.js.map +1 -1
- package/dist/providers/fork.d.ts +5 -1
- package/dist/providers/fork.d.ts.map +1 -1
- package/dist/providers/fork.js.map +1 -1
- package/dist/providers/index.d.ts +2 -1
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +1 -0
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/live.d.ts.map +1 -1
- package/dist/providers/live.js +2 -0
- package/dist/providers/live.js.map +1 -1
- package/dist/providers/option-catalog.d.ts +7 -0
- package/dist/providers/option-catalog.d.ts.map +1 -1
- package/dist/providers/option-catalog.js +20 -0
- package/dist/providers/option-catalog.js.map +1 -1
- package/dist/providers/types.d.ts +17 -0
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/providers/types.js +3 -0
- package/dist/providers/types.js.map +1 -1
- package/dist/startup-tui.d.ts.map +1 -1
- package/dist/startup-tui.js +33 -29
- package/dist/startup-tui.js.map +1 -1
- package/dist/text-editing/emacs-input.d.ts +1 -0
- package/dist/text-editing/emacs-input.d.ts.map +1 -1
- package/dist/text-editing/emacs-input.js +8 -4
- package/dist/text-editing/emacs-input.js.map +1 -1
- package/package.json +1 -1
package/dist/preview-panel.js
CHANGED
|
@@ -3,7 +3,8 @@ import { breakKillRun } from "./text-editing/kill-ring.js";
|
|
|
3
3
|
import { availableDriversForRole } from "./agents/registry.js";
|
|
4
4
|
import { diagramHeight, renderFlowDiagram, computeMinWidth, detailedDiagramHeight, renderDetailedFlowDiagram, computeDetailedMinWidth } from "./flow/diagram.js";
|
|
5
5
|
import { configurationGroupOf, getConfigurationGroupModelEffortKeys, getProviderForConfigurationGroup, } from "./flow/params.js";
|
|
6
|
-
import { defaultEffort, defaultModel, defaultSubagentModel, isKnownEffort, isKnownModel, isKnownSubagentModel, providerEfforts, providerModels, subagentModels, } from "./providers/option-catalog.js";
|
|
6
|
+
import { defaultEffort, defaultFast, defaultModel, defaultSubagentModel, isFastAvailable, defaultContext, isKnownContext, isKnownEffort, isKnownModel, isKnownSubagentModel, providerContexts, providerEfforts, providerModels, subagentModels, } from "./providers/option-catalog.js";
|
|
7
|
+
import { compactProviderConfigurationTokens, } from "./providers/configuration-presentation.js";
|
|
7
8
|
import { visibleLength, padToWidth, dim, bold, reset, green, red } from "./ansi.js";
|
|
8
9
|
import { renderWrappedLine } from "./text-editing/soft-wrap.js";
|
|
9
10
|
// ─── Constants ───────────────────────────────────────────────────────────
|
|
@@ -23,7 +24,7 @@ export function buildFieldsForTemplate(template, defaults, existingFields) {
|
|
|
23
24
|
const fields = [];
|
|
24
25
|
const groupBuckets = new Map();
|
|
25
26
|
for (const param of template.params) {
|
|
26
|
-
if (param
|
|
27
|
+
if (!isProviderConfigurationParam(param)) {
|
|
27
28
|
continue;
|
|
28
29
|
}
|
|
29
30
|
const group = configurationGroupOf(param);
|
|
@@ -34,6 +35,10 @@ export function buildFieldsForTemplate(template, defaults, existingFields) {
|
|
|
34
35
|
bucket.model = param;
|
|
35
36
|
if (param.type === "effort")
|
|
36
37
|
bucket.effort = param;
|
|
38
|
+
if (param.type === "fast")
|
|
39
|
+
bucket.fast = param;
|
|
40
|
+
if (param.type === "context")
|
|
41
|
+
bucket.context = param;
|
|
37
42
|
groupBuckets.set(group, bucket);
|
|
38
43
|
}
|
|
39
44
|
const groupedConfigurations = new Set([...groupBuckets.entries()]
|
|
@@ -41,16 +46,18 @@ export function buildFieldsForTemplate(template, defaults, existingFields) {
|
|
|
41
46
|
.map(([group]) => group));
|
|
42
47
|
const emittedGroups = new Set();
|
|
43
48
|
for (const param of template.params) {
|
|
44
|
-
if (param
|
|
49
|
+
if (isProviderConfigurationParam(param)) {
|
|
45
50
|
const configurationGroup = configurationGroupOf(param);
|
|
46
51
|
const bucket = groupBuckets.get(configurationGroup);
|
|
47
52
|
const isGroupedParam = groupedConfigurations.has(configurationGroup) && bucket && (param.key === bucket.driver?.key ||
|
|
48
53
|
param.key === bucket.model?.key ||
|
|
49
|
-
param.key === bucket.effort?.key
|
|
54
|
+
param.key === bucket.effort?.key ||
|
|
55
|
+
param.key === bucket.fast?.key ||
|
|
56
|
+
param.key === bucket.context?.key);
|
|
50
57
|
if (isGroupedParam) {
|
|
51
58
|
if (emittedGroups.has(configurationGroup))
|
|
52
59
|
continue;
|
|
53
|
-
fields.push(buildRoleGroupField(param.role, configurationGroup, bucket.driver, bucket.model, bucket.effort, template, defaults, existingFields));
|
|
60
|
+
fields.push(buildRoleGroupField(param.role, configurationGroup, bucket.driver, bucket.model, bucket.effort, bucket.fast, bucket.context, template, defaults, existingFields));
|
|
54
61
|
emittedGroups.add(configurationGroup);
|
|
55
62
|
continue;
|
|
56
63
|
}
|
|
@@ -113,6 +120,38 @@ export function buildFieldsForTemplate(template, defaults, existingFields) {
|
|
|
113
120
|
});
|
|
114
121
|
break;
|
|
115
122
|
}
|
|
123
|
+
case "fast": {
|
|
124
|
+
const fp = param;
|
|
125
|
+
const provider = getAvailableProviderForGroup(configurationGroupOf(fp), fp.role, template, defaults, existingFields);
|
|
126
|
+
fields.push({
|
|
127
|
+
kind: "toggle",
|
|
128
|
+
label: fp.label,
|
|
129
|
+
key: fp.key,
|
|
130
|
+
value: defaultVal ?? defaultFast(provider),
|
|
131
|
+
hidden: true,
|
|
132
|
+
});
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
case "context": {
|
|
136
|
+
const cp = param;
|
|
137
|
+
const provider = getAvailableProviderForGroup(configurationGroupOf(cp), cp.role, template, defaults, existingFields);
|
|
138
|
+
const options = providerContexts(provider);
|
|
139
|
+
const requested = defaultVal;
|
|
140
|
+
const value = requested && isKnownContext(provider, requested)
|
|
141
|
+
? requested
|
|
142
|
+
: defaultContext(provider) ?? "default";
|
|
143
|
+
fields.push({
|
|
144
|
+
kind: "select",
|
|
145
|
+
label: cp.label,
|
|
146
|
+
key: cp.key,
|
|
147
|
+
options: [...options],
|
|
148
|
+
value,
|
|
149
|
+
expanded: false,
|
|
150
|
+
expandedIndex: 0,
|
|
151
|
+
hidden: options.length === 0,
|
|
152
|
+
});
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
116
155
|
case "number": {
|
|
117
156
|
const np = param;
|
|
118
157
|
fields.push({
|
|
@@ -188,7 +227,7 @@ function getAvailableModelForGroup(configurationGroup, template, defaults, exist
|
|
|
188
227
|
return value;
|
|
189
228
|
return defaultModel(provider);
|
|
190
229
|
}
|
|
191
|
-
function buildRoleGroupField(role, configurationGroup, driverParam, modelParam, effortParam, template, defaults, existingFields) {
|
|
230
|
+
function buildRoleGroupField(role, configurationGroup, driverParam, modelParam, effortParam, fastParam, contextParam, template, defaults, existingFields) {
|
|
192
231
|
const existingProvider = existingFields ? findFieldByKey(existingFields, driverParam.key) : undefined;
|
|
193
232
|
const previous = existingFields?.find((f) => f.kind === "group" && f.providerKey === driverParam.key);
|
|
194
233
|
const availableProviders = availableDriverOptions(role);
|
|
@@ -198,8 +237,22 @@ function buildRoleGroupField(role, configurationGroup, driverParam, modelParam,
|
|
|
198
237
|
driverParam.default));
|
|
199
238
|
const existingModel = existingFields ? findFieldByKey(existingFields, modelParam.key) : undefined;
|
|
200
239
|
const existingEffort = existingFields ? findFieldByKey(existingFields, effortParam.key) : undefined;
|
|
240
|
+
const existingFast = fastParam && existingFields ? findFieldByKey(existingFields, fastParam.key) : undefined;
|
|
241
|
+
const existingContext = contextParam && existingFields ? findFieldByKey(existingFields, contextParam.key) : undefined;
|
|
201
242
|
const model = (existingModel?.value ?? defaults[modelParam.key] ?? defaultModel(provider));
|
|
202
243
|
const effort = (existingEffort?.value ?? defaults[effortParam.key] ?? defaultEffort(provider));
|
|
244
|
+
const rawFast = fastParam
|
|
245
|
+
? existingFast?.value
|
|
246
|
+
?? defaults[fastParam.key]
|
|
247
|
+
?? defaultFast(provider)
|
|
248
|
+
: undefined;
|
|
249
|
+
const context = contextParam
|
|
250
|
+
? existingContext?.value
|
|
251
|
+
?? defaults[contextParam.key]
|
|
252
|
+
?? defaultContext(provider)
|
|
253
|
+
?? "default"
|
|
254
|
+
: undefined;
|
|
255
|
+
const focusKey = previous?.children[previous.focusedChild]?.key;
|
|
203
256
|
const group = {
|
|
204
257
|
kind: "group",
|
|
205
258
|
key: driverParam.key,
|
|
@@ -210,6 +263,8 @@ function buildRoleGroupField(role, configurationGroup, driverParam, modelParam,
|
|
|
210
263
|
providerKey: driverParam.key,
|
|
211
264
|
modelKey: modelParam.key,
|
|
212
265
|
effortKey: effortParam.key,
|
|
266
|
+
fastKey: fastParam?.key,
|
|
267
|
+
contextKey: contextParam?.key,
|
|
213
268
|
children: [
|
|
214
269
|
{
|
|
215
270
|
kind: "select",
|
|
@@ -238,11 +293,27 @@ function buildRoleGroupField(role, configurationGroup, driverParam, modelParam,
|
|
|
238
293
|
expanded: false,
|
|
239
294
|
expandedIndex: 0,
|
|
240
295
|
},
|
|
296
|
+
...(contextParam ? [{
|
|
297
|
+
kind: "select",
|
|
298
|
+
label: "Context",
|
|
299
|
+
key: contextParam.key,
|
|
300
|
+
options: [],
|
|
301
|
+
value: context,
|
|
302
|
+
expanded: false,
|
|
303
|
+
expandedIndex: 0,
|
|
304
|
+
}] : []),
|
|
305
|
+
...(fastParam ? [{
|
|
306
|
+
kind: "toggle",
|
|
307
|
+
label: "Fast",
|
|
308
|
+
key: fastParam.key,
|
|
309
|
+
value: rawFast,
|
|
310
|
+
}] : []),
|
|
241
311
|
],
|
|
242
312
|
groupExpanded: previous?.groupExpanded ?? false,
|
|
243
313
|
focusedChild: previous?.focusedChild ?? 0,
|
|
244
314
|
};
|
|
245
|
-
|
|
315
|
+
reconcileProviderSettingsForGroup(group);
|
|
316
|
+
restoreGroupFocus(group, focusKey);
|
|
246
317
|
return group;
|
|
247
318
|
}
|
|
248
319
|
// ─── Field Utilities ─────────────────────────────────────────────────────
|
|
@@ -279,6 +350,93 @@ function selectedOptionLabel(field) {
|
|
|
279
350
|
function formatEffortValue(value, label = value) {
|
|
280
351
|
return value === "ultra" ? `${red}${label}${reset}` : label;
|
|
281
352
|
}
|
|
353
|
+
function renderCompactProviderConfigurationToken(token) {
|
|
354
|
+
const text = token.kind === "effort"
|
|
355
|
+
? formatEffortValue(token.text)
|
|
356
|
+
: token.text;
|
|
357
|
+
return token.dimmed ? `${dim}${text}${reset}` : text;
|
|
358
|
+
}
|
|
359
|
+
function selectChild(group, key) {
|
|
360
|
+
const field = group.children.find((child) => child.kind === "select" && child.key === key);
|
|
361
|
+
if (!field)
|
|
362
|
+
throw new Error(`Missing select child "${key}" in ${group.key}`);
|
|
363
|
+
return field;
|
|
364
|
+
}
|
|
365
|
+
function optionalSelectChild(group, key) {
|
|
366
|
+
if (!key)
|
|
367
|
+
return undefined;
|
|
368
|
+
return group.children.find((child) => child.kind === "select" && child.key === key);
|
|
369
|
+
}
|
|
370
|
+
function toggleChild(group, key) {
|
|
371
|
+
const field = group.children.find((child) => child.kind === "toggle" && child.key === key);
|
|
372
|
+
if (!field)
|
|
373
|
+
throw new Error(`Missing toggle child "${key}" in ${group.key}`);
|
|
374
|
+
return field;
|
|
375
|
+
}
|
|
376
|
+
function optionalToggleChild(group, key) {
|
|
377
|
+
if (!key)
|
|
378
|
+
return undefined;
|
|
379
|
+
return group.children.find((child) => child.kind === "toggle" && child.key === key);
|
|
380
|
+
}
|
|
381
|
+
function providerChild(group) {
|
|
382
|
+
return selectChild(group, group.providerKey);
|
|
383
|
+
}
|
|
384
|
+
function modelChild(group) {
|
|
385
|
+
return selectChild(group, group.modelKey);
|
|
386
|
+
}
|
|
387
|
+
function effortChild(group) {
|
|
388
|
+
return selectChild(group, group.effortKey);
|
|
389
|
+
}
|
|
390
|
+
function fastChild(group) {
|
|
391
|
+
return optionalToggleChild(group, group.fastKey);
|
|
392
|
+
}
|
|
393
|
+
function contextChild(group) {
|
|
394
|
+
return optionalSelectChild(group, group.contextKey);
|
|
395
|
+
}
|
|
396
|
+
function visibleGroupChildIndexes(group) {
|
|
397
|
+
return group.children
|
|
398
|
+
.map((child, index) => child.hidden ? -1 : index)
|
|
399
|
+
.filter((index) => index >= 0);
|
|
400
|
+
}
|
|
401
|
+
function firstVisibleGroupChildIndex(group) {
|
|
402
|
+
return visibleGroupChildIndexes(group)[0] ?? 0;
|
|
403
|
+
}
|
|
404
|
+
function nextVisibleGroupChildIndex(group, direction) {
|
|
405
|
+
const visible = visibleGroupChildIndexes(group);
|
|
406
|
+
if (visible.length === 0)
|
|
407
|
+
return 0;
|
|
408
|
+
const currentIndex = visible.indexOf(group.focusedChild);
|
|
409
|
+
const current = currentIndex >= 0 ? currentIndex : 0;
|
|
410
|
+
return visible[(current + direction + visible.length) % visible.length];
|
|
411
|
+
}
|
|
412
|
+
function ensureGroupFocusVisible(group) {
|
|
413
|
+
if (!group.children[group.focusedChild]?.hidden)
|
|
414
|
+
return;
|
|
415
|
+
group.focusedChild = firstVisibleGroupChildIndex(group);
|
|
416
|
+
}
|
|
417
|
+
function restoreGroupFocus(group, focusKey) {
|
|
418
|
+
if (focusKey) {
|
|
419
|
+
const next = group.children.findIndex((child) => child.key === focusKey);
|
|
420
|
+
if (next >= 0)
|
|
421
|
+
group.focusedChild = next;
|
|
422
|
+
}
|
|
423
|
+
ensureGroupFocusVisible(group);
|
|
424
|
+
}
|
|
425
|
+
export function snapshotGroupToDriverMemory(memory, group, providerOverride) {
|
|
426
|
+
const provider = providerOverride ?? providerChild(group).value;
|
|
427
|
+
const fast = fastChild(group);
|
|
428
|
+
const entry = {
|
|
429
|
+
model: modelChild(group).value,
|
|
430
|
+
effort: effortChild(group).value,
|
|
431
|
+
...(fast ? { fast: fast.value } : {}),
|
|
432
|
+
};
|
|
433
|
+
const context = contextChild(group);
|
|
434
|
+
if (context && isKnownContext(provider, context.value)) {
|
|
435
|
+
Object.assign(entry, { context: context.value });
|
|
436
|
+
}
|
|
437
|
+
memory[group.configurationGroup] ??= {};
|
|
438
|
+
memory[group.configurationGroup][provider] = entry;
|
|
439
|
+
}
|
|
282
440
|
function findFieldOwnerByKey(fields, key) {
|
|
283
441
|
for (const owner of fields) {
|
|
284
442
|
if (owner.kind === "group") {
|
|
@@ -311,41 +469,80 @@ function defaultParamValue(param) {
|
|
|
311
469
|
return param.default;
|
|
312
470
|
case "model":
|
|
313
471
|
case "effort":
|
|
472
|
+
case "fast":
|
|
473
|
+
case "context":
|
|
314
474
|
return undefined;
|
|
315
475
|
}
|
|
316
476
|
}
|
|
317
|
-
export function
|
|
318
|
-
const provider = group.
|
|
477
|
+
export function reconcileProviderSettingsForGroup(group, driverMemory, opts = {}) {
|
|
478
|
+
const provider = providerChild(group).value;
|
|
319
479
|
group.value = provider;
|
|
320
|
-
const model = group
|
|
321
|
-
const effort = group
|
|
480
|
+
const model = modelChild(group);
|
|
481
|
+
const effort = effortChild(group);
|
|
482
|
+
const fast = fastChild(group);
|
|
483
|
+
const context = contextChild(group);
|
|
322
484
|
model.options = [...providerModels(provider)];
|
|
323
485
|
const memory = driverMemory?.[group.configurationGroup]?.[provider];
|
|
324
486
|
if (memory?.model && isKnownModel(provider, memory.model)) {
|
|
325
487
|
model.value = memory.model;
|
|
326
488
|
}
|
|
327
|
-
else if (!isKnownModel(provider, model.value)) {
|
|
489
|
+
else if (opts.providerChanged || !isKnownModel(provider, model.value)) {
|
|
328
490
|
model.value = defaultModel(provider);
|
|
329
491
|
}
|
|
330
492
|
effort.options = [...providerEfforts(provider, model.value)];
|
|
331
493
|
if (memory?.effort && isKnownEffort(provider, memory.effort, model.value)) {
|
|
332
494
|
effort.value = memory.effort;
|
|
333
495
|
}
|
|
334
|
-
else if (!isKnownEffort(provider, effort.value, model.value)) {
|
|
496
|
+
else if (opts.providerChanged || !isKnownEffort(provider, effort.value, model.value)) {
|
|
335
497
|
effort.value = defaultEffort(provider);
|
|
336
498
|
}
|
|
499
|
+
if (fast) {
|
|
500
|
+
if (typeof memory?.fast === "boolean") {
|
|
501
|
+
fast.value = memory.fast;
|
|
502
|
+
}
|
|
503
|
+
else if (opts.providerChanged) {
|
|
504
|
+
fast.value = defaultFast(provider);
|
|
505
|
+
}
|
|
506
|
+
fast.hidden = !isFastAvailable(provider, model.value);
|
|
507
|
+
}
|
|
508
|
+
if (context) {
|
|
509
|
+
const options = providerContexts(provider);
|
|
510
|
+
context.options = [...options];
|
|
511
|
+
if (options.length === 0) {
|
|
512
|
+
context.hidden = true;
|
|
513
|
+
}
|
|
514
|
+
else {
|
|
515
|
+
context.hidden = false;
|
|
516
|
+
if (memory?.context && isKnownContext(provider, memory.context)) {
|
|
517
|
+
context.value = memory.context;
|
|
518
|
+
}
|
|
519
|
+
else if (opts.providerChanged ||
|
|
520
|
+
!isKnownContext(provider, context.value)) {
|
|
521
|
+
context.value = defaultContext(provider) ?? "default";
|
|
522
|
+
}
|
|
523
|
+
context.expandedIndex = Math.max(0, selectOptionIndex(context, context.value));
|
|
524
|
+
}
|
|
525
|
+
}
|
|
337
526
|
model.expandedIndex = Math.max(0, selectOptionIndex(model, model.value));
|
|
338
527
|
effort.expandedIndex = Math.max(0, selectOptionIndex(effort, effort.value));
|
|
528
|
+
ensureGroupFocusVisible(group);
|
|
339
529
|
}
|
|
340
|
-
function
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
530
|
+
export function reconcileModelEffortForGroup(group, driverMemory) {
|
|
531
|
+
reconcileProviderSettingsForGroup(group, driverMemory);
|
|
532
|
+
}
|
|
533
|
+
function reconcileSettingsForCurrentModel(group) {
|
|
534
|
+
const provider = providerChild(group).value;
|
|
535
|
+
const model = modelChild(group);
|
|
536
|
+
const effort = effortChild(group);
|
|
344
537
|
effort.options = [...providerEfforts(provider, model.value)];
|
|
345
538
|
if (!isKnownEffort(provider, effort.value, model.value)) {
|
|
346
539
|
effort.value = defaultEffort(provider);
|
|
347
540
|
}
|
|
348
541
|
effort.expandedIndex = Math.max(0, selectOptionIndex(effort, effort.value));
|
|
542
|
+
const fast = fastChild(group);
|
|
543
|
+
if (fast)
|
|
544
|
+
fast.hidden = !isFastAvailable(provider, model.value);
|
|
545
|
+
ensureGroupFocusVisible(group);
|
|
349
546
|
}
|
|
350
547
|
/**
|
|
351
548
|
* Mutate `field.hidden` in place based on each template param's
|
|
@@ -390,8 +587,8 @@ export function configRowCount(fields) {
|
|
|
390
587
|
rows += f.options.length;
|
|
391
588
|
}
|
|
392
589
|
else if (f.kind === "group" && f.groupExpanded) {
|
|
393
|
-
rows += f.children.length;
|
|
394
|
-
const expandedChild = f.children.find((c) => c.expanded);
|
|
590
|
+
rows += f.children.filter((child) => !child.hidden).length;
|
|
591
|
+
const expandedChild = f.children.find((c) => c.kind === "select" && !c.hidden && c.expanded);
|
|
395
592
|
if (expandedChild)
|
|
396
593
|
rows += expandedChild.options.length;
|
|
397
594
|
}
|
|
@@ -402,12 +599,33 @@ export function extractFlowValues(fields, template) {
|
|
|
402
599
|
const values = {};
|
|
403
600
|
for (const param of template.params) {
|
|
404
601
|
const field = findFieldByKey(fields, param.key);
|
|
602
|
+
if (param.type === "context" && !isApplicableContextField(fields, param)) {
|
|
603
|
+
continue;
|
|
604
|
+
}
|
|
405
605
|
const value = field?.value ?? defaultParamValue(param);
|
|
406
606
|
if (value !== undefined)
|
|
407
607
|
values[param.key] = value;
|
|
408
608
|
}
|
|
409
609
|
return values;
|
|
410
610
|
}
|
|
611
|
+
function isApplicableContextField(fields, param) {
|
|
612
|
+
const group = fields.find((field) => field.kind === "group" &&
|
|
613
|
+
field.contextKey === param.key);
|
|
614
|
+
if (!group)
|
|
615
|
+
return false;
|
|
616
|
+
const provider = providerChild(group).value;
|
|
617
|
+
return defaultContext(provider) !== undefined;
|
|
618
|
+
}
|
|
619
|
+
function isProviderConfigurationParam(param) {
|
|
620
|
+
return param.type === "driver" ||
|
|
621
|
+
param.type === "model" ||
|
|
622
|
+
param.type === "effort" ||
|
|
623
|
+
param.type === "fast" ||
|
|
624
|
+
param.type === "context";
|
|
625
|
+
}
|
|
626
|
+
function isDriverName(value) {
|
|
627
|
+
return value === "claude" || value === "codex" || value === "copilot";
|
|
628
|
+
}
|
|
411
629
|
export function diagramWidth(flow, termCols, detailed) {
|
|
412
630
|
const minW = detailed ? computeDetailedMinWidth(flow.steps) : computeMinWidth(flow.steps);
|
|
413
631
|
return Math.min(minW + DIAGRAM_PADDING, termCols - 4);
|
|
@@ -518,62 +736,95 @@ function handleExpandedSelectEvent(field, event) {
|
|
|
518
736
|
}
|
|
519
737
|
}
|
|
520
738
|
function handleGroupFieldEvent(group, event, driverMemory) {
|
|
521
|
-
|
|
522
|
-
const
|
|
739
|
+
ensureGroupFocusVisible(group);
|
|
740
|
+
const provider = providerChild(group);
|
|
741
|
+
const model = modelChild(group);
|
|
742
|
+
const effort = effortChild(group);
|
|
743
|
+
const beforeProvider = provider.value;
|
|
744
|
+
const beforeModel = model.value;
|
|
523
745
|
let consumed = false;
|
|
524
746
|
if (!group.groupExpanded) {
|
|
747
|
+
const isArrow = event.type === "arrow";
|
|
748
|
+
const ctrl = isArrow && event.ctrl === true;
|
|
749
|
+
const alt = isArrow && event.alt === true;
|
|
525
750
|
if (event.type === "enter") {
|
|
526
751
|
group.groupExpanded = true;
|
|
527
|
-
group.focusedChild =
|
|
752
|
+
group.focusedChild = firstVisibleGroupChildIndex(group);
|
|
753
|
+
consumed = true;
|
|
754
|
+
}
|
|
755
|
+
else if (isArrow
|
|
756
|
+
&& ctrl
|
|
757
|
+
&& (event.direction === "left" || event.direction === "right")) {
|
|
758
|
+
clampSelectValue(effort, event.direction === "left" ? -1 : 1);
|
|
759
|
+
consumed = true;
|
|
760
|
+
}
|
|
761
|
+
else if (isArrow
|
|
762
|
+
&& ctrl
|
|
763
|
+
&& (event.direction === "up" || event.direction === "down")) {
|
|
764
|
+
cycleSelectValue(model, event.direction === "up" ? -1 : 1);
|
|
528
765
|
consumed = true;
|
|
529
766
|
}
|
|
530
|
-
else if (
|
|
531
|
-
&&
|
|
767
|
+
else if (isArrow
|
|
768
|
+
&& alt
|
|
532
769
|
&& (event.direction === "left" || event.direction === "right")) {
|
|
533
|
-
|
|
770
|
+
const context = contextChild(group);
|
|
771
|
+
if (context && !context.hidden) {
|
|
772
|
+
cycleSelectValue(context, event.direction === "left" ? -1 : 1);
|
|
773
|
+
}
|
|
534
774
|
consumed = true;
|
|
535
775
|
}
|
|
536
|
-
else if (
|
|
537
|
-
&&
|
|
776
|
+
else if (isArrow
|
|
777
|
+
&& alt
|
|
538
778
|
&& (event.direction === "up" || event.direction === "down")) {
|
|
539
|
-
|
|
779
|
+
const fast = fastChild(group);
|
|
780
|
+
if (fast && !fast.hidden) {
|
|
781
|
+
fast.value = !fast.value;
|
|
782
|
+
}
|
|
540
783
|
consumed = true;
|
|
541
784
|
}
|
|
542
|
-
else if (
|
|
785
|
+
else if (isArrow
|
|
786
|
+
&& !ctrl
|
|
787
|
+
&& !alt
|
|
543
788
|
&& (event.direction === "left" || event.direction === "right")) {
|
|
544
|
-
cycleSelectValue(
|
|
789
|
+
cycleSelectValue(provider, event.direction === "left" ? -1 : 1);
|
|
545
790
|
consumed = true;
|
|
546
791
|
}
|
|
547
792
|
}
|
|
548
793
|
else {
|
|
549
794
|
const child = group.children[group.focusedChild];
|
|
550
|
-
if (child.expanded) {
|
|
795
|
+
if (child?.kind === "select" && child.expanded) {
|
|
551
796
|
consumed = handleExpandedSelectEvent(child, event);
|
|
552
797
|
}
|
|
553
798
|
else {
|
|
554
799
|
switch (event.type) {
|
|
555
800
|
case "arrow":
|
|
556
801
|
if (event.direction === "up") {
|
|
557
|
-
group.focusedChild = (group
|
|
558
|
-
group.children.length;
|
|
802
|
+
group.focusedChild = nextVisibleGroupChildIndex(group, -1);
|
|
559
803
|
}
|
|
560
804
|
else if (event.direction === "down") {
|
|
561
|
-
group.focusedChild = (group
|
|
805
|
+
group.focusedChild = nextVisibleGroupChildIndex(group, 1);
|
|
562
806
|
}
|
|
563
|
-
else {
|
|
564
|
-
|
|
807
|
+
else if (child) {
|
|
808
|
+
handleFieldAdjust(child, event.direction === "left" ? -1 : 1);
|
|
565
809
|
}
|
|
566
810
|
consumed = true;
|
|
567
811
|
break;
|
|
568
812
|
case "enter":
|
|
569
|
-
child
|
|
570
|
-
|
|
813
|
+
if (child?.kind === "select") {
|
|
814
|
+
child.expanded = true;
|
|
815
|
+
child.expandedIndex = Math.max(0, selectOptionIndex(child, child.value));
|
|
816
|
+
}
|
|
817
|
+
else if (child?.kind === "toggle") {
|
|
818
|
+
child.value = !child.value;
|
|
819
|
+
}
|
|
571
820
|
consumed = true;
|
|
572
821
|
break;
|
|
573
822
|
case "escape":
|
|
574
823
|
group.groupExpanded = false;
|
|
575
|
-
for (const c of group.children)
|
|
576
|
-
c.
|
|
824
|
+
for (const c of group.children) {
|
|
825
|
+
if (c.kind === "select")
|
|
826
|
+
c.expanded = false;
|
|
827
|
+
}
|
|
577
828
|
consumed = true;
|
|
578
829
|
break;
|
|
579
830
|
case "tab":
|
|
@@ -582,13 +833,16 @@ function handleGroupFieldEvent(group, event, driverMemory) {
|
|
|
582
833
|
}
|
|
583
834
|
}
|
|
584
835
|
}
|
|
585
|
-
if (
|
|
586
|
-
|
|
836
|
+
if (provider.value !== beforeProvider) {
|
|
837
|
+
if (driverMemory && isDriverName(beforeProvider)) {
|
|
838
|
+
snapshotGroupToDriverMemory(driverMemory, group, beforeProvider);
|
|
839
|
+
}
|
|
840
|
+
reconcileProviderSettingsForGroup(group, driverMemory, { providerChanged: true });
|
|
587
841
|
}
|
|
588
|
-
else if (
|
|
589
|
-
|
|
842
|
+
else if (model.value !== beforeModel) {
|
|
843
|
+
reconcileSettingsForCurrentModel(group);
|
|
590
844
|
}
|
|
591
|
-
group.value =
|
|
845
|
+
group.value = provider.value;
|
|
592
846
|
return consumed;
|
|
593
847
|
}
|
|
594
848
|
function handleNumberEditingEvent(field, event) {
|
|
@@ -706,9 +960,20 @@ export function renderConfigFields(fields, focusedIndex, isConfigFocused, cols)
|
|
|
706
960
|
: `${dim}off${reset}`;
|
|
707
961
|
}
|
|
708
962
|
else {
|
|
709
|
-
const
|
|
963
|
+
const provider = providerChild(field);
|
|
964
|
+
const model = modelChild(field);
|
|
965
|
+
const effort = effortChild(field);
|
|
966
|
+
const fast = fastChild(field);
|
|
967
|
+
const context = contextChild(field);
|
|
968
|
+
const summary = compactProviderConfigurationTokens({
|
|
969
|
+
driver: provider.value,
|
|
970
|
+
model: model.value,
|
|
971
|
+
effort: effort.value,
|
|
972
|
+
fast: fast?.value,
|
|
973
|
+
context: context && !context.hidden ? context.value : undefined,
|
|
974
|
+
}).map(renderCompactProviderConfigurationToken).join(` ${dim}/${reset} `);
|
|
710
975
|
const marker = field.groupExpanded ? `${bold}▴${reset}` : `${dim}▾${reset}`;
|
|
711
|
-
valueStr = `${
|
|
976
|
+
valueStr = `${summary} ${marker}`;
|
|
712
977
|
}
|
|
713
978
|
lines.push(padToWidth(` ${indicator} ${dimWrap}${labelStr}${dimEnd}${valueStr}`, cols));
|
|
714
979
|
// Expanded dropdown options
|
|
@@ -723,17 +988,27 @@ export function renderConfigFields(fields, focusedIndex, isConfigFocused, cols)
|
|
|
723
988
|
else if (field.kind === "group" && field.groupExpanded) {
|
|
724
989
|
for (let childIdx = 0; childIdx < field.children.length; childIdx++) {
|
|
725
990
|
const child = field.children[childIdx];
|
|
991
|
+
if (child.hidden)
|
|
992
|
+
continue;
|
|
726
993
|
const childFocused = focused && field.focusedChild === childIdx;
|
|
727
994
|
const childIndicator = childFocused ? `${bold}▸${reset}` : " ";
|
|
728
995
|
const childLabel = child.label.padEnd(LABEL_WIDTH - 2);
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
996
|
+
let childValue;
|
|
997
|
+
if (child.kind === "toggle") {
|
|
998
|
+
childValue = child.value
|
|
999
|
+
? `${green}on${reset}`
|
|
1000
|
+
: `${dim}off${reset}`;
|
|
1001
|
+
}
|
|
1002
|
+
else {
|
|
1003
|
+
const childDisplayValue = child.key === field.effortKey
|
|
1004
|
+
? formatEffortValue(child.value)
|
|
1005
|
+
: child.value;
|
|
1006
|
+
childValue = child.expanded
|
|
1007
|
+
? `${childDisplayValue} ${bold}▴${reset}`
|
|
1008
|
+
: `${childDisplayValue} ${dim}▾${reset}`;
|
|
1009
|
+
}
|
|
735
1010
|
lines.push(padToWidth(` ${childIndicator} ${dimWrap}${childLabel}${dimEnd}${childValue}`, cols));
|
|
736
|
-
if (child.expanded) {
|
|
1011
|
+
if (child.kind === "select" && child.expanded) {
|
|
737
1012
|
for (let j = 0; j < child.options.length; j++) {
|
|
738
1013
|
const opt = child.options[j];
|
|
739
1014
|
const optIndicator = j === child.expandedIndex ? `${bold}▸${reset}` : " ";
|