hoomanjs 1.35.3 → 1.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -13
- package/dist/acp/acp-agent.d.ts +40 -66
- package/dist/acp/acp-agent.js +786 -398
- package/dist/acp/acp-agent.js.map +1 -1
- package/dist/acp/approvals.d.ts +2 -2
- package/dist/acp/approvals.js +66 -58
- package/dist/acp/approvals.js.map +1 -1
- package/dist/acp/commands.d.ts +20 -0
- package/dist/acp/commands.js +66 -0
- package/dist/acp/commands.js.map +1 -0
- package/dist/acp/index.d.ts +1 -1
- package/dist/acp/index.js +1 -1
- package/dist/acp/index.js.map +1 -1
- package/dist/acp/mcp-servers.js +14 -8
- package/dist/acp/mcp-servers.js.map +1 -1
- package/dist/acp/prompt-invoke.js +103 -49
- package/dist/acp/prompt-invoke.js.map +1 -1
- package/dist/acp/session-config.d.ts +18 -0
- package/dist/acp/session-config.js +52 -0
- package/dist/acp/session-config.js.map +1 -0
- package/dist/acp/sessions/replay.d.ts +2 -2
- package/dist/acp/sessions/replay.js +28 -44
- package/dist/acp/sessions/replay.js.map +1 -1
- package/dist/acp/sessions/store.d.ts +4 -0
- package/dist/acp/sessions/store.js +5 -1
- package/dist/acp/sessions/store.js.map +1 -1
- package/dist/acp/utils/tool-kind.js +2 -2
- package/dist/acp/utils/tool-kind.js.map +1 -1
- package/dist/acp/utils/tool-result-content.d.ts +7 -0
- package/dist/acp/utils/tool-result-content.js +18 -0
- package/dist/acp/utils/tool-result-content.js.map +1 -1
- package/dist/chat/app.js +117 -1
- package/dist/chat/app.js.map +1 -1
- package/dist/chat/components/BottomChrome.d.ts +2 -1
- package/dist/chat/components/BottomChrome.js +2 -2
- package/dist/chat/components/BottomChrome.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/chat/components/markdown/CodeBlock.js.map +1 -1
- package/dist/cli.js +24 -1
- package/dist/cli.js.map +1 -1
- package/dist/configure/app.js +287 -64
- 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 +17 -4
- package/dist/core/agent/index.js.map +1 -1
- package/dist/core/approvals/allowlist.d.ts +52 -0
- package/dist/core/approvals/allowlist.js +265 -0
- package/dist/core/approvals/allowlist.js.map +1 -0
- package/dist/core/approvals/bash-arity.d.ts +10 -0
- package/dist/core/approvals/bash-arity.js +178 -0
- package/dist/core/approvals/bash-arity.js.map +1 -0
- package/dist/core/approvals/intervention.d.ts +1 -2
- package/dist/core/approvals/intervention.js +5 -20
- package/dist/core/approvals/intervention.js.map +1 -1
- package/dist/core/approvals/wildcard.d.ts +14 -0
- package/dist/core/approvals/wildcard.js +27 -0
- package/dist/core/approvals/wildcard.js.map +1 -0
- 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/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/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/skills/built-in/hooman-config/SKILL.md +20 -12
- package/dist/core/state/file-tool-display.d.ts +6 -0
- package/dist/core/state/file-tool-display.js.map +1 -1
- package/dist/core/state/todos.d.ts +11 -0
- package/dist/core/state/todos.js +2 -0
- package/dist/core/state/todos.js.map +1 -1
- package/dist/core/state/tool-approvals.d.ts +6 -7
- package/dist/core/state/tool-approvals.js +7 -50
- package/dist/core/state/tool-approvals.js.map +1 -1
- package/dist/core/tools/filesystem.js +83 -27
- package/dist/core/tools/filesystem.js.map +1 -1
- package/dist/core/tools/shell.js +39 -0
- package/dist/core/tools/shell.js.map +1 -1
- package/dist/core/tools/terminal-backend.d.ts +41 -0
- package/dist/core/tools/terminal-backend.js +9 -0
- package/dist/core/tools/terminal-backend.js.map +1 -0
- package/dist/core/tools/text-fs-backend.d.ts +25 -0
- package/dist/core/tools/text-fs-backend.js +9 -0
- package/dist/core/tools/text-fs-backend.js.map +1 -0
- package/dist/core/tools/todo.d.ts +1 -0
- package/dist/core/tools/todo.js +2 -1
- package/dist/core/tools/todo.js.map +1 -1
- package/dist/core/tools/web-search.js +56 -1
- package/dist/core/tools/web-search.js.map +1 -1
- package/dist/core/utils/attachments.js.map +1 -1
- package/dist/core/utils/paths.d.ts +1 -0
- package/dist/core/utils/paths.js +1 -0
- package/dist/core/utils/paths.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
- package/dist/acp/sessions/options.d.ts +0 -10
- package/dist/acp/sessions/options.js +0 -89
- package/dist/acp/sessions/options.js.map +0 -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": {
|
|
595
|
+
const value = normalizeOptional(input);
|
|
596
|
+
if (value === undefined) {
|
|
597
|
+
return undefined;
|
|
598
|
+
}
|
|
599
|
+
if (value === "chat" || value === "responses") {
|
|
600
|
+
return value;
|
|
601
|
+
}
|
|
602
|
+
throw new Error(`${definition.label} must be "chat" or "responses".`);
|
|
603
|
+
}
|
|
604
|
+
case "reasoningEffort": {
|
|
496
605
|
const value = normalizeOptional(input);
|
|
497
606
|
if (value === undefined) {
|
|
498
607
|
return undefined;
|
|
499
608
|
}
|
|
500
|
-
if (value === "
|
|
609
|
+
if (value === "minimal" ||
|
|
610
|
+
value === "low" ||
|
|
611
|
+
value === "medium" ||
|
|
612
|
+
value === "high") {
|
|
501
613
|
return value;
|
|
502
614
|
}
|
|
503
|
-
throw new Error(`${definition.label} must be "
|
|
615
|
+
throw new Error(`${definition.label} must be "minimal", "low", "medium", or "high".`);
|
|
504
616
|
}
|
|
505
|
-
case "
|
|
617
|
+
case "reasoningSummary": {
|
|
506
618
|
const value = normalizeOptional(input);
|
|
507
619
|
if (value === undefined) {
|
|
508
620
|
return undefined;
|
|
509
621
|
}
|
|
510
|
-
if (value === "
|
|
622
|
+
if (value === "auto" ||
|
|
623
|
+
value === "concise" ||
|
|
624
|
+
value === "detailed" ||
|
|
625
|
+
value === "none") {
|
|
511
626
|
return value;
|
|
512
627
|
}
|
|
513
|
-
|
|
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") {
|
|
1263
1412
|
setScreen({
|
|
1264
|
-
kind: "config-provider-
|
|
1413
|
+
kind: "config-provider-reasoning-effort",
|
|
1265
1414
|
name: entry.name,
|
|
1266
1415
|
});
|
|
1267
1416
|
return;
|
|
1268
1417
|
}
|
|
1269
|
-
if (definition.kind === "
|
|
1418
|
+
if (definition.kind === "reasoningSummary") {
|
|
1270
1419
|
setScreen({
|
|
1271
|
-
kind: "config-provider-
|
|
1420
|
+
kind: "config-provider-reasoning-summary",
|
|
1421
|
+
name: entry.name,
|
|
1422
|
+
});
|
|
1423
|
+
return;
|
|
1424
|
+
}
|
|
1425
|
+
if (definition.kind === "reasoningDisplay") {
|
|
1426
|
+
setScreen({
|
|
1427
|
+
kind: "config-provider-reasoning-display",
|
|
1272
1428
|
name: entry.name,
|
|
1273
1429
|
});
|
|
1274
1430
|
return;
|
|
@@ -1357,69 +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({ providers: patchProvider(entry.name, {
|
|
1531
|
+
if (updateConfig({ providers: patchProvider(entry.name, { api: undefined }) }, `Cleared API for "${entry.name}".`)) {
|
|
1382
1532
|
setScreen({ kind: "config-provider-edit", name: entry.name });
|
|
1383
1533
|
}
|
|
1384
1534
|
},
|
|
1385
1535
|
},
|
|
1386
|
-
{
|
|
1387
|
-
label: current ===
|
|
1536
|
+
...["responses", "chat"].map((value) => ({
|
|
1537
|
+
label: current === value ? `${value} • current` : value,
|
|
1388
1538
|
value: () => {
|
|
1389
|
-
if (updateConfig({ providers: patchProvider(entry.name, {
|
|
1539
|
+
if (updateConfig({ providers: patchProvider(entry.name, { api: value }) }, `Updated API for "${entry.name}" to "${value}".`)) {
|
|
1390
1540
|
setScreen({ kind: "config-provider-edit", name: entry.name });
|
|
1391
1541
|
}
|
|
1392
1542
|
},
|
|
1393
|
-
},
|
|
1543
|
+
})),
|
|
1394
1544
|
{
|
|
1395
1545
|
label: "Back",
|
|
1396
1546
|
value: () => setScreen({ kind: "config-provider-edit", name: entry.name }),
|
|
1397
1547
|
},
|
|
1398
1548
|
];
|
|
1399
|
-
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 }));
|
|
1400
1550
|
};
|
|
1401
|
-
const
|
|
1402
|
-
if (screen.kind !==
|
|
1551
|
+
const renderOpenAIEnumMenu = (screenKind, subKey, title, description, values, clearedLabel) => {
|
|
1552
|
+
if (screen.kind !== screenKind) {
|
|
1403
1553
|
return null;
|
|
1404
1554
|
}
|
|
1405
1555
|
const entry = config.providers.find((provider) => provider.name === screen.name);
|
|
1406
1556
|
if (!entry) {
|
|
1407
1557
|
return null;
|
|
1408
1558
|
}
|
|
1409
|
-
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
|
+
};
|
|
1410
1572
|
const items = [
|
|
1411
1573
|
{
|
|
1412
|
-
label: current === undefined ?
|
|
1574
|
+
label: current === undefined ? clearedLabel : "Not set (clear value)",
|
|
1413
1575
|
value: () => {
|
|
1414
|
-
if (updateConfig({ providers:
|
|
1576
|
+
if (updateConfig({ providers: patchReasoning(undefined) }, `Cleared reasoning.${subKey} for "${entry.name}".`)) {
|
|
1415
1577
|
setScreen({ kind: "config-provider-edit", name: entry.name });
|
|
1416
1578
|
}
|
|
1417
1579
|
},
|
|
1418
1580
|
},
|
|
1419
|
-
...
|
|
1420
|
-
label: current === value ? `${
|
|
1581
|
+
...values.map((value) => ({
|
|
1582
|
+
label: current === value ? `${value} • current` : value,
|
|
1421
1583
|
value: () => {
|
|
1422
|
-
if (updateConfig({ providers:
|
|
1584
|
+
if (updateConfig({ providers: patchReasoning(value) }, `Updated reasoning.${subKey} for "${entry.name}" to "${value}".`)) {
|
|
1423
1585
|
setScreen({ kind: "config-provider-edit", name: entry.name });
|
|
1424
1586
|
}
|
|
1425
1587
|
},
|
|
@@ -1429,7 +1591,7 @@ export function ConfigureApp({ config, mcpConfig, mcpManager, skills, onExit, })
|
|
|
1429
1591
|
value: () => setScreen({ kind: "config-provider-edit", name: entry.name }),
|
|
1430
1592
|
},
|
|
1431
1593
|
];
|
|
1432
|
-
return
|
|
1594
|
+
return _jsx(MenuScreen, { title: title, description: description, items: items });
|
|
1433
1595
|
};
|
|
1434
1596
|
const renderProviderTypeMenu = () => {
|
|
1435
1597
|
if (screen.kind !== "config-provider-type") {
|
|
@@ -1758,7 +1920,7 @@ export function ConfigureApp({ config, mcpConfig, mcpManager, skills, onExit, })
|
|
|
1758
1920
|
};
|
|
1759
1921
|
const renderSearchProviderMenu = () => {
|
|
1760
1922
|
const items = [
|
|
1761
|
-
...["brave", "exa", "firecrawl", "serper", "tavily"].map((provider) => ({
|
|
1923
|
+
...["brave", "exa", "firecrawl", "litellm", "serper", "tavily"].map((provider) => ({
|
|
1762
1924
|
label: provider === configData.search.provider
|
|
1763
1925
|
? `${SEARCH_PROVIDER_LABELS[provider]} • current`
|
|
1764
1926
|
: SEARCH_PROVIDER_LABELS[provider],
|
|
@@ -1783,8 +1945,64 @@ export function ConfigureApp({ config, mcpConfig, mcpManager, skills, onExit, })
|
|
|
1783
1945
|
const renderSearchConfigMenu = () => {
|
|
1784
1946
|
const activeProvider = configData.search.provider;
|
|
1785
1947
|
const activeProviderLabel = SEARCH_PROVIDER_LABELS[activeProvider];
|
|
1948
|
+
const isLiteLLM = activeProvider === "litellm";
|
|
1949
|
+
const credentialLabel = isLiteLLM ? "Virtual key" : "API key";
|
|
1786
1950
|
const apiKey = configData.search[activeProvider].apiKey;
|
|
1787
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
|
+
: [];
|
|
1788
2006
|
const items = [
|
|
1789
2007
|
{
|
|
1790
2008
|
label: `Enabled • ${yesNo(configData.search.enabled)}`,
|
|
@@ -1803,16 +2021,17 @@ export function ConfigureApp({ config, mcpConfig, mcpManager, skills, onExit, })
|
|
|
1803
2021
|
label: `Provider • ${activeProviderLabel}`,
|
|
1804
2022
|
value: () => setScreen({ kind: "config-search-provider" }),
|
|
1805
2023
|
},
|
|
2024
|
+
...litellmItems,
|
|
1806
2025
|
{
|
|
1807
|
-
label: `${activeProviderLabel}
|
|
2026
|
+
label: `${activeProviderLabel} ${credentialLabel.toLowerCase()} • ${truncate(redacted, 44)}`,
|
|
1808
2027
|
value: () => promptValue({
|
|
1809
|
-
title: `Update ${activeProviderLabel}
|
|
1810
|
-
label:
|
|
2028
|
+
title: `Update ${activeProviderLabel} ${credentialLabel.toLowerCase()}`,
|
|
2029
|
+
label: credentialLabel,
|
|
1811
2030
|
initialValue: apiKey ?? "",
|
|
1812
2031
|
onSubmit: async (value) => {
|
|
1813
2032
|
const nextApiKey = value.trim();
|
|
1814
2033
|
if (!nextApiKey) {
|
|
1815
|
-
throw new Error(
|
|
2034
|
+
throw new Error(`${credentialLabel} is required.`);
|
|
1816
2035
|
}
|
|
1817
2036
|
if (updateConfig({
|
|
1818
2037
|
search: {
|
|
@@ -1822,7 +2041,7 @@ export function ConfigureApp({ config, mcpConfig, mcpManager, skills, onExit, })
|
|
|
1822
2041
|
apiKey: nextApiKey,
|
|
1823
2042
|
},
|
|
1824
2043
|
},
|
|
1825
|
-
}, `Updated ${activeProviderLabel}
|
|
2044
|
+
}, `Updated ${activeProviderLabel} ${credentialLabel.toLowerCase()}.`)) {
|
|
1826
2045
|
setPrompt(null);
|
|
1827
2046
|
}
|
|
1828
2047
|
},
|
|
@@ -2134,10 +2353,14 @@ export function ConfigureApp({ config, mcpConfig, mcpManager, skills, onExit, })
|
|
|
2134
2353
|
return renderProviderEditMenu();
|
|
2135
2354
|
case "config-provider-type":
|
|
2136
2355
|
return renderProviderTypeMenu();
|
|
2137
|
-
case "config-provider-
|
|
2138
|
-
return
|
|
2139
|
-
case "config-provider-
|
|
2140
|
-
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");
|
|
2141
2364
|
case "config-provider-delete-confirm":
|
|
2142
2365
|
return renderProviderDeleteConfirm();
|
|
2143
2366
|
case "config-llms":
|