@tyvm/knowhow 0.0.145 → 0.0.147
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/autodoc/cli-reference.md +36 -7
- package/bin/knowhow.js +8 -6
- package/package.json +1 -1
- package/src/agents/base/base.ts +24 -0
- package/src/agents/historyRollback.ts +36 -0
- package/src/agents/tools/startAgentTask.ts +41 -9
- package/src/auth/browserLogin.ts +9 -3
- package/src/auth/keyAuth.ts +115 -0
- package/src/auth/keyManager.ts +166 -0
- package/src/chat/CliChatService.ts +16 -0
- package/src/chat/modules/AgentModule.ts +144 -56
- package/src/chat/modules/AskModule.ts +2 -0
- package/src/chat/modules/BaseChatModule.ts +0 -1
- package/src/chat/modules/CustomCommandsModule.ts +2 -0
- package/src/chat/modules/InternalChatModule.ts +2 -0
- package/src/chat/modules/RemoteSyncModule.ts +4 -0
- package/src/chat/modules/RendererModule.ts +2 -0
- package/src/chat/modules/SearchModule.ts +2 -0
- package/src/chat/modules/SessionsModule.ts +110 -39
- package/src/chat/modules/SetupModule.ts +2 -0
- package/src/chat/modules/ShellCommandModule.ts +2 -0
- package/src/chat/modules/SystemModule.ts +2 -0
- package/src/chat/types.ts +5 -2
- package/src/cli.ts +1 -1
- package/src/clients/anthropic.ts +24 -0
- package/src/clients/fireworks.ts +3 -0
- package/src/clients/gemini.ts +8 -0
- package/src/clients/index.ts +2 -0
- package/src/clients/openai.ts +7 -4
- package/src/clients/types.ts +30 -7
- package/src/clients/xai.ts +23 -4
- package/src/commands/agent.ts +11 -39
- package/src/commands/agents.ts +403 -53
- package/src/commands/misc.ts +3 -2
- package/src/commands/services.ts +49 -3
- package/src/login.ts +89 -28
- package/src/plugins/plugins.ts +16 -0
- package/src/processors/TokenCompressor.ts +40 -8
- package/src/processors/ToolResponseCache.ts +17 -8
- package/src/processors/tools/boundedToolResponse.ts +49 -0
- package/src/processors/tools/grepToolResponse.ts +164 -38
- package/src/processors/tools/index.ts +2 -0
- package/src/processors/tools/jqToolResponse.ts +40 -10
- package/src/processors/tools/listStoredToolResponses.ts +51 -10
- package/src/processors/tools/tailToolResponse.ts +85 -17
- package/src/services/AgentService.ts +2 -0
- package/src/services/AgentSyncFs.ts +65 -0
- package/src/services/AgentSyncKnowhowWeb.ts +22 -4
- package/src/services/BehaviorsService.ts +2 -0
- package/src/services/DockerService.ts +2 -0
- package/src/services/EmbeddingService.ts +2 -0
- package/src/services/EmbeddingsService.ts +3 -0
- package/src/services/KnowhowClient.ts +68 -7
- package/src/services/LazyToolsService.ts +16 -0
- package/src/services/Mcp.ts +11 -2
- package/src/services/McpServer.ts +2 -0
- package/src/services/MessageProcessor.ts +2 -0
- package/src/services/MinimalToolsService.ts +2 -0
- package/src/services/RuntimeReloadService.ts +31 -0
- package/src/services/SessionManager.ts +5 -0
- package/src/services/SkillsService.ts +2 -0
- package/src/services/SyncedAgentWatcher.ts +2 -0
- package/src/services/SyncerService.ts +23 -8
- package/src/services/TaskRegistry.ts +2 -0
- package/src/services/Tools.ts +13 -0
- package/src/services/TracingService.ts +116 -0
- package/src/services/index.ts +10 -0
- package/src/services/modules/index.ts +49 -3
- package/src/services/modules/types.ts +8 -0
- package/src/types.ts +2 -0
- package/src/util/Trace.ts +236 -0
- package/src/utils/http.ts +18 -2
- package/tests/clients/fireworks.test.ts +65 -0
- package/tests/clients/reasoningEffort.test.ts +79 -0
- package/tests/compressor/toolResponseCache.test.ts +2 -1
- package/tests/manual/clients/completions.test.ts +27 -10
- package/tests/processors/TokenCompressor.test.ts +17 -3
- package/tests/processors/tools/boundedRetrievalTools.test.ts +68 -0
- package/tests/processors/tools/grepToolResponse.test.ts +88 -1
- package/tests/unit/agents/historyRollback.test.ts +53 -0
- package/tests/unit/auth/keyAuth.test.ts +102 -0
- package/tests/unit/auth/keyManager.test.ts +67 -0
- package/tests/unit/chat/historyCommandArgs.test.ts +37 -0
- package/tests/unit/commands/agents.test.ts +68 -0
- package/tests/unit/login.test.ts +119 -0
- package/tests/unit/plugins/pluginLoading.test.ts +31 -0
- package/tests/unit/services/AgentSyncKnowhowWeb.test.ts +38 -0
- package/tests/unit/services/LazyToolsService.test.ts +29 -0
- package/tests/unit/services/RuntimeReloadService.test.ts +29 -0
- package/tests/unit/services/SessionManager.test.ts +43 -0
- package/tests/unit/services/SyncerService.test.ts +45 -0
- package/tests/unit/util/Trace.test.ts +119 -0
- package/tests/unit/utils/http.test.ts +43 -0
- package/ts_build/package.json +1 -1
- package/ts_build/src/agents/base/base.d.ts +1 -0
- package/ts_build/src/agents/base/base.js +31 -2
- package/ts_build/src/agents/base/base.js.map +1 -1
- package/ts_build/src/agents/historyRollback.d.ts +2 -0
- package/ts_build/src/agents/historyRollback.js +22 -0
- package/ts_build/src/agents/historyRollback.js.map +1 -0
- package/ts_build/src/agents/tools/startAgentTask.d.ts +2 -0
- package/ts_build/src/agents/tools/startAgentTask.js +36 -9
- package/ts_build/src/agents/tools/startAgentTask.js.map +1 -1
- package/ts_build/src/auth/browserLogin.d.ts +1 -0
- package/ts_build/src/auth/browserLogin.js +5 -2
- package/ts_build/src/auth/browserLogin.js.map +1 -1
- package/ts_build/src/auth/keyAuth.d.ts +5 -0
- package/ts_build/src/auth/keyAuth.js +79 -0
- package/ts_build/src/auth/keyAuth.js.map +1 -0
- package/ts_build/src/auth/keyManager.d.ts +14 -0
- package/ts_build/src/auth/keyManager.js +145 -0
- package/ts_build/src/auth/keyManager.js.map +1 -0
- package/ts_build/src/chat/CliChatService.js +15 -0
- package/ts_build/src/chat/CliChatService.js.map +1 -1
- package/ts_build/src/chat/modules/AgentModule.d.ts +13 -1
- package/ts_build/src/chat/modules/AgentModule.js +96 -43
- package/ts_build/src/chat/modules/AgentModule.js.map +1 -1
- package/ts_build/src/chat/modules/AskModule.js +12 -2
- package/ts_build/src/chat/modules/AskModule.js.map +1 -1
- package/ts_build/src/chat/modules/BaseChatModule.js.map +1 -1
- package/ts_build/src/chat/modules/CustomCommandsModule.js +12 -2
- package/ts_build/src/chat/modules/CustomCommandsModule.js.map +1 -1
- package/ts_build/src/chat/modules/InternalChatModule.js +16 -2
- package/ts_build/src/chat/modules/InternalChatModule.js.map +1 -1
- package/ts_build/src/chat/modules/RemoteSyncModule.js +19 -2
- package/ts_build/src/chat/modules/RemoteSyncModule.js.map +1 -1
- package/ts_build/src/chat/modules/RendererModule.js +17 -2
- package/ts_build/src/chat/modules/RendererModule.js.map +1 -1
- package/ts_build/src/chat/modules/SearchModule.js +12 -2
- package/ts_build/src/chat/modules/SearchModule.js.map +1 -1
- package/ts_build/src/chat/modules/SessionsModule.d.ts +6 -0
- package/ts_build/src/chat/modules/SessionsModule.js +114 -24
- package/ts_build/src/chat/modules/SessionsModule.js.map +1 -1
- package/ts_build/src/chat/modules/SetupModule.js +17 -2
- package/ts_build/src/chat/modules/SetupModule.js.map +1 -1
- package/ts_build/src/chat/modules/ShellCommandModule.js +12 -2
- package/ts_build/src/chat/modules/ShellCommandModule.js.map +1 -1
- package/ts_build/src/chat/modules/SystemModule.js +12 -2
- package/ts_build/src/chat/modules/SystemModule.js.map +1 -1
- package/ts_build/src/chat/types.d.ts +5 -2
- package/ts_build/src/cli.js +1 -1
- package/ts_build/src/cli.js.map +1 -1
- package/ts_build/src/clients/anthropic.d.ts +1 -0
- package/ts_build/src/clients/anthropic.js +12 -0
- package/ts_build/src/clients/anthropic.js.map +1 -1
- package/ts_build/src/clients/fireworks.js +1 -0
- package/ts_build/src/clients/fireworks.js.map +1 -1
- package/ts_build/src/clients/gemini.js +8 -0
- package/ts_build/src/clients/gemini.js.map +1 -1
- package/ts_build/src/clients/index.js +19 -4
- package/ts_build/src/clients/index.js.map +1 -1
- package/ts_build/src/clients/openai.js +4 -2
- package/ts_build/src/clients/openai.js.map +1 -1
- package/ts_build/src/clients/types.d.ts +4 -1
- package/ts_build/src/clients/types.js +14 -0
- package/ts_build/src/clients/types.js.map +1 -1
- package/ts_build/src/clients/xai.d.ts +1 -0
- package/ts_build/src/clients/xai.js +23 -4
- package/ts_build/src/clients/xai.js.map +1 -1
- package/ts_build/src/commands/agent.js +7 -22
- package/ts_build/src/commands/agent.js.map +1 -1
- package/ts_build/src/commands/agents.d.ts +1 -1
- package/ts_build/src/commands/agents.js +174 -16
- package/ts_build/src/commands/agents.js.map +1 -1
- package/ts_build/src/commands/misc.js +3 -2
- package/ts_build/src/commands/misc.js.map +1 -1
- package/ts_build/src/commands/services.d.ts +2 -0
- package/ts_build/src/commands/services.js +45 -3
- package/ts_build/src/commands/services.js.map +1 -1
- package/ts_build/src/login.d.ts +1 -1
- package/ts_build/src/login.js +53 -15
- package/ts_build/src/login.js.map +1 -1
- package/ts_build/src/plugins/plugins.d.ts +1 -0
- package/ts_build/src/plugins/plugins.js +14 -0
- package/ts_build/src/plugins/plugins.js.map +1 -1
- package/ts_build/src/processors/TokenCompressor.js +15 -6
- package/ts_build/src/processors/TokenCompressor.js.map +1 -1
- package/ts_build/src/processors/ToolResponseCache.d.ts +3 -3
- package/ts_build/src/processors/ToolResponseCache.js +8 -8
- package/ts_build/src/processors/ToolResponseCache.js.map +1 -1
- package/ts_build/src/processors/tools/boundedToolResponse.d.ts +7 -0
- package/ts_build/src/processors/tools/boundedToolResponse.js +27 -0
- package/ts_build/src/processors/tools/boundedToolResponse.js.map +1 -0
- package/ts_build/src/processors/tools/grepToolResponse.d.ts +4 -0
- package/ts_build/src/processors/tools/grepToolResponse.js +101 -25
- package/ts_build/src/processors/tools/grepToolResponse.js.map +1 -1
- package/ts_build/src/processors/tools/index.d.ts +2 -2
- package/ts_build/src/processors/tools/index.js.map +1 -1
- package/ts_build/src/processors/tools/jqToolResponse.d.ts +5 -1
- package/ts_build/src/processors/tools/jqToolResponse.js +26 -9
- package/ts_build/src/processors/tools/jqToolResponse.js.map +1 -1
- package/ts_build/src/processors/tools/listStoredToolResponses.d.ts +7 -1
- package/ts_build/src/processors/tools/listStoredToolResponses.js +39 -9
- package/ts_build/src/processors/tools/listStoredToolResponses.js.map +1 -1
- package/ts_build/src/processors/tools/tailToolResponse.d.ts +5 -0
- package/ts_build/src/processors/tools/tailToolResponse.js +56 -13
- package/ts_build/src/processors/tools/tailToolResponse.js.map +1 -1
- package/ts_build/src/services/AgentService.js +18 -2
- package/ts_build/src/services/AgentService.js.map +1 -1
- package/ts_build/src/services/AgentSyncFs.d.ts +3 -0
- package/ts_build/src/services/AgentSyncFs.js +62 -15
- package/ts_build/src/services/AgentSyncFs.js.map +1 -1
- package/ts_build/src/services/AgentSyncKnowhowWeb.d.ts +2 -0
- package/ts_build/src/services/AgentSyncKnowhowWeb.js +28 -6
- package/ts_build/src/services/AgentSyncKnowhowWeb.js.map +1 -1
- package/ts_build/src/services/BehaviorsService.js +12 -2
- package/ts_build/src/services/BehaviorsService.js.map +1 -1
- package/ts_build/src/services/DockerService.js +20 -8
- package/ts_build/src/services/DockerService.js.map +1 -1
- package/ts_build/src/services/EmbeddingService.js +16 -2
- package/ts_build/src/services/EmbeddingService.js.map +1 -1
- package/ts_build/src/services/EmbeddingsService.js +12 -2
- package/ts_build/src/services/EmbeddingsService.js.map +1 -1
- package/ts_build/src/services/KnowhowClient.d.ts +7 -2
- package/ts_build/src/services/KnowhowClient.js +108 -10
- package/ts_build/src/services/KnowhowClient.js.map +1 -1
- package/ts_build/src/services/LazyToolsService.d.ts +2 -0
- package/ts_build/src/services/LazyToolsService.js +26 -2
- package/ts_build/src/services/LazyToolsService.js.map +1 -1
- package/ts_build/src/services/Mcp.js +20 -4
- package/ts_build/src/services/Mcp.js.map +1 -1
- package/ts_build/src/services/McpServer.js +17 -2
- package/ts_build/src/services/McpServer.js.map +1 -1
- package/ts_build/src/services/MessageProcessor.js +16 -2
- package/ts_build/src/services/MessageProcessor.js.map +1 -1
- package/ts_build/src/services/MinimalToolsService.js +16 -2
- package/ts_build/src/services/MinimalToolsService.js.map +1 -1
- package/ts_build/src/services/RuntimeReloadService.d.ts +12 -0
- package/ts_build/src/services/RuntimeReloadService.js +26 -0
- package/ts_build/src/services/RuntimeReloadService.js.map +1 -0
- package/ts_build/src/services/SessionManager.js +19 -2
- package/ts_build/src/services/SessionManager.js.map +1 -1
- package/ts_build/src/services/SkillsService.js +16 -2
- package/ts_build/src/services/SkillsService.js.map +1 -1
- package/ts_build/src/services/SyncedAgentWatcher.js +16 -2
- package/ts_build/src/services/SyncedAgentWatcher.js.map +1 -1
- package/ts_build/src/services/SyncerService.d.ts +1 -0
- package/ts_build/src/services/SyncerService.js +27 -5
- package/ts_build/src/services/SyncerService.js.map +1 -1
- package/ts_build/src/services/TaskRegistry.js +12 -2
- package/ts_build/src/services/TaskRegistry.js.map +1 -1
- package/ts_build/src/services/Tools.d.ts +1 -0
- package/ts_build/src/services/Tools.js +21 -2
- package/ts_build/src/services/Tools.js.map +1 -1
- package/ts_build/src/services/TracingService.d.ts +16 -0
- package/ts_build/src/services/TracingService.js +35 -0
- package/ts_build/src/services/TracingService.js.map +1 -0
- package/ts_build/src/services/index.d.ts +8 -0
- package/ts_build/src/services/index.js +9 -1
- package/ts_build/src/services/index.js.map +1 -1
- package/ts_build/src/services/modules/index.d.ts +6 -0
- package/ts_build/src/services/modules/index.js +29 -3
- package/ts_build/src/services/modules/index.js.map +1 -1
- package/ts_build/src/services/modules/types.d.ts +3 -0
- package/ts_build/src/types.d.ts +1 -0
- package/ts_build/src/types.js.map +1 -1
- package/ts_build/src/util/Trace.d.ts +11 -0
- package/ts_build/src/util/Trace.js +107 -0
- package/ts_build/src/util/Trace.js.map +1 -0
- package/ts_build/src/utils/http.d.ts +6 -2
- package/ts_build/src/utils/http.js +8 -2
- package/ts_build/src/utils/http.js.map +1 -1
- package/ts_build/tests/clients/fireworks.test.d.ts +1 -0
- package/ts_build/tests/clients/fireworks.test.js +65 -0
- package/ts_build/tests/clients/fireworks.test.js.map +1 -0
- package/ts_build/tests/clients/reasoningEffort.test.d.ts +1 -0
- package/ts_build/tests/clients/reasoningEffort.test.js +68 -0
- package/ts_build/tests/clients/reasoningEffort.test.js.map +1 -0
- package/ts_build/tests/compressor/toolResponseCache.test.js +1 -1
- package/ts_build/tests/compressor/toolResponseCache.test.js.map +1 -1
- package/ts_build/tests/manual/clients/completions.test.js +19 -6
- package/ts_build/tests/manual/clients/completions.test.js.map +1 -1
- package/ts_build/tests/processors/TokenCompressor.test.js +11 -2
- package/ts_build/tests/processors/TokenCompressor.test.js.map +1 -1
- package/ts_build/tests/processors/tools/boundedRetrievalTools.test.d.ts +1 -0
- package/ts_build/tests/processors/tools/boundedRetrievalTools.test.js +57 -0
- package/ts_build/tests/processors/tools/boundedRetrievalTools.test.js.map +1 -0
- package/ts_build/tests/processors/tools/grepToolResponse.test.js +37 -0
- package/ts_build/tests/processors/tools/grepToolResponse.test.js.map +1 -1
- package/ts_build/tests/unit/agents/historyRollback.test.d.ts +1 -0
- package/ts_build/tests/unit/agents/historyRollback.test.js +42 -0
- package/ts_build/tests/unit/agents/historyRollback.test.js.map +1 -0
- package/ts_build/tests/unit/auth/keyAuth.test.d.ts +1 -0
- package/ts_build/tests/unit/auth/keyAuth.test.js +77 -0
- package/ts_build/tests/unit/auth/keyAuth.test.js.map +1 -0
- package/ts_build/tests/unit/auth/keyManager.test.d.ts +1 -0
- package/ts_build/tests/unit/auth/keyManager.test.js +52 -0
- package/ts_build/tests/unit/auth/keyManager.test.js.map +1 -0
- package/ts_build/tests/unit/chat/historyCommandArgs.test.d.ts +1 -0
- package/ts_build/tests/unit/chat/historyCommandArgs.test.js +29 -0
- package/ts_build/tests/unit/chat/historyCommandArgs.test.js.map +1 -0
- package/ts_build/tests/unit/commands/agents.test.d.ts +1 -0
- package/ts_build/tests/unit/commands/agents.test.js +91 -0
- package/ts_build/tests/unit/commands/agents.test.js.map +1 -0
- package/ts_build/tests/unit/login.test.d.ts +1 -0
- package/ts_build/tests/unit/login.test.js +97 -0
- package/ts_build/tests/unit/login.test.js.map +1 -0
- package/ts_build/tests/unit/plugins/pluginLoading.test.js +59 -0
- package/ts_build/tests/unit/plugins/pluginLoading.test.js.map +1 -1
- package/ts_build/tests/unit/services/AgentSyncKnowhowWeb.test.d.ts +1 -0
- package/ts_build/tests/unit/services/AgentSyncKnowhowWeb.test.js +32 -0
- package/ts_build/tests/unit/services/AgentSyncKnowhowWeb.test.js.map +1 -0
- package/ts_build/tests/unit/services/LazyToolsService.test.d.ts +1 -0
- package/ts_build/tests/unit/services/LazyToolsService.test.js +27 -0
- package/ts_build/tests/unit/services/LazyToolsService.test.js.map +1 -0
- package/ts_build/tests/unit/services/RuntimeReloadService.test.d.ts +1 -0
- package/ts_build/tests/unit/services/RuntimeReloadService.test.js +26 -0
- package/ts_build/tests/unit/services/RuntimeReloadService.test.js.map +1 -0
- package/ts_build/tests/unit/services/SessionManager.test.d.ts +1 -0
- package/ts_build/tests/unit/services/SessionManager.test.js +72 -0
- package/ts_build/tests/unit/services/SessionManager.test.js.map +1 -0
- package/ts_build/tests/unit/services/SyncerService.test.d.ts +1 -0
- package/ts_build/tests/unit/services/SyncerService.test.js +40 -0
- package/ts_build/tests/unit/services/SyncerService.test.js.map +1 -0
- package/ts_build/tests/unit/util/Trace.test.d.ts +1 -0
- package/ts_build/tests/unit/util/Trace.test.js +107 -0
- package/ts_build/tests/unit/util/Trace.test.js.map +1 -0
- package/ts_build/tests/unit/utils/http.test.d.ts +1 -0
- package/ts_build/tests/unit/utils/http.test.js +69 -0
- package/ts_build/tests/unit/utils/http.test.js.map +1 -0
|
@@ -5,11 +5,13 @@
|
|
|
5
5
|
* Command semantics:
|
|
6
6
|
* /attach <taskId> - Attach to a RUNNING session (in-memory, filesystem, or web).
|
|
7
7
|
* If the task is completed, the user is told to use /resume instead.
|
|
8
|
-
* /resume <taskId>
|
|
8
|
+
* /resume <taskId> [--rollback N] - Continue the same saved task.
|
|
9
|
+
* /fork <taskId> [--rollback N] - Start a new task from saved history.
|
|
9
10
|
* /sessions - List sessions that can be attached to or resumed.
|
|
10
11
|
* /logs [N] - Show the last N messages from the currently attached agent.
|
|
11
12
|
*/
|
|
12
13
|
import { BaseChatModule } from "./BaseChatModule";
|
|
14
|
+
import { TraceAll } from "../../util/Trace";
|
|
13
15
|
import { ChatCommand, ChatMode, ChatContext } from "../types";
|
|
14
16
|
import { AgentModule } from "./AgentModule";
|
|
15
17
|
import {
|
|
@@ -24,6 +26,33 @@ import { Marked } from "../../utils/index";
|
|
|
24
26
|
import * as fs from "fs";
|
|
25
27
|
import * as path from "path";
|
|
26
28
|
|
|
29
|
+
export function parseHistoryCommandArgs(args: string[]): {
|
|
30
|
+
id?: string;
|
|
31
|
+
rollback: number;
|
|
32
|
+
showAll: boolean;
|
|
33
|
+
} {
|
|
34
|
+
let id: string | undefined;
|
|
35
|
+
let rollback = 0;
|
|
36
|
+
let showAll = false;
|
|
37
|
+
for (let i = 0; i < args.length; i++) {
|
|
38
|
+
if (args[i] === "--all") {
|
|
39
|
+
showAll = true;
|
|
40
|
+
} else if (args[i] === "--rollback") {
|
|
41
|
+
const value = args[++i];
|
|
42
|
+
rollback = Number(value);
|
|
43
|
+
if (!Number.isInteger(rollback) || rollback < 0) {
|
|
44
|
+
throw new Error("--rollback must be a non-negative integer");
|
|
45
|
+
}
|
|
46
|
+
} else if (!id) {
|
|
47
|
+
id = args[i];
|
|
48
|
+
} else {
|
|
49
|
+
throw new Error(`Unexpected argument: ${args[i]}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return { id, rollback, showAll };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@TraceAll()
|
|
27
56
|
export class SessionsModule extends BaseChatModule {
|
|
28
57
|
name = "sessions";
|
|
29
58
|
description = "Session and attachment management";
|
|
@@ -49,6 +78,12 @@ export class SessionsModule extends BaseChatModule {
|
|
|
49
78
|
"Resume a completed/saved session with optional additional context",
|
|
50
79
|
handler: this.handleResumeCommand.bind(this),
|
|
51
80
|
},
|
|
81
|
+
{
|
|
82
|
+
name: "fork",
|
|
83
|
+
description:
|
|
84
|
+
"Fork a saved session into a new task; use --rollback N to discard recent agent interactions",
|
|
85
|
+
handler: this.handleForkCommand.bind(this),
|
|
86
|
+
},
|
|
52
87
|
{
|
|
53
88
|
name: "sessions",
|
|
54
89
|
description:
|
|
@@ -214,7 +249,6 @@ export class SessionsModule extends BaseChatModule {
|
|
|
214
249
|
// ── Case 1: in-memory running task ──────────────────────────────────────
|
|
215
250
|
if (taskRegistry.has(id)) {
|
|
216
251
|
const taskInfo = taskRegistry.get(id)!;
|
|
217
|
-
const renderer = this.agentModule.getRenderer();
|
|
218
252
|
const context = this.chatService?.getContext();
|
|
219
253
|
const selectedAgent = taskInfo.agent;
|
|
220
254
|
|
|
@@ -222,13 +256,9 @@ export class SessionsModule extends BaseChatModule {
|
|
|
222
256
|
context.selectedAgent = selectedAgent;
|
|
223
257
|
context.agentMode = true;
|
|
224
258
|
context.currentAgent = taskInfo.agentName;
|
|
225
|
-
context.activeAgentTaskId = id;
|
|
226
259
|
context.currentModel = selectedAgent.getModel();
|
|
227
260
|
context.currentProvider = selectedAgent.getProvider();
|
|
228
261
|
}
|
|
229
|
-
this.agentModule.setActiveAgentTaskId(id);
|
|
230
|
-
renderer.setActiveTaskId(id);
|
|
231
|
-
if (this.chatService) this.chatService.setMode("agent:attached");
|
|
232
262
|
|
|
233
263
|
console.log(`🔄 Attached to running task: ${id}`);
|
|
234
264
|
console.log(` Agent : ${taskInfo.agentName}`);
|
|
@@ -237,6 +267,13 @@ export class SessionsModule extends BaseChatModule {
|
|
|
237
267
|
console.log(
|
|
238
268
|
` Type /logs to see recent messages, or /detach to detach.`
|
|
239
269
|
);
|
|
270
|
+
|
|
271
|
+
// Route through attachedAgentChatLoop so that:
|
|
272
|
+
// 1. wireAgentRendering is called (new output becomes visible)
|
|
273
|
+
// 2. attachedAgent is set (so /poke, /kill, /compact work)
|
|
274
|
+
// 3. a done listener is registered (mode resets when agent finishes)
|
|
275
|
+
// Do NOT pass initialInput — agent is already running, no need to call it again.
|
|
276
|
+
await this.agentModule.attachedAgentChatLoop(id, selectedAgent as any);
|
|
240
277
|
return;
|
|
241
278
|
}
|
|
242
279
|
|
|
@@ -303,10 +340,17 @@ export class SessionsModule extends BaseChatModule {
|
|
|
303
340
|
|
|
304
341
|
async handleResumeCommand(args: string[]): Promise<void> {
|
|
305
342
|
const sessionManager = this.agentModule.getSessionManager();
|
|
343
|
+
let parsed;
|
|
344
|
+
try {
|
|
345
|
+
parsed = parseHistoryCommandArgs(args);
|
|
346
|
+
} catch (error: any) {
|
|
347
|
+
console.error(`Usage: /resume <taskId> [--rollback N] [--all]\n${error.message}`);
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
306
350
|
|
|
307
|
-
if (
|
|
351
|
+
if (!parsed.id) {
|
|
308
352
|
// Interactive: show saved sessions for selection
|
|
309
|
-
const showAll =
|
|
353
|
+
const showAll = parsed.showAll;
|
|
310
354
|
const allSessions = sessionManager.listAvailableSessions();
|
|
311
355
|
const savedSessions = showAll ? allSessions : allSessions.slice(0, 10);
|
|
312
356
|
if (savedSessions.length === 0) {
|
|
@@ -326,18 +370,32 @@ export class SessionsModule extends BaseChatModule {
|
|
|
326
370
|
);
|
|
327
371
|
|
|
328
372
|
if (selectedId) {
|
|
329
|
-
await this.resumeById(selectedId);
|
|
373
|
+
await this.resumeById(selectedId, parsed.rollback);
|
|
330
374
|
}
|
|
331
375
|
return;
|
|
332
376
|
}
|
|
333
377
|
|
|
334
|
-
await this.resumeById(
|
|
378
|
+
await this.resumeById(parsed.id, parsed.rollback);
|
|
335
379
|
}
|
|
336
380
|
|
|
337
|
-
|
|
381
|
+
async handleForkCommand(args: string[]): Promise<void> {
|
|
382
|
+
let parsed;
|
|
383
|
+
try {
|
|
384
|
+
parsed = parseHistoryCommandArgs(args);
|
|
385
|
+
} catch (error: any) {
|
|
386
|
+
console.error(`Usage: /fork <taskId> [--rollback N]\n${error.message}`);
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
if (!parsed.id) {
|
|
390
|
+
console.error("Usage: /fork <taskId> [--rollback N]");
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
await this.resumeById(parsed.id, parsed.rollback, true);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
private async resumeById(id: string, rollback = 0, fork = false): Promise<void> {
|
|
338
397
|
const sessionManager = this.agentModule.getSessionManager();
|
|
339
398
|
|
|
340
|
-
// Check saved sessions first
|
|
341
399
|
try {
|
|
342
400
|
const session = sessionManager.loadSession(id);
|
|
343
401
|
if (session) {
|
|
@@ -347,34 +405,46 @@ export class SessionsModule extends BaseChatModule {
|
|
|
347
405
|
console.log(` Status : ${session.status}`);
|
|
348
406
|
|
|
349
407
|
const additionalContext = await this.chatService?.getInput(
|
|
350
|
-
|
|
351
|
-
);
|
|
352
|
-
await this.agentModule.resumeSession(
|
|
353
|
-
id,
|
|
354
|
-
additionalContext?.trim() || undefined
|
|
408
|
+
`Add any additional context for ${fork ? "forking" : "resuming"} this session (or press Enter to skip): `
|
|
355
409
|
);
|
|
410
|
+
if (fork) {
|
|
411
|
+
const result = await this.agentModule.resumeFromMessages({
|
|
412
|
+
agentName: session.agentName,
|
|
413
|
+
threads: session.threads,
|
|
414
|
+
input: additionalContext?.trim() || session.initialInput,
|
|
415
|
+
interactive: true,
|
|
416
|
+
rollback,
|
|
417
|
+
fork: true,
|
|
418
|
+
model: session.model,
|
|
419
|
+
provider: session.provider,
|
|
420
|
+
reasoningEffort: session.reasoningEffort,
|
|
421
|
+
summarizeReasoning: session.summarizeReasoning,
|
|
422
|
+
enabledTools: session.enabledTools,
|
|
423
|
+
});
|
|
424
|
+
console.log(`🌿 Forked ${id} into new task ${result.taskId}`);
|
|
425
|
+
} else {
|
|
426
|
+
await this.agentModule.resumeSession(
|
|
427
|
+
id,
|
|
428
|
+
additionalContext?.trim() || undefined,
|
|
429
|
+
rollback
|
|
430
|
+
);
|
|
431
|
+
}
|
|
356
432
|
return;
|
|
357
433
|
}
|
|
358
|
-
} catch {
|
|
434
|
+
} catch (e: any) {
|
|
435
|
+
if (e?.message?.includes("rollback")) throw e;
|
|
359
436
|
// not found as a saved session
|
|
360
437
|
}
|
|
361
438
|
|
|
362
|
-
// Check filesystem agent (may have metadata with threads)
|
|
363
439
|
const fsAgentPath = path.join(".knowhow", "processes", "agents", id);
|
|
364
440
|
if (fs.existsSync(fsAgentPath)) {
|
|
365
|
-
// Try to load threads from metadata.json and resume
|
|
366
441
|
const metadataPath = path.join(fsAgentPath, "metadata.json");
|
|
367
442
|
if (fs.existsSync(metadataPath)) {
|
|
368
443
|
try {
|
|
369
|
-
const
|
|
370
|
-
const metadata = JSON.parse(raw);
|
|
444
|
+
const metadata = JSON.parse(fs.readFileSync(metadataPath, "utf-8"));
|
|
371
445
|
const threads: any[] = metadata.threads || [];
|
|
372
446
|
const agentName = metadata.agentName || "Developer";
|
|
373
|
-
|
|
374
|
-
// Try to get initialInput from the saved session file (more complete)
|
|
375
|
-
// since metadata.json doesn't always store it
|
|
376
|
-
const savedSession = sessionManager.loadSession(id);
|
|
377
|
-
const initialInput = savedSession?.initialInput || metadata.initialInput || metadata.prompt || "";
|
|
447
|
+
const initialInput = metadata.initialInput || metadata.prompt || "";
|
|
378
448
|
|
|
379
449
|
console.log(`\n📋 Found task in filesystem: ${id}`);
|
|
380
450
|
console.log(` Agent : ${agentName}`);
|
|
@@ -382,30 +452,33 @@ export class SessionsModule extends BaseChatModule {
|
|
|
382
452
|
console.log(` Status : ${metadata.status || "unknown"}`);
|
|
383
453
|
|
|
384
454
|
const additionalContext = await this.chatService?.getInput(
|
|
385
|
-
|
|
455
|
+
`Add any additional context for ${fork ? "forking" : "resuming"} this session (or press Enter to skip): `
|
|
386
456
|
);
|
|
387
|
-
|
|
388
|
-
// Normalize threads: if flat Message[] (old buggy format), wrap in array
|
|
389
457
|
const normalizedThreads = threads.length > 0 && !Array.isArray(threads[0])
|
|
390
458
|
? [threads]
|
|
391
459
|
: threads;
|
|
392
|
-
|
|
393
|
-
await this.agentModule.resumeFromMessages({
|
|
460
|
+
const result = await this.agentModule.resumeFromMessages({
|
|
394
461
|
agentName,
|
|
395
|
-
|
|
462
|
+
remoteTaskId: fork
|
|
463
|
+
? undefined
|
|
464
|
+
: metadata.remoteTaskId || metadata.knowhowTaskId,
|
|
465
|
+
taskId: fork ? undefined : id,
|
|
396
466
|
threads: normalizedThreads,
|
|
397
|
-
input: additionalContext?.trim() || initialInput
|
|
467
|
+
input: additionalContext?.trim() || initialInput,
|
|
398
468
|
interactive: true,
|
|
399
|
-
|
|
400
|
-
|
|
469
|
+
rollback,
|
|
470
|
+
fork,
|
|
401
471
|
model: metadata.model,
|
|
402
472
|
provider: metadata.provider,
|
|
403
473
|
reasoningEffort: metadata.reasoningEffort,
|
|
404
474
|
summarizeReasoning: metadata.summarizeReasoning,
|
|
475
|
+
enabledTools: metadata.enabledTools,
|
|
405
476
|
});
|
|
477
|
+
if (fork) console.log(`🌿 Forked ${id} into new task ${result.taskId}`);
|
|
406
478
|
return;
|
|
407
479
|
} catch (e: any) {
|
|
408
480
|
console.error(`⚠️ Failed to load metadata for task ${id}: ${e.message}`);
|
|
481
|
+
return;
|
|
409
482
|
}
|
|
410
483
|
}
|
|
411
484
|
console.log(
|
|
@@ -415,9 +488,7 @@ export class SessionsModule extends BaseChatModule {
|
|
|
415
488
|
return;
|
|
416
489
|
}
|
|
417
490
|
|
|
418
|
-
console.log(
|
|
419
|
-
`Session "${id}" not found. Use /sessions to list available sessions.`
|
|
420
|
-
);
|
|
491
|
+
console.log(`Session "${id}" not found. Use /sessions to list available sessions.`);
|
|
421
492
|
}
|
|
422
493
|
|
|
423
494
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { services } from "../../services";
|
|
2
|
+
import { TraceAll } from "../../util/Trace";
|
|
2
3
|
import { login } from "../../login";
|
|
3
4
|
import { ask } from "../../utils";
|
|
4
5
|
import { CliChatService } from "../CliChatService";
|
|
@@ -6,6 +7,7 @@ import { ChatCommand, ChatMode } from "../types";
|
|
|
6
7
|
import { AgentModule } from "./AgentModule";
|
|
7
8
|
import { BaseChatModule } from "./BaseChatModule";
|
|
8
9
|
|
|
10
|
+
@TraceAll()
|
|
9
11
|
export class SetupModule extends BaseChatModule {
|
|
10
12
|
name = "setup";
|
|
11
13
|
description = "Setup commands";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BaseChatModule } from "./BaseChatModule";
|
|
2
|
+
import { TraceAll } from "../../util/Trace";
|
|
2
3
|
import { ChatCommand, ChatContext, CommandResult } from "../types";
|
|
3
4
|
import { execSync } from "child_process";
|
|
4
5
|
|
|
@@ -7,6 +8,7 @@ import { execSync } from "child_process";
|
|
|
7
8
|
* /! - Execute command and display output in console (interactive if needed)
|
|
8
9
|
* /!! - Execute command and send output to the AI agent
|
|
9
10
|
*/
|
|
11
|
+
@TraceAll()
|
|
10
12
|
export class ShellCommandModule extends BaseChatModule {
|
|
11
13
|
name = "shell-command";
|
|
12
14
|
description = "Execute shell commands with /! and /!!";
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { BaseChatModule } from "./BaseChatModule";
|
|
2
|
+
import { TraceAll } from "../../util/Trace";
|
|
2
3
|
import { CliChatService } from "../CliChatService";
|
|
3
4
|
import { ChatCommand, ChatMode, ChatContext } from "../types";
|
|
4
5
|
import { ask } from "../../utils";
|
|
5
6
|
import { services } from "../../services";
|
|
6
7
|
import { Models } from "../../types";
|
|
7
8
|
|
|
9
|
+
@TraceAll()
|
|
8
10
|
export class SystemModule extends BaseChatModule {
|
|
9
11
|
name = "system";
|
|
10
12
|
description = "System commands for model, provider, debug, and clear";
|
package/src/chat/types.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { ChatInteraction, Config } from "../types";
|
|
5
5
|
import { BaseAgent } from "../agents/base/base";
|
|
6
|
+
import { ReasoningEffort } from "../clients/types";
|
|
6
7
|
import { ToolsService } from "../services";
|
|
7
8
|
import { AgentRenderer } from "./renderer/types";
|
|
8
9
|
|
|
@@ -101,8 +102,9 @@ export interface TaskInfo {
|
|
|
101
102
|
// restore the exact configuration instead of falling back to agent defaults.
|
|
102
103
|
model?: string;
|
|
103
104
|
provider?: string;
|
|
104
|
-
reasoningEffort?:
|
|
105
|
+
reasoningEffort?: ReasoningEffort;
|
|
105
106
|
summarizeReasoning?: boolean;
|
|
107
|
+
enabledTools?: string[];
|
|
106
108
|
}
|
|
107
109
|
|
|
108
110
|
export interface ChatSession {
|
|
@@ -123,8 +125,9 @@ export interface ChatSession {
|
|
|
123
125
|
// Persisted run configuration for exact resume restoration.
|
|
124
126
|
model?: string;
|
|
125
127
|
provider?: string;
|
|
126
|
-
reasoningEffort?:
|
|
128
|
+
reasoningEffort?: ReasoningEffort;
|
|
127
129
|
summarizeReasoning?: boolean;
|
|
130
|
+
enabledTools?: string[];
|
|
128
131
|
}
|
|
129
132
|
|
|
130
133
|
export interface ChatHistory {
|
package/src/cli.ts
CHANGED
|
@@ -128,7 +128,7 @@ async function main() {
|
|
|
128
128
|
addReplayCommand(program);
|
|
129
129
|
addBehaviorsCommand(program);
|
|
130
130
|
addSkillsCommand(program);
|
|
131
|
-
addAgentsCommand(program);
|
|
131
|
+
addAgentsCommand(program, getChatService);
|
|
132
132
|
addHashCommand(program);
|
|
133
133
|
addSandboxCommand(program);
|
|
134
134
|
|
package/src/clients/anthropic.ts
CHANGED
|
@@ -88,6 +88,25 @@ export class GenericAnthropicClient implements GenericClient {
|
|
|
88
88
|
return undefined;
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
+
/** Map provider-neutral effort names to Anthropic's output_config.effort. */
|
|
92
|
+
getEffortOutputConfig(
|
|
93
|
+
model: string,
|
|
94
|
+
reasoningEffort?: CompletionOptions["reasoning_effort"]
|
|
95
|
+
): Anthropic.OutputConfig | undefined {
|
|
96
|
+
if (
|
|
97
|
+
reasoningEffort === undefined ||
|
|
98
|
+
reasoningEffort === "none" ||
|
|
99
|
+
(!alwaysOnModels.includes(model) && !optInModels.includes(model))
|
|
100
|
+
) {
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
// Anthropic uses `low` for the provider-neutral `minimal` level.
|
|
106
|
+
effort: reasoningEffort === "minimal" ? "low" : reasoningEffort,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
91
110
|
/**
|
|
92
111
|
* Clean JSON Schema for Anthropic API compatibility.
|
|
93
112
|
* Removes unsupported fields like additionalProperties, $ref, $defs, positional.
|
|
@@ -423,6 +442,10 @@ export class GenericAnthropicClient implements GenericClient {
|
|
|
423
442
|
options.reasoning_effort,
|
|
424
443
|
options.reasoning_summary,
|
|
425
444
|
);
|
|
445
|
+
const effortOutputConfig = this.getEffortOutputConfig(
|
|
446
|
+
options.model,
|
|
447
|
+
options.reasoning_effort
|
|
448
|
+
);
|
|
426
449
|
|
|
427
450
|
const systemMessage = options.messages
|
|
428
451
|
.filter((msg) => msg.role === "system")
|
|
@@ -447,6 +470,7 @@ export class GenericAnthropicClient implements GenericClient {
|
|
|
447
470
|
: undefined,
|
|
448
471
|
max_tokens: options.max_tokens || 8000,
|
|
449
472
|
...(thinkingParam && { thinking: thinkingParam }),
|
|
473
|
+
...(effortOutputConfig && { output_config: effortOutputConfig }),
|
|
450
474
|
...(tools.length && {
|
|
451
475
|
tool_choice: { type: "auto" },
|
|
452
476
|
tools,
|
package/src/clients/fireworks.ts
CHANGED
|
@@ -51,6 +51,9 @@ export class GenericFireworksClient extends HttpClient {
|
|
|
51
51
|
...options,
|
|
52
52
|
// Strip Anthropic-specific field not accepted by Fireworks
|
|
53
53
|
long_ttl_cache: undefined,
|
|
54
|
+
// This is translated by the OpenAI/Anthropic clients, but is not part of
|
|
55
|
+
// Fireworks' OpenAI-compatible chat completion schema.
|
|
56
|
+
reasoning_summary: undefined,
|
|
54
57
|
};
|
|
55
58
|
|
|
56
59
|
if (sanitized.tools) {
|
package/src/clients/gemini.ts
CHANGED
|
@@ -434,9 +434,13 @@ export class GenericGeminiClient implements GenericClient {
|
|
|
434
434
|
// Gemini 3.x — use thinkingLevel
|
|
435
435
|
if (GoogleThinkingLevelModels.includes(model)) {
|
|
436
436
|
const levelMap: Record<string, string> = {
|
|
437
|
+
none: "minimal",
|
|
438
|
+
minimal: "minimal",
|
|
437
439
|
low: "low",
|
|
438
440
|
medium: "medium",
|
|
439
441
|
high: "high",
|
|
442
|
+
xhigh: "high",
|
|
443
|
+
max: "high",
|
|
440
444
|
};
|
|
441
445
|
return {
|
|
442
446
|
thinkingLevel: levelMap[effort] ?? "low",
|
|
@@ -447,9 +451,13 @@ export class GenericGeminiClient implements GenericClient {
|
|
|
447
451
|
if (GoogleThinkingBudgetModels.includes(model)) {
|
|
448
452
|
// Map effort to token budget
|
|
449
453
|
const budgetMap: Record<string, number> = {
|
|
454
|
+
none: 0,
|
|
455
|
+
minimal: 512,
|
|
450
456
|
low: 1024,
|
|
451
457
|
medium: 8192,
|
|
452
458
|
high: -1, // dynamic
|
|
459
|
+
xhigh: -1,
|
|
460
|
+
max: -1,
|
|
453
461
|
};
|
|
454
462
|
return {
|
|
455
463
|
thinkingBudget: budgetMap[effort] ?? 1024,
|
package/src/clients/index.ts
CHANGED
|
@@ -59,6 +59,7 @@ import { GenericLlamaClient } from "./llama";
|
|
|
59
59
|
import { GenericFireworksClient } from "./fireworks";
|
|
60
60
|
import { GenericMetaClient } from "./meta";
|
|
61
61
|
import { GenericQwenClient } from "./qwen";
|
|
62
|
+
import { TraceAll } from "../util/Trace";
|
|
62
63
|
export {
|
|
63
64
|
OpenAiTextPricing,
|
|
64
65
|
AnthropicTextPricing,
|
|
@@ -139,6 +140,7 @@ const DEFAULT_PROVIDERS: ModelProvider[] = [
|
|
|
139
140
|
{ provider: "qwen", envKey: "QWEN_CLOUD_API_KEY" },
|
|
140
141
|
];
|
|
141
142
|
|
|
143
|
+
@TraceAll()
|
|
142
144
|
export class AIClient {
|
|
143
145
|
clients: Record<string, GenericClient> = {};
|
|
144
146
|
|
package/src/clients/openai.ts
CHANGED
|
@@ -112,9 +112,10 @@ export class GenericOpenAiClient implements GenericClient {
|
|
|
112
112
|
|
|
113
113
|
resolveReasoningEffort(options: CompletionOptions): "low" | "medium" | "high" {
|
|
114
114
|
const effort = options.reasoning_effort ?? this.detectReasoningEffort(options.messages);
|
|
115
|
-
//
|
|
116
|
-
//
|
|
117
|
-
if (effort === "none") return "low";
|
|
115
|
+
// Chat Completions only accepts low/medium/high. Preserve newer values on
|
|
116
|
+
// the Responses API, but map them to the nearest legacy level here.
|
|
117
|
+
if (effort === "none" || effort === "minimal") return "low";
|
|
118
|
+
if (effort === "xhigh" || effort === "max") return "high";
|
|
118
119
|
return effort;
|
|
119
120
|
}
|
|
120
121
|
|
|
@@ -125,7 +126,9 @@ export class GenericOpenAiClient implements GenericClient {
|
|
|
125
126
|
*/
|
|
126
127
|
resolveReasoningEffortForModel(options: CompletionOptions): string {
|
|
127
128
|
const raw = options.reasoning_effort ?? this.detectReasoningEffort(options.messages);
|
|
128
|
-
|
|
129
|
+
// Anthropic calls its highest level `max`; OpenAI calls it `xhigh`.
|
|
130
|
+
// Accept both provider-neutral CLI spellings.
|
|
131
|
+
const requested = raw === "max" ? "xhigh" : raw;
|
|
129
132
|
const pricing = OpenAiTextPricing[options.model];
|
|
130
133
|
const supportedLevels = pricing?.reasoningLevels;
|
|
131
134
|
if (!supportedLevels || supportedLevels.length === 0) {
|
package/src/clients/types.ts
CHANGED
|
@@ -136,6 +136,26 @@ export interface RetryOptions {
|
|
|
136
136
|
signal?: AbortSignal;
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
+
/**
|
|
140
|
+
* Every reasoning-effort spelling currently exposed by a supported provider.
|
|
141
|
+
* Individual models may support only a subset; provider clients are responsible
|
|
142
|
+
* for translating or clamping values where their APIs require it.
|
|
143
|
+
*/
|
|
144
|
+
export const REASONING_EFFORTS = [
|
|
145
|
+
"none",
|
|
146
|
+
"minimal",
|
|
147
|
+
"low",
|
|
148
|
+
"medium",
|
|
149
|
+
"high",
|
|
150
|
+
"xhigh",
|
|
151
|
+
"max",
|
|
152
|
+
] as const;
|
|
153
|
+
export type ReasoningEffort = (typeof REASONING_EFFORTS)[number];
|
|
154
|
+
|
|
155
|
+
export function isReasoningEffort(value: unknown): value is ReasoningEffort {
|
|
156
|
+
return typeof value === "string" && REASONING_EFFORTS.includes(value as ReasoningEffort);
|
|
157
|
+
}
|
|
158
|
+
|
|
139
159
|
export interface CompletionOptions extends RetryOptions {
|
|
140
160
|
model: string;
|
|
141
161
|
messages: Message[];
|
|
@@ -147,14 +167,17 @@ export interface CompletionOptions extends RetryOptions {
|
|
|
147
167
|
* Maps to: OpenAI reasoning_effort/reasoning.effort, xAI reasoning.effort,
|
|
148
168
|
* Gemini thinkingLevel/thinkingBudget, Anthropic thinking mode.
|
|
149
169
|
*
|
|
150
|
-
* "none"
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
* "
|
|
154
|
-
* "
|
|
155
|
-
* "
|
|
170
|
+
* "none" = disable thinking where supported
|
|
171
|
+
* "minimal" = provider-defined minimum (for example Gemini/OpenAI)
|
|
172
|
+
* "low" = low reasoning
|
|
173
|
+
* "medium" = balanced reasoning
|
|
174
|
+
* "high" = high reasoning
|
|
175
|
+
* "xhigh" = extra-high reasoning (for example OpenAI/xAI/Anthropic)
|
|
176
|
+
* "max" = maximum reasoning (Anthropic)
|
|
177
|
+
*
|
|
178
|
+
* A model may support only a subset of these provider-level values.
|
|
156
179
|
*/
|
|
157
|
-
reasoning_effort?:
|
|
180
|
+
reasoning_effort?: ReasoningEffort;
|
|
158
181
|
/**
|
|
159
182
|
* When true, request a summarized view of the model's thinking process.
|
|
160
183
|
* - Anthropic: thinking.display = "summarized"
|
package/src/clients/xai.ts
CHANGED
|
@@ -52,6 +52,15 @@ export class GenericXAIClient implements GenericClient {
|
|
|
52
52
|
});
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
resolveLegacyReasoningEffort(
|
|
56
|
+
effort: CompletionOptions["reasoning_effort"]
|
|
57
|
+
): "low" | "medium" | "high" | undefined {
|
|
58
|
+
if (effort === undefined || effort === "none") return undefined;
|
|
59
|
+
if (effort === "minimal") return "low";
|
|
60
|
+
if (effort === "xhigh" || effort === "max") return "high";
|
|
61
|
+
return effort;
|
|
62
|
+
}
|
|
63
|
+
|
|
55
64
|
async createChatCompletion(
|
|
56
65
|
options: CompletionOptions
|
|
57
66
|
): Promise<CompletionResponse> {
|
|
@@ -72,13 +81,14 @@ export class GenericXAIClient implements GenericClient {
|
|
|
72
81
|
return msg as ChatCompletionMessageParam;
|
|
73
82
|
});
|
|
74
83
|
|
|
84
|
+
const reasoningEffort = this.resolveLegacyReasoningEffort(options.reasoning_effort);
|
|
75
85
|
const response = await this.client.chat.completions.create({
|
|
76
86
|
model: options.model,
|
|
77
87
|
messages: xaiMessages,
|
|
78
88
|
max_tokens: options.max_tokens,
|
|
79
|
-
...(XaiReasoningModels.includes(options.model) &&
|
|
89
|
+
...(XaiReasoningModels.includes(options.model) && reasoningEffort && {
|
|
80
90
|
// grok-3-mini models support reasoning_effort: "low" | "medium" | "high"
|
|
81
|
-
reasoning_effort:
|
|
91
|
+
reasoning_effort: reasoningEffort,
|
|
82
92
|
}),
|
|
83
93
|
...(options.tools && {
|
|
84
94
|
tools: options.tools,
|
|
@@ -206,8 +216,17 @@ export class GenericXAIClient implements GenericClient {
|
|
|
206
216
|
// Resolve reasoning effort, clamping to supported levels if defined in pricing
|
|
207
217
|
const pricing = XaiTextPricing[options.model];
|
|
208
218
|
const supportedLevels = pricing?.reasoningLevels;
|
|
209
|
-
|
|
210
|
-
|
|
219
|
+
const requestedEffort = options.reasoning_effort;
|
|
220
|
+
let reasoningEffort: string | undefined;
|
|
221
|
+
if (requestedEffort !== "none") {
|
|
222
|
+
reasoningEffort =
|
|
223
|
+
requestedEffort === "minimal"
|
|
224
|
+
? "low"
|
|
225
|
+
: requestedEffort === "max"
|
|
226
|
+
? "xhigh"
|
|
227
|
+
: requestedEffort;
|
|
228
|
+
}
|
|
229
|
+
if (requestedEffort !== "none" && supportedLevels?.length) {
|
|
211
230
|
if (!reasoningEffort || !supportedLevels.includes(reasoningEffort)) {
|
|
212
231
|
reasoningEffort = supportedLevels[0];
|
|
213
232
|
}
|
package/src/commands/agent.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { SessionsModule } from "../chat/modules/SessionsModule";
|
|
|
8
8
|
import { SetupModule } from "../chat/modules/SetupModule";
|
|
9
9
|
import { PlainRenderer } from "../chat/renderer/PlainRenderer";
|
|
10
10
|
import { loadRenderer } from "../chat/renderer/loadRenderer";
|
|
11
|
+
import { isReasoningEffort, REASONING_EFFORTS } from "../clients/types";
|
|
11
12
|
import { getConfig } from "../config";
|
|
12
13
|
|
|
13
14
|
async function setupRenderer(chatService: any, rendererSpecifier: string): Promise<void> {
|
|
@@ -54,10 +55,10 @@ export function addAgentCommand(program: Command, getChatService: () => any): vo
|
|
|
54
55
|
"AI provider (openai, anthropic, google, xai)"
|
|
55
56
|
)
|
|
56
57
|
.option("--model <model>", "Specific model for the provider")
|
|
57
|
-
.option("--agent-name <name>", "Which agent to use
|
|
58
|
+
.option("--agent-name <name>", "Which agent to use (default: Patcher)")
|
|
58
59
|
.option(
|
|
59
60
|
"--reasoning-effort <effort>",
|
|
60
|
-
|
|
61
|
+
`Reasoning effort: ${REASONING_EFFORTS.join(", ")}. Individual models support different subsets.`
|
|
61
62
|
)
|
|
62
63
|
.option(
|
|
63
64
|
"--max-time-limit <minutes>",
|
|
@@ -93,16 +94,20 @@ export function addAgentCommand(program: Command, getChatService: () => any): vo
|
|
|
93
94
|
)
|
|
94
95
|
.option("--prompt-file <path>", "Custom prompt template file with {text}")
|
|
95
96
|
.option("--input <text>", "Task input (fallback to stdin if not provided)")
|
|
96
|
-
.option(
|
|
97
|
-
"--resume",
|
|
98
|
-
"Resume a previously started task using the --task-id (local FS or remote)"
|
|
99
|
-
)
|
|
100
97
|
.option(
|
|
101
98
|
"--renderer <name>",
|
|
102
99
|
"Renderer to use: basic, compact, fancy, or a path/package (default: from config or basic)"
|
|
103
100
|
)
|
|
104
101
|
.action(async (options) => {
|
|
105
102
|
try {
|
|
103
|
+
if (
|
|
104
|
+
options.reasoningEffort !== undefined &&
|
|
105
|
+
!isReasoningEffort(options.reasoningEffort)
|
|
106
|
+
) {
|
|
107
|
+
throw new Error(
|
|
108
|
+
`Invalid reasoning effort "${options.reasoningEffort}". Expected one of: ${REASONING_EFFORTS.join(", ")}.`
|
|
109
|
+
);
|
|
110
|
+
}
|
|
106
111
|
const { setupServices } = await import("./services");
|
|
107
112
|
await setupServices();
|
|
108
113
|
const chatService = getChatService();
|
|
@@ -115,39 +120,6 @@ export function addAgentCommand(program: Command, getChatService: () => any): vo
|
|
|
115
120
|
|
|
116
121
|
const agentModule = new AgentModule();
|
|
117
122
|
|
|
118
|
-
if (options.resume) {
|
|
119
|
-
const threads = await agentModule.loadThreadsForTask(
|
|
120
|
-
options.taskId,
|
|
121
|
-
options.messageId
|
|
122
|
-
);
|
|
123
|
-
// Restore the exact model/provider/reasoning the original run used
|
|
124
|
-
// (falls back to agent defaults when not persisted / remote-only).
|
|
125
|
-
const savedSettings = await agentModule.loadTaskSettings(
|
|
126
|
-
options.taskId,
|
|
127
|
-
options.messageId
|
|
128
|
-
);
|
|
129
|
-
const resumeInput =
|
|
130
|
-
options.input || "Please continue from where you left off.";
|
|
131
|
-
|
|
132
|
-
await agentModule.initialize(chatService);
|
|
133
|
-
const { taskCompleted: resumed } =
|
|
134
|
-
await agentModule.resumeFromMessages({
|
|
135
|
-
agentName:
|
|
136
|
-
options.agentName || savedSettings.agentName || "Patcher",
|
|
137
|
-
input: resumeInput,
|
|
138
|
-
threads,
|
|
139
|
-
messageId: options.messageId,
|
|
140
|
-
taskId: options.taskId,
|
|
141
|
-
// CLI-provided model/provider still win over persisted ones.
|
|
142
|
-
model: options.model || savedSettings.model,
|
|
143
|
-
provider: options.provider || savedSettings.provider,
|
|
144
|
-
reasoningEffort: savedSettings.reasoningEffort,
|
|
145
|
-
summarizeReasoning: savedSettings.summarizeReasoning,
|
|
146
|
-
});
|
|
147
|
-
await resumed;
|
|
148
|
-
return;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
123
|
let input = options.input;
|
|
152
124
|
|
|
153
125
|
if (!input && !options.promptFile) {
|