iosm-cli 0.2.7 → 0.2.9

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.
Files changed (149) hide show
  1. package/CHANGELOG.md +61 -1
  2. package/README.md +4 -4
  3. package/dist/cli/args.d.ts.map +1 -1
  4. package/dist/cli/args.js +12 -4
  5. package/dist/cli/args.js.map +1 -1
  6. package/dist/core/agent-profiles.d.ts.map +1 -1
  7. package/dist/core/agent-profiles.js +15 -2
  8. package/dist/core/agent-profiles.js.map +1 -1
  9. package/dist/core/agent-session.d.ts +3 -0
  10. package/dist/core/agent-session.d.ts.map +1 -1
  11. package/dist/core/agent-session.js +214 -2
  12. package/dist/core/agent-session.js.map +1 -1
  13. package/dist/core/sdk.d.ts +2 -2
  14. package/dist/core/sdk.d.ts.map +1 -1
  15. package/dist/core/sdk.js +7 -4
  16. package/dist/core/sdk.js.map +1 -1
  17. package/dist/core/settings-manager.d.ts +57 -0
  18. package/dist/core/settings-manager.d.ts.map +1 -1
  19. package/dist/core/settings-manager.js +197 -0
  20. package/dist/core/settings-manager.js.map +1 -1
  21. package/dist/core/shadow-guard.d.ts.map +1 -1
  22. package/dist/core/shadow-guard.js +12 -1
  23. package/dist/core/shadow-guard.js.map +1 -1
  24. package/dist/core/system-prompt.d.ts.map +1 -1
  25. package/dist/core/system-prompt.js +109 -4
  26. package/dist/core/system-prompt.js.map +1 -1
  27. package/dist/core/tools/db-run.d.ts +84 -0
  28. package/dist/core/tools/db-run.d.ts.map +1 -0
  29. package/dist/core/tools/db-run.js +690 -0
  30. package/dist/core/tools/db-run.js.map +1 -0
  31. package/dist/core/tools/git-common.d.ts +45 -0
  32. package/dist/core/tools/git-common.d.ts.map +1 -0
  33. package/dist/core/tools/git-common.js +185 -0
  34. package/dist/core/tools/git-common.js.map +1 -0
  35. package/dist/core/tools/git-read.d.ts +15 -13
  36. package/dist/core/tools/git-read.d.ts.map +1 -1
  37. package/dist/core/tools/git-read.js +101 -153
  38. package/dist/core/tools/git-read.js.map +1 -1
  39. package/dist/core/tools/git-write.d.ts +75 -0
  40. package/dist/core/tools/git-write.d.ts.map +1 -0
  41. package/dist/core/tools/git-write.js +298 -0
  42. package/dist/core/tools/git-write.js.map +1 -0
  43. package/dist/core/tools/index.d.ts +91 -1
  44. package/dist/core/tools/index.d.ts.map +1 -1
  45. package/dist/core/tools/index.js +26 -0
  46. package/dist/core/tools/index.js.map +1 -1
  47. package/dist/core/tools/lint-run.d.ts +42 -0
  48. package/dist/core/tools/lint-run.d.ts.map +1 -0
  49. package/dist/core/tools/lint-run.js +276 -0
  50. package/dist/core/tools/lint-run.js.map +1 -0
  51. package/dist/core/tools/task.js +1 -1
  52. package/dist/core/tools/task.js.map +1 -1
  53. package/dist/core/tools/test-run.d.ts +36 -0
  54. package/dist/core/tools/test-run.d.ts.map +1 -0
  55. package/dist/core/tools/test-run.js +255 -0
  56. package/dist/core/tools/test-run.js.map +1 -0
  57. package/dist/core/tools/typecheck-run.d.ts +44 -0
  58. package/dist/core/tools/typecheck-run.d.ts.map +1 -0
  59. package/dist/core/tools/typecheck-run.js +343 -0
  60. package/dist/core/tools/typecheck-run.js.map +1 -0
  61. package/dist/core/tools/verification-runner.d.ts +53 -0
  62. package/dist/core/tools/verification-runner.d.ts.map +1 -0
  63. package/dist/core/tools/verification-runner.js +235 -0
  64. package/dist/core/tools/verification-runner.js.map +1 -0
  65. package/dist/core/tools/web-search.d.ts +72 -0
  66. package/dist/core/tools/web-search.d.ts.map +1 -0
  67. package/dist/core/tools/web-search.js +702 -0
  68. package/dist/core/tools/web-search.js.map +1 -0
  69. package/dist/index.d.ts +2 -2
  70. package/dist/index.d.ts.map +1 -1
  71. package/dist/index.js +1 -1
  72. package/dist/index.js.map +1 -1
  73. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  74. package/dist/modes/interactive/components/branch-summary-message.js +2 -1
  75. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  76. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  77. package/dist/modes/interactive/components/compaction-summary-message.js +2 -1
  78. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  79. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  80. package/dist/modes/interactive/components/config-selector.js +7 -2
  81. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  82. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  83. package/dist/modes/interactive/components/custom-message.js +2 -1
  84. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  85. package/dist/modes/interactive/components/mcp-selector.d.ts.map +1 -1
  86. package/dist/modes/interactive/components/mcp-selector.js +3 -1
  87. package/dist/modes/interactive/components/mcp-selector.js.map +1 -1
  88. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  89. package/dist/modes/interactive/components/model-selector.js +12 -2
  90. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  91. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  92. package/dist/modes/interactive/components/oauth-selector.js +11 -0
  93. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  94. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  95. package/dist/modes/interactive/components/scoped-models-selector.js +16 -5
  96. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  97. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  98. package/dist/modes/interactive/components/session-selector.js +4 -2
  99. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  100. package/dist/modes/interactive/components/settings-selector.d.ts +25 -0
  101. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  102. package/dist/modes/interactive/components/settings-selector.js +182 -2
  103. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  104. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
  105. package/dist/modes/interactive/components/show-images-selector.js +7 -2
  106. package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
  107. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  108. package/dist/modes/interactive/components/skill-invocation-message.js +4 -2
  109. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  110. package/dist/modes/interactive/components/subagent-message.d.ts.map +1 -1
  111. package/dist/modes/interactive/components/subagent-message.js +3 -1
  112. package/dist/modes/interactive/components/subagent-message.js.map +1 -1
  113. package/dist/modes/interactive/components/task-plan-message.d.ts.map +1 -1
  114. package/dist/modes/interactive/components/task-plan-message.js +2 -1
  115. package/dist/modes/interactive/components/task-plan-message.js.map +1 -1
  116. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
  117. package/dist/modes/interactive/components/theme-selector.js +7 -2
  118. package/dist/modes/interactive/components/theme-selector.js.map +1 -1
  119. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  120. package/dist/modes/interactive/components/thinking-selector.js +7 -2
  121. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  122. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  123. package/dist/modes/interactive/components/tool-execution.js +25 -7
  124. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  125. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  126. package/dist/modes/interactive/components/tree-selector.js +18 -3
  127. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  128. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  129. package/dist/modes/interactive/components/user-message-selector.js +8 -0
  130. package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  131. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  132. package/dist/modes/interactive/components/user-message.js +2 -1
  133. package/dist/modes/interactive/components/user-message.js.map +1 -1
  134. package/dist/modes/interactive/interactive-mode.d.ts +8 -0
  135. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  136. package/dist/modes/interactive/interactive-mode.js +622 -11
  137. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  138. package/dist/modes/interactive/theme/dark.json +39 -38
  139. package/dist/modes/interactive/theme/light.json +29 -29
  140. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  141. package/dist/modes/interactive/theme/theme.js +16 -25
  142. package/dist/modes/interactive/theme/theme.js.map +1 -1
  143. package/dist/modes/interactive/theme/universal.json +85 -0
  144. package/docs/cli-reference.md +32 -2
  145. package/docs/configuration.md +86 -2
  146. package/docs/development-and-testing.md +1 -1
  147. package/docs/interactive-mode.md +8 -3
  148. package/docs/rpc-json-sdk.md +1 -1
  149. package/package.json +1 -1
