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
|
@@ -9,211 +9,36 @@ service channels, LLM providers, or observability backends.
|
|
|
9
9
|
from __future__ import annotations
|
|
10
10
|
|
|
11
11
|
import argparse
|
|
12
|
-
|
|
12
|
+
import json
|
|
13
13
|
from pathlib import Path
|
|
14
|
-
from typing import Literal, cast
|
|
15
14
|
|
|
16
|
-
import
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
_REPO_ROOT = Path(__file__).resolve().parents[3]
|
|
23
|
-
_DEFAULT_SCENARIO_PATH = _REPO_ROOT / "evidence/scenarios/national_ax_citizen_requests_v1.yaml"
|
|
24
|
-
_DEFAULT_TASK_REGISTRY_PATH = _REPO_ROOT / "evidence/registry.yaml"
|
|
25
|
-
_DEFAULT_DATASET_REF = "ummaya/national-ax-core@local"
|
|
26
|
-
_BANNED_MODEL_VISIBLE_KEYS = frozenset(
|
|
27
|
-
{
|
|
28
|
-
"adapter_id",
|
|
29
|
-
"tool_id",
|
|
30
|
-
"expected_tool_id",
|
|
31
|
-
"fixture_refs",
|
|
32
|
-
"fixture_ref",
|
|
33
|
-
"current_adapter_id",
|
|
34
|
-
}
|
|
15
|
+
from ummaya.evidence.dataset_contract import (
|
|
16
|
+
DEFAULT_DATASET_REF,
|
|
17
|
+
DEFAULT_SCENARIO_PATH,
|
|
18
|
+
DEFAULT_TASK_REGISTRY_PATH,
|
|
19
|
+
EvidenceContractError,
|
|
20
|
+
resolve_repo_path,
|
|
35
21
|
)
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
"tax",
|
|
39
|
-
"civil_affairs",
|
|
40
|
-
"payments",
|
|
41
|
-
"utilities",
|
|
42
|
-
"identity",
|
|
43
|
-
"welfare",
|
|
44
|
-
"healthcare",
|
|
45
|
-
"housing",
|
|
46
|
-
"mobility",
|
|
47
|
-
"business",
|
|
48
|
-
"labor",
|
|
49
|
-
"education",
|
|
50
|
-
"safety",
|
|
51
|
-
"immigration",
|
|
52
|
-
"legal",
|
|
53
|
-
"personal_data",
|
|
54
|
-
}
|
|
22
|
+
from ummaya.evidence.dataset_contract import (
|
|
23
|
+
parse_dataset as _parse_dataset,
|
|
55
24
|
)
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
purpose: str
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
class PermissionRequirements(BaseModel):
|
|
72
|
-
"""Permission requirements attached to a citizen scenario."""
|
|
73
|
-
|
|
74
|
-
model_config = ConfigDict(frozen=True, extra="allow")
|
|
75
|
-
|
|
76
|
-
identity_assurance: str
|
|
77
|
-
user_confirmations: tuple[str, ...] = Field(default_factory=tuple)
|
|
78
|
-
sensitive_data: tuple[str, ...] = Field(default_factory=tuple)
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
class Scenario(BaseModel):
|
|
82
|
-
"""Minimum scenario shape needed by Evidence Fabric v2."""
|
|
83
|
-
|
|
84
|
-
model_config = ConfigDict(frozen=True, extra="allow")
|
|
85
|
-
|
|
86
|
-
id: str
|
|
87
|
-
priority: str = "P2"
|
|
88
|
-
lifecycle_domain: str
|
|
89
|
-
request_ko: str
|
|
90
|
-
expected_ax_chain: tuple[ExpectedStep, ...]
|
|
91
|
-
permission_requirements: PermissionRequirements
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
class ScenarioDataset(BaseModel):
|
|
95
|
-
"""Versioned citizen-demand scenario dataset."""
|
|
96
|
-
|
|
97
|
-
model_config = ConfigDict(frozen=True, extra="allow")
|
|
98
|
-
|
|
99
|
-
version: int
|
|
100
|
-
dataset_id: str
|
|
101
|
-
coverage_domains: tuple[str, ...]
|
|
102
|
-
scenarios: tuple[Scenario, ...]
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
def _load_yaml_mapping(path: Path) -> Mapping[str, object]:
|
|
106
|
-
if not path.exists():
|
|
107
|
-
raise EvidenceContractError(f"scenario dataset not found: {path}")
|
|
108
|
-
loaded = yaml.safe_load(path.read_text(encoding="utf-8"))
|
|
109
|
-
if not isinstance(loaded, Mapping):
|
|
110
|
-
raise EvidenceContractError(f"scenario dataset must be a mapping: {path}")
|
|
111
|
-
return cast(Mapping[str, object], loaded)
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
def _find_banned_keys(value: object, path: str = "$") -> tuple[str, ...]:
|
|
115
|
-
if isinstance(value, Mapping):
|
|
116
|
-
hits: list[str] = []
|
|
117
|
-
for key, nested in value.items():
|
|
118
|
-
key_text = str(key)
|
|
119
|
-
nested_path = f"{path}.{key_text}"
|
|
120
|
-
if key_text in _BANNED_MODEL_VISIBLE_KEYS:
|
|
121
|
-
hits.append(nested_path)
|
|
122
|
-
hits.extend(_find_banned_keys(nested, nested_path))
|
|
123
|
-
return tuple(hits)
|
|
124
|
-
if isinstance(value, Sequence) and not isinstance(value, str | bytes | bytearray):
|
|
125
|
-
hits = []
|
|
126
|
-
for index, nested in enumerate(value):
|
|
127
|
-
hits.extend(_find_banned_keys(nested, f"{path}[{index}]"))
|
|
128
|
-
return tuple(hits)
|
|
129
|
-
return ()
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
def _parse_dataset(path: Path) -> ScenarioDataset:
|
|
133
|
-
raw = _load_yaml_mapping(path)
|
|
134
|
-
banned = _find_banned_keys(raw)
|
|
135
|
-
if banned:
|
|
136
|
-
raise EvidenceContractError(
|
|
137
|
-
"model-visible scenario dataset contains banned implementation keys: "
|
|
138
|
-
+ ", ".join(banned)
|
|
139
|
-
)
|
|
140
|
-
try:
|
|
141
|
-
return ScenarioDataset.model_validate(raw)
|
|
142
|
-
except ValidationError as exc:
|
|
143
|
-
raise EvidenceContractError(str(exc)) from exc
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
def _gate(
|
|
147
|
-
name: Literal["contract", "scenario", "observability", "adversarial", "ux", "live_canary"],
|
|
148
|
-
status: Literal["pass", "fail", "skip"],
|
|
149
|
-
summary: str,
|
|
150
|
-
check_ids: tuple[str, ...],
|
|
151
|
-
) -> EvidenceGate:
|
|
152
|
-
return EvidenceGate(name=name, status=status, summary=summary, check_ids=check_ids)
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
def _build_gates(dataset: ScenarioDataset) -> tuple[EvidenceGate, ...]:
|
|
156
|
-
covered_domains = set(dataset.coverage_domains)
|
|
157
|
-
missing_domains = tuple(sorted(_REQUIRED_DOMAINS - covered_domains))
|
|
158
|
-
scenario_domains = {scenario.lifecycle_domain for scenario in dataset.scenarios}
|
|
159
|
-
uncovered_scenario_domains = tuple(sorted(scenario_domains - covered_domains))
|
|
160
|
-
|
|
161
|
-
scenario_status: Literal["pass", "fail"] = (
|
|
162
|
-
"pass" if not missing_domains and not uncovered_scenario_domains else "fail"
|
|
163
|
-
)
|
|
164
|
-
scenario_summary = (
|
|
165
|
-
"all required citizen infrastructure domains are covered"
|
|
166
|
-
if scenario_status == "pass"
|
|
167
|
-
else "missing coverage: " + ", ".join(missing_domains + uncovered_scenario_domains)
|
|
168
|
-
)
|
|
169
|
-
|
|
170
|
-
return (
|
|
171
|
-
_gate(
|
|
172
|
-
"contract",
|
|
173
|
-
"pass",
|
|
174
|
-
"dataset is versioned, typed, and free of model-visible implementation keys",
|
|
175
|
-
("dataset-schema", "task-registry", "no-adapter-leakage"),
|
|
176
|
-
),
|
|
177
|
-
_gate(
|
|
178
|
-
"scenario",
|
|
179
|
-
scenario_status,
|
|
180
|
-
scenario_summary,
|
|
181
|
-
("coverage-domains", "scenario-shape"),
|
|
182
|
-
),
|
|
183
|
-
_gate(
|
|
184
|
-
"observability",
|
|
185
|
-
"pass",
|
|
186
|
-
"RunEvidence carries trace join keys for OTEL/Langfuse correlation",
|
|
187
|
-
("trace-join-keys",),
|
|
188
|
-
),
|
|
189
|
-
_gate(
|
|
190
|
-
"adversarial",
|
|
191
|
-
"pass",
|
|
192
|
-
"adapter IDs, fixture references, and expected tool IDs are rejected before scoring",
|
|
193
|
-
("reward-hack-surface", "hidden-implementation-leakage"),
|
|
194
|
-
),
|
|
195
|
-
_gate(
|
|
196
|
-
"ux",
|
|
197
|
-
"skip",
|
|
198
|
-
"UX frame artifacts are attached by interactive runners, not by dataset validation",
|
|
199
|
-
("ux-artifact-slot",),
|
|
200
|
-
),
|
|
201
|
-
_gate(
|
|
202
|
-
"live_canary",
|
|
203
|
-
"skip",
|
|
204
|
-
"live public-service checks are manual-only and excluded from CI",
|
|
205
|
-
("no-live-ci",),
|
|
206
|
-
),
|
|
207
|
-
)
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
def _resolve_repo_path(path: Path) -> Path:
|
|
211
|
-
return path if path.is_absolute() else _REPO_ROOT / path
|
|
25
|
+
from ummaya.evidence.document_viewer_ux import DocumentViewerUxArtifact
|
|
26
|
+
from ummaya.evidence.gates import build_gates
|
|
27
|
+
from ummaya.evidence.models import RunEvidence
|
|
28
|
+
from ummaya.evidence.output_payload import build_evidence_output_payload
|
|
29
|
+
from ummaya.evidence.route_contracts import (
|
|
30
|
+
route_selection_assertions as _route_selection_assertions,
|
|
31
|
+
)
|
|
32
|
+
from ummaya.evidence.route_contracts import (
|
|
33
|
+
route_trace_records as _route_trace_records,
|
|
34
|
+
)
|
|
35
|
+
from ummaya.evidence.task_registry import EvidenceDatasetRef, load_task_registry
|
|
36
|
+
from ummaya.evidence.tool_layer import build_tool_layer_events
|
|
212
37
|
|
|
213
38
|
|
|
214
39
|
def _resolve_task_dataset(
|
|
215
40
|
*,
|
|
216
|
-
|
|
41
|
+
dataset_id: str,
|
|
217
42
|
scenario_path: Path,
|
|
218
43
|
task_registry_path: Path | None,
|
|
219
44
|
dataset_ref: str,
|
|
@@ -222,12 +47,12 @@ def _resolve_task_dataset(
|
|
|
222
47
|
return None, None
|
|
223
48
|
registry = load_task_registry(task_registry_path)
|
|
224
49
|
task_dataset = registry.resolve_dataset(dataset_ref)
|
|
225
|
-
if task_dataset.dataset_id !=
|
|
50
|
+
if task_dataset.dataset_id != dataset_id:
|
|
226
51
|
raise EvidenceContractError(
|
|
227
52
|
f"task registry dataset_id {task_dataset.dataset_id!r} does not match "
|
|
228
|
-
f"scenario dataset_id {
|
|
53
|
+
f"scenario dataset_id {dataset_id!r}"
|
|
229
54
|
)
|
|
230
|
-
if
|
|
55
|
+
if resolve_repo_path(task_dataset.scenario_path) != resolve_repo_path(scenario_path):
|
|
231
56
|
raise EvidenceContractError(
|
|
232
57
|
f"task registry scenario_path {task_dataset.scenario_path} does not match "
|
|
233
58
|
f"run scenario_path {scenario_path}"
|
|
@@ -237,20 +62,21 @@ def _resolve_task_dataset(
|
|
|
237
62
|
|
|
238
63
|
def run_dataset(
|
|
239
64
|
*,
|
|
240
|
-
scenario_path: Path =
|
|
65
|
+
scenario_path: Path = DEFAULT_SCENARIO_PATH,
|
|
241
66
|
source_ref: str = "local",
|
|
242
|
-
task_registry_path: Path | None =
|
|
243
|
-
dataset_ref: str =
|
|
67
|
+
task_registry_path: Path | None = DEFAULT_TASK_REGISTRY_PATH,
|
|
68
|
+
dataset_ref: str = DEFAULT_DATASET_REF,
|
|
244
69
|
) -> RunEvidence:
|
|
245
70
|
"""Validate a scenario dataset and return a typed evidence document."""
|
|
246
71
|
|
|
247
72
|
dataset = _parse_dataset(scenario_path)
|
|
248
73
|
task_registry_id, task_dataset = _resolve_task_dataset(
|
|
249
|
-
|
|
74
|
+
dataset_id=dataset.dataset_id,
|
|
250
75
|
scenario_path=scenario_path,
|
|
251
76
|
task_registry_path=task_registry_path,
|
|
252
77
|
dataset_ref=dataset_ref,
|
|
253
78
|
)
|
|
79
|
+
traces = _route_trace_records(dataset)
|
|
254
80
|
return RunEvidence(
|
|
255
81
|
source_ref=source_ref,
|
|
256
82
|
dataset_id=dataset.dataset_id,
|
|
@@ -260,7 +86,10 @@ def run_dataset(
|
|
|
260
86
|
task_ids=tuple(task.task_id for task in task_dataset.tasks) if task_dataset else (),
|
|
261
87
|
scenario_count=len(dataset.scenarios),
|
|
262
88
|
scenario_ids=tuple(scenario.id for scenario in dataset.scenarios),
|
|
263
|
-
|
|
89
|
+
route_trace_records=traces,
|
|
90
|
+
route_selection_assertions=_route_selection_assertions(dataset, traces),
|
|
91
|
+
tool_layer_events=build_tool_layer_events(traces),
|
|
92
|
+
gates=build_gates(dataset),
|
|
264
93
|
)
|
|
265
94
|
|
|
266
95
|
|
|
@@ -271,7 +100,7 @@ def main() -> None:
|
|
|
271
100
|
parser.add_argument(
|
|
272
101
|
"--scenarios",
|
|
273
102
|
type=Path,
|
|
274
|
-
default=
|
|
103
|
+
default=DEFAULT_SCENARIO_PATH,
|
|
275
104
|
help="Path to the Evidence Fabric scenario dataset.",
|
|
276
105
|
)
|
|
277
106
|
parser.add_argument(
|
|
@@ -282,19 +111,39 @@ def main() -> None:
|
|
|
282
111
|
parser.add_argument(
|
|
283
112
|
"--task-registry",
|
|
284
113
|
type=Path,
|
|
285
|
-
default=
|
|
114
|
+
default=DEFAULT_TASK_REGISTRY_PATH,
|
|
286
115
|
help="Path to the Harbor-style Evidence Fabric task registry.",
|
|
287
116
|
)
|
|
288
117
|
parser.add_argument(
|
|
289
118
|
"--dataset-ref",
|
|
290
|
-
default=
|
|
119
|
+
default=DEFAULT_DATASET_REF,
|
|
291
120
|
help="Harbor-style dataset ref to resolve from the task registry.",
|
|
292
121
|
)
|
|
293
122
|
parser.add_argument(
|
|
294
|
-
"--out",
|
|
123
|
+
"--out", type=Path, default=Path(".evidence/run.json"), help="Output JSON path."
|
|
124
|
+
)
|
|
125
|
+
parser.add_argument(
|
|
126
|
+
"--document-viewer-html",
|
|
295
127
|
type=Path,
|
|
296
|
-
|
|
297
|
-
|
|
128
|
+
action="append",
|
|
129
|
+
default=None,
|
|
130
|
+
help="Local document viewer HTML path to capture as a Playwright UX artifact.",
|
|
131
|
+
)
|
|
132
|
+
parser.add_argument(
|
|
133
|
+
"--document-viewer-ux-out-dir",
|
|
134
|
+
type=Path,
|
|
135
|
+
default=None,
|
|
136
|
+
help="Directory for Playwright document viewer PNG artifacts.",
|
|
137
|
+
)
|
|
138
|
+
parser.add_argument(
|
|
139
|
+
"--document-viewer-correlation-id",
|
|
140
|
+
default=None,
|
|
141
|
+
help="Correlation ID to attach when the viewer manifest does not carry one.",
|
|
142
|
+
)
|
|
143
|
+
parser.add_argument(
|
|
144
|
+
"--document-viewer-diff-id",
|
|
145
|
+
default=None,
|
|
146
|
+
help="Document diff ID to attach when the viewer manifest does not carry one.",
|
|
298
147
|
)
|
|
299
148
|
args = parser.parse_args()
|
|
300
149
|
|
|
@@ -305,4 +154,24 @@ def main() -> None:
|
|
|
305
154
|
dataset_ref=args.dataset_ref,
|
|
306
155
|
)
|
|
307
156
|
args.out.parent.mkdir(parents=True, exist_ok=True)
|
|
308
|
-
args.out.
|
|
157
|
+
ux_out_dir = args.document_viewer_ux_out_dir or args.out.parent / "ux-artifacts"
|
|
158
|
+
document_viewer_ux_artifacts: list[DocumentViewerUxArtifact] = []
|
|
159
|
+
document_viewer_html_paths = tuple(args.document_viewer_html or ())
|
|
160
|
+
if document_viewer_html_paths:
|
|
161
|
+
from ummaya.evidence.document_viewer_ux import capture_document_viewer_ux_artifact
|
|
162
|
+
|
|
163
|
+
for viewer_html_path in document_viewer_html_paths:
|
|
164
|
+
document_viewer_ux_artifacts.append(
|
|
165
|
+
capture_document_viewer_ux_artifact(
|
|
166
|
+
viewer_html_path=viewer_html_path,
|
|
167
|
+
output_dir=ux_out_dir,
|
|
168
|
+
source_ref=args.source_ref,
|
|
169
|
+
correlation_id=args.document_viewer_correlation_id,
|
|
170
|
+
document_diff_id=args.document_viewer_diff_id,
|
|
171
|
+
)
|
|
172
|
+
)
|
|
173
|
+
payload = build_evidence_output_payload(
|
|
174
|
+
evidence,
|
|
175
|
+
document_viewer_ux_artifacts=tuple(document_viewer_ux_artifacts),
|
|
176
|
+
)
|
|
177
|
+
args.out.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
from typing import Literal, Self
|
|
6
|
+
|
|
7
|
+
from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
|
|
8
|
+
from pydantic_core import PydanticCustomError
|
|
9
|
+
|
|
10
|
+
from ummaya.evidence.source_provenance_redaction import (
|
|
11
|
+
PromptInjectionState,
|
|
12
|
+
RedactionCategory,
|
|
13
|
+
detect_prompt_injection,
|
|
14
|
+
ordered_redaction_categories,
|
|
15
|
+
redact_source_text,
|
|
16
|
+
redact_source_url,
|
|
17
|
+
redaction_categories_for_text,
|
|
18
|
+
)
|
|
19
|
+
from ummaya.tools.routing.schema import sha256, unique
|
|
20
|
+
|
|
21
|
+
SourceKind = Literal["web", "mcp", "agent", "file"]
|
|
22
|
+
SourceUseState = Literal["used", "blocked"]
|
|
23
|
+
SourceTrust = Literal["trusted", "untrusted"]
|
|
24
|
+
SynthesisState = Literal[
|
|
25
|
+
"eligible_for_synthesis",
|
|
26
|
+
"blocked_pending_user_approval",
|
|
27
|
+
"blocked_untrusted",
|
|
28
|
+
"blocked_missing_source",
|
|
29
|
+
]
|
|
30
|
+
DocumentAuthoringState = Literal[
|
|
31
|
+
"approved_for_document",
|
|
32
|
+
"blocked_pending_user_approval",
|
|
33
|
+
"blocked_untrusted",
|
|
34
|
+
"blocked_missing_source",
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class SourceRedactionMetadata(BaseModel):
|
|
39
|
+
model_config = ConfigDict(frozen=True, extra="forbid")
|
|
40
|
+
|
|
41
|
+
redacted: bool
|
|
42
|
+
categories: tuple[RedactionCategory, ...] = Field(default_factory=tuple)
|
|
43
|
+
raw_private_document_stored: Literal[False] = False
|
|
44
|
+
secret_values_stored: Literal[False] = False
|
|
45
|
+
pii_values_stored: Literal[False] = False
|
|
46
|
+
|
|
47
|
+
@model_validator(mode="after")
|
|
48
|
+
def _categories_match_redacted_flag(self) -> Self:
|
|
49
|
+
if self.redacted and not self.categories:
|
|
50
|
+
raise PydanticCustomError(
|
|
51
|
+
"source_provenance_missing_redaction_categories",
|
|
52
|
+
"redacted provenance requires redaction categories",
|
|
53
|
+
)
|
|
54
|
+
if not self.redacted and self.categories:
|
|
55
|
+
raise PydanticCustomError(
|
|
56
|
+
"source_provenance_unexpected_redaction_categories",
|
|
57
|
+
"unredacted provenance cannot carry redaction categories",
|
|
58
|
+
)
|
|
59
|
+
return self
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class SourceProvenanceRecord(BaseModel):
|
|
63
|
+
model_config = ConfigDict(frozen=True, extra="forbid")
|
|
64
|
+
|
|
65
|
+
source_kind: SourceKind
|
|
66
|
+
source_url: str | None
|
|
67
|
+
local_evidence_handle: str | None
|
|
68
|
+
title: str | None
|
|
69
|
+
description: str | None
|
|
70
|
+
tool_id: str = Field(min_length=1)
|
|
71
|
+
observed_at: datetime
|
|
72
|
+
state: SourceUseState
|
|
73
|
+
citation_id: str = Field(min_length=1)
|
|
74
|
+
provenance_id: str = Field(min_length=1)
|
|
75
|
+
trust: SourceTrust
|
|
76
|
+
prompt_injection: PromptInjectionState = "not_detected"
|
|
77
|
+
redaction: SourceRedactionMetadata
|
|
78
|
+
|
|
79
|
+
@field_validator(
|
|
80
|
+
"source_url",
|
|
81
|
+
"local_evidence_handle",
|
|
82
|
+
"title",
|
|
83
|
+
"description",
|
|
84
|
+
"tool_id",
|
|
85
|
+
"citation_id",
|
|
86
|
+
"provenance_id",
|
|
87
|
+
)
|
|
88
|
+
@classmethod
|
|
89
|
+
def _reject_unredacted_sensitive_value(cls, value: str | None) -> str | None:
|
|
90
|
+
if value is not None and redaction_categories_for_text(value):
|
|
91
|
+
raise PydanticCustomError(
|
|
92
|
+
"source_provenance_unredacted_sensitive_value",
|
|
93
|
+
"source provenance contains unredacted sensitive value",
|
|
94
|
+
)
|
|
95
|
+
return value
|
|
96
|
+
|
|
97
|
+
@model_validator(mode="after")
|
|
98
|
+
def _requires_source_handle_and_label(self) -> Self:
|
|
99
|
+
if self.source_url is None and self.local_evidence_handle is None:
|
|
100
|
+
raise PydanticCustomError(
|
|
101
|
+
"source_provenance_missing_source",
|
|
102
|
+
"source provenance requires source_url or local_evidence_handle",
|
|
103
|
+
)
|
|
104
|
+
if self.title is None and self.description is None:
|
|
105
|
+
raise PydanticCustomError(
|
|
106
|
+
"source_provenance_missing_label",
|
|
107
|
+
"source provenance requires title or description when available",
|
|
108
|
+
)
|
|
109
|
+
return self
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class SourceProvenanceDecision(BaseModel):
|
|
113
|
+
model_config = ConfigDict(frozen=True, extra="forbid")
|
|
114
|
+
|
|
115
|
+
decision_id: str = Field(min_length=1)
|
|
116
|
+
provenance_ids: tuple[str, ...] = Field(min_length=1)
|
|
117
|
+
synthesis_state: SynthesisState
|
|
118
|
+
document_authoring_state: DocumentAuthoringState
|
|
119
|
+
requires_user_approval: bool
|
|
120
|
+
approved_by_user: bool
|
|
121
|
+
rationale: str = Field(min_length=1)
|
|
122
|
+
|
|
123
|
+
@model_validator(mode="after")
|
|
124
|
+
def _document_approval_requires_user_approval(self) -> Self:
|
|
125
|
+
if self.document_authoring_state == "approved_for_document" and (
|
|
126
|
+
self.requires_user_approval or not self.approved_by_user
|
|
127
|
+
):
|
|
128
|
+
raise PydanticCustomError(
|
|
129
|
+
"source_provenance_document_approval_missing_user_approval",
|
|
130
|
+
"approved document authoring requires completed user approval",
|
|
131
|
+
)
|
|
132
|
+
return self
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
class SourceProvenanceLedger(BaseModel):
|
|
136
|
+
model_config = ConfigDict(frozen=True, extra="forbid")
|
|
137
|
+
|
|
138
|
+
schema_version: Literal["source_provenance_ledger.v1"] = "source_provenance_ledger.v1"
|
|
139
|
+
ledger_id: str = Field(min_length=1)
|
|
140
|
+
records: tuple[SourceProvenanceRecord, ...] = Field(min_length=1)
|
|
141
|
+
decisions: tuple[SourceProvenanceDecision, ...] = Field(default_factory=tuple)
|
|
142
|
+
|
|
143
|
+
@model_validator(mode="after")
|
|
144
|
+
def _decisions_reference_known_provenance_ids(self) -> Self:
|
|
145
|
+
known_ids = {record.provenance_id for record in self.records}
|
|
146
|
+
if len(known_ids) != len(self.records):
|
|
147
|
+
raise PydanticCustomError(
|
|
148
|
+
"source_provenance_duplicate_ids",
|
|
149
|
+
"source provenance ledger contains duplicate provenance ids",
|
|
150
|
+
)
|
|
151
|
+
unknown_ids = tuple(
|
|
152
|
+
unique(
|
|
153
|
+
provenance_id
|
|
154
|
+
for decision in self.decisions
|
|
155
|
+
for provenance_id in decision.provenance_ids
|
|
156
|
+
if provenance_id not in known_ids
|
|
157
|
+
)
|
|
158
|
+
)
|
|
159
|
+
if unknown_ids:
|
|
160
|
+
raise PydanticCustomError(
|
|
161
|
+
"source_provenance_unknown_ids",
|
|
162
|
+
"unknown provenance ids: " + ", ".join(unknown_ids),
|
|
163
|
+
)
|
|
164
|
+
return self
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def build_source_provenance_record(
|
|
168
|
+
*,
|
|
169
|
+
source_kind: SourceKind,
|
|
170
|
+
tool_id: str,
|
|
171
|
+
source_url: str | None,
|
|
172
|
+
local_evidence_handle: str | None,
|
|
173
|
+
title: str | None,
|
|
174
|
+
description: str | None,
|
|
175
|
+
observed_at: datetime,
|
|
176
|
+
state: SourceUseState,
|
|
177
|
+
trust: SourceTrust,
|
|
178
|
+
citation_id: str,
|
|
179
|
+
) -> SourceProvenanceRecord:
|
|
180
|
+
redacted_url, url_categories = redact_source_url(source_url)
|
|
181
|
+
redacted_handle, handle_categories = redact_source_text(local_evidence_handle)
|
|
182
|
+
redacted_title, title_categories = redact_source_text(title)
|
|
183
|
+
redacted_description, description_categories = redact_source_text(description)
|
|
184
|
+
categories = ordered_redaction_categories(
|
|
185
|
+
(
|
|
186
|
+
*url_categories,
|
|
187
|
+
*handle_categories,
|
|
188
|
+
*title_categories,
|
|
189
|
+
*description_categories,
|
|
190
|
+
)
|
|
191
|
+
)
|
|
192
|
+
prompt_injection_text_parts = (
|
|
193
|
+
title or "",
|
|
194
|
+
description or "",
|
|
195
|
+
source_url or "",
|
|
196
|
+
local_evidence_handle or "",
|
|
197
|
+
)
|
|
198
|
+
return SourceProvenanceRecord(
|
|
199
|
+
source_kind=source_kind,
|
|
200
|
+
source_url=redacted_url,
|
|
201
|
+
local_evidence_handle=redacted_handle,
|
|
202
|
+
title=redacted_title,
|
|
203
|
+
description=redacted_description,
|
|
204
|
+
tool_id=tool_id,
|
|
205
|
+
observed_at=observed_at,
|
|
206
|
+
state=state,
|
|
207
|
+
citation_id=citation_id,
|
|
208
|
+
provenance_id=stable_source_provenance_id(
|
|
209
|
+
source_kind=source_kind,
|
|
210
|
+
tool_id=tool_id,
|
|
211
|
+
source_url=redacted_url,
|
|
212
|
+
local_evidence_handle=redacted_handle,
|
|
213
|
+
citation_id=citation_id,
|
|
214
|
+
),
|
|
215
|
+
trust=trust,
|
|
216
|
+
prompt_injection=detect_prompt_injection(
|
|
217
|
+
"\n".join(part for part in prompt_injection_text_parts if part)
|
|
218
|
+
),
|
|
219
|
+
redaction=SourceRedactionMetadata(
|
|
220
|
+
redacted=bool(categories),
|
|
221
|
+
categories=categories,
|
|
222
|
+
raw_private_document_stored=False,
|
|
223
|
+
secret_values_stored=False,
|
|
224
|
+
pii_values_stored=False,
|
|
225
|
+
),
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def stable_source_provenance_id(
|
|
230
|
+
*,
|
|
231
|
+
source_kind: SourceKind,
|
|
232
|
+
tool_id: str,
|
|
233
|
+
source_url: str | None,
|
|
234
|
+
local_evidence_handle: str | None,
|
|
235
|
+
citation_id: str,
|
|
236
|
+
) -> str:
|
|
237
|
+
digest = sha256(
|
|
238
|
+
{
|
|
239
|
+
"citation_id": citation_id,
|
|
240
|
+
"local_evidence_handle": local_evidence_handle,
|
|
241
|
+
"source_kind": source_kind,
|
|
242
|
+
"source_url": source_url,
|
|
243
|
+
"tool_id": tool_id,
|
|
244
|
+
}
|
|
245
|
+
)
|
|
246
|
+
return f"prov-{digest[:24]}"
|