ummaya 0.2.3 → 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 +17 -3
- package/bin/ummaya +10 -1
- package/npm-shrinkwrap.json +253 -2
- package/package.json +5 -1
- package/prompts/manifest.yaml +2 -2
- package/prompts/session_guidance_v1.md +3 -1
- package/prompts/system_v1.md +9 -7
- package/pyproject.toml +26 -7
- package/specs/2803-document-production-hardening/contracts/document-tools.schema.json +1043 -0
- package/src/ummaya/_canonical/__init__.py +2 -0
- package/src/ummaya/context/builder.py +17 -11
- package/src/ummaya/engine/engine.py +30 -113
- package/src/ummaya/engine/query.py +20 -0
- package/src/ummaya/evidence/__init__.py +44 -0
- package/src/ummaya/evidence/__main__.py +7 -0
- 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 +145 -0
- 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 +177 -0
- package/src/ummaya/evidence/source_provenance.py +246 -0
- package/src/ummaya/evidence/source_provenance_redaction.py +176 -0
- package/src/ummaya/evidence/task_registry.py +264 -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 +52 -5
- package/src/ummaya/ipc/route_diagnostics.py +73 -0
- package/src/ummaya/ipc/stdio.py +2282 -417
- package/src/ummaya/llm/client.py +234 -59
- package/src/ummaya/llm/config.py +8 -3
- package/src/ummaya/llm/reasoning.py +84 -0
- 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 +34 -2
- 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 +61 -12
- package/src/ummaya/tools/geocoding/kakao_client.py +1 -2
- package/src/ummaya/tools/kma/apihub_catalog.py +984 -1
- package/src/ummaya/tools/kma/apihub_structured_adapter.py +86 -6
- package/src/ummaya/tools/kma/apihub_url_adapter.py +593 -0
- package/src/ummaya/tools/kma/apihub_url_catalog.py +296 -0
- package/src/ummaya/tools/live_proxy.py +0 -3
- package/src/ummaya/tools/location_adapters.py +8 -6
- package/src/ummaya/tools/manifest_metadata.py +16 -3
- package/src/ummaya/tools/models.py +5 -1
- package/src/ummaya/tools/mvp_surface.py +2 -2
- package/src/ummaya/tools/nmc/emergency_search.py +8 -6
- package/src/ummaya/tools/register_all.py +17 -0
- package/src/ummaya/tools/registry.py +10 -1
- package/src/ummaya/tools/resolve_location.py +4 -4
- 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 +40 -106
- package/src/ummaya/tools/verified_data_go_kr/_manifest.py +115 -25
- package/src/ummaya/tools/verified_data_go_kr/airkorea_air_quality.py +109 -4
- package/src/ummaya/tools/verified_data_go_kr/nmc_aed_site.py +108 -2
- package/src/ummaya/tools/verified_data_go_kr/pps_bid_public_info.py +174 -9
- package/src/ummaya/tools/verified_data_go_kr/tago_bus_arrival.py +66 -3
- package/src/ummaya/tools/verified_data_go_kr/tago_bus_location.py +12 -2
- package/src/ummaya/tools/verified_data_go_kr/tago_bus_route.py +8 -2
- package/src/ummaya/tools/verified_data_go_kr/tago_bus_route_station.py +114 -0
- package/src/ummaya/tools/verified_data_go_kr/tago_bus_station.py +14 -3
- package/src/ummaya/tools/verify_canonical_map.py +21 -0
- package/tests/fixtures/documents/public_forms/baselines.yaml +113 -0
- package/tui/package.json +1 -2
- package/tui/src/.cc-byte-identical-whitelist.yaml +266 -0
- package/tui/src/QueryEngine.ts +12 -4
- package/tui/src/bridge/inboundAttachments.ts +3 -3
- package/tui/src/cli/handlers/auth.ts +4 -13
- package/tui/src/cli/handlers/mcp.tsx +3 -3
- package/tui/src/cli/print.ts +69 -18
- package/tui/src/cli/update.ts +13 -13
- package/tui/src/commands/copy/index.ts +1 -1
- package/tui/src/commands/cost/cost.ts +2 -2
- package/tui/src/commands/init-verifiers.ts +5 -5
- package/tui/src/commands/init.ts +30 -30
- package/tui/src/commands/insights.ts +44 -44
- package/tui/src/commands/install-github-app/install-github-app.tsx +2 -2
- package/tui/src/commands/install-github-app/setupGitHubActions.ts +3 -3
- package/tui/src/commands/install-github-app/types.ts +8 -30
- package/tui/src/commands/install.tsx +5 -5
- package/tui/src/commands/mcp/addCommand.ts +5 -5
- package/tui/src/commands/mcp/xaaIdpCommand.ts +2 -2
- package/tui/src/commands/plugin/ManageMarketplaces.tsx +2 -2
- package/tui/src/commands/plugin/types.ts +6 -28
- package/tui/src/commands/plugin/unifiedTypes.ts +4 -26
- package/tui/src/commands/reasoning/index.ts +13 -0
- package/tui/src/commands/reasoning/reasoning.tsx +177 -0
- package/tui/src/commands/rename/generateSessionName.ts +1 -1
- package/tui/src/commands/thinkback/thinkback.tsx +3 -3
- package/tui/src/commands.ts +2 -0
- 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/Messages.tsx +2 -1
- package/tui/src/components/ScrollKeybindingHandler.tsx +6 -6
- package/tui/src/components/Spinner/types.ts +6 -28
- package/tui/src/components/Spinner.tsx +2 -2
- 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/design-system/LoadingState.tsx +2 -2
- 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 +29 -3
- package/tui/src/ipc/frames.generated.ts +407 -312
- package/tui/src/ipc/llmClient.ts +279 -76
- package/tui/src/ipc/llmTypes.ts +16 -1
- package/tui/src/ipc/schema/frame.schema.json +1 -3475
- package/tui/src/keybindings/defaultBindings.ts +4 -0
- package/tui/src/main.tsx +32 -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 -1721
- package/tui/src/screens/REPL.tsx +42 -31
- 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 +98 -14
- 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 -364
- 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/skills/bundled/stuck.ts +12 -12
- package/tui/src/state/AppStateStore.ts +7 -0
- 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 +1239 -163
- 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 +48 -29
- package/tui/src/tools/LookupPrimitive/prompt.ts +6 -7
- 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 +30 -19
- 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 +51 -18
- 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 +27 -10
- 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/citizenUserText.ts +49 -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/locationInputRepair.ts +112 -0
- package/tui/src/tools/_shared/pendingCallRegistry.ts +1 -6
- package/tui/src/tools/_shared/rootPrimitiveInput.ts +68 -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 +61 -0
- 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/attachments.ts +1 -1
- 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/kExaoneReasoning.ts +138 -0
- package/tui/src/utils/mcp/dateTimeParser.ts +1 -1
- package/tui/src/utils/messages.ts +19 -0
- package/tui/src/utils/migrateSessions.ts +3 -3
- package/tui/src/utils/model/model.ts +6 -6
- package/tui/src/utils/multiToolLayout.ts +13 -0
- 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/processUserInput/processSlashCommand.tsx +2 -2
- package/tui/src/utils/processUserInput/processUserInput.ts +26 -0
- 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/applySettingsChange.ts +4 -0
- package/tui/src/utils/settings/permissionValidation.ts +14 -2
- package/tui/src/utils/settings/types.ts +9 -3
- package/tui/src/utils/shell/prefix.ts +1 -1
- package/tui/src/utils/sideQuery.ts +1 -1
- package/tui/src/utils/stats.ts +1 -1
- package/tui/src/utils/systemThemeWatcher.ts +13 -3
- package/tui/src/utils/teleport.tsx +1 -1
- package/uv.lock +394 -22
- package/assets/copilot-gate-logo.svg +0 -58
- package/assets/govon-logo.svg +0 -40
- package/src/ummaya/eval/__init__.py +0 -5
- package/src/ummaya/eval/retrieval.py +0 -713
- package/tui/src/services/api/claude.ts +0 -3510
- package/tui/src/utils/messageStream.ts +0 -186
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
"""Public-form conformance validation for extracted document artifacts."""
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import hashlib
|
|
7
|
+
from decimal import Decimal
|
|
8
|
+
|
|
9
|
+
from ummaya.tools.documents.baselines import (
|
|
10
|
+
BaselineTableGeometry,
|
|
11
|
+
BaselineTextAnchor,
|
|
12
|
+
ConformanceBaseline,
|
|
13
|
+
)
|
|
14
|
+
from ummaya.tools.documents.models import (
|
|
15
|
+
BlockedReason,
|
|
16
|
+
DocumentExtraction,
|
|
17
|
+
DocumentToolResult,
|
|
18
|
+
PublicFormValidationReport,
|
|
19
|
+
ToolResultStatus,
|
|
20
|
+
ValidationDecision,
|
|
21
|
+
ValidationFinding,
|
|
22
|
+
ValidationReadiness,
|
|
23
|
+
)
|
|
24
|
+
from ummaya.tools.documents.scorecard import compute_public_form_metrics, table_shape
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def validate_public_form(
|
|
28
|
+
extraction: DocumentExtraction,
|
|
29
|
+
*,
|
|
30
|
+
baseline: ConformanceBaseline,
|
|
31
|
+
artifact_id: str,
|
|
32
|
+
correlation_id: str,
|
|
33
|
+
round_trip_passed: bool = True,
|
|
34
|
+
render_passed: bool = True,
|
|
35
|
+
security_passed: bool = True,
|
|
36
|
+
) -> DocumentToolResult:
|
|
37
|
+
"""Validate one extracted derivative against a public-form baseline."""
|
|
38
|
+
if not baseline.supports_conformance:
|
|
39
|
+
finding = _finding(
|
|
40
|
+
code="unsupported_for_conformance",
|
|
41
|
+
message=baseline.unsupported_reason or "Public-form conformance is not supported.",
|
|
42
|
+
anchor=f"template:{baseline.template_id}",
|
|
43
|
+
remediation_hint="Use a promoted editable format with conformance evidence.",
|
|
44
|
+
)
|
|
45
|
+
report = _report(
|
|
46
|
+
extraction,
|
|
47
|
+
baseline=baseline,
|
|
48
|
+
artifact_id=artifact_id,
|
|
49
|
+
findings=[finding],
|
|
50
|
+
decision=ValidationDecision.blocked,
|
|
51
|
+
readiness=ValidationReadiness.unsupported,
|
|
52
|
+
round_trip_passed=round_trip_passed,
|
|
53
|
+
render_passed=render_passed,
|
|
54
|
+
security_passed=security_passed,
|
|
55
|
+
)
|
|
56
|
+
return _result(
|
|
57
|
+
report,
|
|
58
|
+
status=ToolResultStatus.blocked,
|
|
59
|
+
blocked_reason=BlockedReason.unsupported_operation,
|
|
60
|
+
summary="Public-form validation blocked: conformance is unsupported.",
|
|
61
|
+
correlation_id=correlation_id,
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
findings = _hard_rule_findings(extraction, baseline)
|
|
65
|
+
if not security_passed:
|
|
66
|
+
findings.append(
|
|
67
|
+
_finding(
|
|
68
|
+
code="security_check_failed",
|
|
69
|
+
message="Security validation failed before public-form readiness.",
|
|
70
|
+
anchor=f"artifact:{artifact_id}",
|
|
71
|
+
remediation_hint="Resolve document security findings before validation.",
|
|
72
|
+
)
|
|
73
|
+
)
|
|
74
|
+
if not round_trip_passed:
|
|
75
|
+
findings.append(
|
|
76
|
+
_finding(
|
|
77
|
+
code="round_trip_mismatch",
|
|
78
|
+
message="Round-trip extraction did not match intended document values.",
|
|
79
|
+
anchor=f"artifact:{artifact_id}",
|
|
80
|
+
remediation_hint="Re-read the derivative and repair mismatched values.",
|
|
81
|
+
)
|
|
82
|
+
)
|
|
83
|
+
if not render_passed:
|
|
84
|
+
findings.append(
|
|
85
|
+
_finding(
|
|
86
|
+
code="render_mismatch",
|
|
87
|
+
message="Rendered derivative evidence did not match the expected layout.",
|
|
88
|
+
anchor=f"artifact:{artifact_id}",
|
|
89
|
+
remediation_hint="Repair layout drift and regenerate render evidence.",
|
|
90
|
+
)
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
metrics = compute_public_form_metrics(extraction, baseline)
|
|
94
|
+
hard_failure = any(finding.severity == "hard_failure" for finding in findings)
|
|
95
|
+
decision, readiness = _decision(
|
|
96
|
+
aggregate_score=metrics.aggregate_score,
|
|
97
|
+
hard_failure=hard_failure,
|
|
98
|
+
round_trip_passed=round_trip_passed,
|
|
99
|
+
render_passed=render_passed,
|
|
100
|
+
security_passed=security_passed,
|
|
101
|
+
)
|
|
102
|
+
report = _report(
|
|
103
|
+
extraction,
|
|
104
|
+
baseline=baseline,
|
|
105
|
+
artifact_id=artifact_id,
|
|
106
|
+
findings=findings,
|
|
107
|
+
decision=decision,
|
|
108
|
+
readiness=readiness,
|
|
109
|
+
round_trip_passed=round_trip_passed,
|
|
110
|
+
render_passed=render_passed,
|
|
111
|
+
security_passed=security_passed,
|
|
112
|
+
)
|
|
113
|
+
if decision is ValidationDecision.pass_:
|
|
114
|
+
return _result(
|
|
115
|
+
report,
|
|
116
|
+
status=ToolResultStatus.ok,
|
|
117
|
+
blocked_reason=None,
|
|
118
|
+
summary="Public-form validation passed; artifact is ready for human review.",
|
|
119
|
+
correlation_id=correlation_id,
|
|
120
|
+
)
|
|
121
|
+
blocked_reason = (
|
|
122
|
+
BlockedReason.unsupported_operation
|
|
123
|
+
if readiness is ValidationReadiness.unsupported
|
|
124
|
+
else BlockedReason.validation_failed
|
|
125
|
+
)
|
|
126
|
+
return _result(
|
|
127
|
+
report,
|
|
128
|
+
status=ToolResultStatus.blocked,
|
|
129
|
+
blocked_reason=blocked_reason,
|
|
130
|
+
summary="Public-form validation failed; artifact is not ready.",
|
|
131
|
+
correlation_id=correlation_id,
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def _hard_rule_findings(
|
|
136
|
+
extraction: DocumentExtraction,
|
|
137
|
+
baseline: ConformanceBaseline,
|
|
138
|
+
) -> list[ValidationFinding]:
|
|
139
|
+
findings: list[ValidationFinding] = []
|
|
140
|
+
findings.extend(_required_field_findings(extraction, baseline))
|
|
141
|
+
findings.extend(
|
|
142
|
+
_required_text_findings(
|
|
143
|
+
extraction,
|
|
144
|
+
baseline.protected_text,
|
|
145
|
+
"protected_text_missing",
|
|
146
|
+
)
|
|
147
|
+
)
|
|
148
|
+
findings.extend(
|
|
149
|
+
_required_text_findings(
|
|
150
|
+
extraction,
|
|
151
|
+
baseline.required_labels,
|
|
152
|
+
"required_label_missing",
|
|
153
|
+
)
|
|
154
|
+
)
|
|
155
|
+
findings.extend(_table_geometry_findings(extraction, baseline.table_geometries))
|
|
156
|
+
findings.extend(
|
|
157
|
+
_required_text_findings(
|
|
158
|
+
extraction,
|
|
159
|
+
baseline.signature_regions,
|
|
160
|
+
"signature_or_seal_region_missing",
|
|
161
|
+
)
|
|
162
|
+
)
|
|
163
|
+
findings.extend(_metadata_findings(extraction, baseline))
|
|
164
|
+
return findings
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def _required_field_findings(
|
|
168
|
+
extraction: DocumentExtraction,
|
|
169
|
+
baseline: ConformanceBaseline,
|
|
170
|
+
) -> list[ValidationFinding]:
|
|
171
|
+
by_field_id = {field.field_id: field for field in extraction.fields}
|
|
172
|
+
findings: list[ValidationFinding] = []
|
|
173
|
+
for required in baseline.required_fields:
|
|
174
|
+
observed = by_field_id.get(required.field_id)
|
|
175
|
+
if observed is None or observed.current_value in {None, ""}:
|
|
176
|
+
findings.append(
|
|
177
|
+
_finding(
|
|
178
|
+
code="required_field_missing",
|
|
179
|
+
message=f"Required field {required.label!r} is missing or empty.",
|
|
180
|
+
anchor=required.path,
|
|
181
|
+
remediation_hint=f"Fill the {required.label!r} field before export.",
|
|
182
|
+
)
|
|
183
|
+
)
|
|
184
|
+
return findings
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def _required_text_findings(
|
|
188
|
+
extraction: DocumentExtraction,
|
|
189
|
+
expected: tuple[BaselineTextAnchor, ...],
|
|
190
|
+
code: str,
|
|
191
|
+
) -> list[ValidationFinding]:
|
|
192
|
+
observed_text = _combined_text(extraction)
|
|
193
|
+
findings: list[ValidationFinding] = []
|
|
194
|
+
for item in expected:
|
|
195
|
+
if item.text not in observed_text:
|
|
196
|
+
findings.append(
|
|
197
|
+
_finding(
|
|
198
|
+
code=code,
|
|
199
|
+
message=f"Required public-form text {item.text!r} is missing.",
|
|
200
|
+
anchor=item.anchor,
|
|
201
|
+
remediation_hint=f"Restore required text {item.text!r} at the baseline anchor.",
|
|
202
|
+
)
|
|
203
|
+
)
|
|
204
|
+
return findings
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def _table_geometry_findings(
|
|
208
|
+
extraction: DocumentExtraction,
|
|
209
|
+
expected: tuple[BaselineTableGeometry, ...],
|
|
210
|
+
) -> list[ValidationFinding]:
|
|
211
|
+
tables_by_id = {table.block_id: table for table in extraction.tables}
|
|
212
|
+
findings: list[ValidationFinding] = []
|
|
213
|
+
for geometry in expected:
|
|
214
|
+
observed = tables_by_id.get(geometry.table_id)
|
|
215
|
+
observed_rows, observed_columns = table_shape(observed)
|
|
216
|
+
if observed_rows != geometry.rows or observed_columns != geometry.columns:
|
|
217
|
+
findings.append(
|
|
218
|
+
_finding(
|
|
219
|
+
code="table_geometry_mismatch",
|
|
220
|
+
message=(
|
|
221
|
+
f"Table {geometry.table_id!r} shape is "
|
|
222
|
+
f"{observed_rows}x{observed_columns}, expected "
|
|
223
|
+
f"{geometry.rows}x{geometry.columns}."
|
|
224
|
+
),
|
|
225
|
+
anchor=geometry.anchor,
|
|
226
|
+
remediation_hint="Restore the protected table row and column geometry.",
|
|
227
|
+
)
|
|
228
|
+
)
|
|
229
|
+
return findings
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def _metadata_findings(
|
|
233
|
+
extraction: DocumentExtraction,
|
|
234
|
+
baseline: ConformanceBaseline,
|
|
235
|
+
) -> list[ValidationFinding]:
|
|
236
|
+
findings: list[ValidationFinding] = []
|
|
237
|
+
expected_metadata = dict(baseline.metadata_exact_matches)
|
|
238
|
+
if baseline.expected_page_count is not None:
|
|
239
|
+
expected_metadata["page_count"] = baseline.expected_page_count
|
|
240
|
+
for key, expected in expected_metadata.items():
|
|
241
|
+
observed = extraction.metadata.get(key)
|
|
242
|
+
if observed != expected:
|
|
243
|
+
findings.append(
|
|
244
|
+
_finding(
|
|
245
|
+
code="metadata_mismatch",
|
|
246
|
+
message=f"Metadata {key!r} is {observed!r}, expected {expected!r}.",
|
|
247
|
+
anchor=f"metadata:{key}",
|
|
248
|
+
remediation_hint=f"Restore metadata {key!r} to the baseline value.",
|
|
249
|
+
)
|
|
250
|
+
)
|
|
251
|
+
return findings
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
def _report(
|
|
255
|
+
extraction: DocumentExtraction,
|
|
256
|
+
*,
|
|
257
|
+
baseline: ConformanceBaseline,
|
|
258
|
+
artifact_id: str,
|
|
259
|
+
findings: list[ValidationFinding],
|
|
260
|
+
decision: ValidationDecision,
|
|
261
|
+
readiness: ValidationReadiness,
|
|
262
|
+
round_trip_passed: bool,
|
|
263
|
+
render_passed: bool,
|
|
264
|
+
security_passed: bool,
|
|
265
|
+
) -> PublicFormValidationReport:
|
|
266
|
+
metrics = compute_public_form_metrics(extraction, baseline)
|
|
267
|
+
return PublicFormValidationReport(
|
|
268
|
+
report_id=f"validation-{artifact_id}-{baseline.template_id}",
|
|
269
|
+
artifact_id=artifact_id,
|
|
270
|
+
template_id=baseline.template_id,
|
|
271
|
+
schema_id=baseline.schema_id,
|
|
272
|
+
paragraph_block_f1=metrics.paragraph_block_f1,
|
|
273
|
+
table_cell_f1=metrics.table_cell_f1,
|
|
274
|
+
image_reference_f1=metrics.image_reference_f1,
|
|
275
|
+
metadata_exact_match=metrics.metadata_exact_match,
|
|
276
|
+
aggregate_score=metrics.aggregate_score,
|
|
277
|
+
round_trip_passed=round_trip_passed,
|
|
278
|
+
render_passed=render_passed,
|
|
279
|
+
security_passed=security_passed,
|
|
280
|
+
findings=findings,
|
|
281
|
+
decision=decision,
|
|
282
|
+
readiness=readiness,
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
def _result(
|
|
287
|
+
report: PublicFormValidationReport,
|
|
288
|
+
*,
|
|
289
|
+
status: ToolResultStatus,
|
|
290
|
+
blocked_reason: BlockedReason | None,
|
|
291
|
+
summary: str,
|
|
292
|
+
correlation_id: str,
|
|
293
|
+
) -> DocumentToolResult:
|
|
294
|
+
return DocumentToolResult(
|
|
295
|
+
tool_id="document_validate_public_form",
|
|
296
|
+
correlation_id=correlation_id,
|
|
297
|
+
status=status,
|
|
298
|
+
artifact_refs=[report.artifact_id],
|
|
299
|
+
validation_report=report,
|
|
300
|
+
findings=list(report.findings),
|
|
301
|
+
text_summary=summary,
|
|
302
|
+
blocked_reason=blocked_reason,
|
|
303
|
+
)
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
def _decision(
|
|
307
|
+
*,
|
|
308
|
+
aggregate_score: Decimal,
|
|
309
|
+
hard_failure: bool,
|
|
310
|
+
round_trip_passed: bool,
|
|
311
|
+
render_passed: bool,
|
|
312
|
+
security_passed: bool,
|
|
313
|
+
) -> tuple[ValidationDecision, ValidationReadiness]:
|
|
314
|
+
if not security_passed:
|
|
315
|
+
return ValidationDecision.blocked, ValidationReadiness.blocked
|
|
316
|
+
if hard_failure or not round_trip_passed or not render_passed:
|
|
317
|
+
if not round_trip_passed or not render_passed:
|
|
318
|
+
return ValidationDecision.needs_manual_review, ValidationReadiness.not_ready
|
|
319
|
+
return ValidationDecision.fail, ValidationReadiness.not_ready
|
|
320
|
+
if aggregate_score < Decimal("0.85"):
|
|
321
|
+
return ValidationDecision.fail, ValidationReadiness.not_ready
|
|
322
|
+
return ValidationDecision.pass_, ValidationReadiness.ready_for_review
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
def _combined_text(extraction: DocumentExtraction) -> str:
|
|
326
|
+
parts = [paragraph.text for paragraph in extraction.paragraphs]
|
|
327
|
+
parts.extend(cell.text for table in extraction.tables for cell in table.cells)
|
|
328
|
+
parts.extend(field.label for field in extraction.fields)
|
|
329
|
+
return "\n".join(parts)
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
def _finding(
|
|
333
|
+
*,
|
|
334
|
+
code: str,
|
|
335
|
+
message: str,
|
|
336
|
+
anchor: str,
|
|
337
|
+
remediation_hint: str,
|
|
338
|
+
) -> ValidationFinding:
|
|
339
|
+
digest = hashlib.sha256(f"{code}\0{anchor}\0{message}".encode()).hexdigest()[:12]
|
|
340
|
+
return ValidationFinding(
|
|
341
|
+
finding_id=f"validation-{code}-{digest}",
|
|
342
|
+
severity="hard_failure",
|
|
343
|
+
code=code,
|
|
344
|
+
message=message,
|
|
345
|
+
anchor=anchor,
|
|
346
|
+
remediation_hint=remediation_hint,
|
|
347
|
+
)
|
|
@@ -30,6 +30,7 @@ from ummaya.tools.envelope import make_error_envelope, normalize
|
|
|
30
30
|
from ummaya.tools.errors import (
|
|
31
31
|
EnvelopeNormalizationError,
|
|
32
32
|
LookupErrorReason,
|
|
33
|
+
ToolExecutionError,
|
|
33
34
|
ToolNotFoundError,
|
|
34
35
|
UmmayaToolError,
|
|
35
36
|
)
|
|
@@ -46,6 +47,7 @@ logger = logging.getLogger(__name__)
|
|
|
46
47
|
_tracer = trace.get_tracer(__name__)
|
|
47
48
|
|
|
48
49
|
AdapterFn = Callable[[BaseModel], Awaitable[dict[str, Any]]]
|
|
50
|
+
SessionAwareAdapterFn = Callable[[BaseModel, object | None], Awaitable[dict[str, Any]]]
|
|
49
51
|
|
|
50
52
|
_LOOKUP_ENVELOPE_KINDS: frozenset[str] = frozenset(
|
|
51
53
|
{"record", "collection", "timeseries", "error", "search"}
|
|
@@ -79,6 +81,11 @@ def _classify_adapter_exception(exc: Exception) -> tuple[LookupErrorReason, bool
|
|
|
79
81
|
if isinstance(exc, Layer3GateViolation):
|
|
80
82
|
# Programming error: stub handler was reached despite auth-gate — never retry.
|
|
81
83
|
return (LookupErrorReason.upstream_unavailable, False)
|
|
84
|
+
if isinstance(exc, ToolExecutionError) and isinstance(exc.cause, httpx.HTTPStatusError):
|
|
85
|
+
status_code = exc.cause.response.status_code
|
|
86
|
+
if status_code in {400, 401, 403, 404}:
|
|
87
|
+
return (LookupErrorReason.upstream_unavailable, False)
|
|
88
|
+
return (LookupErrorReason.upstream_unavailable, True)
|
|
82
89
|
if isinstance(exc, LiveAdapterProxyConfigurationError):
|
|
83
90
|
return (LookupErrorReason.upstream_unavailable, False)
|
|
84
91
|
if isinstance(exc, (ValueError, TypeError, KMADomainError)):
|
|
@@ -118,6 +125,19 @@ def _adapter_validation_recovery_hint(tool_id: str) -> str:
|
|
|
118
125
|
" prefer nmc_emergency_search when authenticated, or a location POI"
|
|
119
126
|
" search when no authenticated NMC session is present."
|
|
120
127
|
)
|
|
128
|
+
if tool_id == "nmc_aed_site_locate":
|
|
129
|
+
return (
|
|
130
|
+
" REGION FILTER ONLY: this AED adapter uses official NMC Q0/Q1"
|
|
131
|
+
" region filters, not ER-search mode. If you have"
|
|
132
|
+
" a place name, call kakao_keyword_search({query:'<장소명>'}), then"
|
|
133
|
+
" kakao_coord_to_region({lat:<lat>, lon:<lon>}). Re-invoke this"
|
|
134
|
+
" tool as nmc_aed_site_locate({q0:region.region_1depth_name,"
|
|
135
|
+
" q1:region.region_2depth_name, page_no:1, num_of_rows:10,"
|
|
136
|
+
" origin_lat:<original place lat>, origin_lon:<original place lon>})."
|
|
137
|
+
" origin_lat/origin_lon are optional client-side distance-sort fields;"
|
|
138
|
+
" copy them from the coordinate-producing locate result when available."
|
|
139
|
+
" Do NOT pass mode, lat/lon, or ER-only fields."
|
|
140
|
+
)
|
|
121
141
|
if tool_id in {"kakao_coord_to_region", "sgis_adm_cd_lookup"}:
|
|
122
142
|
return (
|
|
123
143
|
" COPY EXACT COORDINATES: call this reverse-geocode adapter with"
|
|
@@ -176,6 +196,7 @@ class ToolExecutor:
|
|
|
176
196
|
"""
|
|
177
197
|
self._registry = registry
|
|
178
198
|
self._adapters: dict[str, AdapterFn] = {}
|
|
199
|
+
self._session_adapters: dict[str, SessionAwareAdapterFn] = {}
|
|
179
200
|
self._recovery_executor = recovery_executor
|
|
180
201
|
self._metrics: MetricsCollector | None = metrics
|
|
181
202
|
self._event_logger: ObservabilityEventLogger | None = event_logger
|
|
@@ -192,6 +213,31 @@ class ToolExecutor:
|
|
|
192
213
|
self._adapters[tool_id] = adapter
|
|
193
214
|
logger.debug("Registered adapter for tool: %s", tool_id)
|
|
194
215
|
|
|
216
|
+
def register_session_adapter(self, tool_id: str, adapter: SessionAwareAdapterFn) -> None:
|
|
217
|
+
"""Register an adapter that also receives the caller session identity."""
|
|
218
|
+
|
|
219
|
+
async def _without_session(inp: BaseModel) -> dict[str, Any]:
|
|
220
|
+
return await adapter(inp, None)
|
|
221
|
+
|
|
222
|
+
self._adapters[tool_id] = _without_session
|
|
223
|
+
self._session_adapters[tool_id] = adapter
|
|
224
|
+
logger.debug("Registered session-aware adapter for tool: %s", tool_id)
|
|
225
|
+
|
|
226
|
+
def _adapter_for_session(
|
|
227
|
+
self,
|
|
228
|
+
tool_id: str,
|
|
229
|
+
adapter: AdapterFn,
|
|
230
|
+
session_identity: object | None,
|
|
231
|
+
) -> AdapterFn:
|
|
232
|
+
session_adapter = self._session_adapters.get(tool_id)
|
|
233
|
+
if session_adapter is None:
|
|
234
|
+
return adapter
|
|
235
|
+
|
|
236
|
+
async def _with_session(inp: BaseModel) -> dict[str, Any]:
|
|
237
|
+
return await session_adapter(inp, session_identity)
|
|
238
|
+
|
|
239
|
+
return _with_session
|
|
240
|
+
|
|
195
241
|
async def invoke_raw( # noqa: C901
|
|
196
242
|
self,
|
|
197
243
|
tool_id: str,
|
|
@@ -250,6 +296,7 @@ class ToolExecutor:
|
|
|
250
296
|
elapsed_ms=_elapsed(),
|
|
251
297
|
retryable=False,
|
|
252
298
|
)
|
|
299
|
+
adapter = self._adapter_for_session(tool_id, adapter, session_identity)
|
|
253
300
|
|
|
254
301
|
try:
|
|
255
302
|
validated_input = tool.input_schema.model_validate(params)
|
|
@@ -311,8 +358,9 @@ class ToolExecutor:
|
|
|
311
358
|
reason=reason,
|
|
312
359
|
message=(
|
|
313
360
|
f"Adapter '{tool_id}' raised {type(exc).__name__}: {str(exc)[:240]}. "
|
|
314
|
-
"Do NOT fabricate a response from prior knowledge;
|
|
315
|
-
"
|
|
361
|
+
"Do NOT fabricate a response from prior knowledge; explain that "
|
|
362
|
+
"the lookup failed, cite the official agency channel, and ask "
|
|
363
|
+
"before trying a different adapter."
|
|
316
364
|
),
|
|
317
365
|
request_id=request_id,
|
|
318
366
|
elapsed_ms=_elapsed(),
|
|
@@ -438,6 +486,7 @@ class ToolExecutor:
|
|
|
438
486
|
elapsed_ms=_elapsed(),
|
|
439
487
|
retryable=False,
|
|
440
488
|
)
|
|
489
|
+
adapter = self._adapter_for_session(tool_id, adapter, session_identity)
|
|
441
490
|
|
|
442
491
|
# --- Input validation ---------------------------------------------------
|
|
443
492
|
try:
|
|
@@ -480,20 +529,20 @@ class ToolExecutor:
|
|
|
480
529
|
recovery_hint = _adapter_validation_recovery_hint(tool_id)
|
|
481
530
|
if not recovery_hint and tool_id == "nmc_emergency_search":
|
|
482
531
|
recovery_hint = (
|
|
483
|
-
" LOCATE FIRST: call
|
|
532
|
+
" LOCATE FIRST: call a concrete locate adapter from"
|
|
484
533
|
" <available_adapters>. For a named place use"
|
|
485
|
-
"
|
|
486
|
-
"
|
|
487
|
-
"
|
|
488
|
-
"
|
|
534
|
+
" kakao_keyword_search({query:'<지역명>'}), then call"
|
|
535
|
+
" kakao_coord_to_region({lat:<lat>, lon:<lon>}). Re-invoke"
|
|
536
|
+
" this tool as nmc_emergency_search({mode:'region',"
|
|
537
|
+
" q0:region.region_1depth_name,"
|
|
489
538
|
" q1:region.region_2depth_name, origin_lat:<lat>, origin_lon:<lon>,"
|
|
490
|
-
" limit:<N>}. Copy decimal WGS-84 coordinates exactly from locate;"
|
|
539
|
+
" limit:<N>}). Copy decimal WGS-84 coordinates exactly from locate;"
|
|
491
540
|
" do NOT round, guess coordinates, or set QN unless the citizen"
|
|
492
541
|
" gave a specific institution name."
|
|
493
542
|
)
|
|
494
543
|
elif not recovery_hint and need_resolve:
|
|
495
544
|
recovery_hint = (
|
|
496
|
-
" LOCATE FIRST: call
|
|
545
|
+
" LOCATE FIRST: call the appropriate concrete locate adapter"
|
|
497
546
|
" from <available_adapters> to obtain the missing coordinates /"
|
|
498
547
|
" admin code, then re-invoke this tool with the returned values."
|
|
499
548
|
" Do NOT guess coordinates or codes from prior knowledge."
|
|
@@ -566,8 +615,8 @@ class ToolExecutor:
|
|
|
566
615
|
f"Adapter '{tool_id}' raised an exception during upstream call. "
|
|
567
616
|
f"Detail: {_exc_summary}. "
|
|
568
617
|
"Do NOT fabricate a response from prior knowledge — tell the citizen "
|
|
569
|
-
"the lookup failed, cite the official agency channel, and
|
|
570
|
-
"
|
|
618
|
+
"the lookup failed, cite the official agency channel, and ask "
|
|
619
|
+
"before retrying or trying a different tool."
|
|
571
620
|
),
|
|
572
621
|
request_id=request_id,
|
|
573
622
|
elapsed_ms=_elapsed(),
|
|
@@ -637,7 +686,7 @@ class ToolExecutor:
|
|
|
637
686
|
f"expected envelope schema. Detail: {_exc_detail}. "
|
|
638
687
|
"Do NOT fabricate a response from prior knowledge — tell the citizen "
|
|
639
688
|
"the data could not be parsed, cite the official agency channel, and "
|
|
640
|
-
"
|
|
689
|
+
"ask before retrying or trying a different tool."
|
|
641
690
|
),
|
|
642
691
|
request_id=request_id,
|
|
643
692
|
elapsed_ms=_elapsed(),
|
|
@@ -19,8 +19,7 @@ business logic. Reference: PyKakao 1.x ``Local`` class
|
|
|
19
19
|
endpoints as six methods on a single facade — the industry-standard
|
|
20
20
|
Korean wrapper for this API. UMMAYA originally shipped only
|
|
21
21
|
``search_address`` (Spec 022); ``search_keyword`` is added here to close
|
|
22
|
-
the POI-coverage gap captured
|
|
23
|
-
``specs/integration-verification/donga-univ-poi-bug/``.
|
|
22
|
+
the POI-coverage gap captured during historical live-location debugging.
|
|
24
23
|
|
|
25
24
|
Authentication: REST API key via ``Authorization: KakaoAK {key}`` header.
|
|
26
25
|
Key source: ``UMMAYA_KAKAO_API_KEY`` environment variable.
|