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,384 @@
|
|
|
1
|
+
import type { AssistantMessage, Message } from '../types/message.js'
|
|
2
|
+
import {
|
|
3
|
+
buildGenericPendingFinalAnswerRepairPromptIfNeeded,
|
|
4
|
+
shouldWithholdGenericPendingFinalAnswer,
|
|
5
|
+
} from '../tools/_shared/toolChoiceRepair/publicDataRepair.js'
|
|
6
|
+
import {
|
|
7
|
+
contentBlocks,
|
|
8
|
+
isUserMessage,
|
|
9
|
+
latestTextUserMessageIndex,
|
|
10
|
+
messageText,
|
|
11
|
+
toolUseBlocks,
|
|
12
|
+
} from './messageGuards.js'
|
|
13
|
+
import {
|
|
14
|
+
buildUnavailableToolRepairPromptIfNeeded,
|
|
15
|
+
} from './unavailableToolRepair.js'
|
|
16
|
+
|
|
17
|
+
export {
|
|
18
|
+
buildUnavailableToolFinalAnswerBlockedText,
|
|
19
|
+
shouldBlockFinalAnswerAfterUnavailableToolRepair,
|
|
20
|
+
} from './unavailableToolRepair.js'
|
|
21
|
+
|
|
22
|
+
const UNSUPPORTED_ROUTE_REPAIR_MARKER = 'Unsupported route answer repair:'
|
|
23
|
+
const ROUTE_REQUEST_RE =
|
|
24
|
+
/(경로|대중교통|길\s*찾|길찾|어떻게\s*가|가는\s*법|환승|route|transit|directions|public\s+transport)/iu
|
|
25
|
+
const ROUTE_LIMITATION_RE =
|
|
26
|
+
/(실시간\s*(경로|대중교통|교통).*(제한|없|지원하지|연결되지)|경로\s*adapter|대중교통\s*adapter|공식.*(지도|교통|앱)|카카오맵|네이버\s*지도)/iu
|
|
27
|
+
const ROUTE_DETAIL_CLAIM_RE =
|
|
28
|
+
/(\d+\s*호선|[0-90-9]+\s*번\s*버스|승차|하차|환승\s*(하면|후|→|->)|요금[^\n.。]*\d|(?:약|대략)?\s*\d+\s*분(?:입니다|정도|소요)?)/iu
|
|
29
|
+
const EXPLICIT_PRIOR_RESULT_REQUEST_RE =
|
|
30
|
+
/(이전|전에|아까|방금|앞서|지난|다시|그\s*(결과|검색|병원|곳|장소|정보)|prior|previous|again)/iu
|
|
31
|
+
const RELATIVE_LOCATION_FOLLOWUP_RE =
|
|
32
|
+
/(주위|주변|우리\s*동네|여기|이\s*근처|현재\s*위치|내\s*위치|가까운|가까이|인근|근방)/iu
|
|
33
|
+
const LOCATION_SCOPED_PUBLIC_DATA_RE =
|
|
34
|
+
/(응급|응급실|야간\s*진료|야간진료|병원|의료|날씨|비\s*(?:와|오|올|내리)|우산|미세먼지|대기질|공기질|emergency|hospital|weather|rain|umbrella|air\s*quality)/iu
|
|
35
|
+
const PENDING_TOOL_ACTION_RE =
|
|
36
|
+
/(조회하겠습니다|찾아보겠습니다|검색해\s*보겠습니다|검색하겠습니다|확인해\s*보겠습니다|확인하겠습니다|찾기\s*위해|조회하기\s*위해|검색하기\s*위해)/iu
|
|
37
|
+
const PENDING_TOOL_ACTION_REPAIR_MARKER = 'Pending tool action repair:'
|
|
38
|
+
const LOCATION_RESULT_KINDS = new Set([
|
|
39
|
+
'coords',
|
|
40
|
+
'address',
|
|
41
|
+
'adm_cd',
|
|
42
|
+
'poi',
|
|
43
|
+
'region',
|
|
44
|
+
'bundle',
|
|
45
|
+
])
|
|
46
|
+
const SENSITIVE_SCALAR_KEY_RE =
|
|
47
|
+
/(^|[_\-.])(?:id|no|num|number|code|receipt|ref|reference|token|auth|authorization|approval|confirm|confirmation|certificate|serial|registration|payment|tax|amount|fee|price|cost|total|balance|claim|case|application|tracking|invoice|bill|번호|코드|접수|영수|승인|인증|토큰|증명|증서|등록|납부|결제|세금|세액|금액|요금|합계|잔액|청구|사건|신청|추적|송장)(?:$|[_\-.])/iu
|
|
48
|
+
const CODE_LIKE_SCALAR_RE = /^[0-9A-Za-z][0-9A-Za-z._:-]*$/u
|
|
49
|
+
|
|
50
|
+
type ToolResultBlock = {
|
|
51
|
+
readonly type: 'tool_result'
|
|
52
|
+
readonly tool_use_id: string
|
|
53
|
+
readonly content?: unknown
|
|
54
|
+
readonly is_error?: boolean
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function buildPublicDataTerminalRepairPrompt(params: {
|
|
58
|
+
readonly messages: readonly Message[]
|
|
59
|
+
readonly candidate: AssistantMessage
|
|
60
|
+
}): string | undefined {
|
|
61
|
+
const unavailableToolRepairPrompt =
|
|
62
|
+
buildUnavailableToolRepairPromptIfNeeded(params)
|
|
63
|
+
if (unavailableToolRepairPrompt !== undefined) {
|
|
64
|
+
return unavailableToolRepairPrompt
|
|
65
|
+
}
|
|
66
|
+
const pendingToolActionPrompt =
|
|
67
|
+
buildPendingToolActionRepairPromptIfNeeded(params)
|
|
68
|
+
if (pendingToolActionPrompt !== undefined) {
|
|
69
|
+
return pendingToolActionPrompt
|
|
70
|
+
}
|
|
71
|
+
if (
|
|
72
|
+
shouldWithholdGenericPendingFinalAnswer({
|
|
73
|
+
messages: params.messages,
|
|
74
|
+
candidate: params.candidate,
|
|
75
|
+
})
|
|
76
|
+
) {
|
|
77
|
+
return buildGenericPendingFinalAnswerRepairPromptIfNeeded({
|
|
78
|
+
messages: [...params.messages, params.candidate],
|
|
79
|
+
})
|
|
80
|
+
}
|
|
81
|
+
if (shouldWithholdUnsupportedRouteAnswer(params)) {
|
|
82
|
+
return buildUnsupportedRouteRepairPrompt()
|
|
83
|
+
}
|
|
84
|
+
return undefined
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function shouldBlockFinalAnswerAfterUnsupportedRouteRepair(params: {
|
|
88
|
+
readonly messages: readonly Message[]
|
|
89
|
+
readonly candidate: AssistantMessage
|
|
90
|
+
}): boolean {
|
|
91
|
+
return hasUnsupportedRouteRepairPromptAfterLatestUser(params.messages) &&
|
|
92
|
+
toolUseBlocks(params.candidate).length === 0
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function shouldBlockUnsupportedRouteDetailAnswer(params: {
|
|
96
|
+
readonly messages: readonly Message[]
|
|
97
|
+
readonly candidate: AssistantMessage
|
|
98
|
+
}): boolean {
|
|
99
|
+
if (toolUseBlocks(params.candidate).length > 0) return false
|
|
100
|
+
if (!isLatestUserRouteRequest(params.messages)) return false
|
|
101
|
+
if (!hasOnlyLocationEvidenceAfterLatestUser(params.messages)) return false
|
|
102
|
+
return ROUTE_DETAIL_CLAIM_RE.test(messageText(params.candidate))
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export function shouldBlockStalePriorToolResultAnswer(params: {
|
|
106
|
+
readonly messages: readonly Message[]
|
|
107
|
+
readonly candidate: AssistantMessage
|
|
108
|
+
}): boolean {
|
|
109
|
+
if (toolUseBlocks(params.candidate).length > 0) return false
|
|
110
|
+
const latestUserIndex = latestTextUserMessageIndex(params.messages)
|
|
111
|
+
if (latestUserIndex < 0) return false
|
|
112
|
+
const latestUser = params.messages[latestUserIndex]
|
|
113
|
+
if (latestUser === undefined) return false
|
|
114
|
+
const latestUserText = messageText(latestUser)
|
|
115
|
+
if (EXPLICIT_PRIOR_RESULT_REQUEST_RE.test(latestUserText)) return false
|
|
116
|
+
|
|
117
|
+
const currentPhrases = successfulToolResultPhrases(
|
|
118
|
+
params.messages.slice(latestUserIndex + 1),
|
|
119
|
+
)
|
|
120
|
+
const currentEvidenceText = [...currentPhrases, latestUserText]
|
|
121
|
+
.map(normalizePhraseText)
|
|
122
|
+
.join('\n')
|
|
123
|
+
const candidateText = normalizePhraseText(messageText(params.candidate))
|
|
124
|
+
if (candidateText.length === 0) return false
|
|
125
|
+
|
|
126
|
+
for (const phrase of successfulToolResultPhrases(
|
|
127
|
+
params.messages.slice(0, latestUserIndex),
|
|
128
|
+
{ excludeLocationResults: RELATIVE_LOCATION_FOLLOWUP_RE.test(latestUserText) },
|
|
129
|
+
)) {
|
|
130
|
+
const normalizedPhrase = normalizePhraseText(phrase)
|
|
131
|
+
if (normalizedPhrase.length === 0) continue
|
|
132
|
+
if (currentEvidenceText.includes(normalizedPhrase)) continue
|
|
133
|
+
if (candidateText.includes(normalizedPhrase)) return true
|
|
134
|
+
}
|
|
135
|
+
return false
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export function buildUnsupportedRouteFinalAnswerBlockedText(): string {
|
|
139
|
+
return [
|
|
140
|
+
'현재 UMMAYA 실행 도구 표면에는 실시간 경로 adapter 결과가 없습니다.',
|
|
141
|
+
'이번 턴에서 확인된 것은 출발지/도착지 위치 결과뿐이므로 환승역, 버스번호, 요금, 소요시간을 단정하지 않습니다.',
|
|
142
|
+
'실시간 이동 경로는 카카오맵, 네이버지도, 부산교통공사 등 공식 교통 채널에서 확인해야 합니다.',
|
|
143
|
+
].join('\n\n')
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export function buildStalePriorToolResultFinalAnswerBlockedText(): string {
|
|
147
|
+
return [
|
|
148
|
+
'이번 턴에서 확인되지 않은 이전 도구 결과를 현재 요청의 근거로 재사용하지 않습니다.',
|
|
149
|
+
'현재 답변은 최신 사용자 요청 이후 실행된 tool_result에 근거해야 하며, 이전 검색 결과를 새 위치나 새 조건의 결과처럼 단정할 수 없습니다.',
|
|
150
|
+
'필요한 정보는 해당 위치와 조건에 맞는 등록 adapter 결과를 다시 받은 뒤 안내해야 합니다.',
|
|
151
|
+
].join('\n\n')
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function buildPendingToolActionRepairPromptIfNeeded(params: {
|
|
155
|
+
readonly messages: readonly Message[]
|
|
156
|
+
readonly candidate: AssistantMessage
|
|
157
|
+
}): string | undefined {
|
|
158
|
+
if (toolUseBlocks(params.candidate).length > 0) return undefined
|
|
159
|
+
if (hasPendingToolActionRepairPromptAfterLatestUser(params.messages)) {
|
|
160
|
+
return undefined
|
|
161
|
+
}
|
|
162
|
+
const latestUserIndex = latestTextUserMessageIndex(params.messages)
|
|
163
|
+
if (latestUserIndex < 0) return undefined
|
|
164
|
+
const latestUser = params.messages[latestUserIndex]
|
|
165
|
+
if (latestUser === undefined) return undefined
|
|
166
|
+
const latestUserText = messageText(latestUser)
|
|
167
|
+
if (!RELATIVE_LOCATION_FOLLOWUP_RE.test(latestUserText)) return undefined
|
|
168
|
+
if (!LOCATION_SCOPED_PUBLIC_DATA_RE.test(latestUserText)) return undefined
|
|
169
|
+
if (hasSuccessfulToolResultAfter(params.messages, latestUserIndex)) {
|
|
170
|
+
return undefined
|
|
171
|
+
}
|
|
172
|
+
if (!hasLocationEvidenceBefore(params.messages, latestUserIndex)) {
|
|
173
|
+
return undefined
|
|
174
|
+
}
|
|
175
|
+
if (!PENDING_TOOL_ACTION_RE.test(messageText(params.candidate))) {
|
|
176
|
+
return undefined
|
|
177
|
+
}
|
|
178
|
+
return [
|
|
179
|
+
`${PENDING_TOOL_ACTION_REPAIR_MARKER} the assistant ended with a promise to look up current public-service data, but no tool_result exists for the latest citizen request.`,
|
|
180
|
+
'Use the prior location context only as input context, then call a registered adapter tool now when one is available in the current tool schema.',
|
|
181
|
+
'If no registered adapter supports the request, write a Korean fail-closed limitation; do not end with 조회하겠습니다, 확인하겠습니다, 검색하겠습니다, or another promise to answer later.',
|
|
182
|
+
].join(' ')
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function hasPendingToolActionRepairPromptAfterLatestUser(
|
|
186
|
+
messages: readonly Message[],
|
|
187
|
+
): boolean {
|
|
188
|
+
const latestUserIndex = latestTextUserMessageIndex(messages)
|
|
189
|
+
if (latestUserIndex < 0) return false
|
|
190
|
+
return messages.slice(latestUserIndex + 1).some(message =>
|
|
191
|
+
messageText(message).includes(PENDING_TOOL_ACTION_REPAIR_MARKER),
|
|
192
|
+
)
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function shouldWithholdUnsupportedRouteAnswer(params: {
|
|
196
|
+
readonly messages: readonly Message[]
|
|
197
|
+
readonly candidate: AssistantMessage
|
|
198
|
+
}): boolean {
|
|
199
|
+
if (toolUseBlocks(params.candidate).length > 0) return false
|
|
200
|
+
if (hasUnsupportedRouteRepairPromptAfterLatestUser(params.messages)) return false
|
|
201
|
+
if (!isLatestUserRouteRequest(params.messages)) return false
|
|
202
|
+
if (!hasOnlyLocationEvidenceAfterLatestUser(params.messages)) return false
|
|
203
|
+
return !ROUTE_LIMITATION_RE.test(messageText(params.candidate))
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function buildUnsupportedRouteRepairPrompt(): string {
|
|
207
|
+
return [
|
|
208
|
+
`${UNSUPPORTED_ROUTE_REPAIR_MARKER} successful tool_result evidence only located places; no routing, realtime transit, fare, or directions adapter returned route data.`,
|
|
209
|
+
'Do not provide transfer stations, bus numbers, fares, travel times, or step-by-step route instructions from general knowledge.',
|
|
210
|
+
'Write a Korean limitation/handoff answer grounded only in the location tool_results and tell the citizen to verify realtime route details in official transit/map channels.',
|
|
211
|
+
].join(' ')
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function isLatestUserRouteRequest(messages: readonly Message[]): boolean {
|
|
215
|
+
const latestUserIndex = latestTextUserMessageIndex(messages)
|
|
216
|
+
if (latestUserIndex < 0) return false
|
|
217
|
+
const latestUser = messages[latestUserIndex]
|
|
218
|
+
return latestUser !== undefined && ROUTE_REQUEST_RE.test(messageText(latestUser))
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function hasUnsupportedRouteRepairPromptAfterLatestUser(
|
|
222
|
+
messages: readonly Message[],
|
|
223
|
+
): boolean {
|
|
224
|
+
const latestUserIndex = latestTextUserMessageIndex(messages)
|
|
225
|
+
if (latestUserIndex < 0) return false
|
|
226
|
+
return messages.slice(latestUserIndex + 1).some(message =>
|
|
227
|
+
messageText(message).includes(UNSUPPORTED_ROUTE_REPAIR_MARKER),
|
|
228
|
+
)
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function hasOnlyLocationEvidenceAfterLatestUser(messages: readonly Message[]): boolean {
|
|
232
|
+
const latestUserIndex = latestTextUserMessageIndex(messages)
|
|
233
|
+
if (latestUserIndex < 0) return false
|
|
234
|
+
const successfulResults = messages
|
|
235
|
+
.slice(latestUserIndex + 1)
|
|
236
|
+
.flatMap(message => isUserMessage(message) ? toolResultBlocks(message) : [])
|
|
237
|
+
.filter(block => block.is_error !== true)
|
|
238
|
+
return successfulResults.length > 0 &&
|
|
239
|
+
successfulResults.every(block => isLocationToolResult(block.content))
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function hasLocationEvidenceBefore(
|
|
243
|
+
messages: readonly Message[],
|
|
244
|
+
endIndex: number,
|
|
245
|
+
): boolean {
|
|
246
|
+
return messages.slice(0, endIndex).some(message =>
|
|
247
|
+
isUserMessage(message) &&
|
|
248
|
+
toolResultBlocks(message).some(block =>
|
|
249
|
+
block.is_error !== true && isLocationToolResult(block.content),
|
|
250
|
+
),
|
|
251
|
+
)
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function successfulToolResultPhrases(
|
|
255
|
+
messages: readonly Message[],
|
|
256
|
+
options: { readonly excludeLocationResults?: boolean } = {},
|
|
257
|
+
): Set<string> {
|
|
258
|
+
const phrases = new Set<string>()
|
|
259
|
+
for (const message of messages) {
|
|
260
|
+
if (!isUserMessage(message)) continue
|
|
261
|
+
for (const block of toolResultBlocks(message)) {
|
|
262
|
+
if (block.is_error === true) continue
|
|
263
|
+
if (options.excludeLocationResults === true && isLocationToolResult(block.content)) {
|
|
264
|
+
continue
|
|
265
|
+
}
|
|
266
|
+
collectSalientPhrases(block.content, phrases)
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return phrases
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
function collectSalientPhrases(
|
|
273
|
+
value: unknown,
|
|
274
|
+
phrases: Set<string>,
|
|
275
|
+
keyHint?: string,
|
|
276
|
+
): void {
|
|
277
|
+
if (typeof value === 'string') {
|
|
278
|
+
const parsed = parseJsonObject(value)
|
|
279
|
+
if (parsed !== undefined) {
|
|
280
|
+
collectSalientPhrases(parsed, phrases)
|
|
281
|
+
return
|
|
282
|
+
}
|
|
283
|
+
addSalientPhrase(value, phrases, keyHint)
|
|
284
|
+
return
|
|
285
|
+
}
|
|
286
|
+
if (typeof value === 'number') {
|
|
287
|
+
if (Number.isFinite(value)) {
|
|
288
|
+
addSalientPhrase(String(value), phrases, keyHint)
|
|
289
|
+
}
|
|
290
|
+
return
|
|
291
|
+
}
|
|
292
|
+
if (Array.isArray(value)) {
|
|
293
|
+
for (const item of value) collectSalientPhrases(item, phrases, keyHint)
|
|
294
|
+
return
|
|
295
|
+
}
|
|
296
|
+
if (typeof value !== 'object' || value === null) return
|
|
297
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
298
|
+
collectSalientPhrases(entry, phrases, key)
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
function addSalientPhrase(
|
|
303
|
+
value: string,
|
|
304
|
+
phrases: Set<string>,
|
|
305
|
+
keyHint?: string,
|
|
306
|
+
): void {
|
|
307
|
+
const phrase = normalizePhraseText(value)
|
|
308
|
+
if (
|
|
309
|
+
!isSalientToolResultPhrase(phrase) &&
|
|
310
|
+
!isSensitiveScalarToolResultPhrase(keyHint, phrase)
|
|
311
|
+
) {
|
|
312
|
+
return
|
|
313
|
+
}
|
|
314
|
+
phrases.add(phrase)
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
function normalizePhraseText(value: string): string {
|
|
318
|
+
return value.replace(/\s+/g, ' ').trim()
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
function isSalientToolResultPhrase(value: string): boolean {
|
|
322
|
+
if (value.length < 3 || value.length > 80) return false
|
|
323
|
+
if (!/[A-Za-z가-힣]/u.test(value)) return false
|
|
324
|
+
if (/^(ok|true|false|null|none|unknown|collection|bundle|coords|address|region|poi|mock_complete)$/iu.test(value)) {
|
|
325
|
+
return false
|
|
326
|
+
}
|
|
327
|
+
return true
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
function isSensitiveScalarToolResultPhrase(
|
|
331
|
+
keyHint: string | undefined,
|
|
332
|
+
value: string,
|
|
333
|
+
): boolean {
|
|
334
|
+
if (keyHint === undefined) return false
|
|
335
|
+
if (!SENSITIVE_SCALAR_KEY_RE.test(keyHint)) return false
|
|
336
|
+
if (value.length < 3 || value.length > 80) return false
|
|
337
|
+
if (!/[0-9]/u.test(value)) return false
|
|
338
|
+
if (!CODE_LIKE_SCALAR_RE.test(value)) return false
|
|
339
|
+
if (/^(ok|true|false|null|none|unknown|success)$/iu.test(value)) return false
|
|
340
|
+
return true
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
function isLocationToolResult(content: unknown): boolean {
|
|
344
|
+
const parsed = parseJsonObject(content)
|
|
345
|
+
if (parsed === undefined) return false
|
|
346
|
+
const data = parseJsonObject(parsed.data)
|
|
347
|
+
const result = parseJsonObject(parsed.result) ??
|
|
348
|
+
(data !== undefined ? parseJsonObject(data.result) : undefined)
|
|
349
|
+
const kind = result?.kind
|
|
350
|
+
return typeof kind === 'string' && LOCATION_RESULT_KINDS.has(kind)
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
function parseJsonObject(value: unknown): Record<string, unknown> | undefined {
|
|
354
|
+
if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
|
|
355
|
+
return value as Record<string, unknown>
|
|
356
|
+
}
|
|
357
|
+
if (typeof value !== 'string') return undefined
|
|
358
|
+
try {
|
|
359
|
+
const parsed: unknown = JSON.parse(value)
|
|
360
|
+
return typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)
|
|
361
|
+
? parsed as Record<string, unknown>
|
|
362
|
+
: undefined
|
|
363
|
+
} catch {
|
|
364
|
+
return undefined
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
function hasSuccessfulToolResultAfter(
|
|
369
|
+
messages: readonly Message[],
|
|
370
|
+
startIndex: number,
|
|
371
|
+
): boolean {
|
|
372
|
+
return messages.slice(startIndex + 1).some(message =>
|
|
373
|
+
isUserMessage(message) &&
|
|
374
|
+
toolResultBlocks(message).some(block => block.is_error !== true),
|
|
375
|
+
)
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
function toolResultBlocks(message: Message): readonly ToolResultBlock[] {
|
|
379
|
+
return contentBlocks(message).filter(
|
|
380
|
+
(block): block is ToolResultBlock =>
|
|
381
|
+
block.type === 'tool_result' &&
|
|
382
|
+
typeof block.tool_use_id === 'string',
|
|
383
|
+
)
|
|
384
|
+
}
|