ethagent 3.3.3 → 4.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.
Files changed (322) hide show
  1. package/.claude-plugin/marketplace.json +11 -0
  2. package/.claude-plugin/plugin.json +35 -0
  3. package/LICENSE +1 -1
  4. package/README.md +64 -104
  5. package/commands/ethagent.md +40 -0
  6. package/package.json +16 -16
  7. package/src/app/keybindings/KeybindingProvider.tsx +1 -6
  8. package/src/app/keybindings/types.ts +1 -6
  9. package/src/cli/ResetConfirmView.tsx +54 -53
  10. package/src/cli/demo.ts +86 -0
  11. package/src/cli/hookIo.ts +45 -0
  12. package/src/cli/main.tsx +94 -123
  13. package/src/cli/memoryGuard.ts +49 -0
  14. package/src/cli/reset.ts +28 -70
  15. package/src/cli/sessionStart.ts +33 -0
  16. package/src/cli/status.ts +46 -0
  17. package/src/cli/sync.ts +167 -0
  18. package/src/cli/syncAdapters/claude-code.ts +86 -0
  19. package/src/cli/syncAdapters/codex.ts +66 -0
  20. package/src/cli/syncAdapters/index.ts +45 -0
  21. package/src/cli/syncAdapters/managedBlock.ts +175 -0
  22. package/src/cli/syncAdapters/shared.ts +63 -0
  23. package/src/identity/continuity/envelopeParse.ts +20 -1
  24. package/src/identity/continuity/publicSkills.ts +3 -1
  25. package/src/identity/continuity/skills/publicSkillsSync.ts +2 -1
  26. package/src/identity/continuity/skills/scaffold.ts +5 -2
  27. package/src/identity/continuity/snapshots.ts +12 -5
  28. package/src/identity/continuity/storage/defaults.ts +20 -19
  29. package/src/identity/continuity/storage/status.ts +1 -1
  30. package/src/identity/ens/ensLookup/constants.ts +1 -1
  31. package/src/identity/manager/IdentityManager.tsx +33 -0
  32. package/src/identity/{hub → manager}/OperationalRoutes.tsx +37 -18
  33. package/src/identity/{hub → manager}/Routes.tsx +48 -34
  34. package/src/identity/{hub → manager}/continuity/ContinuityDashboardScreen.tsx +9 -19
  35. package/src/identity/{hub → manager}/continuity/RebackupStorageScreen.tsx +3 -3
  36. package/src/identity/manager/continuity/RecoveryConfirmScreen.tsx +102 -0
  37. package/src/identity/{hub → manager}/continuity/SavePromptScreen.tsx +2 -3
  38. package/src/identity/{hub → manager}/continuity/completion.ts +1 -1
  39. package/src/identity/{hub → manager}/continuity/effects.ts +1 -1
  40. package/src/identity/{hub → manager}/continuity/skills/DeleteSkillConfirmScreen.tsx +2 -2
  41. package/src/identity/{hub → manager}/continuity/skills/NewSkillScreen.tsx +0 -5
  42. package/src/identity/{hub → manager}/continuity/skills/NewSkillVisibilityScreen.tsx +4 -4
  43. package/src/identity/{hub → manager}/continuity/skills/SkillActionsScreen.tsx +6 -22
  44. package/src/identity/{hub → manager}/continuity/skills/SkillsTreeScreen.tsx +5 -17
  45. package/src/identity/{hub → manager}/continuity/snapshot.ts +1 -1
  46. package/src/identity/{hub → manager}/continuity/vault.ts +1 -1
  47. package/src/identity/{hub → manager}/create/CreateFlow.tsx +59 -32
  48. package/src/identity/{hub → manager}/create/effects.ts +19 -10
  49. package/src/identity/manager/create/importScan.ts +122 -0
  50. package/src/identity/{hub → manager}/custody/CustodyEditFlow.tsx +17 -61
  51. package/src/identity/{hub → manager}/custody/actions.ts +1 -15
  52. package/src/identity/{hub → manager}/custody/routes.tsx +20 -40
  53. package/src/identity/{hub → manager}/custody/transactions.ts +1 -0
  54. package/src/identity/{hub → manager}/custody/types.ts +1 -2
  55. package/src/identity/{hub → manager}/custody/useCustodyEffects.ts +1 -1
  56. package/src/identity/{hub → manager}/ens/EnsEditAdvancedScreens.tsx +2 -2
  57. package/src/identity/{hub → manager}/ens/EnsEditMaintenanceScreens.tsx +12 -23
  58. package/src/identity/{hub → manager}/ens/EnsEditReviewScreens.tsx +18 -42
  59. package/src/identity/{hub → manager}/ens/EnsEditRunners.tsx +1 -1
  60. package/src/identity/{hub → manager}/ens/EnsEditShared.tsx +0 -2
  61. package/src/identity/{hub → manager}/ens/EnsEditSimpleScreens.tsx +10 -19
  62. package/src/identity/{hub → manager}/ens/EnsFlow.tsx +133 -41
  63. package/src/identity/{hub → manager}/ens/EnsOperatorWalletsScreen.tsx +14 -19
  64. package/src/identity/{hub → manager}/ens/editCopy.ts +1 -14
  65. package/src/identity/{hub → manager}/profile/EditProfileFlow.tsx +99 -66
  66. package/src/identity/{hub → manager}/profile/effects.ts +1 -3
  67. package/src/identity/{hub → manager}/profile/operatorSave.ts +1 -1
  68. package/src/identity/{hub → manager}/profile/state.ts +1 -1
  69. package/src/identity/{hub/identityHubReducer.ts → manager/reducer.ts} +25 -26
  70. package/src/identity/{hub → manager}/restore/RestoreFlow.tsx +16 -24
  71. package/src/identity/{hub → manager}/restore/apply.ts +1 -1
  72. package/src/identity/{hub → manager}/restore/auth.ts +1 -1
  73. package/src/identity/{hub → manager}/restore/discover.ts +1 -1
  74. package/src/identity/{hub → manager}/restore/fetch.ts +1 -1
  75. package/src/identity/{hub → manager}/restore/restoreAdmin.ts +1 -1
  76. package/src/identity/{hub → manager}/restore/useRestoreEffects.ts +2 -9
  77. package/src/identity/{hub → manager}/settings/StorageCredentialScreen.tsx +10 -25
  78. package/src/identity/{hub → manager}/shared/components/DetailsScreen.tsx +5 -7
  79. package/src/identity/{hub → manager}/shared/components/ErrorScreen.tsx +6 -10
  80. package/src/identity/{hub → manager}/shared/components/FlowTimeline.tsx +4 -3
  81. package/src/identity/{hub → manager}/shared/components/IdentitySummary.tsx +19 -59
  82. package/src/identity/manager/shared/components/LazyMenu.tsx +147 -0
  83. package/src/identity/manager/shared/components/MenuScreen.tsx +220 -0
  84. package/src/identity/manager/shared/components/OperationCompleteScreen.tsx +28 -0
  85. package/src/identity/{hub → manager}/shared/components/UnlinkedIdentityScreen.tsx +9 -10
  86. package/src/identity/{hub → manager}/shared/components/WalletApprovalScreen.tsx +1 -2
  87. package/src/identity/manager/shared/components/Wordmark.tsx +54 -0
  88. package/src/identity/{hub → manager}/shared/components/menuFlagsFromReconciliation.ts +39 -15
  89. package/src/identity/{hub → manager}/shared/effects/profilePrep.ts +1 -1
  90. package/src/identity/manager/shared/effects/types.ts +30 -0
  91. package/src/identity/{hub → manager}/shared/model/copy.ts +0 -4
  92. package/src/identity/{hub → manager}/shared/model/errors.ts +32 -3
  93. package/src/identity/{hub → manager}/shared/model/network.ts +2 -2
  94. package/src/identity/{hub → manager}/shared/reconciliation/agentReconciliation/hook.ts +5 -0
  95. package/src/identity/{hub → manager}/shared/reconciliation/agentReconciliation/run.ts +1 -1
  96. package/src/identity/{hub/shared/reconciliation/useAgentReconciliation.ts → manager/shared/reconciliation/index.ts} +6 -0
  97. package/src/identity/{hub → manager}/shared/utils.ts +6 -10
  98. package/src/identity/{hub → manager}/transfer/TokenTransferFlow.tsx +3 -3
  99. package/src/identity/{hub → manager}/transfer/TokenTransferScreens.tsx +4 -10
  100. package/src/identity/{hub → manager}/transfer/effects.ts +1 -1
  101. package/src/identity/{hub → manager}/types.ts +5 -6
  102. package/src/identity/{hub/useIdentityHubContinuity.ts → manager/useContinuity.ts} +59 -27
  103. package/src/identity/{hub/useIdentityHubController.ts → manager/useController.ts} +38 -35
  104. package/src/identity/{hub/useIdentityHubSideEffects.ts → manager/useSideEffects.ts} +40 -4
  105. package/src/identity/registry/erc8004/discovery.ts +3 -17
  106. package/src/identity/registry/erc8004/utils.ts +1 -1
  107. package/src/identity/storage/ipfs.ts +21 -1
  108. package/src/identity/wallet/browserWallet/html.ts +10 -2
  109. package/src/identity/wallet/browserWallet/http.ts +18 -0
  110. package/src/identity/wallet/browserWallet/requestServer.ts +5 -1
  111. package/src/identity/wallet/browserWallet/requests.ts +10 -28
  112. package/src/identity/wallet/browserWallet/session.ts +26 -33
  113. package/src/identity/wallet/browserWallet/validation.ts +14 -0
  114. package/src/identity/wallet/browserWallet/walletPageSource.ts +22 -40
  115. package/src/identity/wallet/page/boot.ts +43 -0
  116. package/src/identity/wallet/page/config.ts +59 -0
  117. package/src/identity/wallet/page/constants.ts +12 -0
  118. package/src/identity/wallet/page/copy.ts +47 -68
  119. package/src/identity/wallet/page/css.ts +638 -0
  120. package/src/identity/wallet/page/{errorView.ts → errors.ts} +5 -14
  121. package/src/identity/wallet/page/{controller.ts → flow.ts} +4 -71
  122. package/src/identity/wallet/page/markup.ts +44 -34
  123. package/src/identity/wallet/page/{walletProvider.ts → provider.ts} +0 -3
  124. package/src/identity/wallet/page/resize.ts +95 -0
  125. package/src/identity/wallet/page/state.ts +135 -8
  126. package/src/identity/wallet/page/timeline.ts +161 -0
  127. package/src/identity/wallet/page/view.ts +22 -302
  128. package/src/storage/config.ts +30 -80
  129. package/src/storage/reset.ts +31 -0
  130. package/src/storage/secrets.ts +1 -16
  131. package/src/ui/Select.tsx +27 -5
  132. package/src/ui/Spinner.tsx +16 -15
  133. package/src/ui/Surface.tsx +21 -17
  134. package/src/ui/TextArea.tsx +173 -0
  135. package/src/ui/TextInput.tsx +31 -133
  136. package/src/ui/theme.ts +22 -13
  137. package/src/utils/clipboard.ts +0 -140
  138. package/src/app/FirstRun.tsx +0 -577
  139. package/src/app/FirstRunTimeline.tsx +0 -51
  140. package/src/app/firstRunConfig.ts +0 -26
  141. package/src/app/hooks/useCancelRequest.ts +0 -22
  142. package/src/app/hooks/useDoublePress.ts +0 -46
  143. package/src/app/hooks/useExitOnCtrlC.ts +0 -36
  144. package/src/auth/openaiOAuth/credentials.ts +0 -47
  145. package/src/auth/openaiOAuth/crypto.ts +0 -23
  146. package/src/auth/openaiOAuth/index.ts +0 -238
  147. package/src/auth/openaiOAuth/landingPage.ts +0 -116
  148. package/src/auth/openaiOAuth/listener.ts +0 -151
  149. package/src/auth/openaiOAuth/refresh.ts +0 -70
  150. package/src/auth/openaiOAuth/shared.ts +0 -115
  151. package/src/chat/ChatBottomPane.tsx +0 -296
  152. package/src/chat/ChatScreen.tsx +0 -1685
  153. package/src/chat/ConversationStack.tsx +0 -56
  154. package/src/chat/MessageList.tsx +0 -638
  155. package/src/chat/SessionStatus.tsx +0 -53
  156. package/src/chat/chatEnvironment.ts +0 -16
  157. package/src/chat/chatScreenUtils.ts +0 -194
  158. package/src/chat/chatSessionState.ts +0 -146
  159. package/src/chat/chatTurnContext.ts +0 -50
  160. package/src/chat/chatTurnOrchestrator.ts +0 -603
  161. package/src/chat/chatTurnRows.ts +0 -64
  162. package/src/chat/commands.ts +0 -494
  163. package/src/chat/continuityEditReview.ts +0 -42
  164. package/src/chat/display/DiffView.tsx +0 -193
  165. package/src/chat/display/SyntaxText.tsx +0 -192
  166. package/src/chat/display/toolCallDisplay.ts +0 -103
  167. package/src/chat/display/toolResultDisplay.ts +0 -19
  168. package/src/chat/input/ChatInput.tsx +0 -625
  169. package/src/chat/input/chatInputHelpers.ts +0 -62
  170. package/src/chat/input/chatInputState.ts +0 -247
  171. package/src/chat/input/chatPaste.ts +0 -49
  172. package/src/chat/input/imageRefs.ts +0 -30
  173. package/src/chat/input/inputRendering.tsx +0 -93
  174. package/src/chat/input/textCursor.ts +0 -212
  175. package/src/chat/messageMarkdown.ts +0 -220
  176. package/src/chat/messageRows.ts +0 -43
  177. package/src/chat/planImplementation.ts +0 -62
  178. package/src/chat/slashCommandHandlers.ts +0 -122
  179. package/src/chat/slashCommandViews.ts +0 -120
  180. package/src/chat/transcript/TranscriptView.tsx +0 -184
  181. package/src/chat/transcript/transcriptViewport.ts +0 -295
  182. package/src/chat/views/ContextLimitView.tsx +0 -95
  183. package/src/chat/views/ContinuityEditReviewView.tsx +0 -50
  184. package/src/chat/views/CopyPicker.tsx +0 -50
  185. package/src/chat/views/PermissionPrompt.tsx +0 -156
  186. package/src/chat/views/PermissionsView.tsx +0 -165
  187. package/src/chat/views/PlanApprovalView.tsx +0 -91
  188. package/src/chat/views/ResumeView.tsx +0 -273
  189. package/src/chat/views/RewindView.tsx +0 -412
  190. package/src/cli/preview.tsx +0 -14
  191. package/src/cli/updateNotice.ts +0 -54
  192. package/src/identity/continuity/privateEdit/apply.ts +0 -170
  193. package/src/identity/continuity/privateEdit/diff.ts +0 -6
  194. package/src/identity/continuity/privateEdit/files.ts +0 -23
  195. package/src/identity/continuity/privateEdit/types.ts +0 -28
  196. package/src/identity/continuity/privateEdit.ts +0 -46
  197. package/src/identity/hub/IdentityHub.tsx +0 -14
  198. package/src/identity/hub/continuity/RecoveryConfirmScreen.tsx +0 -104
  199. package/src/identity/hub/ens/effects.ts +0 -218
  200. package/src/identity/hub/shared/components/MenuScreen.tsx +0 -241
  201. package/src/identity/hub/shared/effects/types.ts +0 -53
  202. package/src/identity/hub/shared/reconciliation/index.ts +0 -14
  203. package/src/identity/wallet/page/grainient.ts +0 -278
  204. package/src/identity/wallet/page/html.ts +0 -28
  205. package/src/identity/wallet/page/styles/base.ts +0 -259
  206. package/src/identity/wallet/page/styles/components.ts +0 -262
  207. package/src/identity/wallet/page/styles/index.ts +0 -5
  208. package/src/identity/wallet/page/styles/responsive.ts +0 -247
  209. package/src/identity/wallet/page.tsx +0 -38
  210. package/src/mcp/approvals.ts +0 -113
  211. package/src/mcp/config.ts +0 -235
  212. package/src/mcp/manager.ts +0 -482
  213. package/src/mcp/managerHelpers.ts +0 -70
  214. package/src/mcp/names.ts +0 -19
  215. package/src/mcp/output.ts +0 -96
  216. package/src/models/ModelPicker.tsx +0 -1009
  217. package/src/models/catalog.ts +0 -327
  218. package/src/models/huggingface.ts +0 -712
  219. package/src/models/huggingfaceStorage.ts +0 -136
  220. package/src/models/llamacpp.ts +0 -848
  221. package/src/models/llamacppCommands.ts +0 -44
  222. package/src/models/llamacppConfig.ts +0 -34
  223. package/src/models/llamacppDiscovery.ts +0 -176
  224. package/src/models/llamacppOutput.ts +0 -65
  225. package/src/models/llamacppPreflight.ts +0 -158
  226. package/src/models/modelDisplay.ts +0 -180
  227. package/src/models/modelPickerCatalogFlow.ts +0 -56
  228. package/src/models/modelPickerCredentials.ts +0 -166
  229. package/src/models/modelPickerData.ts +0 -41
  230. package/src/models/modelPickerDisplay.tsx +0 -132
  231. package/src/models/modelPickerHfFlow.ts +0 -192
  232. package/src/models/modelPickerLocalRunnerFlow.ts +0 -115
  233. package/src/models/modelPickerOptions.ts +0 -457
  234. package/src/models/modelPickerTypes.ts +0 -69
  235. package/src/models/modelPickerUninstallFlow.ts +0 -48
  236. package/src/models/modelPickerViewHelpers.ts +0 -174
  237. package/src/models/modelRecommendation.ts +0 -139
  238. package/src/models/providerDisplay.ts +0 -16
  239. package/src/models/runtimeDetection.ts +0 -81
  240. package/src/models/uncensoredCatalog.ts +0 -86
  241. package/src/providers/anthropic.ts +0 -290
  242. package/src/providers/contracts.ts +0 -71
  243. package/src/providers/errors.ts +0 -80
  244. package/src/providers/gemini.ts +0 -391
  245. package/src/providers/openai-chat.ts +0 -474
  246. package/src/providers/openai-responses-format.ts +0 -177
  247. package/src/providers/openai-responses.ts +0 -306
  248. package/src/providers/openaiChatWire.ts +0 -124
  249. package/src/providers/registry.ts +0 -120
  250. package/src/providers/retry.ts +0 -58
  251. package/src/providers/sse.ts +0 -93
  252. package/src/runtime/compaction.ts +0 -395
  253. package/src/runtime/cwd.ts +0 -43
  254. package/src/runtime/providerTurn.ts +0 -38
  255. package/src/runtime/sessionMode.ts +0 -55
  256. package/src/runtime/systemPrompt.ts +0 -213
  257. package/src/runtime/textToolParser.ts +0 -161
  258. package/src/runtime/toolClaimGuards.ts +0 -143
  259. package/src/runtime/toolExecution.ts +0 -304
  260. package/src/runtime/toolIntent.ts +0 -143
  261. package/src/runtime/turn.ts +0 -369
  262. package/src/runtime/turnNudges.ts +0 -223
  263. package/src/runtime/turnTypes.ts +0 -86
  264. package/src/storage/factoryReset.ts +0 -127
  265. package/src/storage/history.ts +0 -58
  266. package/src/storage/permissions.ts +0 -76
  267. package/src/storage/rewind.ts +0 -266
  268. package/src/storage/sessionExport.ts +0 -49
  269. package/src/storage/sessions.ts +0 -495
  270. package/src/tools/bashSafety.ts +0 -186
  271. package/src/tools/bashTool.ts +0 -140
  272. package/src/tools/changeDirectoryTool.ts +0 -213
  273. package/src/tools/contracts.ts +0 -192
  274. package/src/tools/deleteFileTool.ts +0 -116
  275. package/src/tools/editTool.ts +0 -165
  276. package/src/tools/editUtils.ts +0 -170
  277. package/src/tools/fileDiff.ts +0 -261
  278. package/src/tools/listDirectoryTool.ts +0 -55
  279. package/src/tools/listSkillFilesTool.ts +0 -77
  280. package/src/tools/listSkillsTool.ts +0 -68
  281. package/src/tools/mcpResourceTools.ts +0 -95
  282. package/src/tools/permissionRules.ts +0 -85
  283. package/src/tools/privateContinuityEditTool.ts +0 -187
  284. package/src/tools/privateContinuityReadTool.ts +0 -106
  285. package/src/tools/readSkillTool.ts +0 -107
  286. package/src/tools/readTool.ts +0 -85
  287. package/src/tools/registry.ts +0 -103
  288. package/src/tools/writeFileTool.ts +0 -167
  289. package/src/ui/BrandSplash.tsx +0 -133
  290. package/src/ui/terminalTitle.ts +0 -30
  291. package/src/utils/images.ts +0 -140
  292. package/src/utils/markdownSegments.ts +0 -51
  293. package/src/utils/messages.ts +0 -37
  294. package/src/utils/withRetry.ts +0 -324
  295. /package/src/identity/{hub → manager}/continuity/state.ts +0 -0
  296. /package/src/identity/{hub → manager}/custody/helpers.ts +0 -0
  297. /package/src/identity/{hub → manager}/custody/preflight.ts +0 -0
  298. /package/src/identity/{hub → manager}/custody/state.ts +0 -0
  299. /package/src/identity/{hub → manager}/custody/useCustodyFlow.tsx +0 -0
  300. /package/src/identity/{hub → manager}/ens/EnsEditFlow.tsx +0 -0
  301. /package/src/identity/{hub → manager}/ens/advancedEnsValidation.ts +0 -0
  302. /package/src/identity/{hub → manager}/ens/state.ts +0 -0
  303. /package/src/identity/{hub → manager}/ens/transactions.ts +0 -0
  304. /package/src/identity/{hub → manager}/ens/types.ts +0 -0
  305. /package/src/identity/{hub → manager}/profile/identity.ts +0 -0
  306. /package/src/identity/{hub → manager}/restore/envelopes.ts +0 -0
  307. /package/src/identity/{hub → manager}/restore/helpers.ts +0 -0
  308. /package/src/identity/{hub → manager}/restore/recovery.ts +0 -0
  309. /package/src/identity/{hub → manager}/restore/resolve.ts +0 -0
  310. /package/src/identity/{hub → manager}/shared/components/BusyScreen.tsx +0 -0
  311. /package/src/identity/{hub → manager}/shared/components/NetworkScreen.tsx +0 -0
  312. /package/src/identity/{hub → manager}/shared/components/PinataJwtInput.tsx +0 -0
  313. /package/src/identity/{hub → manager}/shared/effects/receipts.ts +0 -0
  314. /package/src/identity/{hub → manager}/shared/effects/sync.ts +0 -0
  315. /package/src/identity/{hub → manager}/shared/model/format.ts +0 -0
  316. /package/src/identity/{hub → manager}/shared/operatorWallets.ts +0 -0
  317. /package/src/identity/{hub → manager}/shared/reconciliation/agentReconciliation/ownership.ts +0 -0
  318. /package/src/identity/{hub → manager}/shared/reconciliation/agentReconciliation/types.ts +0 -0
  319. /package/src/identity/{hub → manager}/shared/reconciliation/walletSetup.ts +0 -0
  320. /package/src/identity/{hub → manager}/shared/txGuard.ts +0 -0
  321. /package/src/identity/{hub → manager}/transfer/progress.ts +0 -0
  322. /package/src/identity/{hub → manager}/transfer/state.ts +0 -0