@@ -90,6 +90,108 @@ function deriveOrchestrationDisplayText(promptTextWithoutDirective) {
90
90
  }
91
91
  return task;
92
92
  }
93
+ function extractAssistantProtocolText(message) {
94
+ const parts = [];
95
+ for (const content of message.content) {
96
+ if (content.type === "text" && typeof content.text === "string" && content.text.trim()) {
97
+ parts.push(content.text.trim());
98
+ continue;
99
+ }
100
+ if (content.type !== "thinking")
101
+ continue;
102
+ const record = content;
103
+ const thinking = record.thinking;
104
+ if (typeof thinking === "string" && thinking.trim()) {
105
+ parts.push(thinking.trim());
106
+ }
107
+ }
108
+ return parts.join("\n\n").trim();
109
+ }
110
+ function extractAssistantVisibleText(message) {
111
+ return message.content
112
+ .filter((content) => content.type === "text")
113
+ .map((content) => content.text.trim())
114
+ .filter((text) => text.length > 0)
115
+ .join("\n\n")
116
+ .trim();
117
+ }
118
+ function isNonActionableVisibleAssistantText(text) {
119
+ const trimmed = text.trim();
120
+ if (trimmed.length === 0)
121
+ return true;
122
+ return /^\[\s*output\s+truncated[^\]]*\]?\s*\.?$/i.test(trimmed);
123
+ }
124
+ function detectPromptProtocolIssue(text) {
125
+ const trimmed = text.trim();
126
+ if (!trimmed)
127
+ return undefined;
128
+ const hasToolCallOpenBlock = /(^|\n)\s*<\s*tool_call\b/i.test(trimmed);
129
+ const hasToolCallCloseTag = /<\/\s*tool_call\s*>/i.test(trimmed);
130
+ const hasFunctionBlock = /(^|\n)\s*<\s*function\s*=\s*[A-Za-z0-9._:-]+/i.test(trimmed);
131
+ const hasParameterBlock = /(^|\n)\s*<\s*parameter\s*=\s*[A-Za-z0-9._:-]+\s*>/i.test(trimmed);
132
+ // Flag only executable-looking pseudo markup; don't treat inline explanatory mentions as protocol issues.
133
+ const hasToolCallMarkup = (hasToolCallOpenBlock && (hasToolCallCloseTag || hasFunctionBlock || hasParameterBlock)) ||
134
+ (hasFunctionBlock && hasParameterBlock);
135
+ const hasDelegateTaskMarkup = /<\s*delegate_task\b/i.test(trimmed) && /<\/\s*delegate_task\s*>/i.test(trimmed);
136
+ if (!hasToolCallMarkup && !hasDelegateTaskMarkup)
137
+ return undefined;
138
+ return {
139
+ hasToolCallMarkup,
140
+ hasDelegateTaskMarkup,
141
+ };
142
+ }
143
+ function buildPromptProtocolCorrectionPrompt(input) {
144
+ const reasons = [
145
+ input.issue.hasToolCallMarkup ? "raw <tool_call>/<function=...> markup" : undefined,
146
+ input.issue.hasDelegateTaskMarkup ? "raw <delegate_task> blocks" : undefined,
147
+ ].filter((item) => typeof item === "string");
148
+ const boundedOriginal = input.originalPrompt.length > 2_000
149
+ ? `${input.originalPrompt.slice(0, 2_000).trimEnd()}...`
150
+ : input.originalPrompt;
151
+ return [
152
+ "[TOOL_PROTOCOL_CORRECTION]",
153
+ `Previous assistant output included ${reasons.join(" and ")} in plain text.`,
154
+ "These XML-like blocks are not executable tool calls.",
155
+ "Retry now and follow this protocol exactly:",
156
+ "1) Do not output XML/pseudo-call tags (<tool_call>, <function=...>, <delegate_task>).",
157
+ "2) If a tool is needed, emit real structured tool calls only.",
158
+ "3) Prefer structured tools when available instead of ad-hoc pseudo calls.",
159
+ "4) If no tool is needed, provide a direct normal answer.",
160
+ input.hasPriorToolActivity
161
+ ? "5) Continue from the current in-memory state; avoid repeating already completed tool steps unless necessary."
162
+ : undefined,
163
+ "Execute the original user request now.",
164
+ "<original_user_request>",
165
+ boundedOriginal,
166
+ "</original_user_request>",
167
+ "[/TOOL_PROTOCOL_CORRECTION]",
168
+ ]
169
+ .filter((line) => typeof line === "string")
170
+ .join("\n");
171
+ }
172
+ function buildPromptSilentStopRecoveryPrompt(input) {
173
+ const boundedOriginal = input.originalPrompt.length > 2_000
174
+ ? `${input.originalPrompt.slice(0, 2_000).trimEnd()}...`
175
+ : input.originalPrompt;
176
+ return [
177
+ "[ASSISTANT_STALL_RECOVERY]",
178
+ "Previous assistant output ended with stop but produced no visible text and no executable tool calls.",
179
+ "Retry now and continue the same request.",
180
+ "1) Do not return an empty response.",
181
+ "2) If a tool is needed, emit real structured tool calls.",
182
+ "3) If no tool is needed, provide a direct answer.",
183
+ input.hasPriorToolActivity
184
+ ? "4) Continue from the current in-memory state; avoid repeating already completed tool steps unless necessary."
185
+ : undefined,
186
+ "Execute the original user request now.",
187
+ "<original_user_request>",
188
+ boundedOriginal,
189
+ "</original_user_request>",
190
+ "[/ASSISTANT_STALL_RECOVERY]",
191
+ ]
192
+ .filter((line) => typeof line === "string")
193
+ .join("\n");
194
+ }
93
195
  function buildSubagentOrchestrationDirective(text) {
94
196
  const block = parseOrchestrateBlock(text);
95
197
  if (block) {
@@ -147,6 +249,7 @@ function buildMetaProfileOrchestrationDirective(text) {
147
249
  // ============================================================================
148
250
  /** Standard thinking levels */
149
251
  const THINKING_LEVELS = ["off", "minimal", "low", "medium", "high"];
252
+ const MAX_PROMPT_PROTOCOL_AUTO_REPAIR_ATTEMPTS = 2;
150
253
  /** Thinking levels including xhigh (for supported models) */
151
254
  const THINKING_LEVELS_WITH_XHIGH = ["off", "minimal", "low", "medium", "high", "xhigh"];
152
255
  // ============================================================================
@@ -195,6 +298,7 @@ export class AgentSession {
195
298
  this._hooksConfig = emptyHooksConfig();
196
299
  this._pendingHookNotices = [];
197
300
  this._sessionTraceEnabled = isSessionTraceEnabled();
301
+ this._protocolAutoRepairActive = false;
198
302
  // Track last assistant message for auto-compaction check
199
303
  this._lastAssistantMessage = undefined;
200
304
  this._lastTaskPlanSignature = undefined;
@@ -1126,13 +1230,88 @@ export class AgentSession {
1126
1230
  this.agent.setSystemPrompt(this._baseSystemPrompt);
1127
1231
  }
1128
1232
  }
1129
- await this.agent.prompt(messages);
1130
- await this.waitForRetry();
1233
+ const enableProtocolAutoRepair = !options?.skipProtocolAutoRepair && !this._protocolAutoRepairActive;
1234
+ let protocolToolCallsStarted = 0;
1235
+ let latestAssistantProtocolText = "";
1236
+ let latestAssistantMessage;
1237
+ let latestAssistantVisibleText = "";
1238
+ const unsubscribeProtocolMonitor = enableProtocolAutoRepair
1239
+ ? this.subscribe((event) => {
1240
+ if (event.type === "tool_execution_start") {
1241
+ protocolToolCallsStarted += 1;
1242
+ return;
1243
+ }
1244
+ if (event.type === "message_end" && event.message.role === "assistant") {
1245
+ latestAssistantMessage = event.message;
1246
+ latestAssistantProtocolText = extractAssistantProtocolText(latestAssistantMessage);
1247
+ latestAssistantVisibleText = extractAssistantVisibleText(latestAssistantMessage);
1248
+ }
1249
+ })
1250
+ : undefined;
1251
+ try {
1252
+ await this.agent.prompt(messages);
1253
+ await this.waitForRetry();
1254
+ }
1255
+ finally {
1256
+ unsubscribeProtocolMonitor?.();
1257
+ }
1131
1258
  this._appendSessionTrace({
1132
1259
  type: "prompt_dispatched",
1133
1260
  messageCount: messages.length,
1134
1261
  text: promptText,
1135
1262
  });
1263
+ if (enableProtocolAutoRepair) {
1264
+ let nextIssue = detectPromptProtocolIssue(latestAssistantProtocolText);
1265
+ let nextSilentStopWithoutOutput = !nextIssue &&
1266
+ latestAssistantMessage?.stopReason === "stop" &&
1267
+ !latestAssistantMessage.content.some((part) => part.type === "toolCall") &&
1268
+ isNonActionableVisibleAssistantText(latestAssistantVisibleText);
1269
+ if (nextIssue || nextSilentStopWithoutOutput) {
1270
+ this._protocolAutoRepairActive = true;
1271
+ try {
1272
+ for (let repairAttempt = 1; repairAttempt <= MAX_PROMPT_PROTOCOL_AUTO_REPAIR_ATTEMPTS && (nextIssue || nextSilentStopWithoutOutput); repairAttempt += 1) {
1273
+ const hasPriorToolActivity = protocolToolCallsStarted > 0 || repairAttempt > 1;
1274
+ const correctionPrompt = nextIssue
1275
+ ? buildPromptProtocolCorrectionPrompt({
1276
+ originalPrompt: expandedText,
1277
+ issue: nextIssue,
1278
+ hasPriorToolActivity,
1279
+ })
1280
+ : buildPromptSilentStopRecoveryPrompt({
1281
+ originalPrompt: expandedText,
1282
+ hasPriorToolActivity,
1283
+ });
1284
+ this._appendSessionTrace({
1285
+ type: "prompt_protocol_auto_repair",
1286
+ originalPrompt: expandedText,
1287
+ issue: nextIssue ?? { silentStopWithoutOutput: true },
1288
+ hasPriorToolActivity,
1289
+ repairAttempt,
1290
+ maxRepairAttempts: MAX_PROMPT_PROTOCOL_AUTO_REPAIR_ATTEMPTS,
1291
+ });
1292
+ await this.prompt(correctionPrompt, {
1293
+ expandPromptTemplates: false,
1294
+ skipIosmAutopilot: true,
1295
+ skipOrchestrationDirective: true,
1296
+ skipProtocolAutoRepair: true,
1297
+ source: inputSource,
1298
+ });
1299
+ const repairedAssistant = this._findLastAssistantMessage();
1300
+ const repairedProtocolText = repairedAssistant ? extractAssistantProtocolText(repairedAssistant) : "";
1301
+ const repairedVisibleText = repairedAssistant ? extractAssistantVisibleText(repairedAssistant) : "";
1302
+ nextIssue = detectPromptProtocolIssue(repairedProtocolText);
1303
+ nextSilentStopWithoutOutput =
1304
+ !nextIssue &&
1305
+ repairedAssistant?.stopReason === "stop" &&
1306
+ !repairedAssistant.content.some((part) => part.type === "toolCall") &&
1307
+ isNonActionableVisibleAssistantText(repairedVisibleText);
1308
+ }
1309
+ }
1310
+ finally {
1311
+ this._protocolAutoRepairActive = false;
1312
+ }
1313
+ }
1314
+ }
1136
1315
  }
1137
1316
  /**
1138
1317
  * Try to execute an extension command. Returns true if command was found and executed.
@@ -2379,12 +2558,45 @@ export class AgentSession {
2379
2558
  return this._toolPermissionHandler ? this._toolPermissionHandler(request) : true;
2380
2559
  },
2381
2560
  },
2561
+ webSearch: {
2562
+ resolveRuntimeConfig: () => ({
2563
+ enabled: this.settingsManager.getWebSearchEnabled(),
2564
+ providerMode: this.settingsManager.getWebSearchProviderMode(),
2565
+ fallbackMode: this.settingsManager.getWebSearchFallbackMode(),
2566
+ safeSearch: this.settingsManager.getWebSearchSafeSearch(),
2567
+ maxResults: this.settingsManager.getWebSearchMaxResults(),
2568
+ timeoutSeconds: this.settingsManager.getWebSearchTimeoutSeconds(),
2569
+ }),
2570
+ resolveTavilyApiKey: () => this.settingsManager.getWebSearchTavilyApiKey(),
2571
+ resolveSearxngBaseUrl: () => this.settingsManager.getWebSearchSearxngUrl(),
2572
+ permissionGuard: async (request) => {
2573
+ evaluatePreToolHooks(request);
2574
+ return this._toolPermissionHandler ? this._toolPermissionHandler(request) : true;
2575
+ },
2576
+ },
2577
+ gitWrite: {
2578
+ resolveRuntimeConfig: () => ({
2579
+ networkEnabled: this.settingsManager.getGithubToolsNetworkEnabled(),
2580
+ }),
2581
+ resolveGithubToken: () => this.settingsManager.getGithubToolsToken(),
2582
+ permissionGuard: async (request) => {
2583
+ evaluatePreToolHooks(request);
2584
+ return this._toolPermissionHandler ? this._toolPermissionHandler(request) : true;
2585
+ },
2586
+ },
2382
2587
  fsOps: {
2383
2588
  permissionGuard: async (request) => {
2384
2589
  evaluatePreToolHooks(request);
2385
2590
  return this._toolPermissionHandler ? this._toolPermissionHandler(request) : true;
2386
2591
  },
2387
2592
  },
2593
+ dbRun: {
2594
+ resolveRuntimeConfig: () => this.settingsManager.getDbToolsSettings(),
2595
+ permissionGuard: async (request) => {
2596
+ evaluatePreToolHooks(request);
2597
+ return this._toolPermissionHandler ? this._toolPermissionHandler(request) : true;
2598
+ },
2599
+ },
2388
2600
  });
2389
2601
  this._baseToolRegistry = new Map(Object.entries(baseTools).map(([name, tool]) => [name, tool]));
2390
2602
  const extensionsResult = this._resourceLoader.getExtensions();