ethagent 3.3.4 → 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.
- package/.claude-plugin/marketplace.json +11 -0
- package/.claude-plugin/plugin.json +35 -0
- package/LICENSE +1 -1
- package/README.md +64 -104
- package/commands/ethagent.md +40 -0
- package/package.json +16 -16
- package/src/app/keybindings/KeybindingProvider.tsx +1 -6
- package/src/app/keybindings/types.ts +1 -6
- package/src/cli/ResetConfirmView.tsx +54 -53
- package/src/cli/demo.ts +86 -0
- package/src/cli/hookIo.ts +45 -0
- package/src/cli/main.tsx +94 -123
- package/src/cli/memoryGuard.ts +49 -0
- package/src/cli/reset.ts +28 -70
- package/src/cli/sessionStart.ts +33 -0
- package/src/cli/status.ts +46 -0
- package/src/cli/sync.ts +167 -0
- package/src/cli/syncAdapters/claude-code.ts +86 -0
- package/src/cli/syncAdapters/codex.ts +66 -0
- package/src/cli/syncAdapters/index.ts +45 -0
- package/src/cli/syncAdapters/managedBlock.ts +175 -0
- package/src/cli/syncAdapters/shared.ts +63 -0
- package/src/identity/continuity/envelopeParse.ts +20 -1
- package/src/identity/continuity/publicSkills.ts +3 -1
- package/src/identity/continuity/skills/publicSkillsSync.ts +2 -1
- package/src/identity/continuity/skills/scaffold.ts +5 -2
- package/src/identity/continuity/snapshots.ts +12 -5
- package/src/identity/continuity/storage/defaults.ts +20 -19
- package/src/identity/continuity/storage/status.ts +1 -1
- package/src/identity/ens/ensLookup/constants.ts +1 -1
- package/src/identity/manager/IdentityManager.tsx +33 -0
- package/src/identity/{hub → manager}/OperationalRoutes.tsx +37 -18
- package/src/identity/{hub → manager}/Routes.tsx +48 -34
- package/src/identity/{hub → manager}/continuity/ContinuityDashboardScreen.tsx +9 -19
- package/src/identity/{hub → manager}/continuity/RebackupStorageScreen.tsx +3 -3
- package/src/identity/manager/continuity/RecoveryConfirmScreen.tsx +102 -0
- package/src/identity/{hub → manager}/continuity/SavePromptScreen.tsx +2 -3
- package/src/identity/{hub → manager}/continuity/completion.ts +1 -1
- package/src/identity/{hub → manager}/continuity/effects.ts +1 -1
- package/src/identity/{hub → manager}/continuity/skills/DeleteSkillConfirmScreen.tsx +2 -2
- package/src/identity/{hub → manager}/continuity/skills/NewSkillScreen.tsx +0 -5
- package/src/identity/{hub → manager}/continuity/skills/NewSkillVisibilityScreen.tsx +4 -4
- package/src/identity/{hub → manager}/continuity/skills/SkillActionsScreen.tsx +6 -22
- package/src/identity/{hub → manager}/continuity/skills/SkillsTreeScreen.tsx +5 -17
- package/src/identity/{hub → manager}/continuity/snapshot.ts +1 -1
- package/src/identity/{hub → manager}/continuity/vault.ts +1 -1
- package/src/identity/{hub → manager}/create/CreateFlow.tsx +59 -32
- package/src/identity/{hub → manager}/create/effects.ts +19 -10
- package/src/identity/manager/create/importScan.ts +122 -0
- package/src/identity/{hub → manager}/custody/CustodyEditFlow.tsx +17 -61
- package/src/identity/{hub → manager}/custody/actions.ts +1 -15
- package/src/identity/{hub → manager}/custody/routes.tsx +20 -40
- package/src/identity/{hub → manager}/custody/transactions.ts +1 -0
- package/src/identity/{hub → manager}/custody/types.ts +1 -2
- package/src/identity/{hub → manager}/custody/useCustodyEffects.ts +1 -1
- package/src/identity/{hub → manager}/ens/EnsEditAdvancedScreens.tsx +2 -2
- package/src/identity/{hub → manager}/ens/EnsEditMaintenanceScreens.tsx +12 -23
- package/src/identity/{hub → manager}/ens/EnsEditReviewScreens.tsx +18 -42
- package/src/identity/{hub → manager}/ens/EnsEditRunners.tsx +1 -1
- package/src/identity/{hub → manager}/ens/EnsEditShared.tsx +0 -2
- package/src/identity/{hub → manager}/ens/EnsEditSimpleScreens.tsx +10 -19
- package/src/identity/{hub → manager}/ens/EnsFlow.tsx +133 -41
- package/src/identity/{hub → manager}/ens/EnsOperatorWalletsScreen.tsx +14 -19
- package/src/identity/{hub → manager}/ens/editCopy.ts +1 -14
- package/src/identity/{hub → manager}/profile/EditProfileFlow.tsx +99 -66
- package/src/identity/{hub → manager}/profile/effects.ts +1 -3
- package/src/identity/{hub → manager}/profile/operatorSave.ts +1 -1
- package/src/identity/{hub → manager}/profile/state.ts +1 -1
- package/src/identity/{hub/identityHubReducer.ts → manager/reducer.ts} +25 -26
- package/src/identity/{hub → manager}/restore/RestoreFlow.tsx +16 -24
- package/src/identity/{hub → manager}/restore/apply.ts +1 -1
- package/src/identity/{hub → manager}/restore/auth.ts +1 -1
- package/src/identity/{hub → manager}/restore/discover.ts +1 -1
- package/src/identity/{hub → manager}/restore/fetch.ts +1 -1
- package/src/identity/{hub → manager}/restore/restoreAdmin.ts +1 -1
- package/src/identity/{hub → manager}/restore/useRestoreEffects.ts +2 -9
- package/src/identity/{hub → manager}/settings/StorageCredentialScreen.tsx +10 -25
- package/src/identity/{hub → manager}/shared/components/DetailsScreen.tsx +5 -7
- package/src/identity/{hub → manager}/shared/components/ErrorScreen.tsx +6 -10
- package/src/identity/{hub → manager}/shared/components/FlowTimeline.tsx +4 -3
- package/src/identity/{hub → manager}/shared/components/IdentitySummary.tsx +19 -59
- package/src/identity/manager/shared/components/LazyMenu.tsx +147 -0
- package/src/identity/manager/shared/components/MenuScreen.tsx +220 -0
- package/src/identity/manager/shared/components/OperationCompleteScreen.tsx +28 -0
- package/src/identity/{hub → manager}/shared/components/UnlinkedIdentityScreen.tsx +9 -10
- package/src/identity/{hub → manager}/shared/components/WalletApprovalScreen.tsx +1 -2
- package/src/identity/manager/shared/components/Wordmark.tsx +54 -0
- package/src/identity/{hub → manager}/shared/components/menuFlagsFromReconciliation.ts +39 -15
- package/src/identity/{hub → manager}/shared/effects/profilePrep.ts +1 -1
- package/src/identity/manager/shared/effects/types.ts +30 -0
- package/src/identity/{hub → manager}/shared/model/copy.ts +0 -4
- package/src/identity/{hub → manager}/shared/model/errors.ts +32 -3
- package/src/identity/{hub → manager}/shared/model/network.ts +2 -2
- package/src/identity/{hub → manager}/shared/reconciliation/agentReconciliation/hook.ts +5 -0
- package/src/identity/{hub → manager}/shared/reconciliation/agentReconciliation/run.ts +1 -1
- package/src/identity/{hub/shared/reconciliation/useAgentReconciliation.ts → manager/shared/reconciliation/index.ts} +6 -0
- package/src/identity/{hub → manager}/shared/utils.ts +6 -10
- package/src/identity/{hub → manager}/transfer/TokenTransferFlow.tsx +3 -3
- package/src/identity/{hub → manager}/transfer/TokenTransferScreens.tsx +4 -10
- package/src/identity/{hub → manager}/transfer/effects.ts +1 -1
- package/src/identity/{hub → manager}/types.ts +5 -6
- package/src/identity/{hub/useIdentityHubContinuity.ts → manager/useContinuity.ts} +59 -27
- package/src/identity/{hub/useIdentityHubController.ts → manager/useController.ts} +38 -35
- package/src/identity/{hub/useIdentityHubSideEffects.ts → manager/useSideEffects.ts} +40 -4
- package/src/identity/registry/erc8004/discovery.ts +3 -17
- package/src/identity/registry/erc8004/utils.ts +1 -1
- package/src/identity/storage/ipfs.ts +21 -1
- package/src/identity/wallet/browserWallet/html.ts +10 -2
- package/src/identity/wallet/browserWallet/http.ts +18 -0
- package/src/identity/wallet/browserWallet/requestServer.ts +5 -1
- package/src/identity/wallet/browserWallet/requests.ts +10 -28
- package/src/identity/wallet/browserWallet/session.ts +26 -33
- package/src/identity/wallet/browserWallet/validation.ts +14 -0
- package/src/identity/wallet/browserWallet/walletPageSource.ts +22 -40
- package/src/identity/wallet/page/boot.ts +43 -0
- package/src/identity/wallet/page/config.ts +59 -0
- package/src/identity/wallet/page/constants.ts +12 -0
- package/src/identity/wallet/page/copy.ts +47 -68
- package/src/identity/wallet/page/css.ts +638 -0
- package/src/identity/wallet/page/{errorView.ts → errors.ts} +5 -14
- package/src/identity/wallet/page/{controller.ts → flow.ts} +4 -71
- package/src/identity/wallet/page/markup.ts +44 -34
- package/src/identity/wallet/page/{walletProvider.ts → provider.ts} +0 -3
- package/src/identity/wallet/page/resize.ts +95 -0
- package/src/identity/wallet/page/state.ts +135 -8
- package/src/identity/wallet/page/timeline.ts +161 -0
- package/src/identity/wallet/page/view.ts +22 -302
- package/src/storage/config.ts +30 -80
- package/src/storage/reset.ts +31 -0
- package/src/storage/secrets.ts +1 -16
- package/src/ui/Select.tsx +27 -5
- package/src/ui/Spinner.tsx +16 -15
- package/src/ui/Surface.tsx +21 -17
- package/src/ui/TextArea.tsx +173 -0
- package/src/ui/TextInput.tsx +31 -133
- package/src/ui/theme.ts +22 -13
- package/src/utils/clipboard.ts +0 -140
- package/src/app/FirstRun.tsx +0 -577
- package/src/app/FirstRunTimeline.tsx +0 -51
- package/src/app/firstRunConfig.ts +0 -26
- package/src/app/hooks/useCancelRequest.ts +0 -22
- package/src/app/hooks/useDoublePress.ts +0 -46
- package/src/app/hooks/useExitOnCtrlC.ts +0 -36
- package/src/auth/openaiOAuth/credentials.ts +0 -47
- package/src/auth/openaiOAuth/crypto.ts +0 -23
- package/src/auth/openaiOAuth/index.ts +0 -238
- package/src/auth/openaiOAuth/landingPage.ts +0 -116
- package/src/auth/openaiOAuth/listener.ts +0 -151
- package/src/auth/openaiOAuth/refresh.ts +0 -70
- package/src/auth/openaiOAuth/shared.ts +0 -115
- package/src/chat/ChatBottomPane.tsx +0 -296
- package/src/chat/ChatScreen.tsx +0 -1685
- package/src/chat/ConversationStack.tsx +0 -56
- package/src/chat/MessageList.tsx +0 -638
- package/src/chat/SessionStatus.tsx +0 -53
- package/src/chat/chatEnvironment.ts +0 -16
- package/src/chat/chatScreenUtils.ts +0 -194
- package/src/chat/chatSessionState.ts +0 -146
- package/src/chat/chatTurnContext.ts +0 -50
- package/src/chat/chatTurnOrchestrator.ts +0 -603
- package/src/chat/chatTurnRows.ts +0 -64
- package/src/chat/commands.ts +0 -494
- package/src/chat/continuityEditReview.ts +0 -42
- package/src/chat/display/DiffView.tsx +0 -193
- package/src/chat/display/SyntaxText.tsx +0 -192
- package/src/chat/display/toolCallDisplay.ts +0 -103
- package/src/chat/display/toolResultDisplay.ts +0 -19
- package/src/chat/input/ChatInput.tsx +0 -625
- package/src/chat/input/chatInputHelpers.ts +0 -62
- package/src/chat/input/chatInputState.ts +0 -247
- package/src/chat/input/chatPaste.ts +0 -49
- package/src/chat/input/imageRefs.ts +0 -30
- package/src/chat/input/inputRendering.tsx +0 -93
- package/src/chat/input/textCursor.ts +0 -212
- package/src/chat/messageMarkdown.ts +0 -220
- package/src/chat/messageRows.ts +0 -43
- package/src/chat/planImplementation.ts +0 -62
- package/src/chat/slashCommandHandlers.ts +0 -122
- package/src/chat/slashCommandViews.ts +0 -120
- package/src/chat/transcript/TranscriptView.tsx +0 -184
- package/src/chat/transcript/transcriptViewport.ts +0 -295
- package/src/chat/views/ContextLimitView.tsx +0 -95
- package/src/chat/views/ContinuityEditReviewView.tsx +0 -50
- package/src/chat/views/CopyPicker.tsx +0 -50
- package/src/chat/views/PermissionPrompt.tsx +0 -156
- package/src/chat/views/PermissionsView.tsx +0 -165
- package/src/chat/views/PlanApprovalView.tsx +0 -91
- package/src/chat/views/ResumeView.tsx +0 -273
- package/src/chat/views/RewindView.tsx +0 -412
- package/src/cli/preview.tsx +0 -14
- package/src/cli/updateNotice.ts +0 -54
- package/src/identity/continuity/privateEdit/apply.ts +0 -170
- package/src/identity/continuity/privateEdit/diff.ts +0 -6
- package/src/identity/continuity/privateEdit/files.ts +0 -23
- package/src/identity/continuity/privateEdit/types.ts +0 -28
- package/src/identity/continuity/privateEdit.ts +0 -46
- package/src/identity/hub/IdentityHub.tsx +0 -14
- package/src/identity/hub/continuity/RecoveryConfirmScreen.tsx +0 -104
- package/src/identity/hub/ens/effects.ts +0 -218
- package/src/identity/hub/shared/components/MenuScreen.tsx +0 -241
- package/src/identity/hub/shared/effects/types.ts +0 -53
- package/src/identity/hub/shared/reconciliation/index.ts +0 -14
- package/src/identity/wallet/page/grainient.ts +0 -278
- package/src/identity/wallet/page/html.ts +0 -28
- package/src/identity/wallet/page/styles/base.ts +0 -260
- package/src/identity/wallet/page/styles/components.ts +0 -262
- package/src/identity/wallet/page/styles/index.ts +0 -5
- package/src/identity/wallet/page/styles/responsive.ts +0 -247
- package/src/identity/wallet/page.tsx +0 -38
- package/src/mcp/approvals.ts +0 -113
- package/src/mcp/config.ts +0 -235
- package/src/mcp/manager.ts +0 -482
- package/src/mcp/managerHelpers.ts +0 -70
- package/src/mcp/names.ts +0 -19
- package/src/mcp/output.ts +0 -96
- package/src/models/ModelPicker.tsx +0 -1009
- package/src/models/catalog.ts +0 -327
- package/src/models/huggingface.ts +0 -712
- package/src/models/huggingfaceStorage.ts +0 -136
- package/src/models/llamacpp.ts +0 -848
- package/src/models/llamacppCommands.ts +0 -44
- package/src/models/llamacppConfig.ts +0 -34
- package/src/models/llamacppDiscovery.ts +0 -176
- package/src/models/llamacppOutput.ts +0 -65
- package/src/models/llamacppPreflight.ts +0 -158
- package/src/models/modelDisplay.ts +0 -180
- package/src/models/modelPickerCatalogFlow.ts +0 -56
- package/src/models/modelPickerCredentials.ts +0 -166
- package/src/models/modelPickerData.ts +0 -41
- package/src/models/modelPickerDisplay.tsx +0 -132
- package/src/models/modelPickerHfFlow.ts +0 -192
- package/src/models/modelPickerLocalRunnerFlow.ts +0 -115
- package/src/models/modelPickerOptions.ts +0 -457
- package/src/models/modelPickerTypes.ts +0 -69
- package/src/models/modelPickerUninstallFlow.ts +0 -48
- package/src/models/modelPickerViewHelpers.ts +0 -174
- package/src/models/modelRecommendation.ts +0 -139
- package/src/models/providerDisplay.ts +0 -16
- package/src/models/runtimeDetection.ts +0 -81
- package/src/models/uncensoredCatalog.ts +0 -86
- package/src/providers/anthropic.ts +0 -290
- package/src/providers/contracts.ts +0 -71
- package/src/providers/errors.ts +0 -80
- package/src/providers/gemini.ts +0 -391
- package/src/providers/openai-chat.ts +0 -474
- package/src/providers/openai-responses-format.ts +0 -177
- package/src/providers/openai-responses.ts +0 -306
- package/src/providers/openaiChatWire.ts +0 -124
- package/src/providers/registry.ts +0 -120
- package/src/providers/retry.ts +0 -58
- package/src/providers/sse.ts +0 -93
- package/src/runtime/compaction.ts +0 -395
- package/src/runtime/cwd.ts +0 -43
- package/src/runtime/providerTurn.ts +0 -38
- package/src/runtime/sessionMode.ts +0 -55
- package/src/runtime/systemPrompt.ts +0 -213
- package/src/runtime/textToolParser.ts +0 -161
- package/src/runtime/toolClaimGuards.ts +0 -143
- package/src/runtime/toolExecution.ts +0 -304
- package/src/runtime/toolIntent.ts +0 -143
- package/src/runtime/turn.ts +0 -369
- package/src/runtime/turnNudges.ts +0 -223
- package/src/runtime/turnTypes.ts +0 -86
- package/src/storage/factoryReset.ts +0 -127
- package/src/storage/history.ts +0 -58
- package/src/storage/permissions.ts +0 -76
- package/src/storage/rewind.ts +0 -266
- package/src/storage/sessionExport.ts +0 -49
- package/src/storage/sessions.ts +0 -495
- package/src/tools/bashSafety.ts +0 -186
- package/src/tools/bashTool.ts +0 -140
- package/src/tools/changeDirectoryTool.ts +0 -213
- package/src/tools/contracts.ts +0 -192
- package/src/tools/deleteFileTool.ts +0 -116
- package/src/tools/editTool.ts +0 -165
- package/src/tools/editUtils.ts +0 -170
- package/src/tools/fileDiff.ts +0 -261
- package/src/tools/listDirectoryTool.ts +0 -55
- package/src/tools/listSkillFilesTool.ts +0 -77
- package/src/tools/listSkillsTool.ts +0 -68
- package/src/tools/mcpResourceTools.ts +0 -95
- package/src/tools/permissionRules.ts +0 -85
- package/src/tools/privateContinuityEditTool.ts +0 -187
- package/src/tools/privateContinuityReadTool.ts +0 -106
- package/src/tools/readSkillTool.ts +0 -107
- package/src/tools/readTool.ts +0 -85
- package/src/tools/registry.ts +0 -103
- package/src/tools/writeFileTool.ts +0 -167
- package/src/ui/BrandSplash.tsx +0 -133
- package/src/ui/terminalTitle.ts +0 -30
- package/src/utils/images.ts +0 -140
- package/src/utils/markdownSegments.ts +0 -51
- package/src/utils/messages.ts +0 -37
- package/src/utils/withRetry.ts +0 -324
- /package/src/identity/{hub → manager}/continuity/state.ts +0 -0
- /package/src/identity/{hub → manager}/custody/helpers.ts +0 -0
- /package/src/identity/{hub → manager}/custody/preflight.ts +0 -0
- /package/src/identity/{hub → manager}/custody/state.ts +0 -0
- /package/src/identity/{hub → manager}/custody/useCustodyFlow.tsx +0 -0
- /package/src/identity/{hub → manager}/ens/EnsEditFlow.tsx +0 -0
- /package/src/identity/{hub → manager}/ens/advancedEnsValidation.ts +0 -0
- /package/src/identity/{hub → manager}/ens/state.ts +0 -0
- /package/src/identity/{hub → manager}/ens/transactions.ts +0 -0
- /package/src/identity/{hub → manager}/ens/types.ts +0 -0
- /package/src/identity/{hub → manager}/profile/identity.ts +0 -0
- /package/src/identity/{hub → manager}/restore/envelopes.ts +0 -0
- /package/src/identity/{hub → manager}/restore/helpers.ts +0 -0
- /package/src/identity/{hub → manager}/restore/recovery.ts +0 -0
- /package/src/identity/{hub → manager}/restore/resolve.ts +0 -0
- /package/src/identity/{hub → manager}/shared/components/BusyScreen.tsx +0 -0
- /package/src/identity/{hub → manager}/shared/components/NetworkScreen.tsx +0 -0
- /package/src/identity/{hub → manager}/shared/components/PinataJwtInput.tsx +0 -0
- /package/src/identity/{hub → manager}/shared/effects/receipts.ts +0 -0
- /package/src/identity/{hub → manager}/shared/effects/sync.ts +0 -0
- /package/src/identity/{hub → manager}/shared/model/format.ts +0 -0
- /package/src/identity/{hub → manager}/shared/operatorWallets.ts +0 -0
- /package/src/identity/{hub → manager}/shared/reconciliation/agentReconciliation/ownership.ts +0 -0
- /package/src/identity/{hub → manager}/shared/reconciliation/agentReconciliation/types.ts +0 -0
- /package/src/identity/{hub → manager}/shared/reconciliation/walletSetup.ts +0 -0
- /package/src/identity/{hub → manager}/shared/txGuard.ts +0 -0
- /package/src/identity/{hub → manager}/transfer/progress.ts +0 -0
- /package/src/identity/{hub → manager}/transfer/state.ts +0 -0
|
@@ -1,395 +0,0 @@
|
|
|
1
|
-
import type { Message, Provider } from '../providers/contracts.js'
|
|
2
|
-
import { approximateTokens, messageTextContent } from '../utils/messages.js'
|
|
3
|
-
import type { SessionMessage } from '../storage/sessions.js'
|
|
4
|
-
import { getCachedLlamaCppContextSize } from '../models/llamacpp.js'
|
|
5
|
-
|
|
6
|
-
const COMPACT_SYSTEM = `Create a continuation handoff for this coding-agent conversation.
|
|
7
|
-
Keep it concise but complete. Preserve the current goal, user constraints, key decisions, relevant files, tool results, pending tasks, and known failures. Do not claim unverified work was completed. No preamble.`
|
|
8
|
-
|
|
9
|
-
const LOCAL_COMPACTION_INPUT_TOKENS = 6_000
|
|
10
|
-
const CLOUD_COMPACTION_INPUT_TOKENS = 24_000
|
|
11
|
-
const LOCAL_COMPACTION_OUTPUT_TOKENS = 1_000
|
|
12
|
-
const CLOUD_COMPACTION_OUTPUT_TOKENS = 1_600
|
|
13
|
-
const LOCAL_RECENT_MESSAGE_COUNT = 28
|
|
14
|
-
const CLOUD_RECENT_MESSAGE_COUNT = 80
|
|
15
|
-
const LOCAL_MESSAGE_CHAR_LIMIT = 900
|
|
16
|
-
const CLOUD_MESSAGE_CHAR_LIMIT = 2_000
|
|
17
|
-
|
|
18
|
-
export type CompactionStage =
|
|
19
|
-
| 'preparing transcript'
|
|
20
|
-
| 'compressing long context'
|
|
21
|
-
| 'summarizing transcript'
|
|
22
|
-
|
|
23
|
-
export type CompactTranscriptOptions = {
|
|
24
|
-
signal?: AbortSignal
|
|
25
|
-
onStage?: (stage: CompactionStage) => void
|
|
26
|
-
maxInputTokens?: number
|
|
27
|
-
maxOutputTokens?: number
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export type CompactTranscriptResult =
|
|
31
|
-
| { ok: true; summary: string; inputTokens: number; compressed: boolean }
|
|
32
|
-
| { ok: false; reason: string; cancelled?: boolean; inputTokens?: number; compressed?: boolean }
|
|
33
|
-
|
|
34
|
-
export type CompactionSource = {
|
|
35
|
-
text: string
|
|
36
|
-
inputTokens: number
|
|
37
|
-
compressed: boolean
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export type ContextWindowConfidence = 'exact' | 'inferred' | 'fallback'
|
|
41
|
-
|
|
42
|
-
export type ContextWindowInfo = {
|
|
43
|
-
tokens: number
|
|
44
|
-
confidence: ContextWindowConfidence
|
|
45
|
-
source: string
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export type ContextUsage = {
|
|
49
|
-
usedTokens: number
|
|
50
|
-
windowTokens: number
|
|
51
|
-
percent: number
|
|
52
|
-
confidence: ContextWindowConfidence
|
|
53
|
-
source: string
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export function contextWindow(model: string): number {
|
|
57
|
-
return contextWindowInfo('', model).tokens
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export function contextWindowInfo(provider: string, model: string): ContextWindowInfo {
|
|
61
|
-
const lower = model.toLowerCase()
|
|
62
|
-
const providerLower = provider.toLowerCase()
|
|
63
|
-
if (providerLower === 'llamacpp') {
|
|
64
|
-
const cached = getCachedLlamaCppContextSize()
|
|
65
|
-
if (cached) {
|
|
66
|
-
return { tokens: cached, confidence: 'exact', source: 'llama.cpp /props' }
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
if (lower.startsWith('qwen3:4b') || lower.startsWith('qwen3:30b') || lower.startsWith('qwen3:235b')) {
|
|
70
|
-
return { tokens: 256_000, confidence: 'inferred', source: 'qwen3 long-context tag' }
|
|
71
|
-
}
|
|
72
|
-
if (lower.includes('qwen3')) {
|
|
73
|
-
return { tokens: 40_000, confidence: 'inferred', source: 'qwen3 default' }
|
|
74
|
-
}
|
|
75
|
-
if (lower.includes('qwen')) {
|
|
76
|
-
return { tokens: 32_768, confidence: 'inferred', source: 'qwen default' }
|
|
77
|
-
}
|
|
78
|
-
if (lower.includes('llama3')) {
|
|
79
|
-
return { tokens: 128_000, confidence: 'inferred', source: 'llama3 family default' }
|
|
80
|
-
}
|
|
81
|
-
if (providerLower === 'anthropic' || lower.includes('claude')) {
|
|
82
|
-
return { tokens: 200_000, confidence: 'inferred', source: 'claude family default' }
|
|
83
|
-
}
|
|
84
|
-
if (providerLower === 'gemini' || lower.includes('gemini')) {
|
|
85
|
-
return { tokens: 1_000_000, confidence: 'inferred', source: 'gemini family default' }
|
|
86
|
-
}
|
|
87
|
-
if (
|
|
88
|
-
lower.includes('gpt-4.1')
|
|
89
|
-
) {
|
|
90
|
-
return { tokens: 1_000_000, confidence: 'inferred', source: 'gpt-4.1 family default' }
|
|
91
|
-
}
|
|
92
|
-
if (
|
|
93
|
-
providerLower === 'openai'
|
|
94
|
-
|| lower.includes('gpt-4o')
|
|
95
|
-
|| /^o[134](?:-|$)/.test(lower)
|
|
96
|
-
) {
|
|
97
|
-
return { tokens: 128_000, confidence: 'inferred', source: 'openai chat default' }
|
|
98
|
-
}
|
|
99
|
-
return { tokens: 128_000, confidence: 'fallback', source: 'ethagent fallback' }
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
export function contextUsage(messages: Message[], provider: string, model: string): ContextUsage {
|
|
103
|
-
return contextUsageFromTokens(approximateTokens(messages), provider, model)
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export function contextUsageFromTokens(tokens: number, provider: string, model: string): ContextUsage {
|
|
107
|
-
const info = contextWindowInfo(provider, model)
|
|
108
|
-
const usedTokens = Math.max(0, Math.ceil(tokens))
|
|
109
|
-
return {
|
|
110
|
-
usedTokens,
|
|
111
|
-
windowTokens: info.tokens,
|
|
112
|
-
percent: info.tokens > 0 ? Math.round((usedTokens / info.tokens) * 100) : 0,
|
|
113
|
-
confidence: info.confidence,
|
|
114
|
-
source: info.source,
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
export function shouldConfirmContextUsage(usage: Pick<ContextUsage, 'percent'>, thresholdPercent = 90): boolean {
|
|
119
|
-
return usage.percent >= thresholdPercent
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
export async function compactTranscript(
|
|
123
|
-
provider: Provider,
|
|
124
|
-
transcript: Message[],
|
|
125
|
-
options: CompactTranscriptOptions = {},
|
|
126
|
-
): Promise<CompactTranscriptResult> {
|
|
127
|
-
const nonSystem = transcript.filter(m => m.role !== 'system')
|
|
128
|
-
if (nonSystem.length < 2) {
|
|
129
|
-
return { ok: false, reason: 'not enough turns to compact' }
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
options.onStage?.('preparing transcript')
|
|
133
|
-
const source = buildCompactionSource(transcript, provider.id, {
|
|
134
|
-
maxInputTokens: options.maxInputTokens,
|
|
135
|
-
})
|
|
136
|
-
if (source.compressed) options.onStage?.('compressing long context')
|
|
137
|
-
|
|
138
|
-
const prompt: Message[] = [
|
|
139
|
-
{ role: 'system', content: COMPACT_SYSTEM },
|
|
140
|
-
{ role: 'user', content: `Create a continuation handoff from this conversation context:\n\n${source.text}` },
|
|
141
|
-
]
|
|
142
|
-
|
|
143
|
-
const controller = options.signal ? null : new AbortController()
|
|
144
|
-
const signal = options.signal ?? controller!.signal
|
|
145
|
-
let summary = ''
|
|
146
|
-
const local = isLocalProviderId(provider.id)
|
|
147
|
-
options.onStage?.('summarizing transcript')
|
|
148
|
-
try {
|
|
149
|
-
for await (const ev of provider.complete(prompt, signal, {
|
|
150
|
-
maxTokens: options.maxOutputTokens ?? (local ? LOCAL_COMPACTION_OUTPUT_TOKENS : CLOUD_COMPACTION_OUTPUT_TOKENS),
|
|
151
|
-
})) {
|
|
152
|
-
if (signal.aborted) return { ok: false, reason: 'cancelled', cancelled: true, inputTokens: source.inputTokens, compressed: source.compressed }
|
|
153
|
-
if (ev.type === 'text') summary += ev.delta
|
|
154
|
-
else if (ev.type === 'error') return { ok: false, reason: ev.message }
|
|
155
|
-
else if (ev.type === 'done') break
|
|
156
|
-
}
|
|
157
|
-
} catch (err: unknown) {
|
|
158
|
-
if (signal.aborted) return { ok: false, reason: 'cancelled', cancelled: true, inputTokens: source.inputTokens, compressed: source.compressed }
|
|
159
|
-
return { ok: false, reason: (err as Error).message || 'compact stream error' }
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
if (signal.aborted) return { ok: false, reason: 'cancelled', cancelled: true, inputTokens: source.inputTokens, compressed: source.compressed }
|
|
163
|
-
summary = summary.trim()
|
|
164
|
-
if (summary.length < 40) return { ok: false, reason: 'summary too short', inputTokens: source.inputTokens, compressed: source.compressed }
|
|
165
|
-
|
|
166
|
-
return { ok: true, summary, inputTokens: source.inputTokens, compressed: source.compressed }
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
export function buildCompactionSource(
|
|
170
|
-
transcript: Message[],
|
|
171
|
-
providerId: Provider['id'],
|
|
172
|
-
options: { maxInputTokens?: number } = {},
|
|
173
|
-
): CompactionSource {
|
|
174
|
-
const nonSystem = transcript.filter(m => m.role !== 'system')
|
|
175
|
-
const local = isLocalProviderId(providerId)
|
|
176
|
-
const tokenBudget = options.maxInputTokens ?? (local ? LOCAL_COMPACTION_INPUT_TOKENS : CLOUD_COMPACTION_INPUT_TOKENS)
|
|
177
|
-
const charBudget = Math.max(1_000, tokenBudget * 3)
|
|
178
|
-
const recentMessageCount = local ? LOCAL_RECENT_MESSAGE_COUNT : CLOUD_RECENT_MESSAGE_COUNT
|
|
179
|
-
const messageCharLimit = local ? LOCAL_MESSAGE_CHAR_LIMIT : CLOUD_MESSAGE_CHAR_LIMIT
|
|
180
|
-
const rawTokenEstimate = approximateTokens(nonSystem)
|
|
181
|
-
const mustCompress = rawTokenEstimate > tokenBudget || nonSystem.length > recentMessageCount
|
|
182
|
-
|
|
183
|
-
if (!mustCompress) {
|
|
184
|
-
const text = nonSystem.map((message, index) =>
|
|
185
|
-
formatCompactionMessage(message, index + 1, messageCharLimit),
|
|
186
|
-
).join('\n\n')
|
|
187
|
-
return {
|
|
188
|
-
text,
|
|
189
|
-
inputTokens: approximateTextTokens(text),
|
|
190
|
-
compressed: false,
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
const recent = nonSystem.slice(-recentMessageCount)
|
|
195
|
-
const earlier = nonSystem.slice(0, Math.max(0, nonSystem.length - recent.length))
|
|
196
|
-
const parts: string[] = []
|
|
197
|
-
parts.push('Deterministic pre-summary of earlier context:')
|
|
198
|
-
parts.push(summarizeTranscriptLocally(earlier.length > 0 ? earlier : nonSystem, 'input was bounded before model summarization'))
|
|
199
|
-
parts.push('')
|
|
200
|
-
parts.push('Recent transcript excerpts:')
|
|
201
|
-
parts.push(...recent.map((message, index) =>
|
|
202
|
-
formatCompactionMessage(message, nonSystem.length - recent.length + index + 1, messageCharLimit),
|
|
203
|
-
))
|
|
204
|
-
|
|
205
|
-
const bounded = limitCompactionText(parts.join('\n\n'), charBudget)
|
|
206
|
-
return {
|
|
207
|
-
text: bounded,
|
|
208
|
-
inputTokens: approximateTextTokens(bounded),
|
|
209
|
-
compressed: true,
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
export function summarizeTranscriptLocally(
|
|
214
|
-
transcript: Message[],
|
|
215
|
-
reason?: string,
|
|
216
|
-
): string {
|
|
217
|
-
const nonSystem = transcript.filter(m => m.role !== 'system')
|
|
218
|
-
const userRequests: string[] = []
|
|
219
|
-
const assistantReplies: string[] = []
|
|
220
|
-
const toolNotes: string[] = []
|
|
221
|
-
|
|
222
|
-
for (const message of nonSystem) {
|
|
223
|
-
const text = oneLine(messageTextContent(message), 240)
|
|
224
|
-
if (!text) continue
|
|
225
|
-
if (message.role === 'user') userRequests.push(text)
|
|
226
|
-
else if (message.role === 'assistant') assistantReplies.push(text)
|
|
227
|
-
else toolNotes.push(`${message.role}: ${text}`)
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
const parts = [
|
|
231
|
-
'Local conversation summary for continuation.',
|
|
232
|
-
reason ? `Provider summary was unavailable: ${oneLine(reason, 180)}.` : '',
|
|
233
|
-
].filter(Boolean)
|
|
234
|
-
|
|
235
|
-
if (userRequests.length > 0) {
|
|
236
|
-
parts.push('Recent user requests:')
|
|
237
|
-
parts.push(...userRequests.slice(-8).map(item => `- ${item}`))
|
|
238
|
-
}
|
|
239
|
-
if (assistantReplies.length > 0) {
|
|
240
|
-
parts.push('Recent assistant progress:')
|
|
241
|
-
parts.push(...assistantReplies.slice(-6).map(item => `- ${item}`))
|
|
242
|
-
}
|
|
243
|
-
if (toolNotes.length > 0) {
|
|
244
|
-
parts.push('Recent tool context:')
|
|
245
|
-
parts.push(...toolNotes.slice(-6).map(item => `- ${item}`))
|
|
246
|
-
}
|
|
247
|
-
parts.push('Continue from this summary, and verify current files or external state before relying on stale details.')
|
|
248
|
-
|
|
249
|
-
return parts.join('\n')
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
export type MicroCompactOptions = {
|
|
253
|
-
activeTurnId?: string
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
export type MicroCompactResult = {
|
|
257
|
-
messages: SessionMessage[]
|
|
258
|
-
compactedTurns: number
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
const RECENT_TURN_BUDGET = 15
|
|
262
|
-
const TRIGGER_MESSAGE_COUNT = 50
|
|
263
|
-
|
|
264
|
-
export function shouldMicroCompact(messages: SessionMessage[]): boolean {
|
|
265
|
-
return messages.length > TRIGGER_MESSAGE_COUNT
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
export function microCompactSessionMessages(
|
|
269
|
-
messages: SessionMessage[],
|
|
270
|
-
options: MicroCompactOptions = {},
|
|
271
|
-
): MicroCompactResult {
|
|
272
|
-
if (!shouldMicroCompact(messages)) {
|
|
273
|
-
return { messages, compactedTurns: 0 }
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
const turnOrder: string[] = []
|
|
277
|
-
const turnsSeen = new Set<string>()
|
|
278
|
-
for (const message of messages) {
|
|
279
|
-
if (message.role !== 'user') continue
|
|
280
|
-
const turnId = (message as { turnId?: string }).turnId
|
|
281
|
-
if (!turnId || turnsSeen.has(turnId)) continue
|
|
282
|
-
turnsSeen.add(turnId)
|
|
283
|
-
turnOrder.push(turnId)
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
if (turnOrder.length <= RECENT_TURN_BUDGET) {
|
|
287
|
-
return { messages, compactedTurns: 0 }
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
const keepTurnIds = new Set(turnOrder.slice(turnOrder.length - RECENT_TURN_BUDGET))
|
|
291
|
-
if (options.activeTurnId) keepTurnIds.add(options.activeTurnId)
|
|
292
|
-
|
|
293
|
-
const oldMessages: SessionMessage[] = []
|
|
294
|
-
const kept: SessionMessage[] = []
|
|
295
|
-
for (const message of messages) {
|
|
296
|
-
const turnId = (message as { turnId?: string }).turnId
|
|
297
|
-
if (!turnId) {
|
|
298
|
-
kept.push(message)
|
|
299
|
-
continue
|
|
300
|
-
}
|
|
301
|
-
if (keepTurnIds.has(turnId)) {
|
|
302
|
-
kept.push(message)
|
|
303
|
-
} else {
|
|
304
|
-
oldMessages.push(message)
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
if (oldMessages.length === 0) {
|
|
309
|
-
return { messages, compactedTurns: 0 }
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
const compactedTurns = new Set(
|
|
313
|
-
oldMessages
|
|
314
|
-
.map(message => (message as { turnId?: string }).turnId)
|
|
315
|
-
.filter((id): id is string => typeof id === 'string'),
|
|
316
|
-
)
|
|
317
|
-
|
|
318
|
-
const summary = summarizeCompactedTurns(oldMessages)
|
|
319
|
-
const firstKeptIndex = messages.findIndex(m => kept.includes(m))
|
|
320
|
-
const summaryMessage: SessionMessage = {
|
|
321
|
-
role: 'assistant',
|
|
322
|
-
content: summary,
|
|
323
|
-
createdAt: oldMessages[oldMessages.length - 1]!.createdAt,
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
const out: SessionMessage[] = []
|
|
327
|
-
if (firstKeptIndex > 0) {
|
|
328
|
-
out.push(...messages.slice(0, firstKeptIndex).filter(m => !oldMessages.includes(m)))
|
|
329
|
-
}
|
|
330
|
-
out.push(summaryMessage)
|
|
331
|
-
out.push(...kept)
|
|
332
|
-
return { messages: out, compactedTurns: compactedTurns.size }
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
function summarizeCompactedTurns(messages: SessionMessage[]): string {
|
|
336
|
-
const userRequests: string[] = []
|
|
337
|
-
const assistantReplies: string[] = []
|
|
338
|
-
|
|
339
|
-
for (const message of messages) {
|
|
340
|
-
if (message.role === 'user') {
|
|
341
|
-
const content = typeof message.content === 'string' ? message.content : ''
|
|
342
|
-
if (content.trim()) userRequests.push(oneLine(content, 140))
|
|
343
|
-
} else if (message.role === 'assistant') {
|
|
344
|
-
const content = typeof message.content === 'string' ? message.content : ''
|
|
345
|
-
if (content.trim()) assistantReplies.push(oneLine(content, 140))
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
const parts = ['[Earlier conversation context was compacted to fit the model\'s context window.]']
|
|
350
|
-
if (userRequests.length > 0) {
|
|
351
|
-
const sample = userRequests.slice(-5)
|
|
352
|
-
parts.push(`Most recent earlier user requests: ${sample.map(item => `"${item}"`).join('; ')}`)
|
|
353
|
-
}
|
|
354
|
-
if (assistantReplies.length > 0) {
|
|
355
|
-
const last = assistantReplies[assistantReplies.length - 1]!
|
|
356
|
-
parts.push(`Most recent earlier assistant reply: "${last}"`)
|
|
357
|
-
}
|
|
358
|
-
parts.push('Treat the above as background; respond to the current user message next.')
|
|
359
|
-
return parts.join(' ')
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
function oneLine(text: string, limit: number): string {
|
|
363
|
-
const normalized = text.replace(/\s+/g, ' ').trim()
|
|
364
|
-
if (normalized.length <= limit) return normalized
|
|
365
|
-
return `${normalized.slice(0, Math.max(0, limit - 3))}...`
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
function isLocalProviderId(providerId: Provider['id']): boolean {
|
|
369
|
-
return providerId === 'llamacpp'
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
function formatCompactionMessage(message: Message, index: number, limit: number): string {
|
|
373
|
-
const text = oneLine(messageTextContent(message), limit)
|
|
374
|
-
return `${index}. ${message.role}: ${text || '[empty]'}`
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
function limitCompactionText(text: string, charBudget: number): string {
|
|
378
|
-
if (text.length <= charBudget) return text
|
|
379
|
-
const recentHeader = 'Recent transcript excerpts:'
|
|
380
|
-
const recentIndex = text.indexOf(recentHeader)
|
|
381
|
-
if (recentIndex !== -1) {
|
|
382
|
-
const prefixEnd = recentIndex + recentHeader.length
|
|
383
|
-
const prefix = text.slice(0, prefixEnd)
|
|
384
|
-
const marker = '[Earlier recent transcript excerpts omitted to keep local summarization responsive.]'
|
|
385
|
-
const tailBudget = Math.max(0, charBudget - prefix.length - marker.length - 4)
|
|
386
|
-
return `${prefix}\n\n${marker}\n\n${text.slice(Math.max(prefixEnd, text.length - tailBudget))}`
|
|
387
|
-
}
|
|
388
|
-
const marker = '[Earlier bounded compaction text omitted to keep local summarization responsive.]'
|
|
389
|
-
const tailBudget = Math.max(0, charBudget - marker.length - 2)
|
|
390
|
-
return `${marker}\n\n${text.slice(Math.max(0, text.length - tailBudget))}`
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
function approximateTextTokens(text: string): number {
|
|
394
|
-
return Math.ceil(text.length / 3)
|
|
395
|
-
}
|
package/src/runtime/cwd.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs'
|
|
2
|
-
import os from 'node:os'
|
|
3
|
-
import path from 'node:path'
|
|
4
|
-
|
|
5
|
-
let cwdState = normalizeExistingPath(process.cwd())
|
|
6
|
-
|
|
7
|
-
export function getCwd(): string {
|
|
8
|
-
return cwdState
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function syncCwdFromProcess(): string {
|
|
12
|
-
cwdState = normalizeExistingPath(process.cwd())
|
|
13
|
-
return cwdState
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export function setCwd(next: string, relativeTo = cwdState): string {
|
|
17
|
-
const resolved = normalizeRequestedPath(next, relativeTo)
|
|
18
|
-
process.chdir(resolved)
|
|
19
|
-
cwdState = normalizeExistingPath(process.cwd())
|
|
20
|
-
return cwdState
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function resolveUserPath(input: string, relativeTo = cwdState): string {
|
|
24
|
-
return normalizeRequestedPath(input, relativeTo)
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function normalizeRequestedPath(input: string, relativeTo: string): string {
|
|
28
|
-
const expanded = input.startsWith('~')
|
|
29
|
-
? path.join(os.homedir(), input.slice(1))
|
|
30
|
-
: input
|
|
31
|
-
const resolved = path.isAbsolute(expanded)
|
|
32
|
-
? expanded
|
|
33
|
-
: path.resolve(relativeTo, expanded)
|
|
34
|
-
return normalizeExistingPath(resolved)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function normalizeExistingPath(input: string): string {
|
|
38
|
-
try {
|
|
39
|
-
return fs.realpathSync.native(input)
|
|
40
|
-
} catch {
|
|
41
|
-
return path.resolve(input)
|
|
42
|
-
}
|
|
43
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import type { Message, Provider, StreamEvent } from '../providers/contracts.js'
|
|
2
|
-
import type { ProviderTurnEvent } from './turnTypes.js'
|
|
3
|
-
|
|
4
|
-
export async function* runProviderTurn(
|
|
5
|
-
provider: Provider,
|
|
6
|
-
messages: Message[],
|
|
7
|
-
signal: AbortSignal,
|
|
8
|
-
): AsyncIterable<ProviderTurnEvent> {
|
|
9
|
-
if (signal.aborted) {
|
|
10
|
-
yield { type: 'cancelled' }
|
|
11
|
-
return
|
|
12
|
-
}
|
|
13
|
-
for await (const ev of provider.complete(messages, signal)) {
|
|
14
|
-
if (signal.aborted) {
|
|
15
|
-
yield { type: 'cancelled' }
|
|
16
|
-
return
|
|
17
|
-
}
|
|
18
|
-
yield normalize(ev)
|
|
19
|
-
if (ev.type === 'done' || ev.type === 'error') return
|
|
20
|
-
}
|
|
21
|
-
if (signal.aborted) {
|
|
22
|
-
yield { type: 'cancelled' }
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function normalize(event: StreamEvent): ProviderTurnEvent {
|
|
27
|
-
switch (event.type) {
|
|
28
|
-
case 'text': return { type: 'text', delta: event.delta }
|
|
29
|
-
case 'thinking': return { type: 'thinking', delta: event.delta }
|
|
30
|
-
case 'thinking_end': return { type: 'thinking_end' }
|
|
31
|
-
case 'retry': return event
|
|
32
|
-
case 'tool_use_start': return event
|
|
33
|
-
case 'tool_use_delta': return event
|
|
34
|
-
case 'tool_use_stop': return event
|
|
35
|
-
case 'done': return { type: 'done', stopReason: event.stopReason }
|
|
36
|
-
case 'error': return { type: 'error', message: event.message }
|
|
37
|
-
}
|
|
38
|
-
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import type { ToolKind } from '../tools/contracts.js'
|
|
2
|
-
|
|
3
|
-
export type SessionMode = 'chat' | 'plan' | 'accept-edits'
|
|
4
|
-
|
|
5
|
-
export type PermissionMode = 'default' | 'plan' | 'accept-edits'
|
|
6
|
-
|
|
7
|
-
type PolicyMode = SessionMode | 'default'
|
|
8
|
-
|
|
9
|
-
export type ModePolicy = {
|
|
10
|
-
mode: PolicyMode
|
|
11
|
-
exposesToolKind: (kind: ToolKind) => boolean
|
|
12
|
-
autoAllowToolKind: (kind: ToolKind) => boolean
|
|
13
|
-
promptLabel: string
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export function toPermissionMode(mode: SessionMode): PermissionMode {
|
|
17
|
-
if (mode === 'plan') return 'plan'
|
|
18
|
-
if (mode === 'accept-edits') return 'accept-edits'
|
|
19
|
-
return 'default'
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export function nextSessionMode(mode: SessionMode): SessionMode {
|
|
23
|
-
return mode === 'chat' ? 'plan' : mode === 'plan' ? 'accept-edits' : 'chat'
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function sessionModeLabel(mode: SessionMode): string {
|
|
27
|
-
return mode === 'plan' ? 'plan mode' : mode === 'accept-edits' ? 'accept edits on' : ''
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function modePolicy(mode: PolicyMode): ModePolicy {
|
|
31
|
-
if (mode === 'plan') {
|
|
32
|
-
return {
|
|
33
|
-
mode,
|
|
34
|
-
exposesToolKind: kind => kind === 'read' || kind === 'private-continuity-read' || kind === 'mcp',
|
|
35
|
-
autoAllowToolKind: kind => kind === 'private-continuity-read',
|
|
36
|
-
promptLabel: 'plan mode',
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (mode === 'accept-edits') {
|
|
41
|
-
return {
|
|
42
|
-
mode,
|
|
43
|
-
exposesToolKind: () => true,
|
|
44
|
-
autoAllowToolKind: kind => kind === 'read' || kind === 'edit' || kind === 'write' || kind === 'private-continuity-read',
|
|
45
|
-
promptLabel: 'accept edits',
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return {
|
|
50
|
-
mode,
|
|
51
|
-
exposesToolKind: () => true,
|
|
52
|
-
autoAllowToolKind: kind => kind === 'private-continuity-read',
|
|
53
|
-
promptLabel: 'default chat',
|
|
54
|
-
}
|
|
55
|
-
}
|