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,97 @@
|
|
|
1
|
+
import type { ToolPermissionContext } from '../../Tool.js'
|
|
2
|
+
import type { PermissionResult } from '../../utils/permissions/PermissionResult.js'
|
|
3
|
+
|
|
4
|
+
type ShellRiskClass = {
|
|
5
|
+
readonly kind: 'destructive' | 'protected-ax'
|
|
6
|
+
readonly reason: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
type DestructiveWarningFn = (command: string) => string | null
|
|
10
|
+
|
|
11
|
+
const PROTECTED_AX_PATTERNS: readonly { readonly pattern: RegExp; readonly reason: string }[] = [
|
|
12
|
+
{
|
|
13
|
+
pattern:
|
|
14
|
+
/\b(?:curl|wget|http|https|invoke-webrequest|invoke-restmethod|iwr|irm)\b[\s\S]*(?:data\.go\.kr|www\.gov\.kr|gov\.kr|hometax\.go\.kr|wetax\.go\.kr|openbanking|kftc|mobileid|omnidid|omni[-_ ]?one)/iu,
|
|
15
|
+
reason:
|
|
16
|
+
'Shell command appears to call Korean public-service, identity, payment, or government infrastructure',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
pattern:
|
|
20
|
+
/\b(?:hometax|government24|gov24|wetax|openbanking|kftc|mobile[-_ ]?id|certificate|public[-_ ]?certificate|identity|payment|pipa|정부24|홈택스|위택스|모바일신분증|공동인증서|금융인증서)\b/iu,
|
|
21
|
+
reason:
|
|
22
|
+
'Shell command references protected national AX, identity, certificate, or payment surfaces',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
pattern:
|
|
26
|
+
/\bUMMAYA_[A-Z0-9_]*(?:TOKEN|SECRET|PASSWORD|CERT|CERTIFICATE|API_KEY|AUTH_KEY|SERVICE_KEY)\b/u,
|
|
27
|
+
reason:
|
|
28
|
+
'Shell command references UMMAYA credential material for protected infrastructure access',
|
|
29
|
+
},
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
function shouldTreatModeAsBypass(toolPermissionContext: ToolPermissionContext): boolean {
|
|
33
|
+
return (
|
|
34
|
+
toolPermissionContext.mode === 'bypassPermissions' ||
|
|
35
|
+
(toolPermissionContext.mode === 'plan' &&
|
|
36
|
+
toolPermissionContext.isBypassPermissionsModeAvailable)
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function classifyShellRiskForPermissionGauntlet(
|
|
41
|
+
command: string,
|
|
42
|
+
getDestructiveWarning: DestructiveWarningFn,
|
|
43
|
+
): ShellRiskClass | null {
|
|
44
|
+
const destructiveWarning = getDestructiveWarning(command)
|
|
45
|
+
if (destructiveWarning !== null) {
|
|
46
|
+
return {
|
|
47
|
+
kind: 'destructive',
|
|
48
|
+
reason: destructiveWarning,
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
for (const { pattern, reason } of PROTECTED_AX_PATTERNS) {
|
|
53
|
+
if (pattern.test(command)) {
|
|
54
|
+
return {
|
|
55
|
+
kind: 'protected-ax',
|
|
56
|
+
reason,
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return null
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function getBypassImmuneShellPermissionResult(
|
|
65
|
+
command: string,
|
|
66
|
+
toolName: string,
|
|
67
|
+
toolPermissionContext: ToolPermissionContext,
|
|
68
|
+
getDestructiveWarning: DestructiveWarningFn,
|
|
69
|
+
): PermissionResult | null {
|
|
70
|
+
if (!shouldTreatModeAsBypass(toolPermissionContext)) {
|
|
71
|
+
return null
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const risk = classifyShellRiskForPermissionGauntlet(
|
|
75
|
+
command,
|
|
76
|
+
getDestructiveWarning,
|
|
77
|
+
)
|
|
78
|
+
if (risk === null) {
|
|
79
|
+
return null
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const reason =
|
|
83
|
+
risk.kind === 'destructive'
|
|
84
|
+
? `Destructive shell command requires explicit approval even in bypassPermissions mode: ${risk.reason}`
|
|
85
|
+
: `Protected AX-adjacent shell command requires explicit approval even in bypassPermissions mode: ${risk.reason}`
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
behavior: 'ask',
|
|
89
|
+
message: `${toolName} command requires explicit approval. ${reason}`,
|
|
90
|
+
decisionReason: {
|
|
91
|
+
type: 'safetyCheck',
|
|
92
|
+
reason,
|
|
93
|
+
classifierApprovable: false,
|
|
94
|
+
},
|
|
95
|
+
suggestions: [],
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { createRequire } from 'node:module'
|
|
2
|
+
|
|
3
|
+
type BashUIRuntime = Pick<
|
|
4
|
+
typeof import('./UI.js'),
|
|
5
|
+
| 'BackgroundHint'
|
|
6
|
+
| 'renderToolResultMessage'
|
|
7
|
+
| 'renderToolUseErrorMessage'
|
|
8
|
+
| 'renderToolUseMessage'
|
|
9
|
+
| 'renderToolUseProgressMessage'
|
|
10
|
+
| 'renderToolUseQueuedMessage'
|
|
11
|
+
>
|
|
12
|
+
|
|
13
|
+
const requireModule = createRequire(import.meta.url)
|
|
14
|
+
let cachedBashUI: BashUIRuntime | undefined
|
|
15
|
+
|
|
16
|
+
function isBashUIRuntime(value: unknown): value is BashUIRuntime {
|
|
17
|
+
if (typeof value !== 'object' || value === null) return false
|
|
18
|
+
const module = value as Partial<Record<keyof BashUIRuntime, unknown>>
|
|
19
|
+
return (
|
|
20
|
+
typeof module.BackgroundHint === 'function' &&
|
|
21
|
+
typeof module.renderToolResultMessage === 'function' &&
|
|
22
|
+
typeof module.renderToolUseErrorMessage === 'function' &&
|
|
23
|
+
typeof module.renderToolUseMessage === 'function' &&
|
|
24
|
+
typeof module.renderToolUseProgressMessage === 'function' &&
|
|
25
|
+
typeof module.renderToolUseQueuedMessage === 'function'
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function loadBashUI(): BashUIRuntime {
|
|
30
|
+
if (cachedBashUI !== undefined) return cachedBashUI
|
|
31
|
+
const loaded: unknown = requireModule('./UI.js')
|
|
32
|
+
if (!isBashUIRuntime(loaded)) {
|
|
33
|
+
throw new Error('Bash UI module did not expose the expected renderers')
|
|
34
|
+
}
|
|
35
|
+
cachedBashUI = loaded
|
|
36
|
+
return loaded
|
|
37
|
+
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* returned file_uuid alongside the path. Web resolves file_uuid → preview;
|
|
8
8
|
* desktop/local try path first.
|
|
9
9
|
*
|
|
10
|
-
* Best-effort:
|
|
10
|
+
* Best-effort: each failure (no token, bridge off, network error, 4xx) logs
|
|
11
11
|
* debug and returns undefined. The attachment still carries {path, size,
|
|
12
12
|
* isImage}, so local-terminal and same-machine-desktop render unaffected.
|
|
13
13
|
*/
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
* Restricted-grammar expression parser + evaluator using the shunting-yard algorithm.
|
|
3
3
|
*
|
|
4
4
|
* Allowed characters: 0-9 . + - * / % ( ) whitespace
|
|
5
|
-
* Disallowed:
|
|
5
|
+
* Disallowed: letters, underscore, $, !, ^, &, |, ~, <, >, =, etc.
|
|
6
6
|
*
|
|
7
7
|
* Numeric representation strategy:
|
|
8
8
|
* - Parse every numeric literal as a string to avoid IEEE-754 precision loss.
|
|
9
|
-
* - Track whether
|
|
9
|
+
* - Track whether division produces a non-integer result.
|
|
10
10
|
* - Arithmetic is carried out with BigInt when all operands are integers
|
|
11
11
|
* (denominator check for /); otherwise falls back to JS number with
|
|
12
12
|
* toFixed(precision) rounding, which is sufficient for the "up to 28 digits"
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// UMMAYA-original — DocumentPrimitive.
|
|
3
|
+
|
|
4
|
+
import React from 'react'
|
|
5
|
+
import { z } from 'zod/v4'
|
|
6
|
+
import { Text } from '../../ink.js'
|
|
7
|
+
import { buildTool, type ToolDef } from '../../Tool.js'
|
|
8
|
+
import { lazySchema } from '../../utils/lazySchema.js'
|
|
9
|
+
import { getOrCreateUmmayaBridge } from '../../ipc/bridgeSingleton.js'
|
|
10
|
+
import { getOrCreatePendingCallRegistry } from '../../ipc/pendingCallSingleton.js'
|
|
11
|
+
import { dispatchPrimitive } from '../_shared/dispatchPrimitive.js'
|
|
12
|
+
import {
|
|
13
|
+
applyDocumentVisualRenderGateToOutput,
|
|
14
|
+
isDocumentVisualRenderFailedOutput,
|
|
15
|
+
renderDocumentToolResultIfPresent,
|
|
16
|
+
} from '../_shared/documentToolResultRender.js'
|
|
17
|
+
import {
|
|
18
|
+
renderVerboseInputJson,
|
|
19
|
+
renderVerboseOutputJson,
|
|
20
|
+
} from '../_shared/verboseRender.js'
|
|
21
|
+
import {
|
|
22
|
+
isPrimitiveResultPreviewTruncated,
|
|
23
|
+
renderCompactPrimitiveResult,
|
|
24
|
+
} from '../_shared/compactPrimitiveResult.js'
|
|
25
|
+
import { resolveDocumentPrimitiveTimeoutMs } from '../_shared/documentPrimitiveTimeout.js'
|
|
26
|
+
import {
|
|
27
|
+
DOCUMENT_TOOL_NAME,
|
|
28
|
+
DESCRIPTION,
|
|
29
|
+
DOCUMENT_TOOL_PROMPT,
|
|
30
|
+
} from './prompt.js'
|
|
31
|
+
import {
|
|
32
|
+
latestUserTextFromContext,
|
|
33
|
+
normalizeDocumentPrimitiveInputForDispatch as normalizeDispatchInput,
|
|
34
|
+
operationOf,
|
|
35
|
+
} from './dispatchNormalization.js'
|
|
36
|
+
import { modelVisibleDocumentOutput } from './modelVisibleOutput.js'
|
|
37
|
+
|
|
38
|
+
export { normalizeDocumentPrimitiveInputForDispatch } from './dispatchNormalization.js'
|
|
39
|
+
|
|
40
|
+
const documentRefSchema = z
|
|
41
|
+
.object({
|
|
42
|
+
path: z.string().min(1).optional(),
|
|
43
|
+
artifact_id: z.string().min(1).optional(),
|
|
44
|
+
expected_format: z
|
|
45
|
+
.enum(['hwpx', 'hwp', 'docx', 'pdf', 'xlsx', 'pptx'])
|
|
46
|
+
.optional(),
|
|
47
|
+
})
|
|
48
|
+
.passthrough()
|
|
49
|
+
|
|
50
|
+
const inputSchema = lazySchema(() =>
|
|
51
|
+
z
|
|
52
|
+
.object({
|
|
53
|
+
correlation_id: z.string().min(1),
|
|
54
|
+
document: documentRefSchema,
|
|
55
|
+
operation: z
|
|
56
|
+
.enum(['inspect', 'extract', 'fill', 'style', 'validate', 'save'])
|
|
57
|
+
.optional(),
|
|
58
|
+
instruction: z.string().min(1),
|
|
59
|
+
destination_path: z.string().min(1).optional(),
|
|
60
|
+
destination_display_name: z.string().min(1).optional(),
|
|
61
|
+
template_id: z.string().min(1).optional(),
|
|
62
|
+
patches: z.array(z.unknown()).optional(),
|
|
63
|
+
styles: z.array(z.unknown()).optional(),
|
|
64
|
+
})
|
|
65
|
+
.passthrough(),
|
|
66
|
+
)
|
|
67
|
+
type InputSchema = ReturnType<typeof inputSchema>
|
|
68
|
+
export type Input = z.infer<InputSchema>
|
|
69
|
+
|
|
70
|
+
const outputSchema = lazySchema(() =>
|
|
71
|
+
z.discriminatedUnion('ok', [
|
|
72
|
+
z.object({
|
|
73
|
+
ok: z.literal(true),
|
|
74
|
+
result: z.unknown(),
|
|
75
|
+
outbound_traces: z.array(z.unknown()).optional(),
|
|
76
|
+
}),
|
|
77
|
+
z.object({
|
|
78
|
+
ok: z.literal(false),
|
|
79
|
+
error: z.object({
|
|
80
|
+
kind: z.string(),
|
|
81
|
+
message: z.string(),
|
|
82
|
+
}),
|
|
83
|
+
result: z.unknown().optional(),
|
|
84
|
+
outbound_traces: z.array(z.unknown()).optional(),
|
|
85
|
+
}),
|
|
86
|
+
]),
|
|
87
|
+
)
|
|
88
|
+
type OutputSchema = ReturnType<typeof outputSchema>
|
|
89
|
+
export type Output = z.infer<OutputSchema>
|
|
90
|
+
|
|
91
|
+
function documentTarget(input: Input): string {
|
|
92
|
+
const document = input.document as Record<string, unknown>
|
|
93
|
+
const path = typeof document.path === 'string' ? document.path : undefined
|
|
94
|
+
const artifactId =
|
|
95
|
+
typeof document.artifact_id === 'string' ? document.artifact_id : undefined
|
|
96
|
+
return path ?? artifactId ?? 'document'
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function documentAction(input: Input): string {
|
|
100
|
+
switch (operationOf(input)) {
|
|
101
|
+
case 'inspect':
|
|
102
|
+
return 'Inspect document'
|
|
103
|
+
case 'extract':
|
|
104
|
+
return 'Read document'
|
|
105
|
+
case 'style':
|
|
106
|
+
return 'Apply document formatting'
|
|
107
|
+
case 'validate':
|
|
108
|
+
return 'Validate public-form rules'
|
|
109
|
+
case 'save':
|
|
110
|
+
return 'Save document'
|
|
111
|
+
case 'fill':
|
|
112
|
+
default:
|
|
113
|
+
return 'Write document'
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function buildDocumentErrorRows(output: Extract<Output, { ok: false }>): React.ReactNode[] {
|
|
118
|
+
return [
|
|
119
|
+
React.createElement(
|
|
120
|
+
Text,
|
|
121
|
+
{ key: 'document-error', color: 'red' },
|
|
122
|
+
`Document failed: ${output.error.message}`,
|
|
123
|
+
),
|
|
124
|
+
]
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export const DocumentPrimitive = buildTool({
|
|
128
|
+
name: DOCUMENT_TOOL_NAME,
|
|
129
|
+
|
|
130
|
+
searchHint:
|
|
131
|
+
'document hwpx hwp docx pdf xlsx pptx form fill render save diff public document',
|
|
132
|
+
|
|
133
|
+
maxResultSizeChars: 100_000,
|
|
134
|
+
|
|
135
|
+
get inputSchema(): InputSchema {
|
|
136
|
+
return inputSchema()
|
|
137
|
+
},
|
|
138
|
+
|
|
139
|
+
get outputSchema(): OutputSchema {
|
|
140
|
+
return outputSchema()
|
|
141
|
+
},
|
|
142
|
+
|
|
143
|
+
isEnabled() {
|
|
144
|
+
return true
|
|
145
|
+
},
|
|
146
|
+
|
|
147
|
+
isConcurrencySafe() {
|
|
148
|
+
return false
|
|
149
|
+
},
|
|
150
|
+
|
|
151
|
+
isReadOnly(input?: Input) {
|
|
152
|
+
const operation = input ? operationOf(input) : 'fill'
|
|
153
|
+
return operation === 'inspect' || operation === 'extract' || operation === 'validate'
|
|
154
|
+
},
|
|
155
|
+
|
|
156
|
+
isDestructive() {
|
|
157
|
+
return false
|
|
158
|
+
},
|
|
159
|
+
|
|
160
|
+
async description() {
|
|
161
|
+
return DESCRIPTION
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
async prompt() {
|
|
165
|
+
return DOCUMENT_TOOL_PROMPT
|
|
166
|
+
},
|
|
167
|
+
|
|
168
|
+
mapToolResultToToolResultBlockParam(output, toolUseID) {
|
|
169
|
+
const gatedOutput = applyDocumentVisualRenderGateToOutput(output)
|
|
170
|
+
return {
|
|
171
|
+
tool_use_id: toolUseID,
|
|
172
|
+
type: 'tool_result',
|
|
173
|
+
content: JSON.stringify(modelVisibleDocumentOutput(gatedOutput)),
|
|
174
|
+
...(isDocumentVisualRenderFailedOutput(gatedOutput) ? { is_error: true } : {}),
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
|
|
178
|
+
renderToolUseMessage(input: Input, options: { verbose: boolean }) {
|
|
179
|
+
if (options.verbose) return renderVerboseInputJson(input)
|
|
180
|
+
return `${documentAction(input)}: ${documentTarget(input)}`
|
|
181
|
+
},
|
|
182
|
+
|
|
183
|
+
isMcp: false,
|
|
184
|
+
|
|
185
|
+
async validateInput(input: Input, _context: ToolUseContext) {
|
|
186
|
+
if (typeof input !== 'object' || input === null) {
|
|
187
|
+
return {
|
|
188
|
+
result: false as const,
|
|
189
|
+
message: 'document expects a JSON object argument.',
|
|
190
|
+
errorCode: 1,
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
const document = input.document as Record<string, unknown> | undefined
|
|
194
|
+
if (!document || typeof document !== 'object') {
|
|
195
|
+
return {
|
|
196
|
+
result: false as const,
|
|
197
|
+
message: 'document.document is required.',
|
|
198
|
+
errorCode: 1,
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (
|
|
202
|
+
typeof document.path !== 'string' &&
|
|
203
|
+
typeof document.artifact_id !== 'string'
|
|
204
|
+
) {
|
|
205
|
+
return {
|
|
206
|
+
result: false as const,
|
|
207
|
+
message: 'document requires either document.path or document.artifact_id.',
|
|
208
|
+
errorCode: 1,
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (typeof input.instruction !== 'string' || input.instruction.trim() === '') {
|
|
212
|
+
return {
|
|
213
|
+
result: false as const,
|
|
214
|
+
message: 'document.instruction is required.',
|
|
215
|
+
errorCode: 1,
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return { result: true as const }
|
|
219
|
+
},
|
|
220
|
+
|
|
221
|
+
renderToolResultMessage(
|
|
222
|
+
output: Output,
|
|
223
|
+
_progress: unknown,
|
|
224
|
+
options: { verbose: boolean; isTranscriptMode?: boolean } = { verbose: false },
|
|
225
|
+
) {
|
|
226
|
+
const gatedOutput = applyDocumentVisualRenderGateToOutput(output) as Output
|
|
227
|
+
const documentResult = renderDocumentToolResultIfPresent(gatedOutput, options)
|
|
228
|
+
if (documentResult !== null) return documentResult
|
|
229
|
+
if (options.verbose || options.isTranscriptMode) {
|
|
230
|
+
return renderVerboseOutputJson(gatedOutput)
|
|
231
|
+
}
|
|
232
|
+
return renderCompactPrimitiveResult(
|
|
233
|
+
gatedOutput.ok
|
|
234
|
+
? [React.createElement(Text, { key: 'document-ok' }, 'Document result received.')]
|
|
235
|
+
: buildDocumentErrorRows(gatedOutput),
|
|
236
|
+
)
|
|
237
|
+
},
|
|
238
|
+
|
|
239
|
+
isResultTruncated(output: Output): boolean {
|
|
240
|
+
if (output.ok) return false
|
|
241
|
+
return isPrimitiveResultPreviewTruncated(buildDocumentErrorRows(output))
|
|
242
|
+
},
|
|
243
|
+
|
|
244
|
+
async call(input, context) {
|
|
245
|
+
const args = normalizeDispatchInput(
|
|
246
|
+
input as Input,
|
|
247
|
+
latestUserTextFromContext(context),
|
|
248
|
+
)
|
|
249
|
+
const result = await dispatchPrimitive<Output>({
|
|
250
|
+
primitive: 'document',
|
|
251
|
+
args,
|
|
252
|
+
context,
|
|
253
|
+
registry: getOrCreatePendingCallRegistry(),
|
|
254
|
+
bridge: getOrCreateUmmayaBridge(),
|
|
255
|
+
timeoutMs: resolveDocumentPrimitiveTimeoutMs(),
|
|
256
|
+
})
|
|
257
|
+
return {
|
|
258
|
+
...result,
|
|
259
|
+
data: applyDocumentVisualRenderGateToOutput(result.data) as Output,
|
|
260
|
+
}
|
|
261
|
+
},
|
|
262
|
+
} satisfies ToolDef<InputSchema, Output>)
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
|
|
3
|
+
import type { ToolUseContext } from '../../Tool.js'
|
|
4
|
+
import { lastLocalDocumentPath } from './documentDestinationPath.js'
|
|
5
|
+
import { normalizeDocumentMutationPayloadsForDispatch } from './documentPatchNormalization.js'
|
|
6
|
+
|
|
7
|
+
const WRITE_INTENT_RE =
|
|
8
|
+
/(작성|수정|편집|채우|채워|입력|변경|저장|보정|서식|글꼴|글자색|배경색|정렬|굵게|write|edit|fill|apply|save|style|format|bold)/iu
|
|
9
|
+
const READ_ONLY_INTENT_RE =
|
|
10
|
+
/(읽기\s*전용|수정\s*없이|변경\s*없이|저장\s*없이|열람만|확인만|추출|파악|쓰지\s*마|작성하지\s*마|반영하지\s*마|저장하지\s*마|inspect|extract|read\s*only)/iu
|
|
11
|
+
const DEFERRED_WRITE_INTENT_RE =
|
|
12
|
+
/((아직|먼저|초안).{0,40}(쓰지\s*마|작성하지\s*마|저장하지\s*마|반영하지\s*마))|((쓰지\s*마|작성하지\s*마|저장하지\s*마|반영하지\s*마).{0,40}(아직|먼저|초안))/iu
|
|
13
|
+
const APPROVED_DERIVATIVE_SAVE_RE =
|
|
14
|
+
/((승인|approved).{0,100}(저장|복사본|derivative|\/[^\s]+))|((저장|복사본|derivative|\/[^\s]+).{0,100}(승인|approved))/iu
|
|
15
|
+
const QUESTION_FIRST_AUTHORING_RE =
|
|
16
|
+
/(근거|질문|먼저\s*물|먼저\s*질문|초안|승인|evidence|question|draft|approval)/iu
|
|
17
|
+
const STRUCTURE_INSPECTION_RE =
|
|
18
|
+
/(구조|빈칸|문항|양식|필드|항목).*(확인|파악|검토)|(?:확인|파악|검토).*(구조|빈칸|문항|양식|필드|항목)/iu
|
|
19
|
+
const INTERNAL_DISPATCH_KEYS = new Set(['__ummaya_display_operation'])
|
|
20
|
+
const READ_ONLY_OPERATIONS = new Set(['inspect', 'extract', 'validate'])
|
|
21
|
+
const READ_ONLY_MUTATION_KEYS = new Set([
|
|
22
|
+
'destination_path',
|
|
23
|
+
'destination_display_name',
|
|
24
|
+
'patches',
|
|
25
|
+
'styles',
|
|
26
|
+
'approved_draft_id',
|
|
27
|
+
'approved_draft_sha256',
|
|
28
|
+
])
|
|
29
|
+
|
|
30
|
+
export type DocumentPrimitiveDispatchInput = {
|
|
31
|
+
readonly document?: unknown
|
|
32
|
+
readonly operation?: string
|
|
33
|
+
readonly instruction?: string
|
|
34
|
+
readonly destination_path?: string
|
|
35
|
+
readonly patches?: readonly unknown[]
|
|
36
|
+
readonly styles?: readonly unknown[]
|
|
37
|
+
readonly [key: string]: unknown
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function normalizeDocumentPrimitiveInputForDispatch(
|
|
41
|
+
input: DocumentPrimitiveDispatchInput,
|
|
42
|
+
userText: string | undefined,
|
|
43
|
+
): Record<string, unknown> {
|
|
44
|
+
const operation = operationOf(input, userText)
|
|
45
|
+
const text = `${input.instruction ?? ''}\n${userText ?? ''}`
|
|
46
|
+
const destinationPath =
|
|
47
|
+
typeof input.destination_path === 'string' ||
|
|
48
|
+
READ_ONLY_OPERATIONS.has(operation) ||
|
|
49
|
+
!hasApprovedDerivativeSaveIntent(input, text)
|
|
50
|
+
? undefined
|
|
51
|
+
: lastLocalDocumentPath(text)
|
|
52
|
+
const args = normalizeDocumentLocatorForDispatch(
|
|
53
|
+
normalizeDocumentMutationPayloadsForDispatch(
|
|
54
|
+
stripDispatchOnlyFields({
|
|
55
|
+
...input,
|
|
56
|
+
operation,
|
|
57
|
+
...(destinationPath === undefined ? {} : { destination_path: destinationPath }),
|
|
58
|
+
}),
|
|
59
|
+
userText,
|
|
60
|
+
),
|
|
61
|
+
)
|
|
62
|
+
if (userText === undefined || hasPatchOrStylePayload(input)) {
|
|
63
|
+
return args
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const instruction = typeof input.instruction === 'string'
|
|
67
|
+
? input.instruction.trim()
|
|
68
|
+
: ''
|
|
69
|
+
if (instruction.includes(userText)) {
|
|
70
|
+
return args
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
...args,
|
|
74
|
+
instruction: instruction
|
|
75
|
+
? `${instruction}\n\nOriginal user request:\n${userText}`
|
|
76
|
+
: userText,
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function operationOf(
|
|
81
|
+
input: DocumentPrimitiveDispatchInput,
|
|
82
|
+
userText?: string,
|
|
83
|
+
): string {
|
|
84
|
+
const operation = typeof input.operation === 'string' ? input.operation : 'fill'
|
|
85
|
+
if (hasReadOnlyIntentFromText(input, userText)) {
|
|
86
|
+
return operation === 'extract' ? 'extract' : 'inspect'
|
|
87
|
+
}
|
|
88
|
+
if (shouldPreserveQuestionFirstRead(input, userText, operation)) {
|
|
89
|
+
return operation
|
|
90
|
+
}
|
|
91
|
+
const displayOperation =
|
|
92
|
+
typeof input.__ummaya_display_operation === 'string'
|
|
93
|
+
? input.__ummaya_display_operation
|
|
94
|
+
: undefined
|
|
95
|
+
if (
|
|
96
|
+
displayOperation === 'fill' ||
|
|
97
|
+
displayOperation === 'style' ||
|
|
98
|
+
displayOperation === 'save'
|
|
99
|
+
) {
|
|
100
|
+
return displayOperation
|
|
101
|
+
}
|
|
102
|
+
if (
|
|
103
|
+
(operation === 'inspect' || operation === 'extract') &&
|
|
104
|
+
hasWriteIntentFromText(input, userText)
|
|
105
|
+
) {
|
|
106
|
+
return 'fill'
|
|
107
|
+
}
|
|
108
|
+
return operation
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function latestUserTextFromContext(context: ToolUseContext): string | undefined {
|
|
112
|
+
const messages = contextRecord(context).messages
|
|
113
|
+
if (!Array.isArray(messages)) return undefined
|
|
114
|
+
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
115
|
+
const message = recordFrom(messages[index])
|
|
116
|
+
if (message === null) continue
|
|
117
|
+
const sdkMessage = recordFrom(message.message)
|
|
118
|
+
if (!isUserMessageRecord(message, sdkMessage)) continue
|
|
119
|
+
const content = sdkMessage?.content ?? message.content
|
|
120
|
+
const text = textFromMessageContent(content)
|
|
121
|
+
if (text !== undefined) return text
|
|
122
|
+
}
|
|
123
|
+
return undefined
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function normalizeDocumentLocatorForDispatch(
|
|
127
|
+
args: Record<string, unknown>,
|
|
128
|
+
): Record<string, unknown> {
|
|
129
|
+
const document = recordFrom(args.document)
|
|
130
|
+
if (document === null) {
|
|
131
|
+
return args
|
|
132
|
+
}
|
|
133
|
+
if (
|
|
134
|
+
nonEmptyString(document.artifact_id) === undefined ||
|
|
135
|
+
nonEmptyString(document.path) === undefined
|
|
136
|
+
) {
|
|
137
|
+
return args
|
|
138
|
+
}
|
|
139
|
+
const normalizedDocument: Record<string, unknown> = {}
|
|
140
|
+
for (const [key, value] of Object.entries(document)) {
|
|
141
|
+
if (key !== 'path') {
|
|
142
|
+
normalizedDocument[key] = value
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
...args,
|
|
147
|
+
document: normalizedDocument,
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function stripDispatchOnlyFields(args: Record<string, unknown>): Record<string, unknown> {
|
|
152
|
+
const operation = typeof args.operation === 'string' ? args.operation : 'fill'
|
|
153
|
+
const readOnlyOperation = READ_ONLY_OPERATIONS.has(operation)
|
|
154
|
+
const cleaned: Record<string, unknown> = {}
|
|
155
|
+
for (const [key, value] of Object.entries(args)) {
|
|
156
|
+
if (INTERNAL_DISPATCH_KEYS.has(key)) continue
|
|
157
|
+
if (readOnlyOperation && READ_ONLY_MUTATION_KEYS.has(key)) continue
|
|
158
|
+
cleaned[key] = value
|
|
159
|
+
}
|
|
160
|
+
return cleaned
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function shouldPreserveQuestionFirstRead(
|
|
164
|
+
input: DocumentPrimitiveDispatchInput,
|
|
165
|
+
userText: string | undefined,
|
|
166
|
+
operation: string,
|
|
167
|
+
): boolean {
|
|
168
|
+
if (operation !== 'inspect' && operation !== 'extract') {
|
|
169
|
+
return false
|
|
170
|
+
}
|
|
171
|
+
if (hasPatchOrStylePayload(input)) {
|
|
172
|
+
return false
|
|
173
|
+
}
|
|
174
|
+
const text = `${input.instruction ?? ''}\n${userText ?? ''}`
|
|
175
|
+
if (hasApprovedDerivativeSaveIntent(input, text)) {
|
|
176
|
+
return false
|
|
177
|
+
}
|
|
178
|
+
if (operation === 'inspect' && STRUCTURE_INSPECTION_RE.test(input.instruction ?? '')) {
|
|
179
|
+
return true
|
|
180
|
+
}
|
|
181
|
+
return QUESTION_FIRST_AUTHORING_RE.test(text) && WRITE_INTENT_RE.test(text)
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function hasWriteIntentFromText(
|
|
185
|
+
input: DocumentPrimitiveDispatchInput,
|
|
186
|
+
userText: string | undefined,
|
|
187
|
+
): boolean {
|
|
188
|
+
if (typeof input.destination_path === 'string') return true
|
|
189
|
+
if (hasPatchOrStylePayload(input)) return true
|
|
190
|
+
if (userText !== undefined) {
|
|
191
|
+
return !READ_ONLY_INTENT_RE.test(userText) && WRITE_INTENT_RE.test(userText)
|
|
192
|
+
}
|
|
193
|
+
if (READ_ONLY_INTENT_RE.test(input.instruction ?? '')) return false
|
|
194
|
+
return WRITE_INTENT_RE.test(input.instruction ?? '')
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function hasReadOnlyIntentFromText(
|
|
198
|
+
input: DocumentPrimitiveDispatchInput,
|
|
199
|
+
userText: string | undefined,
|
|
200
|
+
): boolean {
|
|
201
|
+
const text = userText ?? input.instruction ?? ''
|
|
202
|
+
if (!READ_ONLY_INTENT_RE.test(text)) {
|
|
203
|
+
return false
|
|
204
|
+
}
|
|
205
|
+
if (hasApprovedDerivativeSaveIntent(input, text)) {
|
|
206
|
+
return false
|
|
207
|
+
}
|
|
208
|
+
return true
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function hasPatchOrStylePayload(input: DocumentPrimitiveDispatchInput): boolean {
|
|
212
|
+
return (Array.isArray(input.patches) && input.patches.length > 0) ||
|
|
213
|
+
(Array.isArray(input.styles) && input.styles.length > 0)
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function hasApprovedDerivativeSaveIntent(
|
|
217
|
+
input: DocumentPrimitiveDispatchInput,
|
|
218
|
+
text: string,
|
|
219
|
+
): boolean {
|
|
220
|
+
if (DEFERRED_WRITE_INTENT_RE.test(text)) {
|
|
221
|
+
return false
|
|
222
|
+
}
|
|
223
|
+
if (APPROVED_DERIVATIVE_SAVE_RE.test(text)) {
|
|
224
|
+
return true
|
|
225
|
+
}
|
|
226
|
+
return typeof input.destination_path === 'string' &&
|
|
227
|
+
/(승인|approved|검토용\s*복사본|원본은\s*건드리지\s*말)/iu.test(text) &&
|
|
228
|
+
/(저장|save|\/[^\s]+)/iu.test(text)
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function textFromMessageContent(content: unknown): string | undefined {
|
|
232
|
+
if (typeof content === 'string' && content.trim() !== '') {
|
|
233
|
+
return content
|
|
234
|
+
}
|
|
235
|
+
if (!Array.isArray(content)) {
|
|
236
|
+
return undefined
|
|
237
|
+
}
|
|
238
|
+
const text = content
|
|
239
|
+
.map(block => {
|
|
240
|
+
const item = recordFrom(block)
|
|
241
|
+
return item?.type === 'text' && typeof item.text === 'string'
|
|
242
|
+
? item.text
|
|
243
|
+
: ''
|
|
244
|
+
})
|
|
245
|
+
.filter(Boolean)
|
|
246
|
+
.join('\n')
|
|
247
|
+
.trim()
|
|
248
|
+
return text === '' ? undefined : text
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function isUserMessageRecord(
|
|
252
|
+
message: Record<string, unknown>,
|
|
253
|
+
sdkMessage: Record<string, unknown> | null,
|
|
254
|
+
): boolean {
|
|
255
|
+
return message.type === 'user' || message.role === 'user' || sdkMessage?.role === 'user'
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function contextRecord(context: ToolUseContext): Record<string, unknown> {
|
|
259
|
+
return context
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function recordFrom(value: unknown): Record<string, unknown> | null {
|
|
263
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value)
|
|
264
|
+
? Object.fromEntries(Object.entries(value))
|
|
265
|
+
: null
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function nonEmptyString(value: unknown): string | undefined {
|
|
269
|
+
return typeof value === 'string' && value.trim() !== '' ? value : undefined
|
|
270
|
+
}
|