@namzu/cli 20.0.0 → 22.0.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/CHANGELOG.md +371 -0
- package/README.md +71 -10
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +24 -2
- package/dist/cli.js.map +1 -1
- package/dist/commands/acp.d.ts.map +1 -1
- package/dist/commands/acp.js +6 -1
- package/dist/commands/acp.js.map +1 -1
- package/dist/commands/run-stream.d.ts.map +1 -1
- package/dist/commands/run-stream.js +9 -1
- package/dist/commands/run-stream.js.map +1 -1
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +15 -12
- package/dist/commands/run.js.map +1 -1
- package/dist/config/load.d.ts.map +1 -1
- package/dist/config/load.js +44 -2
- package/dist/config/load.js.map +1 -1
- package/dist/config/schema.d.ts +24 -13
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js.map +1 -1
- package/dist/doctor/checks/chain.d.ts.map +1 -1
- package/dist/doctor/checks/chain.js +11 -5
- package/dist/doctor/checks/chain.js.map +1 -1
- package/dist/doctor/checks/credentials.d.ts.map +1 -1
- package/dist/doctor/checks/credentials.js +7 -1
- package/dist/doctor/checks/credentials.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/installation.d.ts +5 -0
- package/dist/installation.d.ts.map +1 -0
- package/dist/installation.js +48 -0
- package/dist/installation.js.map +1 -0
- package/dist/integrations/providers/access.d.ts +7 -0
- package/dist/integrations/providers/access.d.ts.map +1 -0
- package/dist/integrations/providers/access.js +17 -0
- package/dist/integrations/providers/access.js.map +1 -0
- package/dist/integrations/providers/current-credential.d.ts +4 -0
- package/dist/integrations/providers/current-credential.d.ts.map +1 -0
- package/dist/integrations/providers/current-credential.js +45 -0
- package/dist/integrations/providers/current-credential.js.map +1 -0
- package/dist/integrations/providers/discover.d.ts +28 -54
- package/dist/integrations/providers/discover.d.ts.map +1 -1
- package/dist/integrations/providers/discover.js +62 -58
- package/dist/integrations/providers/discover.js.map +1 -1
- package/dist/integrations/providers/gemini-credentials.d.ts +13 -0
- package/dist/integrations/providers/gemini-credentials.d.ts.map +1 -0
- package/dist/integrations/providers/gemini-credentials.js +148 -0
- package/dist/integrations/providers/gemini-credentials.js.map +1 -0
- package/dist/integrations/providers/harness-credentials.d.ts +14 -0
- package/dist/integrations/providers/harness-credentials.d.ts.map +1 -1
- package/dist/integrations/providers/harness-credentials.js +46 -0
- package/dist/integrations/providers/harness-credentials.js.map +1 -1
- package/dist/integrations/providers/model-reasoning.d.ts +4 -0
- package/dist/integrations/providers/model-reasoning.d.ts.map +1 -0
- package/dist/integrations/providers/model-reasoning.js +46 -0
- package/dist/integrations/providers/model-reasoning.js.map +1 -0
- package/dist/integrations/providers/register.d.ts +1 -1
- package/dist/integrations/providers/register.d.ts.map +1 -1
- package/dist/integrations/providers/register.js +16 -1
- package/dist/integrations/providers/register.js.map +1 -1
- package/dist/integrations/providers/registry.d.ts +4 -4
- package/dist/integrations/providers/registry.d.ts.map +1 -1
- package/dist/integrations/providers/registry.js +33 -0
- package/dist/integrations/providers/registry.js.map +1 -1
- package/dist/integrations/providers/setup.d.ts +49 -0
- package/dist/integrations/providers/setup.d.ts.map +1 -0
- package/dist/integrations/providers/setup.js +105 -0
- package/dist/integrations/providers/setup.js.map +1 -0
- package/dist/integrations/sessions/context-inventory.d.ts +4 -0
- package/dist/integrations/sessions/context-inventory.d.ts.map +1 -0
- package/dist/integrations/sessions/context-inventory.js +44 -0
- package/dist/integrations/sessions/context-inventory.js.map +1 -0
- package/dist/integrations/sessions/conversation-search.d.ts +60 -0
- package/dist/integrations/sessions/conversation-search.d.ts.map +1 -0
- package/dist/integrations/sessions/conversation-search.js +461 -0
- package/dist/integrations/sessions/conversation-search.js.map +1 -0
- package/dist/integrations/sessions/store.d.ts +1 -0
- package/dist/integrations/sessions/store.d.ts.map +1 -1
- package/dist/integrations/sessions/store.js +17 -4
- package/dist/integrations/sessions/store.js.map +1 -1
- package/dist/integrations/sessions/task-context.d.ts +4 -0
- package/dist/integrations/sessions/task-context.d.ts.map +1 -0
- package/dist/integrations/sessions/task-context.js +73 -0
- package/dist/integrations/sessions/task-context.js.map +1 -0
- package/dist/integrations/subagents/activity.d.ts +3 -1
- package/dist/integrations/subagents/activity.d.ts.map +1 -1
- package/dist/integrations/subagents/activity.js +32 -5
- package/dist/integrations/subagents/activity.js.map +1 -1
- package/dist/integrations/subagents/history.d.ts +26 -0
- package/dist/integrations/subagents/history.d.ts.map +1 -0
- package/dist/integrations/subagents/history.js +76 -0
- package/dist/integrations/subagents/history.js.map +1 -0
- package/dist/integrations/subagents/model-effort.d.ts +4 -0
- package/dist/integrations/subagents/model-effort.d.ts.map +1 -0
- package/dist/integrations/subagents/model-effort.js +12 -0
- package/dist/integrations/subagents/model-effort.js.map +1 -0
- package/dist/integrations/subagents/runtime.d.ts +27 -7
- package/dist/integrations/subagents/runtime.d.ts.map +1 -1
- package/dist/integrations/subagents/runtime.js +305 -35
- package/dist/integrations/subagents/runtime.js.map +1 -1
- package/dist/integrations/web/search.d.ts +11 -0
- package/dist/integrations/web/search.d.ts.map +1 -0
- package/dist/integrations/web/search.js +73 -0
- package/dist/integrations/web/search.js.map +1 -0
- package/dist/memory/io.d.ts +12 -0
- package/dist/memory/io.d.ts.map +1 -0
- package/dist/memory/io.js +177 -0
- package/dist/memory/io.js.map +1 -0
- package/dist/memory/presentation.d.ts +4 -1
- package/dist/memory/presentation.d.ts.map +1 -1
- package/dist/memory/presentation.js +16 -2
- package/dist/memory/presentation.js.map +1 -1
- package/dist/memory/store.d.ts +17 -3
- package/dist/memory/store.d.ts.map +1 -1
- package/dist/memory/store.js +61 -35
- package/dist/memory/store.js.map +1 -1
- package/dist/output-schema.d.ts +4 -0
- package/dist/output-schema.d.ts.map +1 -0
- package/dist/output-schema.js +18 -0
- package/dist/output-schema.js.map +1 -0
- package/dist/tui/AgentExplorer.d.ts +13 -2
- package/dist/tui/AgentExplorer.d.ts.map +1 -1
- package/dist/tui/AgentExplorer.js +85 -23
- package/dist/tui/AgentExplorer.js.map +1 -1
- package/dist/tui/App.d.ts.map +1 -1
- package/dist/tui/App.js +694 -150
- package/dist/tui/App.js.map +1 -1
- package/dist/tui/BrandHeader.d.ts +1 -4
- package/dist/tui/BrandHeader.d.ts.map +1 -1
- package/dist/tui/BrandHeader.js +4 -8
- package/dist/tui/BrandHeader.js.map +1 -1
- package/dist/tui/Composer.d.ts +2 -1
- package/dist/tui/Composer.d.ts.map +1 -1
- package/dist/tui/Composer.js +26 -3
- package/dist/tui/Composer.js.map +1 -1
- package/dist/tui/PermissionOverlay.d.ts +5 -2
- package/dist/tui/PermissionOverlay.d.ts.map +1 -1
- package/dist/tui/PermissionOverlay.js +14 -6
- package/dist/tui/PermissionOverlay.js.map +1 -1
- package/dist/tui/Picker.d.ts +2 -1
- package/dist/tui/Picker.d.ts.map +1 -1
- package/dist/tui/Picker.js +104 -24
- package/dist/tui/Picker.js.map +1 -1
- package/dist/tui/ProviderSetup.d.ts +6 -0
- package/dist/tui/ProviderSetup.d.ts.map +1 -0
- package/dist/tui/ProviderSetup.js +125 -0
- package/dist/tui/ProviderSetup.js.map +1 -0
- package/dist/tui/ResumePicker.d.ts.map +1 -1
- package/dist/tui/ResumePicker.js +5 -3
- package/dist/tui/ResumePicker.js.map +1 -1
- package/dist/tui/StatusPanel.d.ts +5 -0
- package/dist/tui/StatusPanel.d.ts.map +1 -0
- package/dist/tui/StatusPanel.js +11 -0
- package/dist/tui/StatusPanel.js.map +1 -0
- package/dist/tui/TextPrompt.d.ts +3 -1
- package/dist/tui/TextPrompt.d.ts.map +1 -1
- package/dist/tui/TextPrompt.js +55 -9
- package/dist/tui/TextPrompt.js.map +1 -1
- package/dist/tui/ToolOutputViewer.d.ts +11 -0
- package/dist/tui/ToolOutputViewer.d.ts.map +1 -0
- package/dist/tui/ToolOutputViewer.js +39 -0
- package/dist/tui/ToolOutputViewer.js.map +1 -0
- package/dist/tui/Transcript.d.ts.map +1 -1
- package/dist/tui/Transcript.js +10 -4
- package/dist/tui/Transcript.js.map +1 -1
- package/dist/tui/agent.d.ts +24 -3
- package/dist/tui/agent.d.ts.map +1 -1
- package/dist/tui/agent.js +362 -97
- package/dist/tui/agent.js.map +1 -1
- package/dist/tui/live-window.d.ts.map +1 -1
- package/dist/tui/live-window.js +5 -1
- package/dist/tui/live-window.js.map +1 -1
- package/dist/tui/logo.d.ts +4 -4
- package/dist/tui/logo.d.ts.map +1 -1
- package/dist/tui/logo.js +4 -4
- package/dist/tui/logo.js.map +1 -1
- package/dist/tui/model-catalogue-view.d.ts +3 -0
- package/dist/tui/model-catalogue-view.d.ts.map +1 -0
- package/dist/tui/model-catalogue-view.js +50 -0
- package/dist/tui/model-catalogue-view.js.map +1 -0
- package/dist/tui/model-choices.d.ts +3 -1
- package/dist/tui/model-choices.d.ts.map +1 -1
- package/dist/tui/model-choices.js +12 -1
- package/dist/tui/model-choices.js.map +1 -1
- package/dist/tui/model-search.d.ts +4 -0
- package/dist/tui/model-search.d.ts.map +1 -0
- package/dist/tui/model-search.js +11 -0
- package/dist/tui/model-search.js.map +1 -0
- package/dist/tui/model-selection-intent.d.ts +8 -0
- package/dist/tui/model-selection-intent.d.ts.map +1 -0
- package/dist/tui/model-selection-intent.js +96 -0
- package/dist/tui/model-selection-intent.js.map +1 -0
- package/dist/tui/model-switch-tool.d.ts +7 -0
- package/dist/tui/model-switch-tool.d.ts.map +1 -0
- package/dist/tui/model-switch-tool.js +74 -0
- package/dist/tui/model-switch-tool.js.map +1 -0
- package/dist/tui/model-switch.d.ts +35 -0
- package/dist/tui/model-switch.d.ts.map +1 -0
- package/dist/tui/model-switch.js +106 -0
- package/dist/tui/model-switch.js.map +1 -0
- package/dist/tui/permission-review.d.ts +2 -0
- package/dist/tui/permission-review.d.ts.map +1 -1
- package/dist/tui/permission-review.js +82 -15
- package/dist/tui/permission-review.js.map +1 -1
- package/dist/tui/run-interruption.d.ts +7 -0
- package/dist/tui/run-interruption.d.ts.map +1 -1
- package/dist/tui/run-interruption.js +41 -0
- package/dist/tui/run-interruption.js.map +1 -1
- package/dist/tui/slashCommands.d.ts +7 -0
- package/dist/tui/slashCommands.d.ts.map +1 -1
- package/dist/tui/slashCommands.js +77 -2
- package/dist/tui/slashCommands.js.map +1 -1
- package/dist/tui/status-card.d.ts +3 -0
- package/dist/tui/status-card.d.ts.map +1 -0
- package/dist/tui/status-card.js +30 -0
- package/dist/tui/status-card.js.map +1 -0
- package/dist/tui/status-panel-layout.d.ts +11 -0
- package/dist/tui/status-panel-layout.d.ts.map +1 -0
- package/dist/tui/status-panel-layout.js +42 -0
- package/dist/tui/status-panel-layout.js.map +1 -0
- package/dist/tui/types.d.ts +7 -1
- package/dist/tui/types.d.ts.map +1 -1
- package/package.json +9 -7
|
@@ -29,7 +29,18 @@
|
|
|
29
29
|
* @param currentModel The model in force now, if any — so re-opening the picker
|
|
30
30
|
* starts on what is already selected rather than resetting to the default.
|
|
31
31
|
*/
|
|
32
|
-
export function modelStep(defaultModel,
|
|
32
|
+
export function modelStep(defaultModel, suppliedListing, suppliedCurrentModel, options = {}) {
|
|
33
|
+
// A saved pin does not grant access. In particular, losing a Zen account
|
|
34
|
+
// credential must not put a paid model back into its public-only list.
|
|
35
|
+
const currentModel = suppliedCurrentModel && options.allowModel?.(suppliedCurrentModel) === false
|
|
36
|
+
? undefined
|
|
37
|
+
: suppliedCurrentModel;
|
|
38
|
+
const listing = suppliedListing.kind === 'ok' && options.allowModel
|
|
39
|
+
? {
|
|
40
|
+
...suppliedListing,
|
|
41
|
+
models: suppliedListing.models.filter((model) => options.allowModel?.(model.id)),
|
|
42
|
+
}
|
|
43
|
+
: suppliedListing;
|
|
33
44
|
const fallback = (notice) => {
|
|
34
45
|
const choices = [
|
|
35
46
|
{ id: defaultModel, label: defaultModel, note: '(namzu default)' },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-choices.js","sourceRoot":"","sources":["../../src/tui/model-choices.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAwBH;;;;;;;GAOG;AACH,MAAM,UAAU,SAAS,CACxB,YAAoB,EACpB,
|
|
1
|
+
{"version":3,"file":"model-choices.js","sourceRoot":"","sources":["../../src/tui/model-choices.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ModelChoice } from './model-choices.js';
|
|
2
|
+
/** Match every word against IDs and names, retaining catalogue order and identity. */
|
|
3
|
+
export declare function filterModelChoices(choices: readonly ModelChoice[], query: string): readonly ModelChoice[];
|
|
4
|
+
//# sourceMappingURL=model-search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-search.d.ts","sourceRoot":"","sources":["../../src/tui/model-search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAErD,sFAAsF;AACtF,wBAAgB,kBAAkB,CACjC,OAAO,EAAE,SAAS,WAAW,EAAE,EAC/B,KAAK,EAAE,MAAM,GACX,SAAS,WAAW,EAAE,CAOxB"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Match every word against IDs and names, retaining catalogue order and identity. */
|
|
2
|
+
export function filterModelChoices(choices, query) {
|
|
3
|
+
const words = query.normalize('NFKC').toLowerCase().trim().split(/\s+/).filter(Boolean);
|
|
4
|
+
if (words.length === 0)
|
|
5
|
+
return choices;
|
|
6
|
+
return choices.filter((choice) => {
|
|
7
|
+
const text = `${choice.id} ${choice.label}`.normalize('NFKC').toLowerCase();
|
|
8
|
+
return words.every((word) => text.includes(word));
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=model-search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-search.js","sourceRoot":"","sources":["../../src/tui/model-search.ts"],"names":[],"mappings":"AAEA,sFAAsF;AACtF,MAAM,UAAU,kBAAkB,CACjC,OAA+B,EAC/B,KAAa;IAEb,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACvF,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,OAAO,CAAA;IACtC,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE;QAChC,MAAM,IAAI,GAAG,GAAG,MAAM,CAAC,EAAE,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAA;QAC3E,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAA;IAClD,CAAC,CAAC,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ModelSwitchResolution, ModelSwitchResolverOptions } from './model-switch.js';
|
|
2
|
+
/** Only standalone operator selection requests; prose about other work stays model input. */
|
|
3
|
+
export declare function parseModelSelectionIntent(text: string): {
|
|
4
|
+
query: string;
|
|
5
|
+
} | undefined;
|
|
6
|
+
/** Exact IDs first, then a unique complete suffix; never infer a model family or effort. */
|
|
7
|
+
export declare function resolveModelSelectionIntent(query: string, options: ModelSwitchResolverOptions): Promise<ModelSwitchResolution>;
|
|
8
|
+
//# sourceMappingURL=model-selection-intent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-selection-intent.d.ts","sourceRoot":"","sources":["../../src/tui/model-selection-intent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAA;AAoB1F,6FAA6F;AAC7F,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAQrF;AAQD,4FAA4F;AAC5F,wBAAsB,2BAA2B,CAChD,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,0BAA0B,GACjC,OAAO,CAAC,qBAAqB,CAAC,CAiFhC"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { canSelectModel } from '../integrations/providers/access.js';
|
|
2
|
+
const ID = '([a-zA-Z0-9][a-zA-Z0-9._:/-]{0,255})';
|
|
3
|
+
const patterns = [
|
|
4
|
+
/^([a-z0-9][a-z0-9._:/ -]{0,255}(?:['’](?:ya|ye|a|e))?)\s+(?:geç|gec|geçer misin|gecer misin|geçebilir misin|gecebilir misin)[.!?]?$/i,
|
|
5
|
+
new RegExp(`^/model\\s+${ID}$`, 'i'),
|
|
6
|
+
new RegExp(`^(?:please\\s+)?(?:switch|change|set)\\s+(?:the\\s+)?model\\s+to\\s+${ID}(?:\\s+please)?[.!?]?$`, 'i'),
|
|
7
|
+
new RegExp(`^(?:can|could)\\s+you\\s+(?:switch|change|set)\\s+(?:the\\s+)?model\\s+to\\s+${ID}(?:\\s+please)?[.!?]?$`, 'i'),
|
|
8
|
+
new RegExp(`^(?:lütfen\\s+)?modeli\\s+${ID}\\s+(?:yap|yapar mısın|yapar misin|yapabilir misin|olarak değiştir|olarak degistir)[.!?]?$`, 'i'),
|
|
9
|
+
];
|
|
10
|
+
/** Only standalone operator selection requests; prose about other work stays model input. */
|
|
11
|
+
export function parseModelSelectionIntent(text) {
|
|
12
|
+
const trimmed = text.trim();
|
|
13
|
+
if (trimmed.includes('\n'))
|
|
14
|
+
return undefined;
|
|
15
|
+
for (const pattern of patterns) {
|
|
16
|
+
const query = pattern.exec(trimmed)?.[1];
|
|
17
|
+
if (query)
|
|
18
|
+
return { query };
|
|
19
|
+
}
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
const normalized = (id) => id
|
|
23
|
+
.trim()
|
|
24
|
+
.toLowerCase()
|
|
25
|
+
.replace(/[_\s]+/g, '-');
|
|
26
|
+
/** Exact IDs first, then a unique complete suffix; never infer a model family or effort. */
|
|
27
|
+
export async function resolveModelSelectionIntent(query, options) {
|
|
28
|
+
const selectedProvider = options.detected.find(({ entry }) => query.toLowerCase().startsWith(`${entry.id}/`))?.entry.id;
|
|
29
|
+
const modelQuery = selectedProvider ? query.slice(selectedProvider.length + 1) : query;
|
|
30
|
+
const candidates = [];
|
|
31
|
+
let unavailable = false;
|
|
32
|
+
const seen = new Set();
|
|
33
|
+
await Promise.all(options.detected.map(async (detected) => {
|
|
34
|
+
if (!detected.entry.constructible ||
|
|
35
|
+
seen.has(detected.entry.id) ||
|
|
36
|
+
(selectedProvider && detected.entry.id !== selectedProvider))
|
|
37
|
+
return;
|
|
38
|
+
seen.add(detected.entry.id);
|
|
39
|
+
options.signal?.throwIfAborted();
|
|
40
|
+
try {
|
|
41
|
+
const listing = await options.describeModels(detected.entry.id, detected, options.signal);
|
|
42
|
+
if (listing.kind !== 'ok') {
|
|
43
|
+
unavailable = true;
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
for (const item of listing.models) {
|
|
47
|
+
if (canSelectModel(detected.entry, detected.apiKey, item.id))
|
|
48
|
+
candidates.push({ provider: detected.entry.id, model: item.id });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
options.signal?.throwIfAborted();
|
|
53
|
+
unavailable = true;
|
|
54
|
+
}
|
|
55
|
+
}));
|
|
56
|
+
options.signal?.throwIfAborted();
|
|
57
|
+
const needle = normalized(modelQuery);
|
|
58
|
+
let exact = candidates.filter((item) => normalized(item.model) === needle);
|
|
59
|
+
let matches = exact.length > 0
|
|
60
|
+
? exact
|
|
61
|
+
: candidates.filter((item) => /\d/.test(needle) && normalized(item.model).endsWith(`-${needle}`));
|
|
62
|
+
// Turkish dative endings are a fallback, never edits to an already listed ID.
|
|
63
|
+
if (matches.length === 0) {
|
|
64
|
+
const stems = new Set();
|
|
65
|
+
for (const ending of ['ya', 'ye', 'a', 'e']) {
|
|
66
|
+
if (needle.endsWith(ending))
|
|
67
|
+
stems.add(needle.slice(0, -ending.length).replace(/['’]$/, ''));
|
|
68
|
+
}
|
|
69
|
+
exact = candidates.filter((item) => stems.has(normalized(item.model)));
|
|
70
|
+
matches =
|
|
71
|
+
exact.length > 0
|
|
72
|
+
? exact
|
|
73
|
+
: candidates.filter((item) => [...stems].some((stem) => /\d/.test(stem) && normalized(item.model).endsWith(`-${stem}`)));
|
|
74
|
+
}
|
|
75
|
+
const currentExact = exact.filter((item) => item.provider === options.currentProvider);
|
|
76
|
+
if (currentExact.length === 1)
|
|
77
|
+
matches = currentExact;
|
|
78
|
+
const unique = [
|
|
79
|
+
...new Map(matches.map((item) => [`${item.provider}:${item.model}`, item])).values(),
|
|
80
|
+
];
|
|
81
|
+
if (unique.length === 1 && (!unavailable || exact.length > 0)) {
|
|
82
|
+
const match = unique[0];
|
|
83
|
+
if (match)
|
|
84
|
+
return { kind: 'resolved', selection: { id: match.provider, model: match.model } };
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
kind: 'rejected',
|
|
88
|
+
reason: unique.length > 1
|
|
89
|
+
? `Model "${query}" is ambiguous. Use /model to choose a provider and exact model.`
|
|
90
|
+
: unavailable
|
|
91
|
+
? `Could not verify all available model catalogues for "${query}". Use /model to choose explicitly.`
|
|
92
|
+
: `Model "${query}" was not found in authenticated model catalogues. Use /model to choose an available model.`,
|
|
93
|
+
...(unique.length > 0 ? { choices: unique.slice(0, 8) } : {}),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=model-selection-intent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-selection-intent.js","sourceRoot":"","sources":["../../src/tui/model-selection-intent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type ToolContext, type ToolDefinition } from '@namzu/sdk';
|
|
2
|
+
import type { ModelSwitchOutcome, ModelSwitchRequest } from './model-switch.js';
|
|
3
|
+
export type { ModelSwitchOutcome } from './model-switch.js';
|
|
4
|
+
export type RequestModelSwitch = (request: ModelSwitchRequest, context: ToolContext) => Promise<ModelSwitchOutcome>;
|
|
5
|
+
/** Mounted only when the main interactive session supplies this capability. */
|
|
6
|
+
export declare function buildSwitchModelTool(requestSwitch: RequestModelSwitch): ToolDefinition;
|
|
7
|
+
//# sourceMappingURL=model-switch-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-switch-tool.d.ts","sourceRoot":"","sources":["../../src/tui/model-switch-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,cAAc,EAAkC,MAAM,YAAY,CAAA;AAElG,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAE/E,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAE3D,MAAM,MAAM,kBAAkB,GAAG,CAChC,OAAO,EAAE,kBAAkB,EAC3B,OAAO,EAAE,WAAW,KAChB,OAAO,CAAC,kBAAkB,CAAC,CAAA;AAEhC,+EAA+E;AAC/E,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,kBAAkB,GAAG,cAAc,CAwEtF"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { defineTool, mcpJsonSchemaToZod } from '@namzu/sdk';
|
|
2
|
+
/** Mounted only when the main interactive session supplies this capability. */
|
|
3
|
+
export function buildSwitchModelTool(requestSwitch) {
|
|
4
|
+
return defineTool({
|
|
5
|
+
name: 'switch_model',
|
|
6
|
+
description: 'Change the current conversation model when the user requests it. Call this tool directly and alone, after any other work is finished; no tool search is needed. Supply the full model ID including its variant (for example gpt-5.6-luna, not just gpt-5.6), and optionally a provider ID. This tool checks available model catalogues and returns relevant choices on failure. Acceptance ends the turn automatically; the host applies the session-only change and confirms it. Do not repeat an accepted request or use this tool to change a delegated agent.',
|
|
7
|
+
inputSchema: mcpJsonSchemaToZod({
|
|
8
|
+
type: 'object',
|
|
9
|
+
properties: {
|
|
10
|
+
model: {
|
|
11
|
+
type: 'string',
|
|
12
|
+
minLength: 1,
|
|
13
|
+
maxLength: 256,
|
|
14
|
+
description: 'Exact model ID from a detected provider catalogue.',
|
|
15
|
+
},
|
|
16
|
+
provider: {
|
|
17
|
+
type: 'string',
|
|
18
|
+
minLength: 1,
|
|
19
|
+
maxLength: 128,
|
|
20
|
+
description: 'Optional exact provider ID. Omit to prefer the current provider when it lists this model.',
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
required: ['model'],
|
|
24
|
+
additionalProperties: false,
|
|
25
|
+
}),
|
|
26
|
+
category: 'custom',
|
|
27
|
+
permissions: [],
|
|
28
|
+
// This only requests a host-controlled session setting change after an
|
|
29
|
+
// explicit user request. It performs no workspace or external write.
|
|
30
|
+
readOnly: true,
|
|
31
|
+
destructive: false,
|
|
32
|
+
concurrencySafe: false,
|
|
33
|
+
terminal: true,
|
|
34
|
+
presentCall: (input) => ({
|
|
35
|
+
kind: 'generic',
|
|
36
|
+
label: `${input.provider ? `${input.provider}/` : ''}${input.model}`,
|
|
37
|
+
}),
|
|
38
|
+
presentResult: (_input, result) => result.success ? { kind: 'generic', label: result.output, visibility: 'hidden' } : undefined,
|
|
39
|
+
timeoutMs: 10_000,
|
|
40
|
+
async execute(input, context) {
|
|
41
|
+
context.abortSignal?.throwIfAborted();
|
|
42
|
+
let outcome;
|
|
43
|
+
try {
|
|
44
|
+
outcome = await requestSwitch(input, context);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
context.abortSignal?.throwIfAborted();
|
|
48
|
+
return {
|
|
49
|
+
success: false,
|
|
50
|
+
output: '',
|
|
51
|
+
error: 'Could not queue the model change. The active model has not changed.',
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
context.abortSignal?.throwIfAborted();
|
|
55
|
+
if (outcome.kind === 'rejected') {
|
|
56
|
+
const choices = outcome.choices
|
|
57
|
+
?.map((choice) => `${choice.provider}: ${choice.model}`)
|
|
58
|
+
.join('; ');
|
|
59
|
+
return {
|
|
60
|
+
success: false,
|
|
61
|
+
output: '',
|
|
62
|
+
error: `${outcome.reason}${choices ? ` Available choices: ${choices}.` : ''}`,
|
|
63
|
+
...(outcome.choices ? { data: { choices: outcome.choices } } : {}),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
success: true,
|
|
68
|
+
output: `Model change queued: ${outcome.selection.id}/${outcome.selection.model}. Pending host application for this session.`,
|
|
69
|
+
data: { status: 'pending', provider: outcome.selection.id, model: outcome.selection.model },
|
|
70
|
+
};
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=model-switch-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-switch-tool.js","sourceRoot":"","sources":["../../src/tui/model-switch-tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { DetectedProvider, ProviderChoice, ProviderId } from '../integrations/providers/index.js';
|
|
2
|
+
import type { ModelListing } from './agent.js';
|
|
3
|
+
export interface ModelSwitchRequest {
|
|
4
|
+
readonly model: string;
|
|
5
|
+
readonly provider?: string;
|
|
6
|
+
}
|
|
7
|
+
export type ModelSwitchSelection = ProviderChoice & {
|
|
8
|
+
readonly model: string;
|
|
9
|
+
};
|
|
10
|
+
export interface ModelSwitchRejection {
|
|
11
|
+
readonly kind: 'rejected';
|
|
12
|
+
readonly reason: string;
|
|
13
|
+
readonly choices?: readonly {
|
|
14
|
+
readonly provider: ProviderId;
|
|
15
|
+
readonly model: string;
|
|
16
|
+
}[];
|
|
17
|
+
}
|
|
18
|
+
export type ModelSwitchResolution = {
|
|
19
|
+
readonly kind: 'resolved';
|
|
20
|
+
readonly selection: ModelSwitchSelection;
|
|
21
|
+
} | ModelSwitchRejection;
|
|
22
|
+
/** Acceptance schedules a change; only the interactive host can commit it. */
|
|
23
|
+
export type ModelSwitchOutcome = {
|
|
24
|
+
readonly kind: 'pending';
|
|
25
|
+
readonly selection: ModelSwitchSelection;
|
|
26
|
+
} | ModelSwitchRejection;
|
|
27
|
+
export interface ModelSwitchResolverOptions {
|
|
28
|
+
readonly currentProvider: ProviderId;
|
|
29
|
+
readonly detected: readonly DetectedProvider[];
|
|
30
|
+
readonly describeModels: (id: ProviderId, detected: DetectedProvider, signal?: AbortSignal) => Promise<ModelListing>;
|
|
31
|
+
readonly signal?: AbortSignal;
|
|
32
|
+
}
|
|
33
|
+
/** Resolve exact catalogue IDs without inferring a provider from the model's name. */
|
|
34
|
+
export declare function resolveModelSwitch(request: ModelSwitchRequest, options: ModelSwitchResolverOptions): Promise<ModelSwitchResolution>;
|
|
35
|
+
//# sourceMappingURL=model-switch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-switch.d.ts","sourceRoot":"","sources":["../../src/tui/model-switch.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACX,gBAAgB,EAChB,cAAc,EACd,UAAU,EACV,MAAM,oCAAoC,CAAA;AAC3C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE9C,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED,MAAM,MAAM,oBAAoB,GAAG,cAAc,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAE9E,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS;QAAE,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CACvF;AAED,MAAM,MAAM,qBAAqB,GAC9B;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,oBAAoB,CAAA;CAAE,GACvE,oBAAoB,CAAA;AAEvB,8EAA8E;AAC9E,MAAM,MAAM,kBAAkB,GAC3B;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,oBAAoB,CAAA;CAAE,GACtE,oBAAoB,CAAA;AAEvB,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,CAAC,eAAe,EAAE,UAAU,CAAA;IACpC,QAAQ,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,CAAA;IAC9C,QAAQ,CAAC,cAAc,EAAE,CACxB,EAAE,EAAE,UAAU,EACd,QAAQ,EAAE,gBAAgB,EAC1B,MAAM,CAAC,EAAE,WAAW,KAChB,OAAO,CAAC,YAAY,CAAC,CAAA;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAC7B;AAED,sFAAsF;AACtF,wBAAsB,kBAAkB,CACvC,OAAO,EAAE,kBAAkB,EAC3B,OAAO,EAAE,0BAA0B,GACjC,OAAO,CAAC,qBAAqB,CAAC,CAqGhC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { canSelectModel } from '../integrations/providers/access.js';
|
|
2
|
+
/** Resolve exact catalogue IDs without inferring a provider from the model's name. */
|
|
3
|
+
export async function resolveModelSwitch(request, options) {
|
|
4
|
+
const { signal } = options;
|
|
5
|
+
signal?.throwIfAborted();
|
|
6
|
+
const model = request.model.trim();
|
|
7
|
+
const providerId = request.provider?.trim();
|
|
8
|
+
if (!model || model.length > 256 || (providerId !== undefined && !providerId)) {
|
|
9
|
+
return { kind: 'rejected', reason: 'Supply an exact model ID and, optionally, a provider ID.' };
|
|
10
|
+
}
|
|
11
|
+
const seen = new Set();
|
|
12
|
+
const usable = options.detected.filter((detected) => {
|
|
13
|
+
const { entry } = detected;
|
|
14
|
+
if (!entry.constructible || seen.has(entry.id))
|
|
15
|
+
return false;
|
|
16
|
+
seen.add(entry.id);
|
|
17
|
+
return true;
|
|
18
|
+
});
|
|
19
|
+
const selected = providerId ? usable.find(({ entry }) => entry.id === providerId) : undefined;
|
|
20
|
+
if (providerId && !selected) {
|
|
21
|
+
return {
|
|
22
|
+
kind: 'rejected',
|
|
23
|
+
reason: `Provider "${providerId}" is unavailable in this session. Available providers: ${usable.map(({ entry }) => entry.id).join(', ') || 'none'}.`,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
if (selected && !canSelectModel(selected.entry, selected.apiKey, model)) {
|
|
27
|
+
return {
|
|
28
|
+
kind: 'rejected',
|
|
29
|
+
reason: `Model "${model}" requires a credential for provider "${selected.entry.id}".`,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
const listed = new Map();
|
|
33
|
+
const inspect = async (detected) => {
|
|
34
|
+
signal?.throwIfAborted();
|
|
35
|
+
if (!canSelectModel(detected.entry, detected.apiKey, model))
|
|
36
|
+
return false;
|
|
37
|
+
let listing;
|
|
38
|
+
try {
|
|
39
|
+
listing = await options.describeModels(detected.entry.id, detected, signal);
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
signal?.throwIfAborted();
|
|
43
|
+
// Provider failures can contain credentials or private endpoint details.
|
|
44
|
+
listing = { kind: 'failed', reason: 'Model listing failed.' };
|
|
45
|
+
}
|
|
46
|
+
signal?.throwIfAborted();
|
|
47
|
+
listed.set(detected.entry.id, listing);
|
|
48
|
+
return listing.kind === 'ok' && listing.models.some((candidate) => candidate.id === model);
|
|
49
|
+
};
|
|
50
|
+
const resolve = (detected) => ({
|
|
51
|
+
kind: 'resolved',
|
|
52
|
+
selection: { id: detected.entry.id, model },
|
|
53
|
+
});
|
|
54
|
+
const first = selected ?? usable.find(({ entry }) => entry.id === options.currentProvider);
|
|
55
|
+
if (first && (await inspect(first)))
|
|
56
|
+
return resolve(first);
|
|
57
|
+
const candidates = selected ? [selected] : usable;
|
|
58
|
+
const matches = selected
|
|
59
|
+
? []
|
|
60
|
+
: (await Promise.all(candidates
|
|
61
|
+
.filter((candidate) => candidate !== first)
|
|
62
|
+
.map(async (candidate) => ((await inspect(candidate)) ? candidate : undefined)))).filter((candidate) => candidate !== undefined);
|
|
63
|
+
signal?.throwIfAborted();
|
|
64
|
+
const uniqueMatch = matches.length === 1 ? matches[0] : undefined;
|
|
65
|
+
if (uniqueMatch)
|
|
66
|
+
return resolve(uniqueMatch);
|
|
67
|
+
if (matches.length > 1) {
|
|
68
|
+
return {
|
|
69
|
+
kind: 'rejected',
|
|
70
|
+
reason: `Model "${model}" is available from multiple providers. Specify one: ${matches.map(({ entry }) => entry.id).join(', ')}.`,
|
|
71
|
+
choices: matches.map(({ entry }) => ({ provider: entry.id, model })),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
const choices = candidates.flatMap((candidate) => {
|
|
75
|
+
const listing = listed.get(candidate.entry.id);
|
|
76
|
+
return listing?.kind === 'ok'
|
|
77
|
+
? listing.models
|
|
78
|
+
.filter((item) => canSelectModel(candidate.entry, candidate.apiKey, item.id))
|
|
79
|
+
.map((item) => ({ provider: candidate.entry.id, model: item.id }))
|
|
80
|
+
: [];
|
|
81
|
+
});
|
|
82
|
+
const unverified = candidates
|
|
83
|
+
.filter((candidate) => {
|
|
84
|
+
const listing = listed.get(candidate.entry.id);
|
|
85
|
+
return listing && listing.kind !== 'ok';
|
|
86
|
+
})
|
|
87
|
+
.map(({ entry }) => entry.id);
|
|
88
|
+
// Suggest close catalogue IDs first, before bounding the receipt. A large
|
|
89
|
+
// unrelated provider catalogue must not crowd the requested family out.
|
|
90
|
+
// Ranking is recovery guidance only; partial IDs never select a model.
|
|
91
|
+
const terms = model.toLowerCase().match(/[a-z]+|\d+(?:\.\d+)*/g) ?? [];
|
|
92
|
+
const rankedChoices = choices
|
|
93
|
+
.map((choice) => {
|
|
94
|
+
const candidateTerms = new Set(choice.model.toLowerCase().match(/[a-z]+|\d+(?:\.\d+)*/g));
|
|
95
|
+
return { choice, score: terms.filter((term) => candidateTerms.has(term)).length };
|
|
96
|
+
})
|
|
97
|
+
.sort((a, b) => b.score - a.score)
|
|
98
|
+
.slice(0, 8)
|
|
99
|
+
.map(({ choice }) => choice);
|
|
100
|
+
return {
|
|
101
|
+
kind: 'rejected',
|
|
102
|
+
reason: `Model "${model}" was not found in the available model catalogues.${unverified.length > 0 ? ` Could not verify the catalogue for: ${unverified.join(', ')}.` : ''} Use an exact listed model ID.`,
|
|
103
|
+
...(rankedChoices.length > 0 ? { choices: rankedChoices } : {}),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=model-switch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-switch.js","sourceRoot":"","sources":["../../src/tui/model-switch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAA;AAyCpE,sFAAsF;AACtF,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACvC,OAA2B,EAC3B,OAAmC;IAEnC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAA;IAC1B,MAAM,EAAE,cAAc,EAAE,CAAA;IACxB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAA;IAClC,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAA;IAC3C,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,KAAK,SAAS,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/E,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,0DAA0D,EAAE,CAAA;IAChG,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAc,CAAA;IAClC,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE;QACnD,MAAM,EAAE,KAAK,EAAE,GAAG,QAAQ,CAAA;QAC1B,IAAI,CAAC,KAAK,CAAC,aAAa,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAAE,OAAO,KAAK,CAAA;QAC5D,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QAClB,OAAO,IAAI,CAAA;IACZ,CAAC,CAAC,CAAA;IACF,MAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAC7F,IAAI,UAAU,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC7B,OAAO;YACN,IAAI,EAAE,UAAU;YAChB,MAAM,EAAE,aAAa,UAAU,0DAA0D,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,GAAG;SACpJ,CAAA;IACF,CAAC;IACD,IAAI,QAAQ,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC;QACzE,OAAO;YACN,IAAI,EAAE,UAAU;YAChB,MAAM,EAAE,UAAU,KAAK,yCAAyC,QAAQ,CAAC,KAAK,CAAC,EAAE,IAAI;SACrF,CAAA;IACF,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,GAAG,EAA4B,CAAA;IAClD,MAAM,OAAO,GAAG,KAAK,EAAE,QAA0B,EAAoB,EAAE;QACtE,MAAM,EAAE,cAAc,EAAE,CAAA;QACxB,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;YAAE,OAAO,KAAK,CAAA;QACzE,IAAI,OAAqB,CAAA;QACzB,IAAI,CAAC;YACJ,OAAO,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAA;QAC5E,CAAC;QAAC,MAAM,CAAC;YACR,MAAM,EAAE,cAAc,EAAE,CAAA;YACxB,yEAAyE;YACzE,OAAO,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAA;QAC9D,CAAC;QACD,MAAM,EAAE,cAAc,EAAE,CAAA;QACxB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;QACtC,OAAO,OAAO,CAAC,IAAI,KAAK,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,KAAK,CAAC,CAAA;IAC3F,CAAC,CAAA;IACD,MAAM,OAAO,GAAG,CAAC,QAA0B,EAAyB,EAAE,CAAC,CAAC;QACvE,IAAI,EAAE,UAAU;QAChB,SAAS,EAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE;KAC3C,CAAC,CAAA;IACF,MAAM,KAAK,GAAG,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,OAAO,CAAC,eAAe,CAAC,CAAA;IAC1F,IAAI,KAAK,IAAI,CAAC,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC;QAAE,OAAO,OAAO,CAAC,KAAK,CAAC,CAAA;IAC1D,MAAM,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAA;IACjD,MAAM,OAAO,GAAG,QAAQ;QACvB,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,CACA,MAAM,OAAO,CAAC,GAAG,CAChB,UAAU;aACR,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,KAAK,KAAK,CAAC;aAC1C,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAChF,CACD,CAAC,MAAM,CAAC,CAAC,SAAS,EAAiC,EAAE,CAAC,SAAS,KAAK,SAAS,CAAC,CAAA;IACjF,MAAM,EAAE,cAAc,EAAE,CAAA;IACxB,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IACjE,IAAI,WAAW;QAAE,OAAO,OAAO,CAAC,WAAW,CAAC,CAAA;IAC5C,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO;YACN,IAAI,EAAE,UAAU;YAChB,MAAM,EAAE,UAAU,KAAK,wDAAwD,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;YACjI,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;SACpE,CAAA;IACF,CAAC;IACD,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE;QAChD,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QAC9C,OAAO,OAAO,EAAE,IAAI,KAAK,IAAI;YAC5B,CAAC,CAAC,OAAO,CAAC,MAAM;iBACb,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;iBAC5E,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;YACpE,CAAC,CAAC,EAAE,CAAA;IACN,CAAC,CAAC,CAAA;IACF,MAAM,UAAU,GAAG,UAAU;SAC3B,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE;QACrB,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QAC9C,OAAO,OAAO,IAAI,OAAO,CAAC,IAAI,KAAK,IAAI,CAAA;IACxC,CAAC,CAAC;SACD,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;IAC9B,0EAA0E;IAC1E,wEAAwE;IACxE,uEAAuE;IACvE,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,uBAAuB,CAAC,IAAI,EAAE,CAAA;IACtE,MAAM,aAAa,GAAG,OAAO;SAC3B,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QACf,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAA;QACzF,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAA;IAClF,CAAC,CAAC;SACD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;SACjC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,CAAA;IAC7B,OAAO;QACN,IAAI,EAAE,UAAU;QAChB,MAAM,EAAE,UAAU,KAAK,qDAAqD,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,wCAAwC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,gCAAgC;QACzM,GAAG,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC/D,CAAA;AACF,CAAC"}
|
|
@@ -30,6 +30,8 @@ export type PermissionReviewResult = {
|
|
|
30
30
|
readonly reason: 'too_large' | 'unrepresentable';
|
|
31
31
|
};
|
|
32
32
|
export interface PermissionReviewSummary {
|
|
33
|
+
/** Compact agent plan; full prepared arguments remain available in the exact view. */
|
|
34
|
+
readonly compactText?: string;
|
|
33
35
|
/** Complete, terminal-safe source for the readable pager. */
|
|
34
36
|
readonly text: string;
|
|
35
37
|
/** True only when the formatter knows every executable input field. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permission-review.d.ts","sourceRoot":"","sources":["../../src/tui/permission-review.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,OAAQ,CAAA;AAEhD,qEAAqE;AACrE,eAAO,MAAM,2BAA2B,IAAI,CAAA;AAE5C;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAGjF;AAED,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAA;CAC/B;AAED,MAAM,MAAM,sBAAsB,GAC/B;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACpE;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,iBAAiB,CAAA;CAAE,CAAA;AAE3E,MAAM,WAAW,uBAAuB;IACvC,6DAA6D;IAC7D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,uEAAuE;IACvE,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;CAC1B;AASD,6EAA6E;AAC7E,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,WAAW,GAAG,iBAAiB,GAAG,MAAM,CAIvF;AAED,uEAAuE;AACvE,MAAM,WAAW,mBAAmB;IACnC,wDAAwD;IACxD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,8DAA8D;IAC9D,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAA;CAC9B;AAKD;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACpC,KAAK,EAAE,SAAS,oBAAoB,EAAE,EACtC,QAAQ,SAA8B,GACpC,sBAAsB,CAqJxB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,uBAAuB,
|
|
1
|
+
{"version":3,"file":"permission-review.d.ts","sourceRoot":"","sources":["../../src/tui/permission-review.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,OAAQ,CAAA;AAEhD,qEAAqE;AACrE,eAAO,MAAM,2BAA2B,IAAI,CAAA;AAE5C;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAGjF;AAED,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAA;CAC/B;AAED,MAAM,MAAM,sBAAsB,GAC/B;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACpE;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,iBAAiB,CAAA;CAAE,CAAA;AAE3E,MAAM,WAAW,uBAAuB;IACvC,sFAAsF;IACtF,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,6DAA6D;IAC7D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,uEAAuE;IACvE,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;CAC1B;AASD,6EAA6E;AAC7E,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,WAAW,GAAG,iBAAiB,GAAG,MAAM,CAIvF;AAED,uEAAuE;AACvE,MAAM,WAAW,mBAAmB;IACnC,wDAAwD;IACxD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,8DAA8D;IAC9D,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAA;CAC9B;AAKD;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACpC,KAAK,EAAE,SAAS,oBAAoB,EAAE,EACtC,QAAQ,SAA8B,GACpC,sBAAsB,CAqJxB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,uBAAuB,CA+E9E;AAgVD;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CACnC,MAAM,EAAE,MAAM,EACd,eAAe,EAAE,MAAM,GAAG,SAAS,GACjC,SAAS,mBAAmB,EAAE,CA6BhC"}
|
|
@@ -224,22 +224,34 @@ export function buildPermissionSummary(review) {
|
|
|
224
224
|
}
|
|
225
225
|
const readable = summarizeKnownCall(call.name, call.input);
|
|
226
226
|
complete &&= readable.complete;
|
|
227
|
-
calls.push({
|
|
227
|
+
calls.push({
|
|
228
|
+
name: call.name,
|
|
229
|
+
isDestructive: call.isDestructive,
|
|
230
|
+
readable,
|
|
231
|
+
input: call.input,
|
|
232
|
+
});
|
|
228
233
|
}
|
|
234
|
+
const compactText = complete &&
|
|
235
|
+
calls.length > 0 &&
|
|
236
|
+
calls.every((call) => call.name === 'Agent' && call.readable.label !== undefined)
|
|
237
|
+
? compactAgentPlan(calls)
|
|
238
|
+
: undefined;
|
|
229
239
|
if (complete &&
|
|
230
240
|
calls.length > 1 &&
|
|
231
241
|
calls.every((call) => call.name === 'Agent' && call.readable.label !== undefined)) {
|
|
232
|
-
const overview = calls.map((call, index) => `${index + 1}. ${call.readable.label}`);
|
|
242
|
+
const overview = calls.map((call, index) => `${index + 1}. ${call.readable.label}${call.isDestructive ? ' · destructive' : ''}`);
|
|
233
243
|
const details = calls.map((call, index) => [
|
|
234
|
-
`${index + 1}. ${call.readable.label}`,
|
|
244
|
+
`${index + 1}. ${call.readable.label}${call.isDestructive ? ' · destructive' : ''}`,
|
|
235
245
|
...call.readable.lines.map((line) => ` ${line}`),
|
|
236
246
|
].join('\n'));
|
|
237
247
|
return {
|
|
238
248
|
text: [...overview, '', 'Task details', '', ...details].join('\n'),
|
|
249
|
+
...(compactText !== undefined ? { compactText } : {}),
|
|
239
250
|
complete: true,
|
|
240
251
|
};
|
|
241
252
|
}
|
|
242
253
|
return {
|
|
254
|
+
...(compactText !== undefined ? { compactText } : {}),
|
|
243
255
|
text: calls
|
|
244
256
|
.map((call, index) => [
|
|
245
257
|
`${index + 1}. ${call.name}${call.isDestructive ? ' · destructive' : ''}`,
|
|
@@ -289,11 +301,14 @@ function summarizeKnownCall(name, input) {
|
|
|
289
301
|
// exact view has to show, not one this summary may pick a half of.
|
|
290
302
|
(input.content === undefined) !== (input.newStr === undefined);
|
|
291
303
|
if (shapeIsKnown) {
|
|
292
|
-
const lines = body.split('\n');
|
|
304
|
+
const lines = body === '' ? [] : body.split('\n');
|
|
305
|
+
if (lines.at(-1) === '')
|
|
306
|
+
lines.pop();
|
|
293
307
|
return {
|
|
294
308
|
lines: [
|
|
295
309
|
`${input.path} · write ${lines.length} line${lines.length === 1 ? '' : 's'}`,
|
|
296
|
-
|
|
310
|
+
'Full replacement body · may overwrite an existing file',
|
|
311
|
+
...lines.map((line) => ` ${line}`),
|
|
297
312
|
],
|
|
298
313
|
complete: true,
|
|
299
314
|
};
|
|
@@ -304,16 +319,22 @@ function summarizeKnownCall(name, input) {
|
|
|
304
319
|
'description',
|
|
305
320
|
'prompt',
|
|
306
321
|
'subagent_type',
|
|
322
|
+
'model',
|
|
323
|
+
'provider',
|
|
324
|
+
'effort',
|
|
307
325
|
'role',
|
|
308
326
|
'workflow',
|
|
309
327
|
'phase',
|
|
310
328
|
'phase_order',
|
|
329
|
+
'run_in_background',
|
|
311
330
|
]);
|
|
312
331
|
const keys = Object.keys(input);
|
|
313
332
|
const shapeIsKnown = keys.every((key) => allowed.has(key)) &&
|
|
314
333
|
typeof input.description === 'string' &&
|
|
315
334
|
typeof input.prompt === 'string' &&
|
|
335
|
+
(input.run_in_background === undefined || typeof input.run_in_background === 'boolean') &&
|
|
316
336
|
(input.subagent_type === undefined || typeof input.subagent_type === 'string') &&
|
|
337
|
+
['model', 'provider', 'effort'].every((key) => input[key] === undefined || typeof input[key] === 'string') &&
|
|
317
338
|
(input.role === undefined || typeof input.role === 'string') &&
|
|
318
339
|
(input.workflow === undefined || typeof input.workflow === 'string') &&
|
|
319
340
|
(input.phase === undefined || typeof input.phase === 'string') &&
|
|
@@ -324,21 +345,28 @@ function summarizeKnownCall(name, input) {
|
|
|
324
345
|
return {
|
|
325
346
|
lines: [
|
|
326
347
|
...readableField('Task', known.description),
|
|
327
|
-
...(known.subagent_type
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
348
|
+
...readableField('Agent', agentTypeLabel(known.subagent_type)),
|
|
349
|
+
...(known.model !== undefined ? readableField('Model', known.model) : []),
|
|
350
|
+
...(known.provider !== undefined ? readableField('Provider', known.provider) : []),
|
|
351
|
+
...(known.effort !== undefined ? readableField('Effort', known.effort) : []),
|
|
352
|
+
...(known.run_in_background !== undefined
|
|
353
|
+
? [`Execution: ${known.run_in_background ? 'background' : 'wait for result'}`]
|
|
331
354
|
: []),
|
|
332
|
-
...
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
355
|
+
...(known.subagent_type === 'explore'
|
|
356
|
+
? ['Tools: reading and searching only']
|
|
357
|
+
: known.subagent_type === undefined || known.subagent_type === 'general-purpose'
|
|
358
|
+
? ['Tools: files and commands, subject to approval rules']
|
|
359
|
+
: []),
|
|
360
|
+
...(known.role !== undefined ? readableField('Role', known.role) : []),
|
|
361
|
+
...(known.workflow !== undefined ? readableField('Workflow label', known.workflow) : []),
|
|
362
|
+
...(known.phase !== undefined ? readableField('Phase label', known.phase) : []),
|
|
336
363
|
...(known.phase_order !== undefined
|
|
337
|
-
? [`Phase order: ${String(known.phase_order + 1)}`]
|
|
364
|
+
? [`Phase display order: ${String(known.phase_order + 1)}`]
|
|
338
365
|
: []),
|
|
366
|
+
...readableField('Instructions', known.prompt),
|
|
339
367
|
],
|
|
340
368
|
complete: true,
|
|
341
|
-
label: oneLine(known.description)
|
|
369
|
+
label: `${oneLine(known.description)} · ${oneLine(agentTypeLabel(known.subagent_type))}`,
|
|
342
370
|
};
|
|
343
371
|
}
|
|
344
372
|
}
|
|
@@ -369,6 +397,45 @@ function summarizeKnownCall(name, input) {
|
|
|
369
397
|
const PLAIN_TOOL_NAME = /^[\w.:-]+$/u;
|
|
370
398
|
/** The tools with a formatter above; an evolved shape of one opens exact-first. */
|
|
371
399
|
const FORMATTED_TOOLS = new Set(['bash', 'edit', 'write', 'Agent']);
|
|
400
|
+
/** Labels group only the calls in this approval; they never invent execution phases. */
|
|
401
|
+
function compactAgentPlan(calls) {
|
|
402
|
+
const lines = [];
|
|
403
|
+
let previousGroup = '';
|
|
404
|
+
for (const [index, call] of calls.entries()) {
|
|
405
|
+
const input = call.input;
|
|
406
|
+
const workflow = typeof input.workflow === 'string' ? oneLine(input.workflow) : '';
|
|
407
|
+
const phase = typeof input.phase === 'string' ? oneLine(input.phase) : '';
|
|
408
|
+
const group = JSON.stringify([workflow, phase]);
|
|
409
|
+
if (group !== previousGroup) {
|
|
410
|
+
if (workflow || phase)
|
|
411
|
+
lines.push([workflow, phase].filter(Boolean).join(' / '));
|
|
412
|
+
else if (previousGroup)
|
|
413
|
+
lines.push('Other agents');
|
|
414
|
+
previousGroup = group;
|
|
415
|
+
}
|
|
416
|
+
const type = input.subagent_type;
|
|
417
|
+
const access = type === 'explore'
|
|
418
|
+
? 'read-only'
|
|
419
|
+
: type === undefined || type === 'general-purpose'
|
|
420
|
+
? 'files + commands'
|
|
421
|
+
: String(type);
|
|
422
|
+
const background = input.run_in_background === true ? ' · background' : '';
|
|
423
|
+
const selection = [input.provider, input.model, input.effort]
|
|
424
|
+
.filter((value) => typeof value === 'string')
|
|
425
|
+
.map((value) => oneLine(String(value)))
|
|
426
|
+
.join(' / ');
|
|
427
|
+
const modelLabel = selection ? ` · ${selection}` : '';
|
|
428
|
+
lines.push(`${index === calls.length - 1 ? '└' : '├'}─ [ ${index + 1}. ${oneLine(String(input.description))} · ${access}${modelLabel}${background}${call.isDestructive ? ' · destructive' : ''} ]`);
|
|
429
|
+
}
|
|
430
|
+
return terminalDisplayText(lines.join('\n'));
|
|
431
|
+
}
|
|
432
|
+
function agentTypeLabel(type) {
|
|
433
|
+
if (type === undefined)
|
|
434
|
+
return 'general-purpose (default)';
|
|
435
|
+
if (type === 'explore')
|
|
436
|
+
return 'explore (read-only tools)';
|
|
437
|
+
return type;
|
|
438
|
+
}
|
|
372
439
|
function oneLine(value) {
|
|
373
440
|
return value.replace(/\s+/gu, ' ').trim() || '(untitled task)';
|
|
374
441
|
}
|