ummaya 0.2.4 → 0.2.5
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/README.md +15 -2
- package/bin/ummaya +10 -1
- package/npm-shrinkwrap.json +253 -2
- package/package.json +5 -1
- package/prompts/manifest.yaml +1 -1
- package/prompts/system_v1.md +1 -0
- package/pyproject.toml +26 -2
- package/specs/2803-document-production-hardening/contracts/document-tools.schema.json +1043 -0
- package/src/ummaya/_canonical/__init__.py +2 -0
- package/src/ummaya/engine/engine.py +29 -132
- package/src/ummaya/evidence/__init__.py +21 -2
- package/src/ummaya/evidence/dataset_contract.py +193 -0
- package/src/ummaya/evidence/document_authoring_cases.py +33 -0
- package/src/ummaya/evidence/document_harness.py +313 -0
- package/src/ummaya/evidence/document_viewer_ux.py +391 -0
- package/src/ummaya/evidence/gates.py +70 -0
- package/src/ummaya/evidence/json_types.py +20 -0
- package/src/ummaya/evidence/models.py +88 -1
- package/src/ummaya/evidence/output_payload.py +89 -0
- package/src/ummaya/evidence/payload_documents.py +233 -0
- package/src/ummaya/evidence/route_contracts.py +224 -0
- package/src/ummaya/evidence/route_helpers.py +150 -0
- package/src/ummaya/evidence/runner.py +81 -212
- package/src/ummaya/evidence/source_provenance.py +246 -0
- package/src/ummaya/evidence/source_provenance_redaction.py +176 -0
- package/src/ummaya/evidence/tool_layer.py +39 -0
- package/src/ummaya/evidence/tool_layer_models.py +151 -0
- package/src/ummaya/ipc/adapter_manifest_emitter.py +26 -10
- package/src/ummaya/ipc/document_intent_normalization.py +185 -0
- package/src/ummaya/ipc/frame_schema.py +5 -5
- package/src/ummaya/ipc/route_diagnostics.py +73 -0
- package/src/ummaya/ipc/stdio.py +1109 -477
- package/src/ummaya/llm/client.py +102 -3
- package/src/ummaya/llm/config.py +8 -3
- package/src/ummaya/primitives/__init__.py +6 -2
- package/src/ummaya/primitives/delegation.py +1 -1
- package/src/ummaya/primitives/document.py +28 -0
- package/src/ummaya/settings.py +0 -3
- package/src/ummaya/tools/discovery_bridge.py +17 -1
- package/src/ummaya/tools/documents/__init__.py +297 -0
- package/src/ummaya/tools/documents/adapter_registry.py +487 -0
- package/src/ummaya/tools/documents/archive_container_probe.py +167 -0
- package/src/ummaya/tools/documents/artifact_store.py +454 -0
- package/src/ummaya/tools/documents/authoring.py +283 -0
- package/src/ummaya/tools/documents/baselines.py +114 -0
- package/src/ummaya/tools/documents/capability.py +331 -0
- package/src/ummaya/tools/documents/contracts.py +112 -0
- package/src/ummaya/tools/documents/conversion.py +521 -0
- package/src/ummaya/tools/documents/diff.py +275 -0
- package/src/ummaya/tools/documents/engines.py +163 -0
- package/src/ummaya/tools/documents/evaluation.py +291 -0
- package/src/ummaya/tools/documents/explicit_values.py +108 -0
- package/src/ummaya/tools/documents/fixtures.py +174 -0
- package/src/ummaya/tools/documents/format_completion_audit.py +471 -0
- package/src/ummaya/tools/documents/formats/__init__.py +2 -0
- package/src/ummaya/tools/documents/formats/archive.py +528 -0
- package/src/ummaya/tools/documents/formats/base.py +41 -0
- package/src/ummaya/tools/documents/formats/code_file.py +211 -0
- package/src/ummaya/tools/documents/formats/data_file.py +272 -0
- package/src/ummaya/tools/documents/formats/hwp.py +284 -0
- package/src/ummaya/tools/documents/formats/hwpx.py +1837 -0
- package/src/ummaya/tools/documents/formats/odf.py +435 -0
- package/src/ummaya/tools/documents/formats/ooxml.py +1030 -0
- package/src/ummaya/tools/documents/formats/passive.py +766 -0
- package/src/ummaya/tools/documents/formats/pdf.py +702 -0
- package/src/ummaya/tools/documents/formats/text_web.py +268 -0
- package/src/ummaya/tools/documents/hwp_conversion_probe.py +178 -0
- package/src/ummaya/tools/documents/hwp_direct_candidate.py +141 -0
- package/src/ummaya/tools/documents/inspection.py +289 -0
- package/src/ummaya/tools/documents/intake.py +1079 -0
- package/src/ummaya/tools/documents/legacy_office_promotion_probe.py +366 -0
- package/src/ummaya/tools/documents/models.py +1598 -0
- package/src/ummaya/tools/documents/odf_promotion_probe.py +167 -0
- package/src/ummaya/tools/documents/orchestrator.py +96 -0
- package/src/ummaya/tools/documents/passive_capability_probe.py +251 -0
- package/src/ummaya/tools/documents/patch.py +170 -0
- package/src/ummaya/tools/documents/pdfa_conformance.py +284 -0
- package/src/ummaya/tools/documents/pdfa_promotion_probe.py +198 -0
- package/src/ummaya/tools/documents/permissions.py +110 -0
- package/src/ummaya/tools/documents/planner.py +616 -0
- package/src/ummaya/tools/documents/registry.py +2733 -0
- package/src/ummaya/tools/documents/render.py +978 -0
- package/src/ummaya/tools/documents/render_comparison.py +113 -0
- package/src/ummaya/tools/documents/render_comparison_models.py +74 -0
- package/src/ummaya/tools/documents/render_comparison_regions.py +73 -0
- package/src/ummaya/tools/documents/render_comparison_style.py +161 -0
- package/src/ummaya/tools/documents/reread.py +157 -0
- package/src/ummaya/tools/documents/runtime_authoring.py +244 -0
- package/src/ummaya/tools/documents/runtime_authoring_bundle.py +76 -0
- package/src/ummaya/tools/documents/scorecard.py +184 -0
- package/src/ummaya/tools/documents/socratic_planner.py +193 -0
- package/src/ummaya/tools/documents/style.py +48 -0
- package/src/ummaya/tools/documents/tool_defs.py +523 -0
- package/src/ummaya/tools/documents/validate.py +347 -0
- package/src/ummaya/tools/executor.py +29 -0
- package/src/ummaya/tools/live_proxy.py +0 -3
- package/src/ummaya/tools/models.py +5 -1
- package/src/ummaya/tools/register_all.py +8 -0
- package/src/ummaya/tools/registry.py +10 -1
- package/src/ummaya/tools/routing/__init__.py +59 -0
- package/src/ummaya/tools/routing/builder.py +105 -0
- package/src/ummaya/tools/routing/cards.py +29 -0
- package/src/ummaya/tools/routing/decision_service.py +534 -0
- package/src/ummaya/tools/routing/decision_types.py +74 -0
- package/src/ummaya/tools/routing/feasibility.py +122 -0
- package/src/ummaya/tools/routing/intent.py +17 -0
- package/src/ummaya/tools/routing/intent_extractor.py +207 -0
- package/src/ummaya/tools/routing/intent_patterns.py +160 -0
- package/src/ummaya/tools/routing/intent_public_data.py +150 -0
- package/src/ummaya/tools/routing/intent_types.py +48 -0
- package/src/ummaya/tools/routing/lint.py +78 -0
- package/src/ummaya/tools/routing/metadata.py +174 -0
- package/src/ummaya/tools/routing/projection.py +340 -0
- package/src/ummaya/tools/routing/retrieval_policy.py +629 -0
- package/src/ummaya/tools/routing/schema.py +81 -0
- package/src/ummaya/tools/routing/types.py +96 -0
- package/src/ummaya/tools/routing_index.py +2 -2
- package/src/ummaya/tools/search.py +34 -746
- package/tests/fixtures/documents/public_forms/baselines.yaml +113 -0
- package/tui/package.json +1 -1
- package/tui/src/.cc-byte-identical-whitelist.yaml +266 -0
- package/tui/src/QueryEngine.ts +12 -8
- package/tui/src/bridge/inboundAttachments.ts +3 -3
- package/tui/src/cli/handlers/auth.ts +3 -12
- package/tui/src/cli/print.ts +7 -7
- package/tui/src/commands/insights.ts +1 -1
- package/tui/src/commands/install-github-app/types.ts +8 -30
- package/tui/src/commands/plugin/types.ts +6 -28
- package/tui/src/commands/plugin/unifiedTypes.ts +4 -26
- package/tui/src/commands/rename/generateSessionName.ts +1 -1
- package/tui/src/components/Feedback.tsx +1 -1
- package/tui/src/components/LogoV2/EmergencyTip.tsx +11 -2
- package/tui/src/components/LogoV2/WelcomeV2.tsx +1 -3
- package/tui/src/components/ScrollKeybindingHandler.tsx +6 -6
- package/tui/src/components/Spinner/types.ts +6 -28
- package/tui/src/components/agents/generateAgent.ts +1 -1
- package/tui/src/components/agents/new-agent-creation/types.ts +4 -26
- package/tui/src/components/config/EnvSecretIsolatedEditor.tsx +1 -1
- package/tui/src/components/mcp/types.ts +16 -38
- package/tui/src/components/messages/AssistantToolUseMessage.tsx +3 -2
- package/tui/src/components/messages/UserCrossSessionMessage.ts +16 -4
- package/tui/src/components/messages/UserForkBoilerplateMessage.ts +16 -4
- package/tui/src/components/messages/UserGitHubWebhookMessage.ts +16 -4
- package/tui/src/components/messages/UserToolResultMessage/utils.tsx +3 -2
- package/tui/src/components/permissions/MonitorPermissionRequest/MonitorPermissionRequest.ts +9 -4
- package/tui/src/components/permissions/ReviewArtifactPermissionRequest/ReviewArtifactPermissionRequest.ts +9 -4
- package/tui/src/components/primitive/DocumentSocraticReviewBlock.tsx +129 -0
- package/tui/src/components/primitive/DocumentToolResultCard.tsx +224 -0
- package/tui/src/components/primitive/documentSocraticReview.ts +215 -0
- package/tui/src/components/primitive/index.tsx +43 -1
- package/tui/src/components/primitive/types.ts +137 -0
- package/tui/src/components/ui/option.ts +4 -26
- package/tui/src/constants/common.ts +0 -2
- package/tui/src/constants/prompts.ts +4 -3
- package/tui/src/constants/querySource.ts +4 -26
- package/tui/src/entrypoints/sdk/controlTypes.ts +26 -48
- package/tui/src/entrypoints/sdk/coreTypes.generated.ts +3 -25
- package/tui/src/entrypoints/sdk/runtimeTypes.ts +38 -60
- package/tui/src/entrypoints/sdk/sdkUtilityTypes.ts +4 -26
- package/tui/src/entrypoints/sdk/settingsTypes.generated.ts +3 -25
- package/tui/src/entrypoints/sdk/toolTypes.ts +3 -25
- package/tui/src/hooks/toolPermission/handlers/interactiveHandler.ts +10 -0
- package/tui/src/hooks/useApiKeyVerification.ts +1 -1
- package/tui/src/hooks/useVirtualScroll.ts +1 -1
- package/tui/src/ink/ink.tsx +33 -14
- package/tui/src/ink/reconciler.ts +2 -3
- package/tui/src/ink/render-to-screen.ts +30 -10
- package/tui/src/ipc/bridge.ts +62 -15
- package/tui/src/ipc/bridgeSingleton.ts +5 -1
- package/tui/src/ipc/codec.ts +3 -3
- package/tui/src/ipc/frames.generated.ts +12 -12
- package/tui/src/ipc/llmClient.ts +151 -27
- package/tui/src/ipc/schema/frame.schema.json +1 -1
- package/tui/src/keybindings/defaultBindings.ts +4 -0
- package/tui/src/main.tsx +29 -11
- package/tui/src/native-ts/file-index/index.ts +33 -3
- package/tui/src/observability/surface.ts +2 -2
- package/tui/src/probes/toolRegistryProbe.tsx +3 -1
- package/tui/src/projectOnboardingState.ts +7 -6
- package/tui/src/query/chatMessageTypes.ts +18 -0
- package/tui/src/query/chatMessagesBuilder.ts +1 -1
- package/tui/src/query/deps.ts +1 -1
- package/tui/src/query/messageGuards.ts +106 -0
- package/tui/src/query/publicDataTerminalRepair.ts +384 -0
- package/tui/src/query/run.ts +1075 -0
- package/tui/src/query/supportBoundary.ts +168 -0
- package/tui/src/query/toolResultErrors.ts +103 -0
- package/tui/src/query/toolRunner.ts +687 -0
- package/tui/src/query/unavailableToolRepair.ts +118 -0
- package/tui/src/query.ts +9 -2186
- package/tui/src/screens/REPL.tsx +40 -29
- package/tui/src/services/api/adapterManifest.ts +4 -0
- package/tui/src/services/api/backendChat/events.ts +117 -0
- package/tui/src/services/api/backendChat/finalMessage.ts +40 -0
- package/tui/src/services/api/backendChat/frame.ts +9 -0
- package/tui/src/services/api/backendChat/streaming.ts +430 -0
- package/tui/src/services/api/backendChat/types.ts +62 -0
- package/tui/src/services/api/backendChat.ts +1 -0
- package/tui/src/services/api/client.ts +65 -2
- package/tui/src/services/api/errorUtils.ts +5 -5
- package/tui/src/services/api/errors.ts +1 -1
- package/tui/src/services/api/logging.ts +1 -1
- package/tui/src/services/api/ummaya/evidence.ts +194 -0
- package/tui/src/services/api/ummaya/messages.ts +255 -0
- package/tui/src/services/api/ummaya/nonStreaming.ts +66 -0
- package/tui/src/services/api/ummaya/provider.ts +200 -0
- package/tui/src/services/api/ummaya/reasoning.ts +24 -0
- package/tui/src/services/api/ummaya/request.ts +200 -0
- package/tui/src/services/api/ummaya/selectionContext.ts +240 -0
- package/tui/src/services/api/ummaya/streaming.ts +365 -0
- package/tui/src/services/api/ummaya/streamingPayload.ts +129 -0
- package/tui/src/services/api/ummaya/streamingReader.ts +40 -0
- package/tui/src/services/api/ummaya/toolSelection.ts +217 -0
- package/tui/src/services/api/ummaya/types.ts +110 -0
- package/tui/src/services/api/ummaya/usage.ts +30 -0
- package/tui/src/services/api/ummaya.ts +26 -418
- package/tui/src/services/api/withRetry.ts +1 -1
- package/tui/src/services/awaySummary.ts +2 -2
- package/tui/src/services/claudeAiLimits.ts +1 -1
- package/tui/src/services/compact/autoCompact.ts +1 -1
- package/tui/src/services/compact/compact.ts +1 -1
- package/tui/src/services/lsp/types.ts +8 -30
- package/tui/src/services/tips/types.ts +6 -28
- package/tui/src/services/tokenEstimation.ts +1 -1
- package/tui/src/services/toolRegistry/bootGuard.ts +5 -5
- package/tui/src/services/toolUseSummary/toolUseSummaryGenerator.ts +1 -1
- package/tui/src/services/tools/toolExecution.ts +94 -1
- package/tui/src/store/pendingPermissionSlot.ts +1 -1
- package/tui/src/store/session-store.ts +10 -36
- package/tui/src/stubs/any-stub.ts +15 -10
- package/tui/src/stubs/color-diff-napi.ts +37 -23
- package/tui/src/stubs/globals.d.ts +3 -3
- package/tui/src/stubs/macro-preload.ts +23 -12
- package/tui/src/tools/AdapterTool/AdapterTool.ts +1207 -714
- package/tui/src/tools/AdapterTool/routeDiagnostics.ts +75 -0
- package/tui/src/tools/AgentTool/AgentTool.tsx +84 -1371
- package/tui/src/tools/AgentTool/agentToolHandoff.ts +114 -0
- package/tui/src/tools/AgentTool/agentToolPartialResult.ts +16 -0
- package/tui/src/tools/AgentTool/agentToolProgress.ts +32 -0
- package/tui/src/tools/AgentTool/agentToolResolver.ts +161 -0
- package/tui/src/tools/AgentTool/agentToolResult.ts +163 -0
- package/tui/src/tools/AgentTool/agentToolUtils.ts +14 -686
- package/tui/src/tools/AgentTool/asyncAgentLifecycle.ts +208 -0
- package/tui/src/tools/AgentTool/asyncLifecycle.ts +153 -0
- package/tui/src/tools/AgentTool/backgroundedCompletion.ts +126 -0
- package/tui/src/tools/AgentTool/backgroundedLifecycle.ts +174 -0
- package/tui/src/tools/AgentTool/foregroundBackground.ts +83 -0
- package/tui/src/tools/AgentTool/foregroundDrain.tsx +133 -0
- package/tui/src/tools/AgentTool/foregroundFinalize.ts +98 -0
- package/tui/src/tools/AgentTool/foregroundLifecycle.tsx +237 -0
- package/tui/src/tools/AgentTool/foregroundProgress.tsx +169 -0
- package/tui/src/tools/AgentTool/foregroundTask.ts +89 -0
- package/tui/src/tools/AgentTool/forkSubagent.ts +1 -12
- package/tui/src/tools/AgentTool/forkSubagentGate.ts +34 -0
- package/tui/src/tools/AgentTool/launchRouting.ts +203 -0
- package/tui/src/tools/AgentTool/lifecycle.ts +244 -0
- package/tui/src/tools/AgentTool/mcpRouting.ts +73 -0
- package/tui/src/tools/AgentTool/orchestrationSupport.ts +70 -0
- package/tui/src/tools/AgentTool/permissions.ts +39 -0
- package/tui/src/tools/AgentTool/promptSetup.ts +181 -0
- package/tui/src/tools/AgentTool/remoteRouting.ts +62 -0
- package/tui/src/tools/AgentTool/resultMapping.ts +116 -0
- package/tui/src/tools/AgentTool/resumeAgent.ts +39 -107
- package/tui/src/tools/AgentTool/resumeAgentHelpers.ts +140 -0
- package/tui/src/tools/AgentTool/runAgent.ts +1 -1
- package/tui/src/tools/AgentTool/runtimeConfig.ts +57 -0
- package/tui/src/tools/AgentTool/schemas.ts +196 -0
- package/tui/src/tools/AgentTool/sourceVerificationPropagation.ts +263 -0
- package/tui/src/tools/AgentTool/worktreeLifecycle.ts +105 -0
- package/tui/src/tools/AskUserQuestionTool/AskUserQuestionTool.tsx +174 -202
- package/tui/src/tools/BashTool/BashTool.tsx +71 -1072
- package/tui/src/tools/BashTool/bashCommandHelpers.ts +12 -12
- package/tui/src/tools/BashTool/bashPermissions/astPreflight.ts +173 -0
- package/tui/src/tools/BashTool/bashPermissions/classifierChecks.ts +199 -0
- package/tui/src/tools/BashTool/bashPermissions/compoundGuards.ts +53 -0
- package/tui/src/tools/BashTool/bashPermissions/constants.ts +99 -0
- package/tui/src/tools/BashTool/bashPermissions/index.ts +38 -0
- package/tui/src/tools/BashTool/bashPermissions/legacyMisparsing.ts +62 -0
- package/tui/src/tools/BashTool/bashPermissions/main.ts +135 -0
- package/tui/src/tools/BashTool/bashPermissions/normalizedCommands.ts +33 -0
- package/tui/src/tools/BashTool/bashPermissions/operatorFlow.ts +98 -0
- package/tui/src/tools/BashTool/bashPermissions/permissionChecks.ts +200 -0
- package/tui/src/tools/BashTool/bashPermissions/prefixSuggestions.ts +88 -0
- package/tui/src/tools/BashTool/bashPermissions/promptClassifierRules.ts +125 -0
- package/tui/src/tools/BashTool/bashPermissions/ruleDelegates.ts +19 -0
- package/tui/src/tools/BashTool/bashPermissions/ruleMatching.ts +145 -0
- package/tui/src/tools/BashTool/bashPermissions/sandboxAutoAllow.ts +75 -0
- package/tui/src/tools/BashTool/bashPermissions/subcommandFlow.ts +205 -0
- package/tui/src/tools/BashTool/bashPermissions/subcommandGuards.ts +73 -0
- package/tui/src/tools/BashTool/bashPermissions/subcommandResultHelpers.ts +116 -0
- package/tui/src/tools/BashTool/bashPermissions/types.ts +26 -0
- package/tui/src/tools/BashTool/bashPermissions/wrapperStripping.ts +139 -0
- package/tui/src/tools/BashTool/bashPermissions.ts +26 -2621
- package/tui/src/tools/BashTool/call.ts +202 -0
- package/tui/src/tools/BashTool/callLoader.ts +35 -0
- package/tui/src/tools/BashTool/commandClassification.ts +151 -0
- package/tui/src/tools/BashTool/commandClassificationLoader.ts +40 -0
- package/tui/src/tools/BashTool/cwdReset.ts +33 -0
- package/tui/src/tools/BashTool/lineTruncation.ts +11 -0
- package/tui/src/tools/BashTool/modeValidation.ts +13 -1
- package/tui/src/tools/BashTool/outputPersistence.ts +42 -0
- package/tui/src/tools/BashTool/permissionClassification.ts +66 -0
- package/tui/src/tools/BashTool/permissionLoader.ts +44 -0
- package/tui/src/tools/BashTool/resultLoader.ts +29 -0
- package/tui/src/tools/BashTool/resultMapping.ts +83 -0
- package/tui/src/tools/BashTool/sandboxPolicy.ts +79 -0
- package/tui/src/tools/BashTool/schemas.ts +65 -0
- package/tui/src/tools/BashTool/sedEditExecution.ts +59 -0
- package/tui/src/tools/BashTool/shellExecution.tsx +245 -0
- package/tui/src/tools/BashTool/shellOutputUtils.ts +85 -0
- package/tui/src/tools/BashTool/shellPermissionGauntlet.ts +97 -0
- package/tui/src/tools/BashTool/uiLoader.ts +37 -0
- package/tui/src/tools/BriefTool/upload.ts +1 -1
- package/tui/src/tools/CalculatorTool/parser.ts +2 -2
- package/tui/src/tools/DocumentPrimitive/DocumentPrimitive.ts +262 -0
- package/tui/src/tools/DocumentPrimitive/dispatchNormalization.ts +270 -0
- package/tui/src/tools/DocumentPrimitive/documentDestinationPath.ts +18 -0
- package/tui/src/tools/DocumentPrimitive/documentMutationGuard.ts +22 -0
- package/tui/src/tools/DocumentPrimitive/documentPatchNormalization.ts +248 -0
- package/tui/src/tools/DocumentPrimitive/documentSourceVerification.ts +245 -0
- package/tui/src/tools/DocumentPrimitive/documentSourceVerificationFields.ts +103 -0
- package/tui/src/tools/DocumentPrimitive/modelVisibleOutput.ts +40 -0
- package/tui/src/tools/DocumentPrimitive/prompt.ts +35 -0
- package/tui/src/tools/FileEditTool/FileEditTool.ts +9 -507
- package/tui/src/tools/FileEditTool/call.ts +228 -0
- package/tui/src/tools/FileEditTool/validateInput.ts +196 -0
- package/tui/src/tools/FileReadTool/imageProcessor.ts +13 -0
- package/tui/src/tools/FileWriteTool/FileWriteTool.ts +7 -300
- package/tui/src/tools/FileWriteTool/call.ts +223 -0
- package/tui/src/tools/FileWriteTool/validateInput.ts +80 -0
- package/tui/src/tools/ListMcpResourcesTool/ListMcpResourcesTool.ts +19 -3
- package/tui/src/tools/LookupPrimitive/LookupPrimitive.ts +25 -32
- package/tui/src/tools/LookupPrimitive/prompt.ts +0 -2
- package/tui/src/tools/MCPTool/trustPolicy.ts +118 -0
- package/tui/src/tools/McpAuthTool/McpAuthTool.ts +21 -3
- package/tui/src/tools/NotebookEditTool/NotebookEditTool.ts +7 -326
- package/tui/src/tools/NotebookEditTool/call.ts +254 -0
- package/tui/src/tools/NotebookEditTool/notebookModel.ts +51 -0
- package/tui/src/tools/NotebookEditTool/validateInput.ts +142 -0
- package/tui/src/tools/PowerShellTool/PowerShellTool.tsx +46 -937
- package/tui/src/tools/PowerShellTool/acceptEditsCommandValidation.ts +162 -0
- package/tui/src/tools/PowerShellTool/call.ts +179 -0
- package/tui/src/tools/PowerShellTool/callLoader.ts +37 -0
- package/tui/src/tools/PowerShellTool/commandClassification.ts +86 -0
- package/tui/src/tools/PowerShellTool/modeValidation.ts +25 -332
- package/tui/src/tools/PowerShellTool/outputPersistence.ts +42 -0
- package/tui/src/tools/PowerShellTool/permissionClassification.ts +28 -0
- package/tui/src/tools/PowerShellTool/resultLoader.ts +31 -0
- package/tui/src/tools/PowerShellTool/resultMapping.ts +75 -0
- package/tui/src/tools/PowerShellTool/schemas.ts +40 -0
- package/tui/src/tools/PowerShellTool/shellExecution.tsx +258 -0
- package/tui/src/tools/PowerShellTool/symlinkModeValidation.ts +44 -0
- package/tui/src/tools/PowerShellTool/uiLoader.ts +37 -0
- package/tui/src/tools/PowerShellTool/validation.ts +39 -0
- package/tui/src/tools/ReadMcpResourceTool/ReadMcpResourceTool.ts +19 -3
- package/tui/src/tools/ResolveLocationPrimitive/ResolveLocationPrimitive.ts +1 -11
- package/tui/src/tools/ResolveLocationPrimitive/prompt.ts +2 -6
- package/tui/src/tools/SkillTool/SkillTool.ts +2 -2
- package/tui/src/tools/SubmitPrimitive/SubmitPrimitive.ts +27 -10
- package/tui/src/tools/TaskCreateTool/TaskCreateTool.ts +16 -2
- package/tui/src/tools/TaskGetTool/TaskGetTool.ts +23 -3
- package/tui/src/tools/TaskListTool/TaskListTool.ts +22 -4
- package/tui/src/tools/TaskOutputTool/TaskOutputTool.tsx +46 -547
- package/tui/src/tools/TaskOutputTool/lookup.ts +216 -0
- package/tui/src/tools/TaskOutputTool/render.tsx +257 -0
- package/tui/src/tools/TaskOutputTool/schemas.ts +55 -0
- package/tui/src/tools/TaskOutputTool/serialization.ts +36 -0
- package/tui/src/tools/TaskStopTool/TaskStopTool.ts +10 -0
- package/tui/src/tools/TaskUpdateTool/TaskUpdateTool.ts +14 -364
- package/tui/src/tools/TaskUpdateTool/completion.ts +62 -0
- package/tui/src/tools/TaskUpdateTool/schemas.ts +62 -0
- package/tui/src/tools/TaskUpdateTool/serialization.ts +46 -0
- package/tui/src/tools/TaskUpdateTool/statusUpdate.ts +247 -0
- package/tui/src/tools/TodoWriteTool/TodoWriteTool.ts +21 -2
- package/tui/src/tools/ToolSearchTool/ToolSearchTool.ts +21 -302
- package/tui/src/tools/ToolSearchTool/ccSupportTools.ts +223 -0
- package/tui/src/tools/ToolSearchTool/descriptionCache.ts +50 -0
- package/tui/src/tools/ToolSearchTool/keywordSearch.ts +216 -0
- package/tui/src/tools/ToolSearchTool/prompt.ts +10 -4
- package/tui/src/tools/ToolSearchTool/resultMapping.ts +30 -0
- package/tui/src/tools/ToolSearchTool/schemas.ts +30 -0
- package/tui/src/tools/ToolSearchTool/searchPool.ts +47 -0
- package/tui/src/tools/ToolSearchTool/supportIntentHints.ts +140 -0
- package/tui/src/tools/TranslateTool/TranslateTool.ts +1 -1
- package/tui/src/tools/VerifyPrimitive/VerifyPrimitive.ts +2 -1
- package/tui/src/tools/WebFetchTool/WebFetchTool.ts +43 -138
- package/tui/src/tools/WebFetchTool/call.ts +227 -0
- package/tui/src/tools/WebFetchTool/resolvedAddressSafety.ts +78 -0
- package/tui/src/tools/WebFetchTool/sourceVerification.ts +204 -0
- package/tui/src/tools/WebFetchTool/types.ts +23 -0
- package/tui/src/tools/WebFetchTool/urlSafety.ts +181 -0
- package/tui/src/tools/WebFetchTool/utils.ts +1 -1
- package/tui/src/tools/WebSearchTool/UI.tsx +0 -1
- package/tui/src/tools/WebSearchTool/WebSearchTool.ts +9 -313
- package/tui/src/tools/WebSearchTool/call.ts +33 -0
- package/tui/src/tools/WebSearchTool/responseMapping.ts +190 -0
- package/tui/src/tools/WebSearchTool/resultBlock.ts +47 -0
- package/tui/src/tools/WebSearchTool/schemas.ts +47 -0
- package/tui/src/tools/WebSearchTool/toolSchema.ts +12 -0
- package/tui/src/tools/WorkspaceToolAdapter/WorkspaceToolAdapter.ts +79 -0
- package/tui/src/tools/WorkspaceToolAdapter/allowedRootPolicy.ts +85 -0
- package/tui/src/tools/WorkspaceToolAdapter/documentFormatGuards.ts +73 -0
- package/tui/src/tools/WorkspaceToolAdapter/inputNormalization.ts +105 -0
- package/tui/src/tools/WorkspaceToolAdapter/mcpExposurePolicy.ts +64 -0
- package/tui/src/tools/WorkspaceToolAdapter/toolDefFactory.ts +215 -0
- package/tui/src/tools/WorkspaceToolAdapter/toolNames.ts +6 -0
- package/tui/src/tools/WorkspaceToolAdapter/workspacePolicy.ts +15 -0
- package/tui/src/tools/_shared/dispatchPrimitive.ts +6 -6
- package/tui/src/tools/_shared/documentChangeToPatch.ts +125 -0
- package/tui/src/tools/_shared/documentDispatchArguments.ts +87 -0
- package/tui/src/tools/_shared/documentPrimitiveTimeout.ts +13 -0
- package/tui/src/tools/_shared/documentToolResultRender.ts +98 -0
- package/tui/src/tools/_shared/pendingCallRegistry.ts +1 -6
- package/tui/src/tools/_shared/rootPrimitiveInput.ts +1 -0
- package/tui/src/tools/_shared/toolChoiceRepair/documentCompletionPatterns.ts +58 -0
- package/tui/src/tools/_shared/toolChoiceRepair/documentCompletionPrompt.ts +271 -0
- package/tui/src/tools/_shared/toolChoiceRepair/documentRepair.ts +452 -0
- package/tui/src/tools/_shared/toolChoiceRepair/messageAccess.ts +80 -0
- package/tui/src/tools/_shared/toolChoiceRepair/publicDataRepair.ts +92 -0
- package/tui/src/tools/_shared/toolChoiceRepair/supportRepair.ts +135 -0
- package/tui/src/tools/_shared/toolChoiceRepair.ts +55 -860
- package/tui/src/tools/shared/mockDisclaimer.ts +1 -1
- package/tui/src/tools.ts +39 -190
- package/tui/src/types/fileSuggestion.ts +4 -26
- package/tui/src/types/generated/events_mono/claude_code/v1/claude_code_internal_event.ts +186 -148
- package/tui/src/types/generated/events_mono/common/v1/auth.ts +25 -11
- package/tui/src/types/generated/events_mono/growthbook/v1/growthbook_experiment_event.ts +47 -30
- package/tui/src/types/generated/google/protobuf/timestamp.ts +21 -7
- package/tui/src/types/message.ts +80 -102
- package/tui/src/types/messageQueueTypes.ts +6 -28
- package/tui/src/types/notebook.ts +16 -38
- package/tui/src/types/statusLine.ts +4 -26
- package/tui/src/types/tools.ts +24 -46
- package/tui/src/types/utils.ts +6 -28
- package/tui/src/upstreamproxy/relay.ts +7 -3
- package/tui/src/upstreamproxy/upstreamproxy.ts +1 -1
- package/tui/src/utils/assistantMessageFactories.ts +9 -3
- package/tui/src/utils/auth.ts +129 -139
- package/tui/src/utils/bash/ast.ts +23 -23
- package/tui/src/utils/bash/bashParser.ts +5 -5
- package/tui/src/utils/billing.ts +1 -1
- package/tui/src/utils/collapseReadSearch.ts +3 -3
- package/tui/src/utils/cronTasks.ts +1 -1
- package/tui/src/utils/execFileNoThrow.ts +1 -1
- package/tui/src/utils/filePersistence/types.ts +16 -38
- package/tui/src/utils/forkedAgent.ts +1 -1
- package/tui/src/utils/gracefulShutdown.ts +4 -4
- package/tui/src/utils/heapDumpService.ts +12 -8
- package/tui/src/utils/hooks/apiQueryHookHelper.ts +1 -1
- package/tui/src/utils/hooks/execPromptHook.ts +1 -1
- package/tui/src/utils/hooks/skillImprovement.ts +1 -1
- package/tui/src/utils/mcp/dateTimeParser.ts +1 -1
- package/tui/src/utils/messages.ts +18 -0
- package/tui/src/utils/migrateSessions.ts +3 -3
- package/tui/src/utils/model/model.ts +6 -6
- package/tui/src/utils/permissions/yoloClassifier.ts +1 -1
- package/tui/src/utils/plugins/headlessPluginInstall.ts +1 -1
- package/tui/src/utils/plugins/mcpPluginIntegration.ts +1 -1
- package/tui/src/utils/plugins/mcpbHandler.ts +1 -1
- package/tui/src/utils/plugins/pluginLoader.ts +8 -8
- package/tui/src/utils/protectedNamespace.ts +5 -3
- package/tui/src/utils/rawJsonToolCall.ts +242 -0
- package/tui/src/utils/ripgrep.ts +16 -7
- package/tui/src/utils/sessionTitle.ts +1 -1
- package/tui/src/utils/settings/permissionValidation.ts +14 -2
- package/tui/src/utils/shell/prefix.ts +1 -1
- package/tui/src/utils/sideQuery.ts +1 -1
- package/tui/src/utils/systemThemeWatcher.ts +13 -3
- package/tui/src/utils/teleport.tsx +1 -1
- package/uv.lock +400 -14
- package/tui/src/services/api/claude.ts +0 -3540
- package/tui/src/tools/_shared/directPublicDataGuard.ts +0 -362
- package/tui/src/tools/_shared/kmaAnalysisGuard.ts +0 -197
- package/tui/src/tools/_shared/kmaAviationGuard.ts +0 -70
- package/tui/src/tools/_shared/nmcAedGuard.ts +0 -234
- package/tui/src/tools/_shared/protectedCheckGuard.ts +0 -207
- package/tui/src/tools/_shared/textToolCallGuard.ts +0 -91
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import type { ToolResult, ToolUseContext } from '../../Tool.js'
|
|
2
|
+
import { isAgentSwarmsEnabled } from '../../utils/agentSwarmsEnabled.js'
|
|
3
|
+
import {
|
|
4
|
+
blockTask,
|
|
5
|
+
deleteTask,
|
|
6
|
+
getTask,
|
|
7
|
+
getTaskListId,
|
|
8
|
+
type Task,
|
|
9
|
+
type TaskStatus,
|
|
10
|
+
updateTask,
|
|
11
|
+
} from '../../utils/tasks.js'
|
|
12
|
+
import { getAgentName, getTeammateColor } from '../../utils/teammate.js'
|
|
13
|
+
import { writeToMailbox } from '../../utils/teammateMailbox.js'
|
|
14
|
+
import { buildAgentSupportMetadata } from '../AgentTool/orchestrationSupport.js'
|
|
15
|
+
import {
|
|
16
|
+
collectCompletedHookErrors,
|
|
17
|
+
needsVerificationNudge,
|
|
18
|
+
} from './completion.js'
|
|
19
|
+
import type { Output, TaskUpdateToolInput } from './schemas.js'
|
|
20
|
+
|
|
21
|
+
type TaskUpdates = {
|
|
22
|
+
subject?: string
|
|
23
|
+
description?: string
|
|
24
|
+
activeForm?: string
|
|
25
|
+
status?: TaskStatus
|
|
26
|
+
owner?: string
|
|
27
|
+
metadata?: Record<string, unknown>
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function expandTaskList(context: ToolUseContext): void {
|
|
31
|
+
context.setAppState(prev => {
|
|
32
|
+
if (prev.expandedView === 'tasks') return prev
|
|
33
|
+
return { ...prev, expandedView: 'tasks' }
|
|
34
|
+
})
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function addChangedTextField(
|
|
38
|
+
updates: TaskUpdates,
|
|
39
|
+
updatedFields: string[],
|
|
40
|
+
field: 'subject' | 'description' | 'activeForm' | 'owner',
|
|
41
|
+
nextValue: string | undefined,
|
|
42
|
+
currentValue: string | undefined,
|
|
43
|
+
): void {
|
|
44
|
+
if (nextValue === undefined || nextValue === currentValue) return
|
|
45
|
+
updates[field] = nextValue
|
|
46
|
+
updatedFields.push(field)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function applyMetadataUpdate(
|
|
50
|
+
updates: TaskUpdates,
|
|
51
|
+
updatedFields: string[],
|
|
52
|
+
existingTask: Task,
|
|
53
|
+
metadata: Record<string, unknown> | undefined,
|
|
54
|
+
): void {
|
|
55
|
+
if (metadata === undefined) return
|
|
56
|
+
|
|
57
|
+
const merged = { ...(existingTask.metadata ?? {}) }
|
|
58
|
+
for (const [key, value] of Object.entries(metadata)) {
|
|
59
|
+
if (value === null) {
|
|
60
|
+
delete merged[key]
|
|
61
|
+
} else {
|
|
62
|
+
merged[key] = value
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
updates.metadata = merged
|
|
66
|
+
updatedFields.push('metadata')
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function applyImplicitOwner(
|
|
70
|
+
updates: TaskUpdates,
|
|
71
|
+
updatedFields: string[],
|
|
72
|
+
input: TaskUpdateToolInput,
|
|
73
|
+
existingTask: Task,
|
|
74
|
+
): void {
|
|
75
|
+
if (
|
|
76
|
+
!isAgentSwarmsEnabled() ||
|
|
77
|
+
input.status !== 'in_progress' ||
|
|
78
|
+
input.owner !== undefined ||
|
|
79
|
+
existingTask.owner
|
|
80
|
+
) {
|
|
81
|
+
return
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const agentName = getAgentName()
|
|
85
|
+
if (!agentName) return
|
|
86
|
+
updates.owner = agentName
|
|
87
|
+
updatedFields.push('owner')
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async function notifyNewOwner(
|
|
91
|
+
taskListId: string,
|
|
92
|
+
updates: TaskUpdates,
|
|
93
|
+
input: TaskUpdateToolInput,
|
|
94
|
+
existingTask: Task,
|
|
95
|
+
): Promise<void> {
|
|
96
|
+
if (!updates.owner || !isAgentSwarmsEnabled()) return
|
|
97
|
+
|
|
98
|
+
const senderName = getAgentName() || 'team-lead'
|
|
99
|
+
const assignmentMessage = JSON.stringify({
|
|
100
|
+
type: 'task_assignment',
|
|
101
|
+
taskId: input.taskId,
|
|
102
|
+
subject: existingTask.subject,
|
|
103
|
+
description: existingTask.description,
|
|
104
|
+
assignedBy: senderName,
|
|
105
|
+
timestamp: new Date().toISOString(),
|
|
106
|
+
})
|
|
107
|
+
await writeToMailbox(
|
|
108
|
+
updates.owner,
|
|
109
|
+
{
|
|
110
|
+
from: senderName,
|
|
111
|
+
text: assignmentMessage,
|
|
112
|
+
timestamp: new Date().toISOString(),
|
|
113
|
+
color: getTeammateColor(),
|
|
114
|
+
},
|
|
115
|
+
taskListId,
|
|
116
|
+
)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async function applyDependencyUpdates(
|
|
120
|
+
taskListId: string,
|
|
121
|
+
input: TaskUpdateToolInput,
|
|
122
|
+
existingTask: Task,
|
|
123
|
+
updatedFields: string[],
|
|
124
|
+
): Promise<void> {
|
|
125
|
+
if (input.addBlocks && input.addBlocks.length > 0) {
|
|
126
|
+
const newBlocks = input.addBlocks.filter(
|
|
127
|
+
id => !existingTask.blocks.includes(id),
|
|
128
|
+
)
|
|
129
|
+
for (const blockId of newBlocks) {
|
|
130
|
+
await blockTask(taskListId, input.taskId, blockId)
|
|
131
|
+
}
|
|
132
|
+
if (newBlocks.length > 0) updatedFields.push('blocks')
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (input.addBlockedBy && input.addBlockedBy.length > 0) {
|
|
136
|
+
const newBlockedBy = input.addBlockedBy.filter(
|
|
137
|
+
id => !existingTask.blockedBy.includes(id),
|
|
138
|
+
)
|
|
139
|
+
for (const blockerId of newBlockedBy) {
|
|
140
|
+
await blockTask(taskListId, blockerId, input.taskId)
|
|
141
|
+
}
|
|
142
|
+
if (newBlockedBy.length > 0) updatedFields.push('blockedBy')
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function supportFailure(
|
|
147
|
+
input: TaskUpdateToolInput,
|
|
148
|
+
context: ToolUseContext,
|
|
149
|
+
): Output {
|
|
150
|
+
return {
|
|
151
|
+
success: false,
|
|
152
|
+
taskId: input.taskId,
|
|
153
|
+
updatedFields: [],
|
|
154
|
+
error: 'Task not found',
|
|
155
|
+
...buildAgentSupportMetadata({
|
|
156
|
+
taskId: input.taskId,
|
|
157
|
+
parentToolUseId: context.toolUseId,
|
|
158
|
+
}),
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export async function callTaskUpdateTool(
|
|
163
|
+
input: TaskUpdateToolInput,
|
|
164
|
+
context: ToolUseContext,
|
|
165
|
+
): Promise<ToolResult<Output>> {
|
|
166
|
+
const taskListId = getTaskListId()
|
|
167
|
+
const supportMetadata = buildAgentSupportMetadata({
|
|
168
|
+
taskId: input.taskId,
|
|
169
|
+
parentToolUseId: context.toolUseId,
|
|
170
|
+
})
|
|
171
|
+
expandTaskList(context)
|
|
172
|
+
|
|
173
|
+
const existingTask = await getTask(taskListId, input.taskId)
|
|
174
|
+
if (!existingTask) return { data: supportFailure(input, context) }
|
|
175
|
+
|
|
176
|
+
if (input.status === 'deleted') {
|
|
177
|
+
const deleted = await deleteTask(taskListId, input.taskId)
|
|
178
|
+
return {
|
|
179
|
+
data: {
|
|
180
|
+
success: deleted,
|
|
181
|
+
taskId: input.taskId,
|
|
182
|
+
updatedFields: deleted ? ['deleted'] : [],
|
|
183
|
+
error: deleted ? undefined : 'Failed to delete task',
|
|
184
|
+
statusChange: deleted
|
|
185
|
+
? { from: existingTask.status, to: 'deleted' }
|
|
186
|
+
: undefined,
|
|
187
|
+
...supportMetadata,
|
|
188
|
+
},
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const updatedFields: string[] = []
|
|
193
|
+
const updates: TaskUpdates = {}
|
|
194
|
+
addChangedTextField(updates, updatedFields, 'subject', input.subject, existingTask.subject)
|
|
195
|
+
addChangedTextField(updates, updatedFields, 'description', input.description, existingTask.description)
|
|
196
|
+
addChangedTextField(updates, updatedFields, 'activeForm', input.activeForm, existingTask.activeForm)
|
|
197
|
+
addChangedTextField(updates, updatedFields, 'owner', input.owner, existingTask.owner)
|
|
198
|
+
applyImplicitOwner(updates, updatedFields, input, existingTask)
|
|
199
|
+
applyMetadataUpdate(updates, updatedFields, existingTask, input.metadata)
|
|
200
|
+
|
|
201
|
+
if (input.status !== undefined && input.status !== existingTask.status) {
|
|
202
|
+
if (input.status === 'completed') {
|
|
203
|
+
const blockingErrors = await collectCompletedHookErrors(
|
|
204
|
+
input,
|
|
205
|
+
context,
|
|
206
|
+
existingTask,
|
|
207
|
+
)
|
|
208
|
+
if (blockingErrors.length > 0) {
|
|
209
|
+
return {
|
|
210
|
+
data: {
|
|
211
|
+
success: false,
|
|
212
|
+
taskId: input.taskId,
|
|
213
|
+
updatedFields: [],
|
|
214
|
+
error: blockingErrors.join('\n'),
|
|
215
|
+
...supportMetadata,
|
|
216
|
+
},
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
updates.status = input.status
|
|
221
|
+
updatedFields.push('status')
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (Object.keys(updates).length > 0) {
|
|
225
|
+
await updateTask(taskListId, input.taskId, updates)
|
|
226
|
+
}
|
|
227
|
+
await notifyNewOwner(taskListId, updates, input, existingTask)
|
|
228
|
+
await applyDependencyUpdates(taskListId, input, existingTask, updatedFields)
|
|
229
|
+
|
|
230
|
+
return {
|
|
231
|
+
data: {
|
|
232
|
+
success: true,
|
|
233
|
+
taskId: input.taskId,
|
|
234
|
+
updatedFields,
|
|
235
|
+
statusChange:
|
|
236
|
+
updates.status !== undefined
|
|
237
|
+
? { from: existingTask.status, to: updates.status }
|
|
238
|
+
: undefined,
|
|
239
|
+
verificationNudgeNeeded: await needsVerificationNudge(
|
|
240
|
+
taskListId,
|
|
241
|
+
context,
|
|
242
|
+
updates,
|
|
243
|
+
),
|
|
244
|
+
...supportMetadata,
|
|
245
|
+
},
|
|
246
|
+
}
|
|
247
|
+
}
|
|
@@ -7,6 +7,7 @@ import { lazySchema } from '../../utils/lazySchema.js'
|
|
|
7
7
|
import { isTodoV2Enabled } from '../../utils/tasks.js'
|
|
8
8
|
import { TodoListSchema } from '../../utils/todo/types.js'
|
|
9
9
|
import { VERIFICATION_AGENT_TYPE } from '../AgentTool/constants.js'
|
|
10
|
+
import { buildAgentSupportMetadata } from '../AgentTool/orchestrationSupport.js'
|
|
10
11
|
import { TODO_WRITE_TOOL_NAME } from './constants.js'
|
|
11
12
|
import { DESCRIPTION, PROMPT } from './prompt.js'
|
|
12
13
|
|
|
@@ -22,6 +23,10 @@ const outputSchema = lazySchema(() =>
|
|
|
22
23
|
oldTodos: TodoListSchema().describe('The todo list before the update'),
|
|
23
24
|
newTodos: TodoListSchema().describe('The todo list after the update'),
|
|
24
25
|
verificationNudgeNeeded: z.boolean().optional(),
|
|
26
|
+
evidenceJoinKey: z.string(),
|
|
27
|
+
parentToolUseId: z.string(),
|
|
28
|
+
resumeToken: z.string(),
|
|
29
|
+
permissionFlow: z.literal('coordinator_parent_round_trip'),
|
|
25
30
|
}),
|
|
26
31
|
)
|
|
27
32
|
type OutputSchema = ReturnType<typeof outputSchema>
|
|
@@ -98,18 +103,32 @@ export const TodoWriteTool = buildTool({
|
|
|
98
103
|
oldTodos,
|
|
99
104
|
newTodos: todos,
|
|
100
105
|
verificationNudgeNeeded,
|
|
106
|
+
...buildAgentSupportMetadata({
|
|
107
|
+
taskId: todoKey,
|
|
108
|
+
parentToolUseId: context.toolUseId,
|
|
109
|
+
}),
|
|
101
110
|
},
|
|
102
111
|
}
|
|
103
112
|
},
|
|
104
|
-
mapToolResultToToolResultBlockParam(
|
|
113
|
+
mapToolResultToToolResultBlockParam(
|
|
114
|
+
{
|
|
115
|
+
verificationNudgeNeeded,
|
|
116
|
+
evidenceJoinKey,
|
|
117
|
+
parentToolUseId,
|
|
118
|
+
resumeToken,
|
|
119
|
+
permissionFlow,
|
|
120
|
+
},
|
|
121
|
+
toolUseID,
|
|
122
|
+
) {
|
|
105
123
|
const base = `Todos have been modified successfully. Ensure that you continue to use the todo list to track your progress. Please proceed with the current tasks if applicable`
|
|
124
|
+
const support = `\n\nevidence_join_key: ${evidenceJoinKey}\nparent_tool_use_id: ${parentToolUseId}\nresume_token: ${resumeToken}\npermission_flow: ${permissionFlow}`
|
|
106
125
|
const nudge = verificationNudgeNeeded
|
|
107
126
|
? `\n\nNOTE: You just closed out 3+ tasks and none of them was a verification step. Before writing your final summary, spawn the verification agent (subagent_type="${VERIFICATION_AGENT_TYPE}"). You cannot self-assign PARTIAL by listing caveats in your summary \u2014 only the verifier issues a verdict.`
|
|
108
127
|
: ''
|
|
109
128
|
return {
|
|
110
129
|
tool_use_id: toolUseID,
|
|
111
130
|
type: 'tool_result',
|
|
112
|
-
content: base + nudge,
|
|
131
|
+
content: base + support + nudge,
|
|
113
132
|
}
|
|
114
133
|
},
|
|
115
134
|
} satisfies ToolDef<InputSchema, Output>)
|
|
@@ -1,305 +1,26 @@
|
|
|
1
1
|
import type { ToolResultBlockParam } from '@anthropic-ai/sdk/resources/index.mjs'
|
|
2
|
-
import memoize from 'lodash-es/memoize.js'
|
|
3
|
-
import { z } from 'zod/v4'
|
|
4
2
|
import {
|
|
5
3
|
type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
|
6
4
|
logEvent,
|
|
7
5
|
} from '../../services/analytics/index.js'
|
|
8
|
-
import {
|
|
9
|
-
buildTool,
|
|
10
|
-
findToolByName,
|
|
11
|
-
type Tool,
|
|
12
|
-
type ToolDef,
|
|
13
|
-
type Tools,
|
|
14
|
-
} from '../../Tool.js'
|
|
6
|
+
import { buildTool, findToolByName, type ToolDef } from '../../Tool.js'
|
|
15
7
|
import { logForDebugging } from '../../utils/debug.js'
|
|
16
|
-
import { lazySchema } from '../../utils/lazySchema.js'
|
|
17
|
-
import { escapeRegExp } from '../../utils/stringUtils.js'
|
|
18
8
|
import { isToolSearchEnabledOptimistic } from '../../utils/toolSearch.js'
|
|
9
|
+
import {
|
|
10
|
+
clearToolSearchDescriptionCache,
|
|
11
|
+
maybeInvalidateCache,
|
|
12
|
+
} from './descriptionCache.js'
|
|
13
|
+
import { searchToolsWithKeywords } from './keywordSearch.js'
|
|
19
14
|
import { getPrompt, isDeferredTool, TOOL_SEARCH_TOOL_NAME } from './prompt.js'
|
|
15
|
+
import {
|
|
16
|
+
buildSearchResult,
|
|
17
|
+
makeToolReferenceContent,
|
|
18
|
+
} from './resultMapping.js'
|
|
19
|
+
import type { InputSchema, Output, OutputSchema } from './schemas.js'
|
|
20
|
+
import { inputSchema, outputSchema } from './schemas.js'
|
|
21
|
+
import { getToolSearchPool } from './searchPool.js'
|
|
20
22
|
|
|
21
|
-
export
|
|
22
|
-
z.object({
|
|
23
|
-
query: z
|
|
24
|
-
.string()
|
|
25
|
-
.describe(
|
|
26
|
-
'Query to find deferred tools. Use "select:<tool_name>" for direct selection, or keywords to search.',
|
|
27
|
-
),
|
|
28
|
-
max_results: z
|
|
29
|
-
.number()
|
|
30
|
-
.optional()
|
|
31
|
-
.default(5)
|
|
32
|
-
.describe('Maximum number of results to return (default: 5)'),
|
|
33
|
-
}),
|
|
34
|
-
)
|
|
35
|
-
type InputSchema = ReturnType<typeof inputSchema>
|
|
36
|
-
|
|
37
|
-
export const outputSchema = lazySchema(() =>
|
|
38
|
-
z.object({
|
|
39
|
-
matches: z.array(z.string()),
|
|
40
|
-
query: z.string(),
|
|
41
|
-
total_deferred_tools: z.number(),
|
|
42
|
-
pending_mcp_servers: z.array(z.string()).optional(),
|
|
43
|
-
}),
|
|
44
|
-
)
|
|
45
|
-
type OutputSchema = ReturnType<typeof outputSchema>
|
|
46
|
-
|
|
47
|
-
export type Output = z.infer<OutputSchema>
|
|
48
|
-
|
|
49
|
-
// Track deferred tool names to detect when cache should be cleared
|
|
50
|
-
let cachedDeferredToolNames: string | null = null
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Get a cache key representing the current set of deferred tools.
|
|
54
|
-
*/
|
|
55
|
-
function getDeferredToolsCacheKey(deferredTools: Tools): string {
|
|
56
|
-
return deferredTools
|
|
57
|
-
.map(t => t.name)
|
|
58
|
-
.sort()
|
|
59
|
-
.join(',')
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Get tool description, memoized by tool name.
|
|
64
|
-
* Used for keyword search scoring.
|
|
65
|
-
*/
|
|
66
|
-
const getToolDescriptionMemoized = memoize(
|
|
67
|
-
async (toolName: string, tools: Tools): Promise<string> => {
|
|
68
|
-
const tool = findToolByName(tools, toolName)
|
|
69
|
-
if (!tool) {
|
|
70
|
-
return ''
|
|
71
|
-
}
|
|
72
|
-
return tool.prompt({
|
|
73
|
-
getToolPermissionContext: async () => ({
|
|
74
|
-
mode: 'default' as const,
|
|
75
|
-
additionalWorkingDirectories: new Map(),
|
|
76
|
-
alwaysAllowRules: {},
|
|
77
|
-
alwaysDenyRules: {},
|
|
78
|
-
alwaysAskRules: {},
|
|
79
|
-
isBypassPermissionsModeAvailable: false,
|
|
80
|
-
}),
|
|
81
|
-
tools,
|
|
82
|
-
agents: [],
|
|
83
|
-
})
|
|
84
|
-
},
|
|
85
|
-
(toolName: string) => toolName,
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Invalidate the description cache if deferred tools have changed.
|
|
90
|
-
*/
|
|
91
|
-
function maybeInvalidateCache(deferredTools: Tools): void {
|
|
92
|
-
const currentKey = getDeferredToolsCacheKey(deferredTools)
|
|
93
|
-
if (cachedDeferredToolNames !== currentKey) {
|
|
94
|
-
logForDebugging(
|
|
95
|
-
`ToolSearchTool: cache invalidated - deferred tools changed`,
|
|
96
|
-
)
|
|
97
|
-
getToolDescriptionMemoized.cache.clear?.()
|
|
98
|
-
cachedDeferredToolNames = currentKey
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
export function clearToolSearchDescriptionCache(): void {
|
|
103
|
-
getToolDescriptionMemoized.cache.clear?.()
|
|
104
|
-
cachedDeferredToolNames = null
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Build the search result output structure.
|
|
109
|
-
*/
|
|
110
|
-
function buildSearchResult(
|
|
111
|
-
matches: string[],
|
|
112
|
-
query: string,
|
|
113
|
-
totalDeferredTools: number,
|
|
114
|
-
pendingMcpServers?: string[],
|
|
115
|
-
): { data: Output } {
|
|
116
|
-
return {
|
|
117
|
-
data: {
|
|
118
|
-
matches,
|
|
119
|
-
query,
|
|
120
|
-
total_deferred_tools: totalDeferredTools,
|
|
121
|
-
...(pendingMcpServers && pendingMcpServers.length > 0
|
|
122
|
-
? { pending_mcp_servers: pendingMcpServers }
|
|
123
|
-
: {}),
|
|
124
|
-
},
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Parse tool name into searchable parts.
|
|
130
|
-
* Handles both MCP tools (mcp__server__action) and regular tools (CamelCase).
|
|
131
|
-
*/
|
|
132
|
-
function parseToolName(name: string): {
|
|
133
|
-
parts: string[]
|
|
134
|
-
full: string
|
|
135
|
-
isMcp: boolean
|
|
136
|
-
} {
|
|
137
|
-
// Check if it's an MCP tool
|
|
138
|
-
if (name.startsWith('mcp__')) {
|
|
139
|
-
const withoutPrefix = name.replace(/^mcp__/, '').toLowerCase()
|
|
140
|
-
const parts = withoutPrefix.split('__').flatMap(p => p.split('_'))
|
|
141
|
-
return {
|
|
142
|
-
parts: parts.filter(Boolean),
|
|
143
|
-
full: withoutPrefix.replace(/__/g, ' ').replace(/_/g, ' '),
|
|
144
|
-
isMcp: true,
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// Regular tool - split by CamelCase and underscores
|
|
149
|
-
const parts = name
|
|
150
|
-
.replace(/([a-z])([A-Z])/g, '$1 $2') // CamelCase to spaces
|
|
151
|
-
.replace(/_/g, ' ')
|
|
152
|
-
.toLowerCase()
|
|
153
|
-
.split(/\s+/)
|
|
154
|
-
.filter(Boolean)
|
|
155
|
-
|
|
156
|
-
return {
|
|
157
|
-
parts,
|
|
158
|
-
full: parts.join(' '),
|
|
159
|
-
isMcp: false,
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* Pre-compile word-boundary regexes for all search terms.
|
|
165
|
-
* Called once per search instead of tools×terms×2 times.
|
|
166
|
-
*/
|
|
167
|
-
function compileTermPatterns(terms: string[]): Map<string, RegExp> {
|
|
168
|
-
const patterns = new Map<string, RegExp>()
|
|
169
|
-
for (const term of terms) {
|
|
170
|
-
if (!patterns.has(term)) {
|
|
171
|
-
patterns.set(term, new RegExp(`\\b${escapeRegExp(term)}\\b`))
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
return patterns
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Keyword-based search over tool names and descriptions.
|
|
179
|
-
* Handles both MCP tools (mcp__server__action) and regular tools (CamelCase).
|
|
180
|
-
*
|
|
181
|
-
* The model typically queries with:
|
|
182
|
-
* - Server names when it knows the integration (e.g., "slack", "github")
|
|
183
|
-
* - Action words when looking for functionality (e.g., "read", "list", "create")
|
|
184
|
-
* - Tool-specific terms (e.g., "notebook", "shell", "kill")
|
|
185
|
-
*/
|
|
186
|
-
async function searchToolsWithKeywords(
|
|
187
|
-
query: string,
|
|
188
|
-
deferredTools: Tools,
|
|
189
|
-
tools: Tools,
|
|
190
|
-
maxResults: number,
|
|
191
|
-
): Promise<string[]> {
|
|
192
|
-
const queryLower = query.toLowerCase().trim()
|
|
193
|
-
|
|
194
|
-
// Fast path: if query matches a tool name exactly, return it directly.
|
|
195
|
-
// Handles models using a bare tool name instead of select: prefix (seen
|
|
196
|
-
// from subagents/post-compaction). Checks deferred first, then falls back
|
|
197
|
-
// to the full tool set — selecting an already-loaded tool is a harmless
|
|
198
|
-
// no-op that lets the model proceed without retry churn.
|
|
199
|
-
const exactMatch =
|
|
200
|
-
deferredTools.find(t => t.name.toLowerCase() === queryLower) ??
|
|
201
|
-
tools.find(t => t.name.toLowerCase() === queryLower)
|
|
202
|
-
if (exactMatch) {
|
|
203
|
-
return [exactMatch.name]
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// If query looks like an MCP tool prefix (mcp__server), find matching tools.
|
|
207
|
-
// Handles models searching by server name with mcp__ prefix.
|
|
208
|
-
if (queryLower.startsWith('mcp__') && queryLower.length > 5) {
|
|
209
|
-
const prefixMatches = deferredTools
|
|
210
|
-
.filter(t => t.name.toLowerCase().startsWith(queryLower))
|
|
211
|
-
.slice(0, maxResults)
|
|
212
|
-
.map(t => t.name)
|
|
213
|
-
if (prefixMatches.length > 0) {
|
|
214
|
-
return prefixMatches
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
const queryTerms = queryLower.split(/\s+/).filter(term => term.length > 0)
|
|
219
|
-
|
|
220
|
-
// Partition into required (+prefixed) and optional terms
|
|
221
|
-
const requiredTerms: string[] = []
|
|
222
|
-
const optionalTerms: string[] = []
|
|
223
|
-
for (const term of queryTerms) {
|
|
224
|
-
if (term.startsWith('+') && term.length > 1) {
|
|
225
|
-
requiredTerms.push(term.slice(1))
|
|
226
|
-
} else {
|
|
227
|
-
optionalTerms.push(term)
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
const allScoringTerms =
|
|
232
|
-
requiredTerms.length > 0 ? [...requiredTerms, ...optionalTerms] : queryTerms
|
|
233
|
-
const termPatterns = compileTermPatterns(allScoringTerms)
|
|
234
|
-
|
|
235
|
-
// Pre-filter to tools matching ALL required terms in name or description
|
|
236
|
-
let candidateTools = deferredTools
|
|
237
|
-
if (requiredTerms.length > 0) {
|
|
238
|
-
const matches = await Promise.all(
|
|
239
|
-
deferredTools.map(async tool => {
|
|
240
|
-
const parsed = parseToolName(tool.name)
|
|
241
|
-
const description = await getToolDescriptionMemoized(tool.name, tools)
|
|
242
|
-
const descNormalized = description.toLowerCase()
|
|
243
|
-
const hintNormalized = tool.searchHint?.toLowerCase() ?? ''
|
|
244
|
-
const matchesAll = requiredTerms.every(term => {
|
|
245
|
-
const pattern = termPatterns.get(term)!
|
|
246
|
-
return (
|
|
247
|
-
parsed.parts.includes(term) ||
|
|
248
|
-
parsed.parts.some(part => part.includes(term)) ||
|
|
249
|
-
pattern.test(descNormalized) ||
|
|
250
|
-
(hintNormalized && pattern.test(hintNormalized))
|
|
251
|
-
)
|
|
252
|
-
})
|
|
253
|
-
return matchesAll ? tool : null
|
|
254
|
-
}),
|
|
255
|
-
)
|
|
256
|
-
candidateTools = matches.filter((t): t is Tool => t !== null)
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
const scored = await Promise.all(
|
|
260
|
-
candidateTools.map(async tool => {
|
|
261
|
-
const parsed = parseToolName(tool.name)
|
|
262
|
-
const description = await getToolDescriptionMemoized(tool.name, tools)
|
|
263
|
-
const descNormalized = description.toLowerCase()
|
|
264
|
-
const hintNormalized = tool.searchHint?.toLowerCase() ?? ''
|
|
265
|
-
|
|
266
|
-
let score = 0
|
|
267
|
-
for (const term of allScoringTerms) {
|
|
268
|
-
const pattern = termPatterns.get(term)!
|
|
269
|
-
|
|
270
|
-
// Exact part match (high weight for MCP server names, tool name parts)
|
|
271
|
-
if (parsed.parts.includes(term)) {
|
|
272
|
-
score += parsed.isMcp ? 12 : 10
|
|
273
|
-
} else if (parsed.parts.some(part => part.includes(term))) {
|
|
274
|
-
score += parsed.isMcp ? 6 : 5
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
// Full name fallback (for edge cases)
|
|
278
|
-
if (parsed.full.includes(term) && score === 0) {
|
|
279
|
-
score += 3
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
// searchHint match — curated capability phrase, higher signal than prompt
|
|
283
|
-
if (hintNormalized && pattern.test(hintNormalized)) {
|
|
284
|
-
score += 4
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
// Description match - use word boundary to avoid false positives
|
|
288
|
-
if (pattern.test(descNormalized)) {
|
|
289
|
-
score += 2
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
return { name: tool.name, score }
|
|
294
|
-
}),
|
|
295
|
-
)
|
|
296
|
-
|
|
297
|
-
return scored
|
|
298
|
-
.filter(item => item.score > 0)
|
|
299
|
-
.sort((a, b) => b.score - a.score)
|
|
300
|
-
.slice(0, maxResults)
|
|
301
|
-
.map(item => item.name)
|
|
302
|
-
}
|
|
23
|
+
export { clearToolSearchDescriptionCache }
|
|
303
24
|
|
|
304
25
|
export const ToolSearchTool = buildTool({
|
|
305
26
|
isEnabled() {
|
|
@@ -328,7 +49,8 @@ export const ToolSearchTool = buildTool({
|
|
|
328
49
|
async call(input, { options: { tools }, getAppState }) {
|
|
329
50
|
const { query, max_results = 5 } = input
|
|
330
51
|
|
|
331
|
-
const
|
|
52
|
+
const searchableTools = await getToolSearchPool(tools, getAppState, query)
|
|
53
|
+
const deferredTools = searchableTools.filter(isDeferredTool)
|
|
332
54
|
maybeInvalidateCache(deferredTools)
|
|
333
55
|
|
|
334
56
|
// Check for MCP servers still connecting
|
|
@@ -362,7 +84,7 @@ export const ToolSearchTool = buildTool({
|
|
|
362
84
|
// is a harmless no-op that lets the model proceed without retry churn.
|
|
363
85
|
const selectMatch = query.match(/^select:(.+)$/i)
|
|
364
86
|
if (selectMatch) {
|
|
365
|
-
const requested = selectMatch[1]
|
|
87
|
+
const requested = (selectMatch[1] ?? '')
|
|
366
88
|
.split(',')
|
|
367
89
|
.map(s => s.trim())
|
|
368
90
|
.filter(Boolean)
|
|
@@ -372,7 +94,7 @@ export const ToolSearchTool = buildTool({
|
|
|
372
94
|
for (const toolName of requested) {
|
|
373
95
|
const tool =
|
|
374
96
|
findToolByName(deferredTools, toolName) ??
|
|
375
|
-
findToolByName(
|
|
97
|
+
findToolByName(searchableTools, toolName)
|
|
376
98
|
if (tool) {
|
|
377
99
|
if (!found.includes(tool.name)) found.push(tool.name)
|
|
378
100
|
} else {
|
|
@@ -409,7 +131,7 @@ export const ToolSearchTool = buildTool({
|
|
|
409
131
|
const matches = await searchToolsWithKeywords(
|
|
410
132
|
query,
|
|
411
133
|
deferredTools,
|
|
412
|
-
|
|
134
|
+
searchableTools,
|
|
413
135
|
max_results,
|
|
414
136
|
)
|
|
415
137
|
|
|
@@ -462,10 +184,7 @@ export const ToolSearchTool = buildTool({
|
|
|
462
184
|
return {
|
|
463
185
|
type: 'tool_result',
|
|
464
186
|
tool_use_id: toolUseID,
|
|
465
|
-
content: content.matches
|
|
466
|
-
|
|
467
|
-
tool_name: name,
|
|
468
|
-
})),
|
|
469
|
-
} as unknown as ToolResultBlockParam
|
|
187
|
+
content: makeToolReferenceContent(content.matches),
|
|
188
|
+
}
|
|
470
189
|
},
|
|
471
190
|
} satisfies ToolDef<InputSchema, Output>)
|