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
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
import type { ToolUseContext, ValidationResult } from '../../Tool.js'
|
|
2
|
-
import { isNonSyntheticUserMessageText } from './citizenUserText.js'
|
|
3
|
-
|
|
4
|
-
const NMC_EMERGENCY_TOOL_NAME = 'nmc_emergency_search'
|
|
5
|
-
const NMC_AED_TOOL_NAME = 'nmc_aed_site_locate'
|
|
6
|
-
const HIRA_TOOL_NAME_RE = /^hira_/u
|
|
7
|
-
const AED_RE = /(aed|자동심장|심장충격|제세동)/iu
|
|
8
|
-
const ER_RE = /(응급실|응급의료기관|응급의료센터|emergency\s*room|\ber\b)/iu
|
|
9
|
-
const MEDICAL_COLLAPSE_RE =
|
|
10
|
-
/(사람이\s*쓰러|쓰러졌|쓰러짐|쓰러져|의식[을이가은는\s]*(없|잃|불명)|무의식|심정지|심폐소생|cpr|호흡\s*(없|곤란)|숨\s*(안|못)|collapse|collapsed|unconscious|cardiac\s*arrest|not\s*breathing)/iu
|
|
11
|
-
const NON_MEDICAL_EMERGENCY_RE =
|
|
12
|
-
/(비상벨|안심벨|emergency\s*(call\s*)?box|call\s*box)/iu
|
|
13
|
-
const NMC_AED_FOLLOWUP_PROMPT =
|
|
14
|
-
'Required follow-up for this tool chain: the citizen described a collapse, unconsciousness, cardiac-arrest, or AED-relevant medical emergency, and nmc_emergency_search has already returned a successful ER result. Before any final answer, call nmc_aed_site_locate with schema-valid fields using the latest region or location context from this turn. If AED returns no data or an upstream error, report that explicitly with 119 guidance. Do not write final prose until nmc_aed_site_locate has been attempted.'
|
|
15
|
-
const NMC_AED_COMPLETION_PROMPT =
|
|
16
|
-
'Emergency evidence chain complete: nmc_emergency_search and nmc_aed_site_locate have both been attempted for this collapse/unconsciousness request. Do not emit <tool_call> text, JSON tool-call text, or request another medical search. Write the final Korean emergency guidance now using the actual ER and AED tool results already in this conversation. Put 119 first, then nearest ER, then nearby AED locations or AED upstream/no-data status. Copy AED org, buildAddress, buildPlace, clerkTel, operating-time fields, and distance_km exactly when present; do not rename or summarize building places into new labels. Do not invent distances, walking times, building labels, station-inside labels, operating hours, or phone numbers that are absent from the tool results; omit unavailable details instead.'
|
|
17
|
-
|
|
18
|
-
type ToolUseRecord = {
|
|
19
|
-
id: string
|
|
20
|
-
name: string
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function textFromContent(content: unknown): string {
|
|
24
|
-
if (typeof content === 'string') return content
|
|
25
|
-
if (!Array.isArray(content)) return ''
|
|
26
|
-
return content
|
|
27
|
-
.map(block => {
|
|
28
|
-
if (typeof block === 'string') return block
|
|
29
|
-
if (typeof block !== 'object' || block === null) return ''
|
|
30
|
-
const record = block as Record<string, unknown>
|
|
31
|
-
return typeof record.text === 'string' ? record.text : ''
|
|
32
|
-
})
|
|
33
|
-
.filter(Boolean)
|
|
34
|
-
.join('\n')
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function asRecord(value: unknown): Record<string, unknown> | undefined {
|
|
38
|
-
return typeof value === 'object' && value !== null
|
|
39
|
-
? (value as Record<string, unknown>)
|
|
40
|
-
: undefined
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function messageRecord(message: unknown): Record<string, unknown> | undefined {
|
|
44
|
-
const record = asRecord(message)
|
|
45
|
-
return asRecord(record?.message)
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function messageRole(message: unknown): string | undefined {
|
|
49
|
-
const record = asRecord(message)
|
|
50
|
-
const inner = messageRecord(message)
|
|
51
|
-
if (typeof inner?.role === 'string') return inner.role
|
|
52
|
-
if (typeof record?.role === 'string') return record.role
|
|
53
|
-
return typeof record?.type === 'string' ? record.type : undefined
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function messageContent(message: unknown): unknown {
|
|
57
|
-
return messageRecord(message)?.content ?? asRecord(message)?.content
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function latestRoleText(context: ToolUseContext, role: 'assistant' | 'user'): string {
|
|
61
|
-
const messages = Array.isArray(context.messages) ? context.messages : []
|
|
62
|
-
for (let idx = messages.length - 1; idx >= 0; idx -= 1) {
|
|
63
|
-
const message = messages[idx]
|
|
64
|
-
if (messageRole(message) !== role) continue
|
|
65
|
-
const text = textFromContent(messageContent(message))
|
|
66
|
-
if (role === 'user' && !isNonSyntheticUserMessageText(message, text)) continue
|
|
67
|
-
if (text.trim()) return text
|
|
68
|
-
}
|
|
69
|
-
return ''
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function latestUserTurnStartIndex(messages: readonly unknown[]): number {
|
|
73
|
-
for (let idx = messages.length - 1; idx >= 0; idx -= 1) {
|
|
74
|
-
const message = messages[idx]
|
|
75
|
-
if (messageRole(message) !== 'user') continue
|
|
76
|
-
const text = textFromContent(messageContent(message))
|
|
77
|
-
if (isNonSyntheticUserMessageText(message, text)) return idx
|
|
78
|
-
}
|
|
79
|
-
return -1
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function latestUserTurnMessages(messages: readonly unknown[]): readonly unknown[] {
|
|
83
|
-
const startIdx = latestUserTurnStartIndex(messages)
|
|
84
|
-
return startIdx === -1 ? [] : messages.slice(startIdx)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function latestUserTextFromMessages(messages: readonly unknown[]): string {
|
|
88
|
-
const startIdx = latestUserTurnStartIndex(messages)
|
|
89
|
-
if (startIdx === -1) return ''
|
|
90
|
-
return textFromContent(messageContent(messages[startIdx]))
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
function isMedicalCollapseQuery(text: string): boolean {
|
|
94
|
-
if (!text.trim()) return false
|
|
95
|
-
if (AED_RE.test(text) || MEDICAL_COLLAPSE_RE.test(text)) return true
|
|
96
|
-
return false
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
function isOnlyNonMedicalEmergencyQuery(text: string): boolean {
|
|
100
|
-
return NON_MEDICAL_EMERGENCY_RE.test(text) && !isMedicalCollapseQuery(text)
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function toolUsesFromMessages(messages: readonly unknown[]): ToolUseRecord[] {
|
|
104
|
-
const toolUses: ToolUseRecord[] = []
|
|
105
|
-
for (const message of messages) {
|
|
106
|
-
const content = messageContent(message)
|
|
107
|
-
if (!Array.isArray(content)) continue
|
|
108
|
-
for (const block of content) {
|
|
109
|
-
const record = asRecord(block)
|
|
110
|
-
if (record?.type !== 'tool_use') continue
|
|
111
|
-
if (typeof record.id !== 'string' || typeof record.name !== 'string') continue
|
|
112
|
-
const input = asRecord(record.input)
|
|
113
|
-
const nestedToolName =
|
|
114
|
-
typeof input?.tool_id === 'string' ? input.tool_id : undefined
|
|
115
|
-
toolUses.push({ id: record.id, name: nestedToolName ?? record.name })
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
return toolUses
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function parseJsonObject(value: string): Record<string, unknown> | undefined {
|
|
122
|
-
try {
|
|
123
|
-
return asRecord(JSON.parse(value))
|
|
124
|
-
} catch {
|
|
125
|
-
return undefined
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
function isSuccessfulToolResult(block: Record<string, unknown>): boolean {
|
|
130
|
-
if (block.is_error === true) return false
|
|
131
|
-
if (typeof block.content !== 'string') return true
|
|
132
|
-
|
|
133
|
-
const parsed = parseJsonObject(block.content)
|
|
134
|
-
if (!parsed) return true
|
|
135
|
-
if (parsed.ok === false) return false
|
|
136
|
-
if (parsed.error || parsed.error_code || parsed.errorCode) return false
|
|
137
|
-
|
|
138
|
-
const result = asRecord(parsed.result)
|
|
139
|
-
if (result?.kind === 'error') return false
|
|
140
|
-
return true
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
function hasSuccessfulToolResultFor(
|
|
144
|
-
messages: readonly unknown[],
|
|
145
|
-
toolName: string,
|
|
146
|
-
): boolean {
|
|
147
|
-
const idToName = new Map(
|
|
148
|
-
toolUsesFromMessages(messages).map(toolUse => [toolUse.id, toolUse.name]),
|
|
149
|
-
)
|
|
150
|
-
for (const message of messages) {
|
|
151
|
-
const content = messageContent(message)
|
|
152
|
-
if (!Array.isArray(content)) continue
|
|
153
|
-
for (const block of content) {
|
|
154
|
-
const record = asRecord(block)
|
|
155
|
-
if (record?.type !== 'tool_result') continue
|
|
156
|
-
if (typeof record.tool_use_id !== 'string') continue
|
|
157
|
-
if (idToName.get(record.tool_use_id) !== toolName) continue
|
|
158
|
-
if (isSuccessfulToolResult(record)) return true
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
return false
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
function hasToolUse(messages: readonly unknown[], toolName: string): boolean {
|
|
165
|
-
return toolUsesFromMessages(messages).some(toolUse => toolUse.name === toolName)
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
export function buildNmcAedFollowupPromptIfNeeded({
|
|
169
|
-
messages,
|
|
170
|
-
availableToolNames,
|
|
171
|
-
}: {
|
|
172
|
-
messages: readonly unknown[]
|
|
173
|
-
availableToolNames: Iterable<string>
|
|
174
|
-
}): string | undefined {
|
|
175
|
-
const available = new Set(availableToolNames)
|
|
176
|
-
if (!available.has(NMC_AED_TOOL_NAME)) return undefined
|
|
177
|
-
|
|
178
|
-
const userText = latestUserTextFromMessages(messages)
|
|
179
|
-
const turnMessages = latestUserTurnMessages(messages)
|
|
180
|
-
if (isOnlyNonMedicalEmergencyQuery(userText)) return undefined
|
|
181
|
-
if (!isMedicalCollapseQuery(userText)) return undefined
|
|
182
|
-
if (hasToolUse(turnMessages, NMC_AED_TOOL_NAME)) return undefined
|
|
183
|
-
if (!hasSuccessfulToolResultFor(turnMessages, NMC_EMERGENCY_TOOL_NAME)) {
|
|
184
|
-
return undefined
|
|
185
|
-
}
|
|
186
|
-
return NMC_AED_FOLLOWUP_PROMPT
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
export function buildNmcAedCompletionPromptIfNeeded({
|
|
190
|
-
messages,
|
|
191
|
-
}: {
|
|
192
|
-
messages: readonly unknown[]
|
|
193
|
-
}): string | undefined {
|
|
194
|
-
const userText = latestUserTextFromMessages(messages)
|
|
195
|
-
const turnMessages = latestUserTurnMessages(messages)
|
|
196
|
-
if (isOnlyNonMedicalEmergencyQuery(userText)) return undefined
|
|
197
|
-
if (!isMedicalCollapseQuery(userText)) return undefined
|
|
198
|
-
if (!hasToolUse(turnMessages, NMC_AED_TOOL_NAME)) return undefined
|
|
199
|
-
if (!hasToolUse(turnMessages, NMC_EMERGENCY_TOOL_NAME)) return undefined
|
|
200
|
-
return NMC_AED_COMPLETION_PROMPT
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
export function validateNmcAedToolChoice(
|
|
204
|
-
toolId: string,
|
|
205
|
-
context: ToolUseContext,
|
|
206
|
-
): ValidationResult | undefined {
|
|
207
|
-
if (HIRA_TOOL_NAME_RE.test(toolId)) {
|
|
208
|
-
const userText = latestRoleText(context, 'user')
|
|
209
|
-
if (!isOnlyNonMedicalEmergencyQuery(userText) && isMedicalCollapseQuery(userText)) {
|
|
210
|
-
return {
|
|
211
|
-
result: false,
|
|
212
|
-
message:
|
|
213
|
-
'NMC emergency tool-choice mismatch: a collapse, unconsciousness, cardiac-arrest, or AED-relevant emergency must use official emergency-care evidence, not the general HIRA hospital/clinic search. ' +
|
|
214
|
-
`Call ${NMC_EMERGENCY_TOOL_NAME} for nearest emergency-room/ER institution data and then ${NMC_AED_TOOL_NAME} for AED locations. ` +
|
|
215
|
-
'If either NMC adapter returns no data or an upstream error, report that directly with 119 guidance.',
|
|
216
|
-
errorCode: 1,
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
if (toolId !== NMC_EMERGENCY_TOOL_NAME) return undefined
|
|
221
|
-
const assistantText = latestRoleText(context, 'assistant')
|
|
222
|
-
const userText = latestRoleText(context, 'user')
|
|
223
|
-
const assistantIsAskingForAed = AED_RE.test(assistantText) && !ER_RE.test(assistantText)
|
|
224
|
-
const userAskedOnlyForAed = AED_RE.test(userText) && !ER_RE.test(userText)
|
|
225
|
-
if (!assistantIsAskingForAed && !userAskedOnlyForAed) return undefined
|
|
226
|
-
return {
|
|
227
|
-
result: false,
|
|
228
|
-
message:
|
|
229
|
-
'NMC tool-choice mismatch: nmc_emergency_search answers emergency-room/ER institution data, not AED locations. ' +
|
|
230
|
-
`Call ${NMC_AED_TOOL_NAME} for AED/자동심장충격기/자동제세동기 requests. ` +
|
|
231
|
-
'If the AED API returns no data or an upstream error, report that result directly instead of substituting ER data.',
|
|
232
|
-
errorCode: 1,
|
|
233
|
-
}
|
|
234
|
-
}
|
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
import type { ToolUseContext, ValidationResult } from '../../Tool.js'
|
|
2
|
-
import {
|
|
3
|
-
listAdapters,
|
|
4
|
-
resolveAdapter,
|
|
5
|
-
} from '../../services/api/adapterManifest.js'
|
|
6
|
-
import { isNonSyntheticUserMessageText } from './citizenUserText.js'
|
|
7
|
-
import { textFromContent } from './nmcAedGuard.js'
|
|
8
|
-
|
|
9
|
-
const PROTECTED_QUERY_RE =
|
|
10
|
-
/(본인확인|인증|간편인증|모바일\s*(?:신분증|id)|mobile\s*id|마이데이터|mydata|증명원|소득금액증명|소득금액증명원|주민등록등본|민원|발급)/iu
|
|
11
|
-
const VERIFY_ALIAS_RE =
|
|
12
|
-
/^(?:check|mobile_id|modid|simple_auth_module|ganpyeon_injeung|gongdong_injeungseo|geumyung_injeungseo|mydata|any_id_sso)$/iu
|
|
13
|
-
const PROTECTED_CHECK_TOOL_NAMES = new Set([
|
|
14
|
-
'mock_verify_module_simple_auth',
|
|
15
|
-
'mock_verify_ganpyeon_injeung',
|
|
16
|
-
'mock_verify_mobile_id',
|
|
17
|
-
'mock_verify_mydata',
|
|
18
|
-
'mock_verify_digital_onepass',
|
|
19
|
-
'mock_verify_gongdong_injeungseo',
|
|
20
|
-
'mock_verify_geumyung_injeungseo',
|
|
21
|
-
'mock_verify_module_modid',
|
|
22
|
-
'mock_verify_module_kec',
|
|
23
|
-
'mock_verify_module_geumyung',
|
|
24
|
-
'mock_verify_module_any_id_sso',
|
|
25
|
-
])
|
|
26
|
-
const PROTECTED_CHECK_COMPLETION_PROMPT =
|
|
27
|
-
'Protected-domain evidence chain complete: a registered check adapter has already been attempted for this certificate, authentication, identity, or protected-service request. Do not emit <tool_call> text, JSON tool-call text, or request another identity tool. Write the final Korean answer now using the actual check result already in this conversation. If the result is permission_denied, unavailable, or mock-only, state that UMMAYA cannot complete the protected action in-session, then give official handoff options without claiming issuance succeeded.'
|
|
28
|
-
const PROTECTED_CHECK_REPAIR_PROMPT =
|
|
29
|
-
'Protected-domain final-answer repair: the previous assistant message was invalid because it printed JSON tool-call text after a registered check adapter result. Do not call or print any tool. Write one Korean prose answer only. Use the existing check result already in this conversation. If the result is permission_denied, unavailable, or mock-only, state that UMMAYA cannot complete the protected action in-session, then give official handoff options such as Government24, Hometax, mobile ID, or 간편인증 without claiming issuance succeeded.'
|
|
30
|
-
const PROTECTED_TOOL_CALL_TEXT_RE =
|
|
31
|
-
/<tool_call>|"name"\s*:\s*"[^"]*(?:check|verify|auth|mobile|simple|ganpyeon|mydata)[^"]*"|"arguments"\s*:\s*\{/iu
|
|
32
|
-
|
|
33
|
-
function asRecord(value: unknown): Record<string, unknown> | undefined {
|
|
34
|
-
return typeof value === 'object' && value !== null
|
|
35
|
-
? (value as Record<string, unknown>)
|
|
36
|
-
: undefined
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function messageRecord(message: unknown): Record<string, unknown> | undefined {
|
|
40
|
-
return asRecord(asRecord(message)?.message)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function messageRole(message: unknown): string | undefined {
|
|
44
|
-
const record = asRecord(message)
|
|
45
|
-
const inner = messageRecord(message)
|
|
46
|
-
if (typeof inner?.role === 'string') return inner.role
|
|
47
|
-
if (typeof record?.role === 'string') return record.role
|
|
48
|
-
return typeof record?.type === 'string' ? record.type : undefined
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function messageContent(message: unknown): unknown {
|
|
52
|
-
return messageRecord(message)?.content ?? asRecord(message)?.content
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function latestUserText(context: ToolUseContext): string {
|
|
56
|
-
const messages = Array.isArray(context.messages) ? context.messages : []
|
|
57
|
-
for (let idx = messages.length - 1; idx >= 0; idx -= 1) {
|
|
58
|
-
const message = messages[idx]
|
|
59
|
-
if (messageRole(message) !== 'user') continue
|
|
60
|
-
const text = textFromContent(messageContent(message))
|
|
61
|
-
if (isNonSyntheticUserMessageText(message, text)) return text
|
|
62
|
-
}
|
|
63
|
-
return ''
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
function userTextFromMessages(messages: readonly unknown[]): string {
|
|
67
|
-
return messages
|
|
68
|
-
.filter(message => messageRole(message) === 'user')
|
|
69
|
-
.map(message => ({ message, text: textFromContent(messageContent(message)) }))
|
|
70
|
-
.filter(({ message, text }) => isNonSyntheticUserMessageText(message, text))
|
|
71
|
-
.map(({ text }) => text)
|
|
72
|
-
.join('\n')
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function hasProtectedCheckToolUse(messages: readonly unknown[]): boolean {
|
|
76
|
-
for (const message of messages) {
|
|
77
|
-
const content = messageContent(message)
|
|
78
|
-
if (!Array.isArray(content)) continue
|
|
79
|
-
for (const block of content) {
|
|
80
|
-
const record = asRecord(block)
|
|
81
|
-
if (record?.type !== 'tool_use') continue
|
|
82
|
-
if (
|
|
83
|
-
typeof record.name === 'string' &&
|
|
84
|
-
PROTECTED_CHECK_TOOL_NAMES.has(record.name)
|
|
85
|
-
) {
|
|
86
|
-
return true
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
return false
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
function latestAssistantText(messages: readonly unknown[]): string {
|
|
94
|
-
for (let idx = messages.length - 1; idx >= 0; idx -= 1) {
|
|
95
|
-
const message = messages[idx]
|
|
96
|
-
if (messageRole(message) !== 'assistant') continue
|
|
97
|
-
const text = textFromContent(messageContent(message))
|
|
98
|
-
if (text.trim()) return text
|
|
99
|
-
}
|
|
100
|
-
return ''
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function hasRepairPrompt(messages: readonly unknown[]): boolean {
|
|
104
|
-
return messages.some(message =>
|
|
105
|
-
textFromContent(messageContent(message)).includes(
|
|
106
|
-
'Protected-domain final-answer repair',
|
|
107
|
-
),
|
|
108
|
-
)
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function checkAdapterIds(): string[] {
|
|
112
|
-
return listAdapters()
|
|
113
|
-
.filter(entry => entry.primitive === 'check')
|
|
114
|
-
.map(entry => entry.tool_id)
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function selectSuggestions(toolId: string, userText: string): string[] {
|
|
118
|
-
const available = checkAdapterIds()
|
|
119
|
-
const wantsMobile = /mobile\s*id|모바일\s*(?:신분증|id)|mobile_id/iu.test(
|
|
120
|
-
`${toolId} ${userText}`,
|
|
121
|
-
)
|
|
122
|
-
const wantsSimple =
|
|
123
|
-
/simple_auth|간편인증|ganpyeon|소득금액증명|증명원|민원|발급/iu.test(
|
|
124
|
-
`${toolId} ${userText}`,
|
|
125
|
-
)
|
|
126
|
-
const wantsMydata = /mydata|마이데이터/iu.test(`${toolId} ${userText}`)
|
|
127
|
-
const preferred = [
|
|
128
|
-
wantsMobile ? 'mock_verify_mobile_id' : undefined,
|
|
129
|
-
wantsSimple ? 'mock_verify_module_simple_auth' : undefined,
|
|
130
|
-
wantsSimple ? 'mock_verify_ganpyeon_injeung' : undefined,
|
|
131
|
-
wantsMydata ? 'mock_verify_mydata' : undefined,
|
|
132
|
-
].filter((id): id is string => typeof id === 'string' && available.includes(id))
|
|
133
|
-
const merged = [...preferred, ...available]
|
|
134
|
-
return [...new Set(merged)].slice(0, 3)
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
export function validateProtectedCheckToolChoice(
|
|
138
|
-
toolId: string,
|
|
139
|
-
context: ToolUseContext,
|
|
140
|
-
): ValidationResult | undefined {
|
|
141
|
-
const userText = latestUserText(context)
|
|
142
|
-
const adapter = resolveAdapter(toolId)
|
|
143
|
-
if (adapter?.primitive === 'check') {
|
|
144
|
-
return {
|
|
145
|
-
result: false,
|
|
146
|
-
message:
|
|
147
|
-
`Protected-domain tool-choice mismatch: ${toolId} is a check adapter but was called through find. ` +
|
|
148
|
-
`Call check({tool_id:${JSON.stringify(toolId)}, params:{...}}) instead. ` +
|
|
149
|
-
'Do not call check adapters through find.',
|
|
150
|
-
errorCode: 1,
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
if (!PROTECTED_QUERY_RE.test(userText) && !VERIFY_ALIAS_RE.test(toolId)) {
|
|
154
|
-
return undefined
|
|
155
|
-
}
|
|
156
|
-
if (!VERIFY_ALIAS_RE.test(toolId)) return undefined
|
|
157
|
-
const suggestions = selectSuggestions(toolId, userText)
|
|
158
|
-
if (suggestions.length === 0) return undefined
|
|
159
|
-
return {
|
|
160
|
-
result: false,
|
|
161
|
-
message:
|
|
162
|
-
`Protected-domain tool-choice mismatch: ${toolId} is not a registered find adapter. ` +
|
|
163
|
-
`Use the check primitive with a registered check adapter such as ${suggestions.join(', ')}. ` +
|
|
164
|
-
'Do not call identity, authentication, consent, or certificate adapters through find.',
|
|
165
|
-
errorCode: 1,
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
export function buildProtectedCheckCompletionPromptIfNeeded({
|
|
170
|
-
messages,
|
|
171
|
-
}: {
|
|
172
|
-
messages: readonly unknown[]
|
|
173
|
-
}): string | undefined {
|
|
174
|
-
const userText = userTextFromMessages(messages)
|
|
175
|
-
if (!PROTECTED_QUERY_RE.test(userText)) return undefined
|
|
176
|
-
if (!hasProtectedCheckToolUse(messages)) return undefined
|
|
177
|
-
return PROTECTED_CHECK_COMPLETION_PROMPT
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
export function buildProtectedCheckFinalAnswerRepairPromptIfNeeded({
|
|
181
|
-
messages,
|
|
182
|
-
}: {
|
|
183
|
-
messages: readonly unknown[]
|
|
184
|
-
}): string | undefined {
|
|
185
|
-
const userText = userTextFromMessages(messages)
|
|
186
|
-
if (!PROTECTED_QUERY_RE.test(userText)) return undefined
|
|
187
|
-
if (!hasProtectedCheckToolUse(messages)) return undefined
|
|
188
|
-
if (hasRepairPrompt(messages)) return undefined
|
|
189
|
-
const assistantText = latestAssistantText(messages)
|
|
190
|
-
if (!PROTECTED_TOOL_CALL_TEXT_RE.test(assistantText)) return undefined
|
|
191
|
-
return PROTECTED_CHECK_REPAIR_PROMPT
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
export function shouldWithholdProtectedCheckToolCallText({
|
|
195
|
-
messages,
|
|
196
|
-
candidate,
|
|
197
|
-
}: {
|
|
198
|
-
messages: readonly unknown[]
|
|
199
|
-
candidate: unknown
|
|
200
|
-
}): boolean {
|
|
201
|
-
if (hasRepairPrompt(messages)) return false
|
|
202
|
-
return (
|
|
203
|
-
buildProtectedCheckFinalAnswerRepairPromptIfNeeded({
|
|
204
|
-
messages: [...messages, candidate],
|
|
205
|
-
}) !== undefined
|
|
206
|
-
)
|
|
207
|
-
}
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import { textFromContent } from './nmcAedGuard.js'
|
|
2
|
-
|
|
3
|
-
const TEXT_TOOL_CALL_RE =
|
|
4
|
-
/<tool_call>|<\/tool_call>|"name"\s*:\s*"[^"]+"[\s\S]*"arguments"\s*:\s*\{/iu
|
|
5
|
-
const TEXT_TOOL_CALL_BLOCK_RE = /\s*<tool_call>[\s\S]*?<\/tool_call>\s*/giu
|
|
6
|
-
const TEXT_TOOL_CALL_REPAIR_MARKER = 'Textual tool-call final-answer repair'
|
|
7
|
-
const TEXT_TOOL_CALL_REPAIR_PROMPT =
|
|
8
|
-
'Textual tool-call final-answer repair: the previous assistant message was invalid because it printed a tool call as text. Never emit <tool_call> text, JSON tool-call text, or a JSON object with name/arguments in prose. If a tool is still needed, call it only through the native structured tool_use interface. If the needed tool has already been attempted, do not call or print any tool; write one Korean prose answer from the actual tool results already in this conversation. If the available result is no-data, upstream failure, approval-required, or insufficient for the requested detail, state that directly and give the official handoff or next action.'
|
|
9
|
-
|
|
10
|
-
function asRecord(value: unknown): Record<string, unknown> | undefined {
|
|
11
|
-
return typeof value === 'object' && value !== null
|
|
12
|
-
? (value as Record<string, unknown>)
|
|
13
|
-
: undefined
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function messageRecord(message: unknown): Record<string, unknown> | undefined {
|
|
17
|
-
return asRecord(asRecord(message)?.message)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function messageRole(message: unknown): string | undefined {
|
|
21
|
-
const outer = asRecord(message)
|
|
22
|
-
const inner = messageRecord(message)
|
|
23
|
-
if (typeof inner?.role === 'string') return inner.role
|
|
24
|
-
if (typeof outer?.role === 'string') return outer.role
|
|
25
|
-
return typeof outer?.type === 'string' ? outer.type : undefined
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function messageContent(message: unknown): unknown {
|
|
29
|
-
return messageRecord(message)?.content ?? asRecord(message)?.content
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function contentBlocks(message: unknown): readonly unknown[] {
|
|
33
|
-
const content = messageContent(message)
|
|
34
|
-
return Array.isArray(content) ? content : []
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function hasToolUseBlock(message: unknown): boolean {
|
|
38
|
-
return contentBlocks(message).some(block => asRecord(block)?.type === 'tool_use')
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function assistantTextContainsToolCall(message: unknown): boolean {
|
|
42
|
-
if (messageRole(message) !== 'assistant') return false
|
|
43
|
-
if (hasToolUseBlock(message)) return false
|
|
44
|
-
return TEXT_TOOL_CALL_RE.test(textFromContent(messageContent(message)))
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function hasRepairPrompt(messages: readonly unknown[]): boolean {
|
|
48
|
-
return messages.some(message =>
|
|
49
|
-
textFromContent(messageContent(message)).includes(TEXT_TOOL_CALL_REPAIR_MARKER),
|
|
50
|
-
)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function latestAssistantMessage(messages: readonly unknown[]): unknown | undefined {
|
|
54
|
-
for (let idx = messages.length - 1; idx >= 0; idx -= 1) {
|
|
55
|
-
if (messageRole(messages[idx]) === 'assistant') return messages[idx]
|
|
56
|
-
}
|
|
57
|
-
return undefined
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export function buildTextToolCallFinalAnswerRepairPromptIfNeeded({
|
|
61
|
-
messages,
|
|
62
|
-
}: {
|
|
63
|
-
messages: readonly unknown[]
|
|
64
|
-
}): string | undefined {
|
|
65
|
-
if (hasRepairPrompt(messages)) return undefined
|
|
66
|
-
const latestAssistant = latestAssistantMessage(messages)
|
|
67
|
-
if (!assistantTextContainsToolCall(latestAssistant)) return undefined
|
|
68
|
-
return TEXT_TOOL_CALL_REPAIR_PROMPT
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export function shouldWithholdTextToolCallFinalAnswer({
|
|
72
|
-
messages,
|
|
73
|
-
candidate,
|
|
74
|
-
}: {
|
|
75
|
-
messages: readonly unknown[]
|
|
76
|
-
candidate: unknown
|
|
77
|
-
}): boolean {
|
|
78
|
-
if (hasRepairPrompt(messages)) return false
|
|
79
|
-
return assistantTextContainsToolCall(candidate)
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export function textContainsToolCall(text: string): boolean {
|
|
83
|
-
return TEXT_TOOL_CALL_RE.test(text)
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export function stripTextToolCallBlocks(text: string): string {
|
|
87
|
-
return text
|
|
88
|
-
.replace(TEXT_TOOL_CALL_BLOCK_RE, '\n')
|
|
89
|
-
.replace(/\n{3,}/gu, '\n\n')
|
|
90
|
-
.trim()
|
|
91
|
-
}
|