@@ -1,369 +0,0 @@
1
- import {
2
- unsupportedToolStateClaims,
3
- type ToolEvidence,
4
- } from './toolClaimGuards.js'
5
- import { parseLocalModelTextToolUses } from './textToolParser.js'
6
- import { runProviderTurn } from './providerTurn.js'
7
- import {
8
- MAX_CONTINUATION_NUDGES,
9
- MAX_TOOL_USES_PER_TURN,
10
- REASONING_ONLY_NUDGE_TEXT,
11
- TOOL_BUDGET_NUDGE_TEXT,
12
- TOOL_DELEGATION_NUDGE_TEXT,
13
- TOOL_PROTOCOL_FAKE_NUDGE_TEXT,
14
- TOOL_STATE_CLAIM_REPAIR_NUDGE_TEXT,
15
- looksLikeFakeToolProtocolText,
16
- looksLikeToolDelegationText,
17
- nextNudge,
18
- nextToolResultRepairNudge,
19
- } from './turnNudges.js'
20
- import type {
21
- PendingToolUse,
22
- RuntimeTurnParams,
23
- TurnEvent,
24
- TurnStopReason,
25
- } from './turnTypes.js'
26
-
27
- export { parseLocalModelTextToolUse, parseLocalModelTextToolUses } from './textToolParser.js'
28
- export {
29
- MAX_CONTINUATION_NUDGES,
30
- MAX_TOOL_USES_PER_TURN,
31
- looksLikeContinuationIntent,
32
- looksLikeFakeToolProtocolText,
33
- looksLikePrivateContinuityWorkspaceCreationIntent,
34
- looksLikeToolCapabilityConfusion,
35
- looksLikeToolDelegationText,
36
- looksLikeToolStateClaimWithoutTool,
37
- } from './turnNudges.js'
38
- export type {
39
- ContinuationNudgeReason,
40
- ExecutedToolUse,
41
- PendingToolUse,
42
- RebuildMessages,
43
- RuntimeTurnParams,
44
- ToolBatchRunner,
45
- TurnEvent,
46
- } from './turnTypes.js'
47
- export async function* runRuntimeTurn(
48
- params: RuntimeTurnParams,
49
- ): AsyncGenerator<TurnEvent, void, void> {
50
- const {
51
- provider,
52
- signal,
53
- initialMessages,
54
- rebuildMessages,
55
- runToolBatch,
56
- maxContinuationNudges = MAX_CONTINUATION_NUDGES,
57
- } = params
58
-
59
- let workingMessages = initialMessages
60
- let continuationNudges = 0
61
- let iterationIndex = 0
62
- let priorIterationHadTools = false
63
- let cumulativeToolUseCount = 0
64
- const toolEvidenceThisTurn: ToolEvidence[] = []
65
-
66
- // eslint-disable-next-line no-constant-condition
67
- while (true) {
68
- const hadToolsLastRound = priorIterationHadTools
69
- priorIterationHadTools = false
70
-
71
- if (signal.aborted) {
72
- yield { type: 'cancelled' }
73
- yield doneEvent(false)
74
- return
75
- }
76
-
77
- yield { type: 'iteration_start', index: iterationIndex }
78
- iterationIndex += 1
79
-
80
- let assistantText = ''
81
- const pendingToolUses: PendingToolUse[] = []
82
- let errored = false
83
- let cancelled = false
84
- let thinkingSeen = false
85
- let stopReason: TurnStopReason = 'unknown'
86
-
87
- try {
88
- for await (const ev of runProviderTurn(provider, workingMessages, signal)) {
89
- if (ev.type === 'retry') {
90
- yield ev
91
- } else if (ev.type === 'text') {
92
- assistantText += ev.delta
93
- yield { type: 'text', delta: ev.delta }
94
- } else if (ev.type === 'thinking') {
95
- thinkingSeen = true
96
- yield { type: 'thinking', delta: ev.delta }
97
- } else if (ev.type === 'thinking_end') {
98
- yield { type: 'thinking_end' }
99
- } else if (ev.type === 'tool_use_start') {
100
- yield { type: 'tool_use_start', id: ev.id, name: ev.name }
101
- } else if (ev.type === 'tool_use_delta') {
102
- yield { type: 'tool_use_delta', id: ev.id, delta: ev.delta }
103
- } else if (ev.type === 'tool_use_stop') {
104
- pendingToolUses.push({ id: ev.id, name: ev.name, input: ev.input })
105
- yield {
106
- type: 'tool_use_stop',
107
- id: ev.id,
108
- name: ev.name,
109
- input: ev.input,
110
- }
111
- } else if (ev.type === 'error') {
112
- errored = true
113
- yield { type: 'error', message: ev.message }
114
- break
115
- } else if (ev.type === 'cancelled') {
116
- cancelled = true
117
- break
118
- } else if (ev.type === 'done') {
119
- stopReason = ev.stopReason ?? 'unknown'
120
- break
121
- }
122
- }
123
- } catch (err: unknown) {
124
- if (signal.aborted) {
125
- cancelled = true
126
- } else {
127
- errored = true
128
- yield { type: 'error', message: (err as Error).message || 'stream error' }
129
- }
130
- }
131
-
132
- if (signal.aborted || cancelled) {
133
- yield { type: 'cancelled' }
134
- yield doneEvent(false, stopReason)
135
- return
136
- }
137
-
138
- if (errored) {
139
- yield doneEvent(false, stopReason)
140
- return
141
- }
142
-
143
- if (pendingToolUses.length === 0) {
144
- const parsedToolUses = parseLocalModelTextToolUses(provider, assistantText, iterationIndex - 1)
145
- if (parsedToolUses.length > 0) {
146
- pendingToolUses.push(...parsedToolUses)
147
- yield { type: 'local_tool_recovery' }
148
- for (const parsedToolUse of parsedToolUses) {
149
- yield {
150
- type: 'tool_use_stop',
151
- id: parsedToolUse.id,
152
- name: parsedToolUse.name,
153
- input: parsedToolUse.input,
154
- }
155
- }
156
- }
157
- }
158
-
159
- if (pendingToolUses.length === 0 && provider.supportsTools && looksLikeFakeToolProtocolText(assistantText)) {
160
- if (continuationNudges < maxContinuationNudges) {
161
- continuationNudges += 1
162
- yield {
163
- type: 'continuation_nudge',
164
- attempt: continuationNudges,
165
- reason: 'tool_protocol_fake',
166
- }
167
- workingMessages = [
168
- ...await rebuildMessages(),
169
- { role: 'user', content: TOOL_PROTOCOL_FAKE_NUDGE_TEXT },
170
- ]
171
- continue
172
- }
173
- yield {
174
- type: 'error',
175
- message: 'Model printed tool names instead of making a tool call',
176
- discardAssistant: true,
177
- }
178
- yield doneEvent(false, stopReason)
179
- return
180
- }
181
-
182
- if (pendingToolUses.length === 0 && provider.supportsTools && looksLikeToolDelegationText(assistantText)) {
183
- if (continuationNudges < maxContinuationNudges) {
184
- continuationNudges += 1
185
- yield {
186
- type: 'continuation_nudge',
187
- attempt: continuationNudges,
188
- reason: 'tool_delegation',
189
- }
190
- workingMessages = [
191
- ...await rebuildMessages(),
192
- { role: 'user', content: TOOL_DELEGATION_NUDGE_TEXT },
193
- ]
194
- continue
195
- }
196
- yield {
197
- type: 'error',
198
- message: 'Model asked the user to run a tool instead of making a tool call',
199
- discardAssistant: true,
200
- }
201
- yield doneEvent(false, stopReason)
202
- return
203
- }
204
-
205
- if (pendingToolUses.length === 0) {
206
- const unsupportedClaims = unsupportedToolStateClaims(assistantText, toolEvidenceThisTurn)
207
- if (unsupportedClaims.length > 0) {
208
- if (continuationNudges < maxContinuationNudges) {
209
- continuationNudges += 1
210
- yield {
211
- type: 'continuation_nudge',
212
- attempt: continuationNudges,
213
- reason: 'tool_state_claim',
214
- }
215
- workingMessages = [
216
- ...await rebuildMessages(),
217
- {
218
- role: 'user',
219
- content:
220
- TOOL_STATE_CLAIM_REPAIR_NUDGE_TEXT,
221
- },
222
- ]
223
- continue
224
- }
225
- yield {
226
- type: 'error',
227
- message: 'Model claimed workspace state without matching tool evidence',
228
- discardAssistant: true,
229
- }
230
- yield doneEvent(false, stopReason)
231
- return
232
- }
233
- }
234
-
235
- if (pendingToolUses.length === 0) {
236
- if (!assistantText && thinkingSeen && continuationNudges < maxContinuationNudges) {
237
- continuationNudges += 1
238
- yield {
239
- type: 'continuation_nudge',
240
- attempt: continuationNudges,
241
- reason: 'reasoning_only',
242
- }
243
- workingMessages = [
244
- ...await rebuildMessages(),
245
- { role: 'user', content: REASONING_ONLY_NUDGE_TEXT },
246
- ]
247
- continue
248
- }
249
-
250
- const nudge = nextNudge(provider, assistantText)
251
- if (assistantText && continuationNudges < maxContinuationNudges && nudge) {
252
- if (hadToolsLastRound && nudge.reason === 'continuation') {
253
- yield { type: 'assistant_message_committed', text: assistantText }
254
- yield doneEvent(true, stopReason)
255
- return
256
- }
257
- continuationNudges += 1
258
- yield {
259
- type: 'continuation_nudge',
260
- attempt: continuationNudges,
261
- reason: nudge.reason,
262
- }
263
- workingMessages = [
264
- ...await rebuildMessages(),
265
- ...(nudge.keepAssistantContext ? [{ role: 'assistant' as const, content: assistantText }] : []),
266
- { role: 'user', content: nudge.text },
267
- ]
268
- continue
269
- }
270
- if (assistantText && nudge?.reason === 'tool_capability') {
271
- yield {
272
- type: 'error',
273
- message: 'Model refused available tools after corrective nudges',
274
- }
275
- yield doneEvent(false, stopReason)
276
- return
277
- }
278
-
279
- if (assistantText) {
280
- yield { type: 'assistant_message_committed', text: assistantText }
281
- }
282
-
283
- yield doneEvent(true, stopReason)
284
- return
285
- }
286
-
287
- if (cumulativeToolUseCount + pendingToolUses.length > MAX_TOOL_USES_PER_TURN) {
288
- if (continuationNudges < maxContinuationNudges) {
289
- continuationNudges += 1
290
- yield {
291
- type: 'continuation_nudge',
292
- attempt: continuationNudges,
293
- reason: 'tool_budget',
294
- }
295
- workingMessages = [
296
- ...await rebuildMessages(),
297
- { role: 'user', content: TOOL_BUDGET_NUDGE_TEXT },
298
- ]
299
- continue
300
- }
301
- yield {
302
- type: 'error',
303
- message: `tool budget exceeded (${MAX_TOOL_USES_PER_TURN} max per turn); ask again with a narrower request`,
304
- }
305
- yield doneEvent(false, stopReason)
306
- return
307
- }
308
- cumulativeToolUseCount += pendingToolUses.length
309
-
310
- const batch = await runToolBatch(pendingToolUses)
311
- for (const completed of batch.completedTools) {
312
- toolEvidenceThisTurn.push({
313
- name: completed.name,
314
- result: { ok: completed.result.ok },
315
- })
316
- }
317
-
318
- for (const completed of batch.completedTools) {
319
- yield {
320
- type: 'tool_executed',
321
- id: completed.id,
322
- name: completed.name,
323
- input: completed.input,
324
- result: completed.result,
325
- cwd: completed.cwd,
326
- }
327
- }
328
-
329
- if (batch.cancelled || signal.aborted) {
330
- yield { type: 'cancelled' }
331
- yield doneEvent(false, stopReason)
332
- return
333
- }
334
-
335
- const repairNudge = nextToolResultRepairNudge(provider, batch.completedTools)
336
- if (repairNudge) {
337
- if (continuationNudges < maxContinuationNudges) {
338
- continuationNudges += 1
339
- yield {
340
- type: 'continuation_nudge',
341
- attempt: continuationNudges,
342
- reason: repairNudge.reason,
343
- }
344
- workingMessages = [
345
- ...await rebuildMessages(),
346
- { role: 'user', content: repairNudge.text },
347
- ]
348
- continue
349
- }
350
- yield {
351
- type: 'error',
352
- message: repairNudge.failureMessage,
353
- discardAssistant: true,
354
- }
355
- yield doneEvent(false, stopReason)
356
- return
357
- }
358
-
359
- priorIterationHadTools = true
360
- workingMessages = await rebuildMessages()
361
- }
362
- }
363
-
364
- function doneEvent(finishedNormally: boolean, stopReason?: TurnStopReason): Extract<TurnEvent, { type: 'done' }> {
365
- if (stopReason && stopReason !== 'end_turn' && stopReason !== 'unknown') {
366
- return { type: 'done', finishedNormally, stopReason }
367
- }
368
- return { type: 'done', finishedNormally }
369
- }
@@ -1,223 +0,0 @@
1
- import type { Provider } from '../providers/contracts.js'
2
- import {
3
- looksLikeToolStateClaim,
4
- } from './toolClaimGuards.js'
5
- import type { ContinuationNudgeReason, ExecutedToolUse } from './turnTypes.js'
6
-
7
- export const MAX_CONTINUATION_NUDGES = 3
8
- export const MAX_TOOL_USES_PER_TURN = 25
9
-
10
- const CONTINUATION_NUDGE_TEXT =
11
- 'Continue with the task. Use the appropriate tools to proceed.'
12
-
13
- const TOOL_CAPABILITY_NUDGE_TEXT =
14
- 'You do have access to the provided tools in this environment. Continue by making the appropriate tool call; do not ask the user to run commands or paste command output.'
15
-
16
- const TOOL_STATE_CLAIM_NUDGE_TEXT =
17
- 'Do not claim that files, directories, or workspace state changed unless you have executed the appropriate tool. Call the tool now.'
18
-
19
- export const TOOL_STATE_CLAIM_REPAIR_NUDGE_TEXT =
20
- 'The previous assistant response claimed workspace state without executing a tool. '
21
- + 'Treat that claim as unreliable. '
22
- + TOOL_STATE_CLAIM_NUDGE_TEXT
23
-
24
- export const TOOL_PROTOCOL_FAKE_NUDGE_TEXT =
25
- 'The previous response printed tool names or a tool menu instead of calling a tool. Tool names are not text output. Make exactly one native tool call now.'
26
-
27
- export const TOOL_DELEGATION_NUDGE_TEXT =
28
- 'Do not ask the user to run native tools. You have access to the tools in this environment. Make exactly one native tool call now.'
29
-
30
- export const TOOL_BUDGET_NUDGE_TEXT =
31
- 'You have reached the tool-call budget for this turn. Do not call any more tools. Produce your final answer now using only what you already know from earlier tool results.'
32
-
33
- const PRIVATE_CONTINUITY_NUDGE_TEXT =
34
- 'SOUL.md and MEMORY.md are existing private identity-vault scaffold files. Do not search workspace folders, read plans/, create files, or overwrite them. If exact private text is needed for a surgical removal or targeted replacement, call read_private_continuity_file with {"file":"MEMORY.md"} or {"file":"SOUL.md"}. If the user wants private continuity changed, call propose_private_continuity_edit. For memory/preferences use {"file":"MEMORY.md","appendToSection":"Durable User Preferences","appendText":"- User preference or memory note."}. For persona use {"file":"SOUL.md","appendToSection":"Persona","appendText":"- Persona or standing behavior note."}.'
35
-
36
- const PRIVATE_CONTINUITY_REPAIR_NUDGE_TEXT =
37
- 'The previous propose_private_continuity_edit call had invalid or missing input. Retry the same native tool now with complete arguments. Do not answer in prose and do not search for markdown files. For memory/preferences use {"file":"MEMORY.md","appendToSection":"Durable User Preferences","appendText":"- User preference or memory note."}. For persona use {"file":"SOUL.md","appendToSection":"Persona","appendText":"- Persona or standing behavior note."}.'
38
-
39
- const WRITE_FILE_REPAIR_NUDGE_TEXT =
40
- 'The previous write_file call was rejected because the arguments were missing or malformed. Retry the same native tool now with a JSON object (not a JSON string) shaped exactly like {"path":"relative/path.ext","content":"...complete file contents..."}. Both fields are required and must be non-empty. Do not answer in prose.'
41
-
42
- export const REASONING_ONLY_NUDGE_TEXT =
43
- 'You produced private reasoning but no user-visible answer. Answer the user now in visible text. Do not continue only with reasoning.'
44
-
45
- type RepairNudge = {
46
- text: string
47
- reason: ContinuationNudgeReason
48
- failureMessage: string
49
- }
50
-
51
- export function nextToolResultRepairNudge(
52
- provider: Pick<Provider, 'id' | 'supportsTools'>,
53
- completedTools: ExecutedToolUse[],
54
- ): RepairNudge | null {
55
- if (!provider.supportsTools) return null
56
- const failedPrivateEdit = completedTools.some(completed =>
57
- completed.name === 'propose_private_continuity_edit'
58
- && !completed.result.ok
59
- && completed.result.summary === 'propose_private_continuity_edit rejected input',
60
- )
61
- if (failedPrivateEdit) {
62
- return {
63
- text: PRIVATE_CONTINUITY_REPAIR_NUDGE_TEXT,
64
- reason: 'private_continuity_tool_repair',
65
- failureMessage: 'Model called propose_private_continuity_edit with invalid input after corrective nudges',
66
- }
67
- }
68
-
69
- const failedWriteFile = completedTools.some(completed =>
70
- completed.name === 'write_file'
71
- && !completed.result.ok
72
- && completed.result.summary === 'write_file rejected input',
73
- )
74
- if (failedWriteFile) {
75
- return {
76
- text: WRITE_FILE_REPAIR_NUDGE_TEXT,
77
- reason: 'write_file_repair',
78
- failureMessage: 'Model called write_file with invalid input after corrective nudges',
79
- }
80
- }
81
-
82
- const failedWorkspacePrivateRead = completedTools.some(completed =>
83
- completed.name === 'read_file'
84
- && !completed.result.ok
85
- && /read_private_continuity_file/.test(completed.result.content),
86
- )
87
- if (failedWorkspacePrivateRead) {
88
- return {
89
- text: 'The previous read_file call targeted private identity continuity markdown. Retry now with read_private_continuity_file and complete input such as {"file":"MEMORY.md"} or {"file":"SOUL.md"}. Do not search workspace folders.',
90
- reason: 'private_continuity_tool_repair',
91
- failureMessage: 'Model kept reading private continuity files via read_file after corrective nudges',
92
- }
93
- }
94
- return null
95
- }
96
-
97
- export function nextNudge(
98
- provider: Pick<Provider, 'supportsTools'>,
99
- assistantText: string,
100
- ): { text: string; reason: ContinuationNudgeReason; keepAssistantContext: boolean } | null {
101
- if (provider.supportsTools && looksLikePrivateContinuityWorkspaceCreationIntent(assistantText)) {
102
- return {
103
- text: PRIVATE_CONTINUITY_NUDGE_TEXT,
104
- reason: 'private_continuity_tool',
105
- keepAssistantContext: false,
106
- }
107
- }
108
- if (provider.supportsTools && looksLikeToolCapabilityConfusion(assistantText)) {
109
- return {
110
- text: TOOL_CAPABILITY_NUDGE_TEXT,
111
- reason: 'tool_capability',
112
- keepAssistantContext: false,
113
- }
114
- }
115
- if (looksLikeContinuationIntent(assistantText)) {
116
- return {
117
- text: CONTINUATION_NUDGE_TEXT,
118
- reason: 'continuation',
119
- keepAssistantContext: true,
120
- }
121
- }
122
- return null
123
- }
124
-
125
- export function looksLikePrivateContinuityWorkspaceCreationIntent(text: string): boolean {
126
- const lower = text.toLowerCase()
127
- if (!/\b(soul|memory)\.md\b/.test(lower)) return false
128
- return [
129
- /\b(create|write|make|generate|scaffold|overwrite|replace|locate|find|search|read|check|inspect)\b.{0,100}\b(soul|memory)\.md\b/,
130
- /\b(soul|memory)\.md\b.{0,100}\b(create|write|make|generate|scaffold|overwrite|replace|locate|find|search|read|check|inspect)\b/,
131
- /\bplans?[\\/][^\s]*\b(soul|memory)\b/,
132
- ].some(pattern => pattern.test(lower))
133
- }
134
-
135
- export function looksLikeToolCapabilityConfusion(text: string): boolean {
136
- const lower = text.toLowerCase()
137
- const limitation =
138
- /\b(i (do not|don't|cannot|can't) (have|access|run|execute|inspect|read|list|use)|no direct access|unable to|not able to|currently operating under|limitations and restrictions)\b/
139
- const toolTask =
140
- /\b(run|execute|shell command|command output|local machine|terminal|files?|directories|workspace|paste|share the contents)\b/
141
- return limitation.test(lower) && toolTask.test(lower)
142
- }
143
-
144
- export function looksLikeToolStateClaimWithoutTool(text: string): boolean {
145
- return looksLikeToolStateClaim(text)
146
- }
147
-
148
- export function looksLikeFakeToolProtocolText(text: string): boolean {
149
- const lower = text.toLowerCase()
150
- if (!lower.trim()) return false
151
-
152
- const toolNames = new Set(
153
- [...lower.matchAll(/\b(change_directory|edit_file|propose_private_continuity_edit|read_private_continuity_file|list_directory|read_file|run_bash|write_file|delete_file)\b/g)]
154
- .map(match => match[1]),
155
- )
156
- if (toolNames.size < 2) return false
157
-
158
- const codeBlock = /```|code\s*(?:-|:)?\s*block/.test(lower)
159
- const toolMenu = /\b(available tools|tool functions|functions are|tools are|native tools)\b/.test(lower)
160
- const actionIntent = /\b(let'?s|let me|i'?ll|i will|first|next)\b.{0,80}\b(list|read|inspect|execute|run|change|edit|write)\b/.test(lower)
161
- const commaSeparatedTools = /(?:change_directory|edit_file|propose_private_continuity_edit|read_private_continuity_file|list_directory|read_file|run_bash|write_file|delete_file)(?:\s*,\s*|\s+){1,}/.test(lower)
162
-
163
- return (codeBlock || toolMenu || actionIntent) && commaSeparatedTools
164
- }
165
-
166
- export function looksLikeToolDelegationText(text: string): boolean {
167
- const lower = text.toLowerCase()
168
- if (!lower.trim()) return false
169
-
170
- const toolName = '(?:change_directory|edit_file|propose_private_continuity_edit|read_private_continuity_file|list_directory|read_file|run_bash|write_file|delete_file)'
171
- if (!new RegExp(`\\b${toolName}\\b`).test(lower)) return false
172
-
173
- const directToolRef = `(?:\`?${toolName}\`?|the\\s+\`?${toolName}\`?\\s+tool)`
174
- const action = '(?:run|execute|call|use|invoke)'
175
- const askPrefix = "(?:please|kindly|can you|could you|would you|you can|you should|you need to|you'll need to|try to|go ahead and)"
176
- const selfPrefix = "(?:i'll|i will|let me|let's|we should|we need to|before proceeding|first|next|now)"
177
-
178
- const askUser = new RegExp(`\\b${askPrefix}\\b.{0,100}\\b${action}\\b.{0,50}${directToolRef}`).test(lower)
179
- const selfIntent = new RegExp(`\\b${selfPrefix}\\b.{0,100}\\b${action}\\b.{0,50}${directToolRef}`).test(lower)
180
- const commandForm = new RegExp(`\\b${action}\\s+${directToolRef}\\b`).test(lower)
181
- && /\b(please|before proceeding|first|next|now|to proceed)\b/.test(lower)
182
- const asksForOutput = new RegExp(`${directToolRef}.{0,120}\\b(output|result|files?|directory structure|working directory)\\b`).test(lower)
183
- && /\b(please|you|run|paste|share|provide)\b/.test(lower)
184
-
185
- return askUser || selfIntent || commandForm || asksForOutput
186
- }
187
-
188
- export function looksLikeContinuationIntent(text: string): boolean {
189
- const lower = text.toLowerCase()
190
-
191
- const completionMarkers =
192
- /\b(done|finished|completed|complete|summary|that's all|that is all|all set|hope this helps|let me know if)\b/
193
- if (completionMarkers.test(lower)) return false
194
-
195
- const actionVerbs =
196
- '(do|create|write|edit|update|fix|implement|add|run|check|make|build|set up|go|proceed|begin)'
197
-
198
- const shortMessage = lower.length < 80
199
-
200
- const patterns: RegExp[] = [
201
- new RegExp(
202
- `\\bso now (i|let me|we) (need to|have to|should|must|will) ${actionVerbs}\\b`,
203
- ),
204
- new RegExp(`\\bnow i('ll| will) ${actionVerbs}\\b`),
205
- new RegExp(
206
- `\\blet me (go ahead and |now )?${actionVerbs}\\b`,
207
- ),
208
- new RegExp(`\\btime to ${actionVerbs}\\b`),
209
- ]
210
-
211
- if (shortMessage) {
212
- patterns.push(
213
- new RegExp(
214
- `\\bi('ll| will| need to| have to| must) (now )?${actionVerbs}\\b`,
215
- ),
216
- new RegExp(
217
- `\\bnext,?\\s+(i('ll| will)|let me|i need to) ${actionVerbs}\\b`,
218
- ),
219
- )
220
- }
221
-
222
- return patterns.some(re => re.test(lower))
223
- }
@@ -1,86 +0,0 @@
1
- import type { Message, Provider, ProviderRetryStreamEvent } from '../providers/contracts.js'
2
- import type { ToolResult } from '../tools/contracts.js'
3
-
4
- export type ProviderTurnEvent =
5
- | { type: 'text'; delta: string }
6
- | { type: 'thinking'; delta: string }
7
- | { type: 'thinking_end' }
8
- | ProviderRetryStreamEvent
9
- | { type: 'tool_use_start'; id: string; name: string }
10
- | { type: 'tool_use_delta'; id: string; delta: string }
11
- | { type: 'tool_use_stop'; id: string; name: string; input: Record<string, unknown> }
12
- | { type: 'done'; stopReason?: TurnStopReason }
13
- | { type: 'error'; message: string }
14
- | { type: 'cancelled' }
15
-
16
- export type TurnStopReason = 'end_turn' | 'tool_use' | 'max_tokens' | 'stop_sequence' | 'unknown'
17
-
18
- export type ContinuationNudgeReason =
19
- | 'continuation'
20
- | 'tool_capability'
21
- | 'tool_state_claim'
22
- | 'tool_protocol_fake'
23
- | 'tool_delegation'
24
- | 'tool_budget'
25
- | 'private_continuity_tool'
26
- | 'private_continuity_tool_repair'
27
- | 'write_file_repair'
28
- | 'reasoning_only'
29
-
30
- export type TurnEvent =
31
- | { type: 'iteration_start'; index: number }
32
- | { type: 'text'; delta: string }
33
- | { type: 'thinking'; delta: string }
34
- | { type: 'thinking_end' }
35
- | ProviderRetryStreamEvent
36
- | { type: 'tool_use_start'; id: string; name: string }
37
- | { type: 'tool_use_delta'; id: string; delta: string }
38
- | {
39
- type: 'tool_use_stop'
40
- id: string
41
- name: string
42
- input: Record<string, unknown>
43
- }
44
- | { type: 'assistant_message_committed'; text: string }
45
- | {
46
- type: 'tool_executed'
47
- id: string
48
- name: string
49
- input: Record<string, unknown>
50
- result: ToolResult
51
- cwd: string
52
- }
53
- | { type: 'continuation_nudge'; attempt: number; reason: ContinuationNudgeReason }
54
- | { type: 'local_tool_recovery' }
55
- | { type: 'error'; message: string; discardAssistant?: boolean }
56
- | { type: 'cancelled' }
57
- | { type: 'done'; finishedNormally: boolean; stopReason?: TurnStopReason }
58
-
59
- export type PendingToolUse = {
60
- id: string
61
- name: string
62
- input: Record<string, unknown>
63
- }
64
-
65
- export type ExecutedToolUse = {
66
- id: string
67
- name: string
68
- input: Record<string, unknown>
69
- result: ToolResult
70
- cwd: string
71
- }
72
-
73
- export type ToolBatchRunner = (
74
- pendingToolUses: PendingToolUse[],
75
- ) => Promise<{ cancelled: boolean; completedTools: ExecutedToolUse[] }>
76
-
77
- export type RebuildMessages = () => Message[] | Promise<Message[]>
78
-
79
- export type RuntimeTurnParams = {
80
- provider: Provider
81
- signal: AbortSignal
82
- initialMessages: Message[]
83
- rebuildMessages: RebuildMessages
84
- runToolBatch: ToolBatchRunner
85
- maxContinuationNudges?: number
86
- }