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,687 @@
|
|
|
1
|
+
import { findToolByName, type Tool, type ToolUseContext } from '../Tool.js'
|
|
2
|
+
import type { AssistantMessage, Message, UserMessage } from '../types/message.js'
|
|
3
|
+
import { getAdapterToolByName } from '../tools/AdapterTool/AdapterTool.js'
|
|
4
|
+
import {
|
|
5
|
+
repairUmmayaDocumentToolInputForDispatch,
|
|
6
|
+
} from '../tools/_shared/toolChoiceRepair.js'
|
|
7
|
+
import { deriveLocationQueryFromUserText } from '../tools/_shared/locationInputRepair.js'
|
|
8
|
+
import { createUserMessage } from '../utils/messages.js'
|
|
9
|
+
import { isUnregisteredRawJsonToolUseId } from '../utils/rawJsonToolCall.js'
|
|
10
|
+
import { formatZodValidationError } from '../utils/toolErrors.js'
|
|
11
|
+
import {
|
|
12
|
+
latestTextUserMessageIndex,
|
|
13
|
+
messageText,
|
|
14
|
+
type ToolUseBlock,
|
|
15
|
+
} from './messageGuards.js'
|
|
16
|
+
import { createToolUnavailableErrorPayload } from './toolResultErrors.js'
|
|
17
|
+
|
|
18
|
+
function serializeToolResult(data: unknown): string {
|
|
19
|
+
if (typeof data === 'string') return data
|
|
20
|
+
if (data === null || data === undefined) return ''
|
|
21
|
+
try {
|
|
22
|
+
return JSON.stringify(data)
|
|
23
|
+
} catch {
|
|
24
|
+
return String(data)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
29
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function parseJsonRecord(value: unknown): Record<string, unknown> | undefined {
|
|
33
|
+
if (isRecord(value)) return value
|
|
34
|
+
if (typeof value !== 'string') return undefined
|
|
35
|
+
try {
|
|
36
|
+
const parsed: unknown = JSON.parse(value)
|
|
37
|
+
return isRecord(parsed) ? parsed : undefined
|
|
38
|
+
} catch {
|
|
39
|
+
return undefined
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function isStructuredFailureResult(value: unknown): boolean {
|
|
44
|
+
return parseJsonRecord(value)?.ok === false
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function normalizeToolResultDataForModel(
|
|
48
|
+
toolName: string,
|
|
49
|
+
data: unknown,
|
|
50
|
+
): unknown {
|
|
51
|
+
if (toolName !== 'document' || !isRecord(data) || data.ok !== false) {
|
|
52
|
+
return data
|
|
53
|
+
}
|
|
54
|
+
if (isRecord(data.result) && data.result.tool_id === 'document') {
|
|
55
|
+
return data
|
|
56
|
+
}
|
|
57
|
+
const error = isRecord(data.error) ? data.error : undefined
|
|
58
|
+
const message = typeof error?.message === 'string'
|
|
59
|
+
? error.message
|
|
60
|
+
: 'Document tool failed before producing a document result.'
|
|
61
|
+
return {
|
|
62
|
+
...data,
|
|
63
|
+
result: {
|
|
64
|
+
tool_id: 'document',
|
|
65
|
+
status: 'failed',
|
|
66
|
+
text_summary: message,
|
|
67
|
+
},
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function permissionErrorMessage(message: string | undefined): string {
|
|
72
|
+
const trimmed = message?.trim()
|
|
73
|
+
return trimmed
|
|
74
|
+
? `Permission denied: ${trimmed}`
|
|
75
|
+
: 'Permission denied: tool execution was not approved.'
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
type ToolInput = { readonly [key: string]: unknown }
|
|
79
|
+
|
|
80
|
+
type SuccessfulToolCall = {
|
|
81
|
+
readonly toolName: string
|
|
82
|
+
readonly input: ToolInput
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const MAX_SUCCESSFUL_CALLS_PER_EFFECTIVE_TOOL = 2
|
|
86
|
+
const HOMETAX_LOOKUP_TOOL_NAME = 'mock_lookup_module_hometax_simplified'
|
|
87
|
+
const KMA_METAR_TOOL_NAME = 'kma_apihub_url_air_metar_decoded'
|
|
88
|
+
const ROOT_FIND_TOOL_NAME = 'find'
|
|
89
|
+
const KAKAO_LOCATION_TOOL_NAMES = new Set([
|
|
90
|
+
'kakao_address_search',
|
|
91
|
+
'kakao_keyword_search',
|
|
92
|
+
])
|
|
93
|
+
const KMA_ORDINARY_WEATHER_TOOL_NAMES = new Set([
|
|
94
|
+
'kma_apihub_upp_mtly_info_service_get_max_wind',
|
|
95
|
+
'kma_current_observation',
|
|
96
|
+
'kma_forecast_fetch',
|
|
97
|
+
'kma_short_term_forecast',
|
|
98
|
+
'kma_ultra_short_term_forecast',
|
|
99
|
+
])
|
|
100
|
+
|
|
101
|
+
function stableJson(value: unknown): string {
|
|
102
|
+
if (Array.isArray(value)) {
|
|
103
|
+
return `[${value.map(stableJson).join(',')}]`
|
|
104
|
+
}
|
|
105
|
+
if (isRecord(value)) {
|
|
106
|
+
return `{${Object.keys(value)
|
|
107
|
+
.sort()
|
|
108
|
+
.map(key => `${JSON.stringify(key)}:${stableJson(value[key])}`)
|
|
109
|
+
.join(',')}}`
|
|
110
|
+
}
|
|
111
|
+
const encoded = JSON.stringify(value)
|
|
112
|
+
return encoded === undefined ? String(value) : encoded
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function toolInputsEquivalent(
|
|
116
|
+
tool: Tool,
|
|
117
|
+
left: ToolInput,
|
|
118
|
+
right: ToolInput,
|
|
119
|
+
): boolean {
|
|
120
|
+
return tool.inputsEquivalent?.(left, right) ?? stableJson(left) === stableJson(right)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function effectiveToolKey(toolName: string, input: ToolInput): string {
|
|
124
|
+
const concreteToolId = input.tool_id
|
|
125
|
+
if (typeof concreteToolId === 'string' && concreteToolId.trim().length > 0) {
|
|
126
|
+
return `${toolName}:${concreteToolId}`
|
|
127
|
+
}
|
|
128
|
+
return toolName
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function isCitizenPromptMessage(message: Message): boolean {
|
|
132
|
+
if (message.type !== 'user') return false
|
|
133
|
+
if (message.isMeta === true) return false
|
|
134
|
+
const content = message.message.content
|
|
135
|
+
if (!Array.isArray(content)) return true
|
|
136
|
+
return !content.every(block => block.type === 'tool_result')
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function latestCitizenPromptIndex(messages: readonly Message[]): number {
|
|
140
|
+
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
141
|
+
const message = messages[index]
|
|
142
|
+
if (message !== undefined && isCitizenPromptMessage(message)) {
|
|
143
|
+
return index
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return -1
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function latestCitizenPromptText(messages: readonly Message[]): string {
|
|
150
|
+
const index = latestTextUserMessageIndex(messages)
|
|
151
|
+
const message = index >= 0 ? messages[index] : undefined
|
|
152
|
+
return message ? messageText(message) : ''
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function successfulToolResultIdsSinceLatestPrompt(
|
|
156
|
+
messages: readonly Message[],
|
|
157
|
+
): ReadonlySet<string> {
|
|
158
|
+
const startIndex = latestCitizenPromptIndex(messages)
|
|
159
|
+
const ids = new Set<string>()
|
|
160
|
+
for (const message of messages.slice(startIndex + 1)) {
|
|
161
|
+
if (message.type !== 'user' || !Array.isArray(message.message.content)) {
|
|
162
|
+
continue
|
|
163
|
+
}
|
|
164
|
+
for (const block of message.message.content) {
|
|
165
|
+
if (
|
|
166
|
+
block.type === 'tool_result' &&
|
|
167
|
+
block.is_error !== true &&
|
|
168
|
+
!isStructuredFailureResult(block.content)
|
|
169
|
+
) {
|
|
170
|
+
ids.add(block.tool_use_id)
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return ids
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function successfulToolCallsSinceLatestPrompt(
|
|
178
|
+
messages: readonly Message[],
|
|
179
|
+
): readonly SuccessfulToolCall[] {
|
|
180
|
+
const startIndex = latestCitizenPromptIndex(messages)
|
|
181
|
+
const successfulResultIds = successfulToolResultIdsSinceLatestPrompt(messages)
|
|
182
|
+
const calls: SuccessfulToolCall[] = []
|
|
183
|
+
for (const message of messages.slice(startIndex + 1)) {
|
|
184
|
+
if (message.type !== 'assistant') continue
|
|
185
|
+
for (const block of message.message.content) {
|
|
186
|
+
if (
|
|
187
|
+
block.type === 'tool_use' &&
|
|
188
|
+
successfulResultIds.has(block.id) &&
|
|
189
|
+
isRecord(block.input)
|
|
190
|
+
) {
|
|
191
|
+
calls.push({
|
|
192
|
+
toolName: block.name,
|
|
193
|
+
input: repairDirectLocationToolInputForValidation({
|
|
194
|
+
toolName: block.name,
|
|
195
|
+
input: block.input,
|
|
196
|
+
messages,
|
|
197
|
+
}),
|
|
198
|
+
})
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return calls
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
type PriorToolResult = {
|
|
206
|
+
readonly toolName: string
|
|
207
|
+
readonly content: unknown
|
|
208
|
+
readonly isError: boolean
|
|
209
|
+
readonly isStructuredFailure: boolean
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function toolResultsSinceLatestPrompt(
|
|
213
|
+
messages: readonly Message[],
|
|
214
|
+
): readonly PriorToolResult[] {
|
|
215
|
+
const startIndex = latestCitizenPromptIndex(messages)
|
|
216
|
+
const toolNamesByUseId = new Map<string, string>()
|
|
217
|
+
const results: PriorToolResult[] = []
|
|
218
|
+
for (const message of messages.slice(startIndex + 1)) {
|
|
219
|
+
if (message.type === 'assistant') {
|
|
220
|
+
for (const block of message.message.content) {
|
|
221
|
+
if (block.type === 'tool_use') {
|
|
222
|
+
toolNamesByUseId.set(block.id, block.name)
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
continue
|
|
226
|
+
}
|
|
227
|
+
if (message.type !== 'user' || !Array.isArray(message.message.content)) {
|
|
228
|
+
continue
|
|
229
|
+
}
|
|
230
|
+
for (const block of message.message.content) {
|
|
231
|
+
if (block.type !== 'tool_result') continue
|
|
232
|
+
const toolName = toolNamesByUseId.get(block.tool_use_id)
|
|
233
|
+
if (toolName === undefined) continue
|
|
234
|
+
results.push({
|
|
235
|
+
toolName,
|
|
236
|
+
content: block.content,
|
|
237
|
+
isError: block.is_error === true,
|
|
238
|
+
isStructuredFailure: isStructuredFailureResult(block.content),
|
|
239
|
+
})
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return results
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function repeatedToolUseMessage(toolName: string): string {
|
|
246
|
+
return `<tool_use_error>RepeatedToolUseError: Tool '${toolName}' already returned a successful result for the same effective inputs in this query loop. Use the prior tool result, or call with different parameters only if the citizen goal requires a broader follow-up.</tool_use_error>`
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
function hometaxProgressionMessage(): string {
|
|
250
|
+
return [
|
|
251
|
+
'Hometax lookup already returned a usable simplified-tax lookup result for this citizen request.',
|
|
252
|
+
'Do not repeat the same lookup before the required 본인확인, 위임, and 동의 progression.',
|
|
253
|
+
'Next valid step: call the verify tool for 본인확인/위임 동의, or write a Korean needs-input answer asking for that approval.',
|
|
254
|
+
].join(' ')
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
function kmaAviationRepeatMessage(kind: 'usable' | 'blocked'): string {
|
|
258
|
+
return kind === 'usable'
|
|
259
|
+
? [
|
|
260
|
+
'KMA aviation lookup already returned usable METAR evidence for this airport request.',
|
|
261
|
+
'Do not repeat the decoded METAR tool in the same query loop.',
|
|
262
|
+
'Use the prior aviation tool_result to answer the delay-risk question and state any remaining manual notification limitation.',
|
|
263
|
+
].join(' ')
|
|
264
|
+
: [
|
|
265
|
+
'KMA aviation lookup already returned a blocked result for this airport request.',
|
|
266
|
+
'Do not retry the decoded METAR tool without new credential/configuration evidence.',
|
|
267
|
+
'Write a Korean handoff answer that names the aviation weather credential limitation.',
|
|
268
|
+
].join(' ')
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function kmaOrdinaryFallbackMessage(toolName: string): string {
|
|
272
|
+
return [
|
|
273
|
+
`Do not call ${toolName} as a fallback for airport aviation weather after aviation METAR evidence exists.`,
|
|
274
|
+
'Do not ask the user for KMA nx/ny grid coordinates for an airport-flight risk question.',
|
|
275
|
+
'Use the aviation weather evidence already returned, or give a Korean handoff answer for official airline/airport status checks.',
|
|
276
|
+
].join(' ')
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function kmaGridRepeatMessage(toolName: string): string {
|
|
280
|
+
return [
|
|
281
|
+
'Do not repeat ordinary KMA current or forecast tools after a missing-grid or invalid-grid result.',
|
|
282
|
+
`Tool ${toolName} already failed for this route/weather turn without required grid parameters.`,
|
|
283
|
+
'Answer from the existing location evidence and ask for a precise district/date-time only if more weather detail is required.',
|
|
284
|
+
].join(' ')
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
function locationRepeatMessage(toolName: string, query: string): string {
|
|
288
|
+
return [
|
|
289
|
+
`Location lookup ${toolName} already returned usable Kakao coordinates for "${query}" in this query loop.`,
|
|
290
|
+
'Do not repeat the same location lookup.',
|
|
291
|
+
'Use the prior location evidence, or call the same adapter with a different origin, destination, radius, or refined query when the citizen goal requires it.',
|
|
292
|
+
].join(' ')
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
function shouldUseGenericRepeatGuard(tool: Tool, toolName: string): boolean {
|
|
296
|
+
return tool.inputsEquivalent !== undefined || toolName === ROOT_FIND_TOOL_NAME
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
function priorKmaAviationResultKind(
|
|
300
|
+
priorResults: readonly PriorToolResult[],
|
|
301
|
+
): 'usable' | 'blocked' | undefined {
|
|
302
|
+
const aviationResult = priorResults.find(
|
|
303
|
+
result => result.toolName === KMA_METAR_TOOL_NAME,
|
|
304
|
+
)
|
|
305
|
+
if (aviationResult === undefined) return undefined
|
|
306
|
+
return aviationResult.isStructuredFailure || aviationResult.isError
|
|
307
|
+
? 'blocked'
|
|
308
|
+
: 'usable'
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
function isKmaGridFailureResult(result: PriorToolResult): boolean {
|
|
312
|
+
if (!KMA_ORDINARY_WEATHER_TOOL_NAMES.has(result.toolName)) return false
|
|
313
|
+
const text = serializeToolResult(result.content)
|
|
314
|
+
return /Missing or invalid fields|LOCATE FIRST|nx\/ny|base_date|base_time/iu.test(text)
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
function createGuardToolResult(
|
|
318
|
+
block: ToolUseBlock,
|
|
319
|
+
assistantMessage: AssistantMessage,
|
|
320
|
+
message: string,
|
|
321
|
+
): UserMessage {
|
|
322
|
+
return createUserMessage({
|
|
323
|
+
content: [
|
|
324
|
+
{
|
|
325
|
+
type: 'tool_result',
|
|
326
|
+
tool_use_id: block.id,
|
|
327
|
+
content: message,
|
|
328
|
+
is_error: true,
|
|
329
|
+
},
|
|
330
|
+
],
|
|
331
|
+
toolUseResult: `Error: ${message}`,
|
|
332
|
+
sourceToolAssistantUUID: assistantMessage.uuid,
|
|
333
|
+
})
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
function domainRepeatGuardMessage(params: {
|
|
337
|
+
readonly block: ToolUseBlock
|
|
338
|
+
readonly input: ToolInput
|
|
339
|
+
readonly priorResults: readonly PriorToolResult[]
|
|
340
|
+
readonly successfulCalls: readonly SuccessfulToolCall[]
|
|
341
|
+
}): string | undefined {
|
|
342
|
+
if (KAKAO_LOCATION_TOOL_NAMES.has(params.block.name)) {
|
|
343
|
+
const query = typeof params.input.query === 'string'
|
|
344
|
+
? params.input.query.trim()
|
|
345
|
+
: ''
|
|
346
|
+
if (
|
|
347
|
+
query.length > 0 &&
|
|
348
|
+
params.successfulCalls.some(call =>
|
|
349
|
+
KAKAO_LOCATION_TOOL_NAMES.has(call.toolName) &&
|
|
350
|
+
typeof call.input.query === 'string' &&
|
|
351
|
+
call.input.query.trim() === query
|
|
352
|
+
)
|
|
353
|
+
) {
|
|
354
|
+
return locationRepeatMessage(params.block.name, query)
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
if (
|
|
359
|
+
params.block.name === HOMETAX_LOOKUP_TOOL_NAME &&
|
|
360
|
+
params.successfulCalls.some(call => call.toolName === HOMETAX_LOOKUP_TOOL_NAME)
|
|
361
|
+
) {
|
|
362
|
+
return hometaxProgressionMessage()
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
if (params.block.name === KMA_METAR_TOOL_NAME) {
|
|
366
|
+
const kind = priorKmaAviationResultKind(params.priorResults)
|
|
367
|
+
return kind ? kmaAviationRepeatMessage(kind) : undefined
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
const aviationKind = priorKmaAviationResultKind(params.priorResults)
|
|
371
|
+
if (aviationKind !== undefined) {
|
|
372
|
+
if (KMA_ORDINARY_WEATHER_TOOL_NAMES.has(params.block.name)) {
|
|
373
|
+
return kmaOrdinaryFallbackMessage(params.block.name)
|
|
374
|
+
}
|
|
375
|
+
if (
|
|
376
|
+
params.block.name === ROOT_FIND_TOOL_NAME &&
|
|
377
|
+
typeof params.block.input.tool_id === 'string' &&
|
|
378
|
+
KMA_ORDINARY_WEATHER_TOOL_NAMES.has(params.block.input.tool_id)
|
|
379
|
+
) {
|
|
380
|
+
return kmaOrdinaryFallbackMessage(params.block.input.tool_id)
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
if (
|
|
385
|
+
KMA_ORDINARY_WEATHER_TOOL_NAMES.has(params.block.name) &&
|
|
386
|
+
params.priorResults.some(
|
|
387
|
+
result =>
|
|
388
|
+
result.toolName === params.block.name && isKmaGridFailureResult(result),
|
|
389
|
+
)
|
|
390
|
+
) {
|
|
391
|
+
return kmaGridRepeatMessage(params.block.name)
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
return undefined
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
function repairDirectLocationToolInputForValidation(params: {
|
|
398
|
+
readonly toolName: string
|
|
399
|
+
readonly input: ToolInput
|
|
400
|
+
readonly messages: readonly Message[]
|
|
401
|
+
}): ToolInput {
|
|
402
|
+
if (
|
|
403
|
+
!KAKAO_LOCATION_TOOL_NAMES.has(params.toolName) ||
|
|
404
|
+
(typeof params.input.query === 'string' &&
|
|
405
|
+
params.input.query.trim().length > 0)
|
|
406
|
+
) {
|
|
407
|
+
return params.input
|
|
408
|
+
}
|
|
409
|
+
const query = deriveLocationQueryFromUserText(
|
|
410
|
+
latestCitizenPromptText(params.messages),
|
|
411
|
+
)
|
|
412
|
+
return query === undefined ? params.input : { ...params.input, query }
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
function unexplainedRepeatedToolMessage(toolName: string): string {
|
|
416
|
+
return `<tool_use_error>RepeatedToolUseError: Tool '${toolName}' already returned a successful result in this query loop. Before calling the same tool again with different inputs, write a visible progress sentence explaining which parameter, radius, source, or scope is changing; otherwise answer from the prior tool_result.</tool_use_error>`
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
function excessiveRepeatedToolMessage(toolName: string): string {
|
|
420
|
+
return `<tool_use_error>RepeatedToolUseError: Tool '${toolName}' already returned multiple successful results in this query loop. Stop calling the same effective tool again; answer from the prior tool_result set or state the remaining limitation.</tool_use_error>`
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
function hasVisibleAssistantText(message: AssistantMessage): boolean {
|
|
424
|
+
return message.message.content.some(
|
|
425
|
+
block => block.type === 'text' && block.text.trim().length > 0,
|
|
426
|
+
)
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
export async function runToolUseBlocks(params: {
|
|
430
|
+
readonly blocks: readonly ToolUseBlock[]
|
|
431
|
+
readonly assistantMessage: AssistantMessage
|
|
432
|
+
readonly messages: readonly Message[]
|
|
433
|
+
readonly toolUseContext: ToolUseContext
|
|
434
|
+
readonly canUseTool: Parameters<
|
|
435
|
+
ToolUseContext['options']['tools'][number]['call']
|
|
436
|
+
>[2]
|
|
437
|
+
}): Promise<readonly UserMessage[]> {
|
|
438
|
+
const results: UserMessage[] = []
|
|
439
|
+
const successfulCalls: SuccessfulToolCall[] = [
|
|
440
|
+
...successfulToolCallsSinceLatestPrompt(params.messages),
|
|
441
|
+
]
|
|
442
|
+
for (const block of params.blocks) {
|
|
443
|
+
const localTool = findToolByName(params.toolUseContext.options.tools, block.name)
|
|
444
|
+
const tool = isUnregisteredRawJsonToolUseId(block.id)
|
|
445
|
+
? undefined
|
|
446
|
+
: localTool ?? getAdapterToolByName(block.name)
|
|
447
|
+
if (!tool) {
|
|
448
|
+
const errorPayload = createToolUnavailableErrorPayload(block.name)
|
|
449
|
+
const errorContent = serializeToolResult(errorPayload)
|
|
450
|
+
results.push(
|
|
451
|
+
createUserMessage({
|
|
452
|
+
content: [
|
|
453
|
+
{
|
|
454
|
+
type: 'tool_result',
|
|
455
|
+
tool_use_id: block.id,
|
|
456
|
+
content: errorContent,
|
|
457
|
+
is_error: true,
|
|
458
|
+
},
|
|
459
|
+
],
|
|
460
|
+
toolUseResult: errorPayload,
|
|
461
|
+
sourceToolAssistantUUID: params.assistantMessage.uuid,
|
|
462
|
+
}),
|
|
463
|
+
)
|
|
464
|
+
continue
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
const documentRepair = repairUmmayaDocumentToolInputForDispatch({
|
|
468
|
+
toolName: block.name,
|
|
469
|
+
input: block.input,
|
|
470
|
+
messages: params.messages,
|
|
471
|
+
})
|
|
472
|
+
if (documentRepair.kind === 'blocked') {
|
|
473
|
+
results.push(
|
|
474
|
+
createUserMessage({
|
|
475
|
+
content: [
|
|
476
|
+
{
|
|
477
|
+
type: 'tool_result',
|
|
478
|
+
tool_use_id: block.id,
|
|
479
|
+
content: documentRepair.message,
|
|
480
|
+
is_error: true,
|
|
481
|
+
},
|
|
482
|
+
],
|
|
483
|
+
toolUseResult: documentRepair.message,
|
|
484
|
+
sourceToolAssistantUUID: params.assistantMessage.uuid,
|
|
485
|
+
}),
|
|
486
|
+
)
|
|
487
|
+
continue
|
|
488
|
+
}
|
|
489
|
+
const toolUseContext = {
|
|
490
|
+
...params.toolUseContext,
|
|
491
|
+
messages: params.messages,
|
|
492
|
+
}
|
|
493
|
+
const inputForValidation = localTool === undefined
|
|
494
|
+
? documentRepair.input
|
|
495
|
+
: repairDirectLocationToolInputForValidation({
|
|
496
|
+
toolName: block.name,
|
|
497
|
+
input: documentRepair.input,
|
|
498
|
+
messages: params.messages,
|
|
499
|
+
})
|
|
500
|
+
const parsedInput = tool.inputSchema.safeParse(inputForValidation)
|
|
501
|
+
if (!parsedInput.success) {
|
|
502
|
+
const errorContent = formatZodValidationError(
|
|
503
|
+
block.name,
|
|
504
|
+
parsedInput.error,
|
|
505
|
+
)
|
|
506
|
+
results.push(
|
|
507
|
+
createUserMessage({
|
|
508
|
+
content: [
|
|
509
|
+
{
|
|
510
|
+
type: 'tool_result',
|
|
511
|
+
tool_use_id: block.id,
|
|
512
|
+
content: `<tool_use_error>InputValidationError: ${errorContent}</tool_use_error>`,
|
|
513
|
+
is_error: true,
|
|
514
|
+
},
|
|
515
|
+
],
|
|
516
|
+
toolUseResult: `InputValidationError: ${parsedInput.error.message}`,
|
|
517
|
+
sourceToolAssistantUUID: params.assistantMessage.uuid,
|
|
518
|
+
}),
|
|
519
|
+
)
|
|
520
|
+
continue
|
|
521
|
+
}
|
|
522
|
+
const priorResults = toolResultsSinceLatestPrompt(params.messages)
|
|
523
|
+
const domainGuardMessage = domainRepeatGuardMessage({
|
|
524
|
+
block,
|
|
525
|
+
input: parsedInput.data,
|
|
526
|
+
priorResults,
|
|
527
|
+
successfulCalls,
|
|
528
|
+
})
|
|
529
|
+
if (domainGuardMessage !== undefined) {
|
|
530
|
+
results.push(
|
|
531
|
+
createGuardToolResult(block, params.assistantMessage, domainGuardMessage),
|
|
532
|
+
)
|
|
533
|
+
continue
|
|
534
|
+
}
|
|
535
|
+
const repeatedSuccessfulCall = successfulCalls.some(
|
|
536
|
+
call =>
|
|
537
|
+
effectiveToolKey(call.toolName, call.input) ===
|
|
538
|
+
effectiveToolKey(block.name, parsedInput.data) &&
|
|
539
|
+
toolInputsEquivalent(tool, parsedInput.data, call.input),
|
|
540
|
+
)
|
|
541
|
+
if (repeatedSuccessfulCall && shouldUseGenericRepeatGuard(tool, block.name)) {
|
|
542
|
+
const errorContent = repeatedToolUseMessage(block.name)
|
|
543
|
+
results.push(
|
|
544
|
+
createUserMessage({
|
|
545
|
+
content: [
|
|
546
|
+
{
|
|
547
|
+
type: 'tool_result',
|
|
548
|
+
tool_use_id: block.id,
|
|
549
|
+
content: errorContent,
|
|
550
|
+
is_error: true,
|
|
551
|
+
},
|
|
552
|
+
],
|
|
553
|
+
toolUseResult: `Error: ${errorContent}`,
|
|
554
|
+
sourceToolAssistantUUID: params.assistantMessage.uuid,
|
|
555
|
+
}),
|
|
556
|
+
)
|
|
557
|
+
continue
|
|
558
|
+
}
|
|
559
|
+
const successfulCallCountForEffectiveTool = successfulCalls.filter(
|
|
560
|
+
call =>
|
|
561
|
+
effectiveToolKey(call.toolName, call.input) ===
|
|
562
|
+
effectiveToolKey(block.name, parsedInput.data),
|
|
563
|
+
).length
|
|
564
|
+
if (
|
|
565
|
+
successfulCallCountForEffectiveTool >=
|
|
566
|
+
MAX_SUCCESSFUL_CALLS_PER_EFFECTIVE_TOOL &&
|
|
567
|
+
shouldUseGenericRepeatGuard(tool, block.name)
|
|
568
|
+
) {
|
|
569
|
+
const errorContent = excessiveRepeatedToolMessage(block.name)
|
|
570
|
+
results.push(
|
|
571
|
+
createUserMessage({
|
|
572
|
+
content: [
|
|
573
|
+
{
|
|
574
|
+
type: 'tool_result',
|
|
575
|
+
tool_use_id: block.id,
|
|
576
|
+
content: errorContent,
|
|
577
|
+
is_error: true,
|
|
578
|
+
},
|
|
579
|
+
],
|
|
580
|
+
toolUseResult: `Error: ${errorContent}`,
|
|
581
|
+
sourceToolAssistantUUID: params.assistantMessage.uuid,
|
|
582
|
+
}),
|
|
583
|
+
)
|
|
584
|
+
continue
|
|
585
|
+
}
|
|
586
|
+
const sameToolAlreadySucceeded = successfulCallCountForEffectiveTool > 0
|
|
587
|
+
if (
|
|
588
|
+
sameToolAlreadySucceeded &&
|
|
589
|
+
shouldUseGenericRepeatGuard(tool, block.name) &&
|
|
590
|
+
!hasVisibleAssistantText(params.assistantMessage)
|
|
591
|
+
) {
|
|
592
|
+
const errorContent = unexplainedRepeatedToolMessage(block.name)
|
|
593
|
+
results.push(
|
|
594
|
+
createUserMessage({
|
|
595
|
+
content: [
|
|
596
|
+
{
|
|
597
|
+
type: 'tool_result',
|
|
598
|
+
tool_use_id: block.id,
|
|
599
|
+
content: errorContent,
|
|
600
|
+
is_error: true,
|
|
601
|
+
},
|
|
602
|
+
],
|
|
603
|
+
toolUseResult: `Error: ${errorContent}`,
|
|
604
|
+
sourceToolAssistantUUID: params.assistantMessage.uuid,
|
|
605
|
+
}),
|
|
606
|
+
)
|
|
607
|
+
continue
|
|
608
|
+
}
|
|
609
|
+
const isValidCall = await tool.validateInput?.(
|
|
610
|
+
parsedInput.data,
|
|
611
|
+
toolUseContext,
|
|
612
|
+
)
|
|
613
|
+
if (isValidCall?.result === false) {
|
|
614
|
+
results.push(
|
|
615
|
+
createUserMessage({
|
|
616
|
+
content: [
|
|
617
|
+
{
|
|
618
|
+
type: 'tool_result',
|
|
619
|
+
tool_use_id: block.id,
|
|
620
|
+
content: `<tool_use_error>${isValidCall.message}</tool_use_error>`,
|
|
621
|
+
is_error: true,
|
|
622
|
+
},
|
|
623
|
+
],
|
|
624
|
+
toolUseResult: `Error: ${isValidCall.message}`,
|
|
625
|
+
sourceToolAssistantUUID: params.assistantMessage.uuid,
|
|
626
|
+
}),
|
|
627
|
+
)
|
|
628
|
+
continue
|
|
629
|
+
}
|
|
630
|
+
const permissionDecision = await params.canUseTool(
|
|
631
|
+
tool,
|
|
632
|
+
parsedInput.data,
|
|
633
|
+
toolUseContext,
|
|
634
|
+
params.assistantMessage,
|
|
635
|
+
block.id,
|
|
636
|
+
)
|
|
637
|
+
if (permissionDecision.behavior !== 'allow') {
|
|
638
|
+
const errorContent = permissionErrorMessage(permissionDecision.message)
|
|
639
|
+
results.push(
|
|
640
|
+
createUserMessage({
|
|
641
|
+
content: [
|
|
642
|
+
{
|
|
643
|
+
type: 'tool_result',
|
|
644
|
+
tool_use_id: block.id,
|
|
645
|
+
content: errorContent,
|
|
646
|
+
is_error: true,
|
|
647
|
+
},
|
|
648
|
+
],
|
|
649
|
+
toolUseResult: `Error: ${errorContent}`,
|
|
650
|
+
sourceToolAssistantUUID: params.assistantMessage.uuid,
|
|
651
|
+
}),
|
|
652
|
+
)
|
|
653
|
+
continue
|
|
654
|
+
}
|
|
655
|
+
const callInput = permissionDecision.updatedInput ?? parsedInput.data
|
|
656
|
+
const result = await tool.call(
|
|
657
|
+
callInput,
|
|
658
|
+
{
|
|
659
|
+
...toolUseContext,
|
|
660
|
+
toolUseId: block.id,
|
|
661
|
+
userModified: permissionDecision.userModified ?? false,
|
|
662
|
+
},
|
|
663
|
+
params.canUseTool,
|
|
664
|
+
params.assistantMessage,
|
|
665
|
+
)
|
|
666
|
+
const modelData = normalizeToolResultDataForModel(block.name, result.data)
|
|
667
|
+
const isStructuredFailure = isStructuredFailureResult(modelData)
|
|
668
|
+
results.push(
|
|
669
|
+
createUserMessage({
|
|
670
|
+
content: [
|
|
671
|
+
{
|
|
672
|
+
type: 'tool_result',
|
|
673
|
+
tool_use_id: block.id,
|
|
674
|
+
content: serializeToolResult(modelData),
|
|
675
|
+
...(isStructuredFailure ? { is_error: true as const } : {}),
|
|
676
|
+
},
|
|
677
|
+
],
|
|
678
|
+
toolUseResult: modelData,
|
|
679
|
+
sourceToolAssistantUUID: params.assistantMessage.uuid,
|
|
680
|
+
}),
|
|
681
|
+
)
|
|
682
|
+
if (!isStructuredFailure) {
|
|
683
|
+
successfulCalls.push({ toolName: block.name, input: parsedInput.data })
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
return results
|
|
687
|
+
}
|