hoomanjs 1.36.0 → 1.37.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/README.md +17 -13
- package/dist/acp/acp-agent.js +128 -2
- package/dist/acp/acp-agent.js.map +1 -1
- package/dist/acp/commands.js +5 -0
- package/dist/acp/commands.js.map +1 -1
- package/dist/acp/session-config.d.ts +2 -0
- package/dist/acp/session-config.js +27 -0
- package/dist/acp/session-config.js.map +1 -1
- package/dist/chat/app.js +130 -1
- package/dist/chat/app.js.map +1 -1
- package/dist/chat/components/BottomChrome.d.ts +3 -1
- package/dist/chat/components/BottomChrome.js +2 -2
- package/dist/chat/components/BottomChrome.js.map +1 -1
- package/dist/chat/components/ChromePicker.d.ts +3 -2
- package/dist/chat/components/ChromePicker.js +15 -1
- package/dist/chat/components/ChromePicker.js.map +1 -1
- package/dist/chat/components/ReasoningStrip.js +3 -1
- package/dist/chat/components/ReasoningStrip.js.map +1 -1
- package/dist/chat/components/StatusBar.d.ts +2 -1
- package/dist/chat/components/StatusBar.js +18 -3
- package/dist/chat/components/StatusBar.js.map +1 -1
- package/dist/chat/components/ThoughtEvent.d.ts +3 -1
- package/dist/chat/components/ThoughtEvent.js +6 -2
- package/dist/chat/components/ThoughtEvent.js.map +1 -1
- package/dist/chat/components/Transcript.d.ts +5 -2
- package/dist/chat/components/Transcript.js +4 -4
- package/dist/chat/components/Transcript.js.map +1 -1
- package/dist/cli.js +23 -0
- package/dist/cli.js.map +1 -1
- package/dist/configure/app.js +287 -68
- package/dist/configure/app.js.map +1 -1
- package/dist/configure/components/MenuScreen.js +29 -5
- package/dist/configure/components/MenuScreen.js.map +1 -1
- package/dist/configure/types.d.ts +8 -2
- package/dist/core/agent/index.js +3 -2
- package/dist/core/agent/index.js.map +1 -1
- package/dist/core/config.d.ts +352 -22
- package/dist/core/config.js +40 -0
- package/dist/core/config.js.map +1 -1
- package/dist/core/models/anthropic.d.ts +7 -1
- package/dist/core/models/anthropic.js +36 -7
- package/dist/core/models/anthropic.js.map +1 -1
- package/dist/core/models/azure.js +13 -0
- package/dist/core/models/azure.js.map +1 -1
- package/dist/core/models/bedrock.js +33 -0
- package/dist/core/models/bedrock.js.map +1 -1
- package/dist/core/models/google.js +5 -0
- package/dist/core/models/google.js.map +1 -1
- package/dist/core/models/groq.js +14 -0
- package/dist/core/models/groq.js.map +1 -1
- package/dist/core/models/minimax.js +2 -2
- package/dist/core/models/minimax.js.map +1 -1
- package/dist/core/models/moonshot.js +5 -0
- package/dist/core/models/moonshot.js.map +1 -1
- package/dist/core/models/ollama/index.js +5 -3
- package/dist/core/models/ollama/index.js.map +1 -1
- package/dist/core/models/openai.js +21 -1
- package/dist/core/models/openai.js.map +1 -1
- package/dist/core/models/openrouter.d.ts +2 -2
- package/dist/core/models/openrouter.js +28 -10
- package/dist/core/models/openrouter.js.map +1 -1
- package/dist/core/models/reasoning-effort.d.ts +55 -0
- package/dist/core/models/reasoning-effort.js +91 -0
- package/dist/core/models/reasoning-effort.js.map +1 -0
- package/dist/core/models/types.d.ts +759 -51
- package/dist/core/models/types.js +43 -7
- package/dist/core/models/types.js.map +1 -1
- package/dist/core/models/xai.js +12 -0
- package/dist/core/models/xai.js.map +1 -1
- package/dist/core/prompts/harness/execution.md +1 -0
- package/dist/core/session-config.d.ts +10 -1
- package/dist/core/session-config.js +16 -0
- package/dist/core/session-config.js.map +1 -1
- package/dist/core/sessions/tolerant-file-storage.d.ts +24 -0
- package/dist/core/sessions/tolerant-file-storage.js +81 -0
- package/dist/core/sessions/tolerant-file-storage.js.map +1 -0
- package/dist/core/skills/built-in/hooman-config/SKILL.md +20 -12
- package/dist/core/state/todos.d.ts +4 -4
- package/dist/core/tools/todo.d.ts +1 -1
- package/dist/core/tools/web-search.js +56 -1
- package/dist/core/tools/web-search.js.map +1 -1
- package/package.json +2 -1
package/dist/configure/app.js
CHANGED
|
@@ -21,6 +21,7 @@ const SEARCH_PROVIDER_LABELS = {
|
|
|
21
21
|
brave: "Brave",
|
|
22
22
|
exa: "Exa",
|
|
23
23
|
firecrawl: "Firecrawl",
|
|
24
|
+
litellm: "LiteLLM",
|
|
24
25
|
serper: "Serper",
|
|
25
26
|
tavily: "Tavily",
|
|
26
27
|
};
|
|
@@ -207,11 +208,18 @@ const PROVIDER_FIELD_DEFINITIONS = {
|
|
|
207
208
|
placeholder: '{"x-my-header":"value"}',
|
|
208
209
|
},
|
|
209
210
|
{
|
|
210
|
-
key: "
|
|
211
|
-
label: "
|
|
212
|
-
kind: "
|
|
213
|
-
placeholder: "
|
|
214
|
-
note: 'Allowed: "
|
|
211
|
+
key: "reasoningEffort",
|
|
212
|
+
label: "Reasoning effort",
|
|
213
|
+
kind: "reasoningEffort",
|
|
214
|
+
placeholder: "medium",
|
|
215
|
+
note: 'Enables extended thinking (thinking: { type: "enabled", budget_tokens }). Allowed: "minimal", "low", "medium", "high", or blank to disable. Effort maps to a budget (1024/2048/4096/8192); defaults to "medium".',
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
key: "reasoningDisplay",
|
|
219
|
+
label: "Reasoning display",
|
|
220
|
+
kind: "reasoningDisplay",
|
|
221
|
+
placeholder: "summarized",
|
|
222
|
+
note: 'For Bedrock Claude via an Anthropic-compatible proxy (Opus 4.7+ hide reasoning by default): "summarized" reveals it (switches to adaptive thinking + output_config.effort); "omitted" to hide; blank keeps the enabled+budget scheme. Do NOT set for the native Anthropic API — it rejects adaptive/display.',
|
|
215
223
|
},
|
|
216
224
|
],
|
|
217
225
|
[LlmProvider.Azure]: [
|
|
@@ -256,6 +264,20 @@ const PROVIDER_FIELD_DEFINITIONS = {
|
|
|
256
264
|
placeholder: "false",
|
|
257
265
|
note: "Allowed: yes/no/true/false. Leave blank to use the AI SDK default.",
|
|
258
266
|
},
|
|
267
|
+
{
|
|
268
|
+
key: "reasoningEffort",
|
|
269
|
+
label: "Reasoning effort",
|
|
270
|
+
kind: "reasoningEffort",
|
|
271
|
+
placeholder: "medium",
|
|
272
|
+
note: 'Responses API. Allowed: "minimal", "low", "medium", "high", or blank. Only reasoning-capable deployments honor it.',
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
key: "reasoningSummary",
|
|
276
|
+
label: "Reasoning summary",
|
|
277
|
+
kind: "reasoningSummary",
|
|
278
|
+
placeholder: "auto",
|
|
279
|
+
note: 'Responses API. Allowed: "auto" (default), "concise", "detailed", or "none" to disable.',
|
|
280
|
+
},
|
|
259
281
|
],
|
|
260
282
|
[LlmProvider.Bedrock]: [
|
|
261
283
|
{
|
|
@@ -284,6 +306,20 @@ const PROVIDER_FIELD_DEFINITIONS = {
|
|
|
284
306
|
placeholder: "...",
|
|
285
307
|
sensitive: true,
|
|
286
308
|
},
|
|
309
|
+
{
|
|
310
|
+
key: "reasoningEffort",
|
|
311
|
+
label: "Reasoning effort",
|
|
312
|
+
kind: "reasoningEffort",
|
|
313
|
+
placeholder: "medium",
|
|
314
|
+
note: 'Enables extended thinking on supported models (e.g. Claude). Allowed: "minimal", "low", "medium", "high", or blank. Effort maps to a thinking budget (1024/2048/4096/8192 tokens); defaults to "medium".',
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
key: "reasoningDisplay",
|
|
318
|
+
label: "Reasoning display",
|
|
319
|
+
kind: "reasoningDisplay",
|
|
320
|
+
placeholder: "summarized",
|
|
321
|
+
note: 'Newer Bedrock Claude (Opus 4.7+) hide reasoning by default. Set "summarized" to reveal it (switches to adaptive thinking + output_config.effort); "omitted" to hide; blank keeps the enabled+budget scheme.',
|
|
322
|
+
},
|
|
287
323
|
],
|
|
288
324
|
[LlmProvider.Google]: [
|
|
289
325
|
{
|
|
@@ -293,6 +329,13 @@ const PROVIDER_FIELD_DEFINITIONS = {
|
|
|
293
329
|
placeholder: "...",
|
|
294
330
|
sensitive: true,
|
|
295
331
|
},
|
|
332
|
+
{
|
|
333
|
+
key: "reasoningEffort",
|
|
334
|
+
label: "Reasoning effort",
|
|
335
|
+
kind: "reasoningEffort",
|
|
336
|
+
placeholder: "medium",
|
|
337
|
+
note: 'Enables Gemini thinking with a dynamic budget. Allowed: "minimal", "low", "medium", "high", or blank to leave at the model default.',
|
|
338
|
+
},
|
|
296
339
|
],
|
|
297
340
|
[LlmProvider.Groq]: [
|
|
298
341
|
{
|
|
@@ -314,6 +357,13 @@ const PROVIDER_FIELD_DEFINITIONS = {
|
|
|
314
357
|
kind: "stringRecord",
|
|
315
358
|
placeholder: '{"x-my-header":"value"}',
|
|
316
359
|
},
|
|
360
|
+
{
|
|
361
|
+
key: "reasoningEffort",
|
|
362
|
+
label: "Reasoning effort",
|
|
363
|
+
kind: "reasoningEffort",
|
|
364
|
+
placeholder: "medium",
|
|
365
|
+
note: 'Maps to Groq reasoning_effort ("minimal" -> "low"). Allowed: "minimal", "low", "medium", "high", or blank. Only reasoning models honor it.',
|
|
366
|
+
},
|
|
317
367
|
],
|
|
318
368
|
[LlmProvider.Minimax]: [
|
|
319
369
|
{
|
|
@@ -330,11 +380,18 @@ const PROVIDER_FIELD_DEFINITIONS = {
|
|
|
330
380
|
placeholder: '{"x-my-header":"value"}',
|
|
331
381
|
},
|
|
332
382
|
{
|
|
333
|
-
key: "
|
|
334
|
-
label: "
|
|
335
|
-
kind: "
|
|
336
|
-
placeholder: "
|
|
337
|
-
note: 'Allowed: "
|
|
383
|
+
key: "reasoningEffort",
|
|
384
|
+
label: "Reasoning effort",
|
|
385
|
+
kind: "reasoningEffort",
|
|
386
|
+
placeholder: "medium",
|
|
387
|
+
note: 'Enables thinking (normalized to MiniMax adaptive, with budget_tokens). Allowed: "minimal", "low", "medium", "high", or blank to disable. Effort maps to a budget (1024/2048/4096/8192); defaults to "medium".',
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
key: "reasoningDisplay",
|
|
391
|
+
label: "Reasoning display",
|
|
392
|
+
kind: "reasoningDisplay",
|
|
393
|
+
placeholder: "summarized",
|
|
394
|
+
note: 'Set "summarized" to switch to adaptive thinking + output_config.effort; "omitted" to hide; blank keeps the adaptive+budget scheme.',
|
|
338
395
|
},
|
|
339
396
|
],
|
|
340
397
|
[LlmProvider.Moonshot]: [
|
|
@@ -358,6 +415,13 @@ const PROVIDER_FIELD_DEFINITIONS = {
|
|
|
358
415
|
kind: "stringRecord",
|
|
359
416
|
placeholder: '{"x-my-header":"value"}',
|
|
360
417
|
},
|
|
418
|
+
{
|
|
419
|
+
key: "reasoningEffort",
|
|
420
|
+
label: "Reasoning effort",
|
|
421
|
+
kind: "reasoningEffort",
|
|
422
|
+
placeholder: "medium",
|
|
423
|
+
note: 'Enables Kimi thinking (thinking: { type: "enabled" }). Allowed: "minimal", "low", "medium", "high", or blank to disable.',
|
|
424
|
+
},
|
|
361
425
|
],
|
|
362
426
|
[LlmProvider.Ollama]: [
|
|
363
427
|
{
|
|
@@ -367,11 +431,11 @@ const PROVIDER_FIELD_DEFINITIONS = {
|
|
|
367
431
|
placeholder: "http://127.0.0.1:11434",
|
|
368
432
|
},
|
|
369
433
|
{
|
|
370
|
-
key: "
|
|
371
|
-
label: "
|
|
372
|
-
kind: "
|
|
434
|
+
key: "reasoningEffort",
|
|
435
|
+
label: "Reasoning effort",
|
|
436
|
+
kind: "reasoningEffort",
|
|
373
437
|
placeholder: "medium",
|
|
374
|
-
note: '
|
|
438
|
+
note: 'Enables Ollama thinking, mapped to the think level ("minimal"/"low" -> "low"). Allowed: "minimal", "low", "medium", "high", or blank to disable.',
|
|
375
439
|
},
|
|
376
440
|
],
|
|
377
441
|
[LlmProvider.OpenAI]: [
|
|
@@ -394,6 +458,27 @@ const PROVIDER_FIELD_DEFINITIONS = {
|
|
|
394
458
|
kind: "stringRecord",
|
|
395
459
|
placeholder: '{"x-my-header":"value"}',
|
|
396
460
|
},
|
|
461
|
+
{
|
|
462
|
+
key: "api",
|
|
463
|
+
label: "API",
|
|
464
|
+
kind: "openaiApi",
|
|
465
|
+
placeholder: "responses",
|
|
466
|
+
note: 'Allowed: "responses" (default, streams reasoning) or "chat" (for OpenAI-compatible endpoints without the Responses API).',
|
|
467
|
+
},
|
|
468
|
+
{
|
|
469
|
+
key: "reasoningEffort",
|
|
470
|
+
label: "Reasoning effort",
|
|
471
|
+
kind: "reasoningEffort",
|
|
472
|
+
placeholder: "medium",
|
|
473
|
+
note: 'Responses API only. Allowed: "minimal", "low", "medium", "high", or blank. Some models (e.g. GPT-5) only emit a reasoning summary at "medium"+.',
|
|
474
|
+
},
|
|
475
|
+
{
|
|
476
|
+
key: "reasoningSummary",
|
|
477
|
+
label: "Reasoning summary",
|
|
478
|
+
kind: "reasoningSummary",
|
|
479
|
+
placeholder: "auto",
|
|
480
|
+
note: 'Responses API only. Allowed: "auto" (default), "concise", "detailed", or "none" to disable.',
|
|
481
|
+
},
|
|
397
482
|
],
|
|
398
483
|
[LlmProvider.OpenRouter]: [
|
|
399
484
|
{
|
|
@@ -417,6 +502,13 @@ const PROVIDER_FIELD_DEFINITIONS = {
|
|
|
417
502
|
placeholder: '{"HTTP-Referer":"https://example.com","X-Title":"Hooman"}',
|
|
418
503
|
note: "Optional extra headers such as attribution metadata for OpenRouter.",
|
|
419
504
|
},
|
|
505
|
+
{
|
|
506
|
+
key: "reasoningEffort",
|
|
507
|
+
label: "Reasoning effort",
|
|
508
|
+
kind: "reasoningEffort",
|
|
509
|
+
placeholder: "medium",
|
|
510
|
+
note: 'Maps to OpenRouter\'s unified reasoning: { effort }. Allowed: "minimal", "low", "medium", "high", or blank. Only reasoning models honor it.',
|
|
511
|
+
},
|
|
420
512
|
],
|
|
421
513
|
[LlmProvider.Xai]: [
|
|
422
514
|
{
|
|
@@ -438,6 +530,13 @@ const PROVIDER_FIELD_DEFINITIONS = {
|
|
|
438
530
|
kind: "stringRecord",
|
|
439
531
|
placeholder: '{"x-my-header":"value"}',
|
|
440
532
|
},
|
|
533
|
+
{
|
|
534
|
+
key: "reasoningEffort",
|
|
535
|
+
label: "Reasoning effort",
|
|
536
|
+
kind: "reasoningEffort",
|
|
537
|
+
placeholder: "high",
|
|
538
|
+
note: 'Maps to xAI reasoning_effort (low/high; "minimal"/"low" -> "low", "medium"/"high" -> "high"). Allowed: "minimal", "low", "medium", "high", or blank. Only reasoning models (e.g. grok-3-mini) honor it.',
|
|
539
|
+
},
|
|
441
540
|
],
|
|
442
541
|
};
|
|
443
542
|
const LLM_FIELD_DEFINITIONS = [
|
|
@@ -492,25 +591,51 @@ function parseTypedFieldValue(input, definition) {
|
|
|
492
591
|
});
|
|
493
592
|
case "bedrockCredentials":
|
|
494
593
|
return undefined;
|
|
495
|
-
case "
|
|
594
|
+
case "openaiApi": {
|
|
496
595
|
const value = normalizeOptional(input);
|
|
497
596
|
if (value === undefined) {
|
|
498
597
|
return undefined;
|
|
499
598
|
}
|
|
500
|
-
if (value === "
|
|
599
|
+
if (value === "chat" || value === "responses") {
|
|
501
600
|
return value;
|
|
502
601
|
}
|
|
503
|
-
throw new Error(`${definition.label} must be "
|
|
602
|
+
throw new Error(`${definition.label} must be "chat" or "responses".`);
|
|
504
603
|
}
|
|
505
|
-
case "
|
|
604
|
+
case "reasoningEffort": {
|
|
506
605
|
const value = normalizeOptional(input);
|
|
507
606
|
if (value === undefined) {
|
|
508
607
|
return undefined;
|
|
509
608
|
}
|
|
510
|
-
if (value === "
|
|
609
|
+
if (value === "minimal" ||
|
|
610
|
+
value === "low" ||
|
|
611
|
+
value === "medium" ||
|
|
612
|
+
value === "high") {
|
|
511
613
|
return value;
|
|
512
614
|
}
|
|
513
|
-
|
|
615
|
+
throw new Error(`${definition.label} must be "minimal", "low", "medium", or "high".`);
|
|
616
|
+
}
|
|
617
|
+
case "reasoningSummary": {
|
|
618
|
+
const value = normalizeOptional(input);
|
|
619
|
+
if (value === undefined) {
|
|
620
|
+
return undefined;
|
|
621
|
+
}
|
|
622
|
+
if (value === "auto" ||
|
|
623
|
+
value === "concise" ||
|
|
624
|
+
value === "detailed" ||
|
|
625
|
+
value === "none") {
|
|
626
|
+
return value;
|
|
627
|
+
}
|
|
628
|
+
throw new Error(`${definition.label} must be "auto", "concise", "detailed", or "none".`);
|
|
629
|
+
}
|
|
630
|
+
case "reasoningDisplay": {
|
|
631
|
+
const value = normalizeOptional(input);
|
|
632
|
+
if (value === undefined) {
|
|
633
|
+
return undefined;
|
|
634
|
+
}
|
|
635
|
+
if (value === "summarized" || value === "omitted") {
|
|
636
|
+
return value;
|
|
637
|
+
}
|
|
638
|
+
throw new Error(`${definition.label} must be "summarized" or "omitted".`);
|
|
514
639
|
}
|
|
515
640
|
}
|
|
516
641
|
}
|
|
@@ -583,6 +708,7 @@ export function ConfigureApp({ config, mcpConfig, mcpManager, skills, onExit, })
|
|
|
583
708
|
prompts: config.prompts,
|
|
584
709
|
tools: config.tools,
|
|
585
710
|
compaction: config.compaction,
|
|
711
|
+
reasoning: config.reasoning,
|
|
586
712
|
}), [config, revision]);
|
|
587
713
|
const mcpServers = useMemo(() => mcpConfig.list(), [mcpConfig, revision]);
|
|
588
714
|
useInput((input, key) => {
|
|
@@ -621,8 +747,10 @@ export function ConfigureApp({ config, mcpConfig, mcpManager, skills, onExit, })
|
|
|
621
747
|
setScreen({ kind: "config-provider-edit", name: screen.name });
|
|
622
748
|
return;
|
|
623
749
|
}
|
|
624
|
-
if (screen.kind === "config-provider-
|
|
625
|
-
screen.kind === "config-provider-
|
|
750
|
+
if (screen.kind === "config-provider-openai-api" ||
|
|
751
|
+
screen.kind === "config-provider-reasoning-effort" ||
|
|
752
|
+
screen.kind === "config-provider-reasoning-summary" ||
|
|
753
|
+
screen.kind === "config-provider-reasoning-display") {
|
|
626
754
|
setScreen({ kind: "config-provider-edit", name: screen.name });
|
|
627
755
|
return;
|
|
628
756
|
}
|
|
@@ -1047,6 +1175,14 @@ export function ConfigureApp({ config, mcpConfig, mcpManager, skills, onExit, })
|
|
|
1047
1175
|
},
|
|
1048
1176
|
}),
|
|
1049
1177
|
},
|
|
1178
|
+
{
|
|
1179
|
+
key: "reasoning-display",
|
|
1180
|
+
label: `Reasoning display • ${configData.reasoning}`,
|
|
1181
|
+
value: () => {
|
|
1182
|
+
const next = configData.reasoning === "collapsed" ? "full" : "collapsed";
|
|
1183
|
+
updateConfig({ reasoning: next }, `Set reasoning display to "${next}".`);
|
|
1184
|
+
},
|
|
1185
|
+
},
|
|
1050
1186
|
{
|
|
1051
1187
|
label: "Back",
|
|
1052
1188
|
value: () => setScreen({ kind: "home" }),
|
|
@@ -1257,18 +1393,38 @@ export function ConfigureApp({ config, mcpConfig, mcpManager, skills, onExit, })
|
|
|
1257
1393
|
key: `provider-field:${entry.name}:${definition.key}`,
|
|
1258
1394
|
label: `${definition.label} • ${formatTypedFieldValue(definition, definition.kind === "bedrockCredentials"
|
|
1259
1395
|
? providerOptions.accessKeyId && providerOptions.secretAccessKey
|
|
1260
|
-
:
|
|
1396
|
+
: definition.kind === "reasoningEffort"
|
|
1397
|
+
? providerOptions.reasoning?.effort
|
|
1398
|
+
: definition.kind === "reasoningSummary"
|
|
1399
|
+
? providerOptions.reasoning?.summary
|
|
1400
|
+
: definition.kind === "reasoningDisplay"
|
|
1401
|
+
? providerOptions.reasoning?.display
|
|
1402
|
+
: providerOptions[definition.key])}`,
|
|
1261
1403
|
value: () => {
|
|
1262
|
-
if (definition.kind === "
|
|
1404
|
+
if (definition.kind === "openaiApi") {
|
|
1405
|
+
setScreen({
|
|
1406
|
+
kind: "config-provider-openai-api",
|
|
1407
|
+
name: entry.name,
|
|
1408
|
+
});
|
|
1409
|
+
return;
|
|
1410
|
+
}
|
|
1411
|
+
if (definition.kind === "reasoningEffort") {
|
|
1412
|
+
setScreen({
|
|
1413
|
+
kind: "config-provider-reasoning-effort",
|
|
1414
|
+
name: entry.name,
|
|
1415
|
+
});
|
|
1416
|
+
return;
|
|
1417
|
+
}
|
|
1418
|
+
if (definition.kind === "reasoningSummary") {
|
|
1263
1419
|
setScreen({
|
|
1264
|
-
kind: "config-provider-
|
|
1420
|
+
kind: "config-provider-reasoning-summary",
|
|
1265
1421
|
name: entry.name,
|
|
1266
1422
|
});
|
|
1267
1423
|
return;
|
|
1268
1424
|
}
|
|
1269
|
-
if (definition.kind === "
|
|
1425
|
+
if (definition.kind === "reasoningDisplay") {
|
|
1270
1426
|
setScreen({
|
|
1271
|
-
kind: "config-provider-
|
|
1427
|
+
kind: "config-provider-reasoning-display",
|
|
1272
1428
|
name: entry.name,
|
|
1273
1429
|
});
|
|
1274
1430
|
return;
|
|
@@ -1357,73 +1513,75 @@ export function ConfigureApp({ config, mcpConfig, mcpManager, skills, onExit, })
|
|
|
1357
1513
|
? `Used by ${usageCount} model(s). Rename updates references automatically; delete is disabled while in use.`
|
|
1358
1514
|
: "Edit shared provider settings or delete this provider.", items: items }));
|
|
1359
1515
|
};
|
|
1360
|
-
const
|
|
1361
|
-
if (screen.kind !== "config-provider-
|
|
1516
|
+
const renderOpenAIApiMenu = () => {
|
|
1517
|
+
if (screen.kind !== "config-provider-openai-api") {
|
|
1362
1518
|
return null;
|
|
1363
1519
|
}
|
|
1364
1520
|
const entry = config.providers.find((provider) => provider.name === screen.name);
|
|
1365
1521
|
if (!entry) {
|
|
1366
1522
|
return null;
|
|
1367
1523
|
}
|
|
1368
|
-
const current = "
|
|
1524
|
+
const current = "api" in entry.options ? entry.options.api : undefined;
|
|
1369
1525
|
const items = [
|
|
1370
1526
|
{
|
|
1371
|
-
label: current === undefined
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
setScreen({ kind: "config-provider-edit", name: entry.name });
|
|
1375
|
-
}
|
|
1376
|
-
},
|
|
1377
|
-
},
|
|
1378
|
-
{
|
|
1379
|
-
label: current === "disabled" ? "disabled • current" : "disabled",
|
|
1527
|
+
label: current === undefined
|
|
1528
|
+
? "Not set (responses) • current"
|
|
1529
|
+
: "Not set (clear value)",
|
|
1380
1530
|
value: () => {
|
|
1381
|
-
if (updateConfig({
|
|
1382
|
-
providers: patchProvider(entry.name, { thinking: "disabled" }),
|
|
1383
|
-
}, `Updated thinking for "${entry.name}" to "disabled".`)) {
|
|
1531
|
+
if (updateConfig({ providers: patchProvider(entry.name, { api: undefined }) }, `Cleared API for "${entry.name}".`)) {
|
|
1384
1532
|
setScreen({ kind: "config-provider-edit", name: entry.name });
|
|
1385
1533
|
}
|
|
1386
1534
|
},
|
|
1387
1535
|
},
|
|
1388
|
-
{
|
|
1389
|
-
label: current ===
|
|
1536
|
+
...["responses", "chat"].map((value) => ({
|
|
1537
|
+
label: current === value ? `${value} • current` : value,
|
|
1390
1538
|
value: () => {
|
|
1391
|
-
if (updateConfig({
|
|
1392
|
-
providers: patchProvider(entry.name, { thinking: "adaptive" }),
|
|
1393
|
-
}, `Updated thinking for "${entry.name}" to "adaptive".`)) {
|
|
1539
|
+
if (updateConfig({ providers: patchProvider(entry.name, { api: value }) }, `Updated API for "${entry.name}" to "${value}".`)) {
|
|
1394
1540
|
setScreen({ kind: "config-provider-edit", name: entry.name });
|
|
1395
1541
|
}
|
|
1396
1542
|
},
|
|
1397
|
-
},
|
|
1543
|
+
})),
|
|
1398
1544
|
{
|
|
1399
1545
|
label: "Back",
|
|
1400
1546
|
value: () => setScreen({ kind: "config-provider-edit", name: entry.name }),
|
|
1401
1547
|
},
|
|
1402
1548
|
];
|
|
1403
|
-
return (_jsx(MenuScreen, { title: `Choose
|
|
1549
|
+
return (_jsx(MenuScreen, { title: `Choose API • ${entry.name}`, description: 'Pick one: "responses" (default, streams reasoning) or "chat" (compatibility mode).', items: items }));
|
|
1404
1550
|
};
|
|
1405
|
-
const
|
|
1406
|
-
if (screen.kind !==
|
|
1551
|
+
const renderOpenAIEnumMenu = (screenKind, subKey, title, description, values, clearedLabel) => {
|
|
1552
|
+
if (screen.kind !== screenKind) {
|
|
1407
1553
|
return null;
|
|
1408
1554
|
}
|
|
1409
1555
|
const entry = config.providers.find((provider) => provider.name === screen.name);
|
|
1410
1556
|
if (!entry) {
|
|
1411
1557
|
return null;
|
|
1412
1558
|
}
|
|
1413
|
-
const
|
|
1559
|
+
const reasoning = "reasoning" in entry.options
|
|
1560
|
+
? entry.options.reasoning
|
|
1561
|
+
: undefined;
|
|
1562
|
+
const current = reasoning?.[subKey];
|
|
1563
|
+
// Merge into the sibling reasoning key, collapsing to `undefined` when the
|
|
1564
|
+
// object would end up empty so we never persist `"reasoning": {}`.
|
|
1565
|
+
const patchReasoning = (next) => {
|
|
1566
|
+
const merged = { ...(reasoning ?? {}), [subKey]: next };
|
|
1567
|
+
const hasValues = Object.values(merged).some((v) => v !== undefined);
|
|
1568
|
+
return patchProvider(entry.name, {
|
|
1569
|
+
reasoning: hasValues ? merged : undefined,
|
|
1570
|
+
});
|
|
1571
|
+
};
|
|
1414
1572
|
const items = [
|
|
1415
1573
|
{
|
|
1416
|
-
label: current === undefined ?
|
|
1574
|
+
label: current === undefined ? clearedLabel : "Not set (clear value)",
|
|
1417
1575
|
value: () => {
|
|
1418
|
-
if (updateConfig({ providers:
|
|
1576
|
+
if (updateConfig({ providers: patchReasoning(undefined) }, `Cleared reasoning.${subKey} for "${entry.name}".`)) {
|
|
1419
1577
|
setScreen({ kind: "config-provider-edit", name: entry.name });
|
|
1420
1578
|
}
|
|
1421
1579
|
},
|
|
1422
1580
|
},
|
|
1423
|
-
...
|
|
1424
|
-
label: current === value ? `${
|
|
1581
|
+
...values.map((value) => ({
|
|
1582
|
+
label: current === value ? `${value} • current` : value,
|
|
1425
1583
|
value: () => {
|
|
1426
|
-
if (updateConfig({ providers:
|
|
1584
|
+
if (updateConfig({ providers: patchReasoning(value) }, `Updated reasoning.${subKey} for "${entry.name}" to "${value}".`)) {
|
|
1427
1585
|
setScreen({ kind: "config-provider-edit", name: entry.name });
|
|
1428
1586
|
}
|
|
1429
1587
|
},
|
|
@@ -1433,7 +1591,7 @@ export function ConfigureApp({ config, mcpConfig, mcpManager, skills, onExit, })
|
|
|
1433
1591
|
value: () => setScreen({ kind: "config-provider-edit", name: entry.name }),
|
|
1434
1592
|
},
|
|
1435
1593
|
];
|
|
1436
|
-
return
|
|
1594
|
+
return _jsx(MenuScreen, { title: title, description: description, items: items });
|
|
1437
1595
|
};
|
|
1438
1596
|
const renderProviderTypeMenu = () => {
|
|
1439
1597
|
if (screen.kind !== "config-provider-type") {
|
|
@@ -1762,7 +1920,7 @@ export function ConfigureApp({ config, mcpConfig, mcpManager, skills, onExit, })
|
|
|
1762
1920
|
};
|
|
1763
1921
|
const renderSearchProviderMenu = () => {
|
|
1764
1922
|
const items = [
|
|
1765
|
-
...["brave", "exa", "firecrawl", "serper", "tavily"].map((provider) => ({
|
|
1923
|
+
...["brave", "exa", "firecrawl", "litellm", "serper", "tavily"].map((provider) => ({
|
|
1766
1924
|
label: provider === configData.search.provider
|
|
1767
1925
|
? `${SEARCH_PROVIDER_LABELS[provider]} • current`
|
|
1768
1926
|
: SEARCH_PROVIDER_LABELS[provider],
|
|
@@ -1787,8 +1945,64 @@ export function ConfigureApp({ config, mcpConfig, mcpManager, skills, onExit, })
|
|
|
1787
1945
|
const renderSearchConfigMenu = () => {
|
|
1788
1946
|
const activeProvider = configData.search.provider;
|
|
1789
1947
|
const activeProviderLabel = SEARCH_PROVIDER_LABELS[activeProvider];
|
|
1948
|
+
const isLiteLLM = activeProvider === "litellm";
|
|
1949
|
+
const credentialLabel = isLiteLLM ? "Virtual key" : "API key";
|
|
1790
1950
|
const apiKey = configData.search[activeProvider].apiKey;
|
|
1791
1951
|
const redacted = compactJson(maskSensitiveParamsForDisplay({ apiKey: apiKey ?? "" }));
|
|
1952
|
+
const litellmItems = isLiteLLM
|
|
1953
|
+
? [
|
|
1954
|
+
{
|
|
1955
|
+
label: `Base URL • ${truncate(configData.search.litellm.baseURL ?? "(unset)", 44)}`,
|
|
1956
|
+
value: () => promptValue({
|
|
1957
|
+
title: "Update LiteLLM base URL",
|
|
1958
|
+
label: "Base URL",
|
|
1959
|
+
initialValue: configData.search.litellm.baseURL ?? "",
|
|
1960
|
+
onSubmit: async (value) => {
|
|
1961
|
+
const nextBaseURL = value.trim();
|
|
1962
|
+
if (!nextBaseURL) {
|
|
1963
|
+
throw new Error("Base URL is required.");
|
|
1964
|
+
}
|
|
1965
|
+
if (updateConfig({
|
|
1966
|
+
search: {
|
|
1967
|
+
...config.search,
|
|
1968
|
+
litellm: {
|
|
1969
|
+
...config.search.litellm,
|
|
1970
|
+
baseURL: nextBaseURL,
|
|
1971
|
+
},
|
|
1972
|
+
},
|
|
1973
|
+
}, "Updated LiteLLM base URL.")) {
|
|
1974
|
+
setPrompt(null);
|
|
1975
|
+
}
|
|
1976
|
+
},
|
|
1977
|
+
}),
|
|
1978
|
+
},
|
|
1979
|
+
{
|
|
1980
|
+
label: `Search tool • ${configData.search.litellm.tool ?? "(unset)"}`,
|
|
1981
|
+
value: () => promptValue({
|
|
1982
|
+
title: "Update LiteLLM search tool",
|
|
1983
|
+
label: "Search tool name",
|
|
1984
|
+
initialValue: configData.search.litellm.tool ?? "",
|
|
1985
|
+
onSubmit: async (value) => {
|
|
1986
|
+
const nextSearchTool = value.trim();
|
|
1987
|
+
if (!nextSearchTool) {
|
|
1988
|
+
throw new Error("Search tool name is required.");
|
|
1989
|
+
}
|
|
1990
|
+
if (updateConfig({
|
|
1991
|
+
search: {
|
|
1992
|
+
...config.search,
|
|
1993
|
+
litellm: {
|
|
1994
|
+
...config.search.litellm,
|
|
1995
|
+
tool: nextSearchTool,
|
|
1996
|
+
},
|
|
1997
|
+
},
|
|
1998
|
+
}, "Updated LiteLLM search tool.")) {
|
|
1999
|
+
setPrompt(null);
|
|
2000
|
+
}
|
|
2001
|
+
},
|
|
2002
|
+
}),
|
|
2003
|
+
},
|
|
2004
|
+
]
|
|
2005
|
+
: [];
|
|
1792
2006
|
const items = [
|
|
1793
2007
|
{
|
|
1794
2008
|
label: `Enabled • ${yesNo(configData.search.enabled)}`,
|
|
@@ -1807,16 +2021,17 @@ export function ConfigureApp({ config, mcpConfig, mcpManager, skills, onExit, })
|
|
|
1807
2021
|
label: `Provider • ${activeProviderLabel}`,
|
|
1808
2022
|
value: () => setScreen({ kind: "config-search-provider" }),
|
|
1809
2023
|
},
|
|
2024
|
+
...litellmItems,
|
|
1810
2025
|
{
|
|
1811
|
-
label: `${activeProviderLabel}
|
|
2026
|
+
label: `${activeProviderLabel} ${credentialLabel.toLowerCase()} • ${truncate(redacted, 44)}`,
|
|
1812
2027
|
value: () => promptValue({
|
|
1813
|
-
title: `Update ${activeProviderLabel}
|
|
1814
|
-
label:
|
|
2028
|
+
title: `Update ${activeProviderLabel} ${credentialLabel.toLowerCase()}`,
|
|
2029
|
+
label: credentialLabel,
|
|
1815
2030
|
initialValue: apiKey ?? "",
|
|
1816
2031
|
onSubmit: async (value) => {
|
|
1817
2032
|
const nextApiKey = value.trim();
|
|
1818
2033
|
if (!nextApiKey) {
|
|
1819
|
-
throw new Error(
|
|
2034
|
+
throw new Error(`${credentialLabel} is required.`);
|
|
1820
2035
|
}
|
|
1821
2036
|
if (updateConfig({
|
|
1822
2037
|
search: {
|
|
@@ -1826,7 +2041,7 @@ export function ConfigureApp({ config, mcpConfig, mcpManager, skills, onExit, })
|
|
|
1826
2041
|
apiKey: nextApiKey,
|
|
1827
2042
|
},
|
|
1828
2043
|
},
|
|
1829
|
-
}, `Updated ${activeProviderLabel}
|
|
2044
|
+
}, `Updated ${activeProviderLabel} ${credentialLabel.toLowerCase()}.`)) {
|
|
1830
2045
|
setPrompt(null);
|
|
1831
2046
|
}
|
|
1832
2047
|
},
|
|
@@ -2138,10 +2353,14 @@ export function ConfigureApp({ config, mcpConfig, mcpManager, skills, onExit, })
|
|
|
2138
2353
|
return renderProviderEditMenu();
|
|
2139
2354
|
case "config-provider-type":
|
|
2140
2355
|
return renderProviderTypeMenu();
|
|
2141
|
-
case "config-provider-
|
|
2142
|
-
return
|
|
2143
|
-
case "config-provider-
|
|
2144
|
-
return
|
|
2356
|
+
case "config-provider-openai-api":
|
|
2357
|
+
return renderOpenAIApiMenu();
|
|
2358
|
+
case "config-provider-reasoning-effort":
|
|
2359
|
+
return renderOpenAIEnumMenu("config-provider-reasoning-effort", "effort", `Choose Reasoning effort • ${screen.name}`, 'Enables thinking/reasoning. Pick one: "minimal", "low", "medium", "high", or clear to disable. GPT-5 needs "medium"+ to show a summary.', ["minimal", "low", "medium", "high"], "Not set (off) • current");
|
|
2360
|
+
case "config-provider-reasoning-summary":
|
|
2361
|
+
return renderOpenAIEnumMenu("config-provider-reasoning-summary", "summary", `Choose Reasoning summary • ${screen.name}`, 'Responses API only. Pick one: "auto" (default), "concise", "detailed", or "none".', ["auto", "concise", "detailed", "none"], "Not set (auto) • current");
|
|
2362
|
+
case "config-provider-reasoning-display":
|
|
2363
|
+
return renderOpenAIEnumMenu("config-provider-reasoning-display", "display", `Choose Reasoning display • ${screen.name}`, 'Bedrock Claude / MiniMax only (not native Anthropic). "summarized" reveals reasoning on newer Bedrock Claude (Opus 4.7+) and switches to adaptive thinking; "omitted" hides it. Clear to keep the enabled+budget scheme.', ["summarized", "omitted"], "Not set • current");
|
|
2145
2364
|
case "config-provider-delete-confirm":
|
|
2146
2365
|
return renderProviderDeleteConfirm();
|
|
2147
2366
|
case "config-llms":
|