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.
Files changed (534) hide show
  1. package/README.md +17 -3
  2. package/bin/ummaya +10 -1
  3. package/npm-shrinkwrap.json +253 -2
  4. package/package.json +5 -1
  5. package/prompts/manifest.yaml +2 -2
  6. package/prompts/session_guidance_v1.md +3 -1
  7. package/prompts/system_v1.md +9 -7
  8. package/pyproject.toml +26 -7
  9. package/specs/2803-document-production-hardening/contracts/document-tools.schema.json +1043 -0
  10. package/src/ummaya/_canonical/__init__.py +2 -0
  11. package/src/ummaya/context/builder.py +17 -11
  12. package/src/ummaya/engine/engine.py +30 -113
  13. package/src/ummaya/engine/query.py +20 -0
  14. package/src/ummaya/evidence/__init__.py +44 -0
  15. package/src/ummaya/evidence/__main__.py +7 -0
  16. package/src/ummaya/evidence/dataset_contract.py +193 -0
  17. package/src/ummaya/evidence/document_authoring_cases.py +33 -0
  18. package/src/ummaya/evidence/document_harness.py +313 -0
  19. package/src/ummaya/evidence/document_viewer_ux.py +391 -0
  20. package/src/ummaya/evidence/gates.py +70 -0
  21. package/src/ummaya/evidence/json_types.py +20 -0
  22. package/src/ummaya/evidence/models.py +145 -0
  23. package/src/ummaya/evidence/output_payload.py +89 -0
  24. package/src/ummaya/evidence/payload_documents.py +233 -0
  25. package/src/ummaya/evidence/route_contracts.py +224 -0
  26. package/src/ummaya/evidence/route_helpers.py +150 -0
  27. package/src/ummaya/evidence/runner.py +177 -0
  28. package/src/ummaya/evidence/source_provenance.py +246 -0
  29. package/src/ummaya/evidence/source_provenance_redaction.py +176 -0
  30. package/src/ummaya/evidence/task_registry.py +264 -0
  31. package/src/ummaya/evidence/tool_layer.py +39 -0
  32. package/src/ummaya/evidence/tool_layer_models.py +151 -0
  33. package/src/ummaya/ipc/adapter_manifest_emitter.py +26 -10
  34. package/src/ummaya/ipc/document_intent_normalization.py +185 -0
  35. package/src/ummaya/ipc/frame_schema.py +52 -5
  36. package/src/ummaya/ipc/route_diagnostics.py +73 -0
  37. package/src/ummaya/ipc/stdio.py +2282 -417
  38. package/src/ummaya/llm/client.py +234 -59
  39. package/src/ummaya/llm/config.py +8 -3
  40. package/src/ummaya/llm/reasoning.py +84 -0
  41. package/src/ummaya/primitives/__init__.py +6 -2
  42. package/src/ummaya/primitives/delegation.py +1 -1
  43. package/src/ummaya/primitives/document.py +28 -0
  44. package/src/ummaya/settings.py +0 -3
  45. package/src/ummaya/tools/discovery_bridge.py +34 -2
  46. package/src/ummaya/tools/documents/__init__.py +297 -0
  47. package/src/ummaya/tools/documents/adapter_registry.py +487 -0
  48. package/src/ummaya/tools/documents/archive_container_probe.py +167 -0
  49. package/src/ummaya/tools/documents/artifact_store.py +454 -0
  50. package/src/ummaya/tools/documents/authoring.py +283 -0
  51. package/src/ummaya/tools/documents/baselines.py +114 -0
  52. package/src/ummaya/tools/documents/capability.py +331 -0
  53. package/src/ummaya/tools/documents/contracts.py +112 -0
  54. package/src/ummaya/tools/documents/conversion.py +521 -0
  55. package/src/ummaya/tools/documents/diff.py +275 -0
  56. package/src/ummaya/tools/documents/engines.py +163 -0
  57. package/src/ummaya/tools/documents/evaluation.py +291 -0
  58. package/src/ummaya/tools/documents/explicit_values.py +108 -0
  59. package/src/ummaya/tools/documents/fixtures.py +174 -0
  60. package/src/ummaya/tools/documents/format_completion_audit.py +471 -0
  61. package/src/ummaya/tools/documents/formats/__init__.py +2 -0
  62. package/src/ummaya/tools/documents/formats/archive.py +528 -0
  63. package/src/ummaya/tools/documents/formats/base.py +41 -0
  64. package/src/ummaya/tools/documents/formats/code_file.py +211 -0
  65. package/src/ummaya/tools/documents/formats/data_file.py +272 -0
  66. package/src/ummaya/tools/documents/formats/hwp.py +284 -0
  67. package/src/ummaya/tools/documents/formats/hwpx.py +1837 -0
  68. package/src/ummaya/tools/documents/formats/odf.py +435 -0
  69. package/src/ummaya/tools/documents/formats/ooxml.py +1030 -0
  70. package/src/ummaya/tools/documents/formats/passive.py +766 -0
  71. package/src/ummaya/tools/documents/formats/pdf.py +702 -0
  72. package/src/ummaya/tools/documents/formats/text_web.py +268 -0
  73. package/src/ummaya/tools/documents/hwp_conversion_probe.py +178 -0
  74. package/src/ummaya/tools/documents/hwp_direct_candidate.py +141 -0
  75. package/src/ummaya/tools/documents/inspection.py +289 -0
  76. package/src/ummaya/tools/documents/intake.py +1079 -0
  77. package/src/ummaya/tools/documents/legacy_office_promotion_probe.py +366 -0
  78. package/src/ummaya/tools/documents/models.py +1598 -0
  79. package/src/ummaya/tools/documents/odf_promotion_probe.py +167 -0
  80. package/src/ummaya/tools/documents/orchestrator.py +96 -0
  81. package/src/ummaya/tools/documents/passive_capability_probe.py +251 -0
  82. package/src/ummaya/tools/documents/patch.py +170 -0
  83. package/src/ummaya/tools/documents/pdfa_conformance.py +284 -0
  84. package/src/ummaya/tools/documents/pdfa_promotion_probe.py +198 -0
  85. package/src/ummaya/tools/documents/permissions.py +110 -0
  86. package/src/ummaya/tools/documents/planner.py +616 -0
  87. package/src/ummaya/tools/documents/registry.py +2733 -0
  88. package/src/ummaya/tools/documents/render.py +978 -0
  89. package/src/ummaya/tools/documents/render_comparison.py +113 -0
  90. package/src/ummaya/tools/documents/render_comparison_models.py +74 -0
  91. package/src/ummaya/tools/documents/render_comparison_regions.py +73 -0
  92. package/src/ummaya/tools/documents/render_comparison_style.py +161 -0
  93. package/src/ummaya/tools/documents/reread.py +157 -0
  94. package/src/ummaya/tools/documents/runtime_authoring.py +244 -0
  95. package/src/ummaya/tools/documents/runtime_authoring_bundle.py +76 -0
  96. package/src/ummaya/tools/documents/scorecard.py +184 -0
  97. package/src/ummaya/tools/documents/socratic_planner.py +193 -0
  98. package/src/ummaya/tools/documents/style.py +48 -0
  99. package/src/ummaya/tools/documents/tool_defs.py +523 -0
  100. package/src/ummaya/tools/documents/validate.py +347 -0
  101. package/src/ummaya/tools/executor.py +61 -12
  102. package/src/ummaya/tools/geocoding/kakao_client.py +1 -2
  103. package/src/ummaya/tools/kma/apihub_catalog.py +984 -1
  104. package/src/ummaya/tools/kma/apihub_structured_adapter.py +86 -6
  105. package/src/ummaya/tools/kma/apihub_url_adapter.py +593 -0
  106. package/src/ummaya/tools/kma/apihub_url_catalog.py +296 -0
  107. package/src/ummaya/tools/live_proxy.py +0 -3
  108. package/src/ummaya/tools/location_adapters.py +8 -6
  109. package/src/ummaya/tools/manifest_metadata.py +16 -3
  110. package/src/ummaya/tools/models.py +5 -1
  111. package/src/ummaya/tools/mvp_surface.py +2 -2
  112. package/src/ummaya/tools/nmc/emergency_search.py +8 -6
  113. package/src/ummaya/tools/register_all.py +17 -0
  114. package/src/ummaya/tools/registry.py +10 -1
  115. package/src/ummaya/tools/resolve_location.py +4 -4
  116. package/src/ummaya/tools/routing/__init__.py +59 -0
  117. package/src/ummaya/tools/routing/builder.py +105 -0
  118. package/src/ummaya/tools/routing/cards.py +29 -0
  119. package/src/ummaya/tools/routing/decision_service.py +534 -0
  120. package/src/ummaya/tools/routing/decision_types.py +74 -0
  121. package/src/ummaya/tools/routing/feasibility.py +122 -0
  122. package/src/ummaya/tools/routing/intent.py +17 -0
  123. package/src/ummaya/tools/routing/intent_extractor.py +207 -0
  124. package/src/ummaya/tools/routing/intent_patterns.py +160 -0
  125. package/src/ummaya/tools/routing/intent_public_data.py +150 -0
  126. package/src/ummaya/tools/routing/intent_types.py +48 -0
  127. package/src/ummaya/tools/routing/lint.py +78 -0
  128. package/src/ummaya/tools/routing/metadata.py +174 -0
  129. package/src/ummaya/tools/routing/projection.py +340 -0
  130. package/src/ummaya/tools/routing/retrieval_policy.py +629 -0
  131. package/src/ummaya/tools/routing/schema.py +81 -0
  132. package/src/ummaya/tools/routing/types.py +96 -0
  133. package/src/ummaya/tools/routing_index.py +2 -2
  134. package/src/ummaya/tools/search.py +40 -106
  135. package/src/ummaya/tools/verified_data_go_kr/_manifest.py +115 -25
  136. package/src/ummaya/tools/verified_data_go_kr/airkorea_air_quality.py +109 -4
  137. package/src/ummaya/tools/verified_data_go_kr/nmc_aed_site.py +108 -2
  138. package/src/ummaya/tools/verified_data_go_kr/pps_bid_public_info.py +174 -9
  139. package/src/ummaya/tools/verified_data_go_kr/tago_bus_arrival.py +66 -3
  140. package/src/ummaya/tools/verified_data_go_kr/tago_bus_location.py +12 -2
  141. package/src/ummaya/tools/verified_data_go_kr/tago_bus_route.py +8 -2
  142. package/src/ummaya/tools/verified_data_go_kr/tago_bus_route_station.py +114 -0
  143. package/src/ummaya/tools/verified_data_go_kr/tago_bus_station.py +14 -3
  144. package/src/ummaya/tools/verify_canonical_map.py +21 -0
  145. package/tests/fixtures/documents/public_forms/baselines.yaml +113 -0
  146. package/tui/package.json +1 -2
  147. package/tui/src/.cc-byte-identical-whitelist.yaml +266 -0
  148. package/tui/src/QueryEngine.ts +12 -4
  149. package/tui/src/bridge/inboundAttachments.ts +3 -3
  150. package/tui/src/cli/handlers/auth.ts +4 -13
  151. package/tui/src/cli/handlers/mcp.tsx +3 -3
  152. package/tui/src/cli/print.ts +69 -18
  153. package/tui/src/cli/update.ts +13 -13
  154. package/tui/src/commands/copy/index.ts +1 -1
  155. package/tui/src/commands/cost/cost.ts +2 -2
  156. package/tui/src/commands/init-verifiers.ts +5 -5
  157. package/tui/src/commands/init.ts +30 -30
  158. package/tui/src/commands/insights.ts +44 -44
  159. package/tui/src/commands/install-github-app/install-github-app.tsx +2 -2
  160. package/tui/src/commands/install-github-app/setupGitHubActions.ts +3 -3
  161. package/tui/src/commands/install-github-app/types.ts +8 -30
  162. package/tui/src/commands/install.tsx +5 -5
  163. package/tui/src/commands/mcp/addCommand.ts +5 -5
  164. package/tui/src/commands/mcp/xaaIdpCommand.ts +2 -2
  165. package/tui/src/commands/plugin/ManageMarketplaces.tsx +2 -2
  166. package/tui/src/commands/plugin/types.ts +6 -28
  167. package/tui/src/commands/plugin/unifiedTypes.ts +4 -26
  168. package/tui/src/commands/reasoning/index.ts +13 -0
  169. package/tui/src/commands/reasoning/reasoning.tsx +177 -0
  170. package/tui/src/commands/rename/generateSessionName.ts +1 -1
  171. package/tui/src/commands/thinkback/thinkback.tsx +3 -3
  172. package/tui/src/commands.ts +2 -0
  173. package/tui/src/components/Feedback.tsx +1 -1
  174. package/tui/src/components/LogoV2/EmergencyTip.tsx +11 -2
  175. package/tui/src/components/LogoV2/WelcomeV2.tsx +1 -3
  176. package/tui/src/components/Messages.tsx +2 -1
  177. package/tui/src/components/ScrollKeybindingHandler.tsx +6 -6
  178. package/tui/src/components/Spinner/types.ts +6 -28
  179. package/tui/src/components/Spinner.tsx +2 -2
  180. package/tui/src/components/agents/generateAgent.ts +1 -1
  181. package/tui/src/components/agents/new-agent-creation/types.ts +4 -26
  182. package/tui/src/components/config/EnvSecretIsolatedEditor.tsx +1 -1
  183. package/tui/src/components/design-system/LoadingState.tsx +2 -2
  184. package/tui/src/components/mcp/types.ts +16 -38
  185. package/tui/src/components/messages/AssistantToolUseMessage.tsx +3 -2
  186. package/tui/src/components/messages/UserCrossSessionMessage.ts +16 -4
  187. package/tui/src/components/messages/UserForkBoilerplateMessage.ts +16 -4
  188. package/tui/src/components/messages/UserGitHubWebhookMessage.ts +16 -4
  189. package/tui/src/components/messages/UserToolResultMessage/utils.tsx +3 -2
  190. package/tui/src/components/permissions/MonitorPermissionRequest/MonitorPermissionRequest.ts +9 -4
  191. package/tui/src/components/permissions/ReviewArtifactPermissionRequest/ReviewArtifactPermissionRequest.ts +9 -4
  192. package/tui/src/components/primitive/DocumentSocraticReviewBlock.tsx +129 -0
  193. package/tui/src/components/primitive/DocumentToolResultCard.tsx +224 -0
  194. package/tui/src/components/primitive/documentSocraticReview.ts +215 -0
  195. package/tui/src/components/primitive/index.tsx +43 -1
  196. package/tui/src/components/primitive/types.ts +137 -0
  197. package/tui/src/components/ui/option.ts +4 -26
  198. package/tui/src/constants/common.ts +0 -2
  199. package/tui/src/constants/prompts.ts +4 -3
  200. package/tui/src/constants/querySource.ts +4 -26
  201. package/tui/src/entrypoints/sdk/controlTypes.ts +26 -48
  202. package/tui/src/entrypoints/sdk/coreTypes.generated.ts +3 -25
  203. package/tui/src/entrypoints/sdk/runtimeTypes.ts +38 -60
  204. package/tui/src/entrypoints/sdk/sdkUtilityTypes.ts +4 -26
  205. package/tui/src/entrypoints/sdk/settingsTypes.generated.ts +3 -25
  206. package/tui/src/entrypoints/sdk/toolTypes.ts +3 -25
  207. package/tui/src/hooks/toolPermission/handlers/interactiveHandler.ts +10 -0
  208. package/tui/src/hooks/useApiKeyVerification.ts +1 -1
  209. package/tui/src/hooks/useVirtualScroll.ts +1 -1
  210. package/tui/src/ink/ink.tsx +33 -14
  211. package/tui/src/ink/reconciler.ts +2 -3
  212. package/tui/src/ink/render-to-screen.ts +30 -10
  213. package/tui/src/ipc/bridge.ts +62 -15
  214. package/tui/src/ipc/bridgeSingleton.ts +5 -1
  215. package/tui/src/ipc/codec.ts +29 -3
  216. package/tui/src/ipc/frames.generated.ts +407 -312
  217. package/tui/src/ipc/llmClient.ts +279 -76
  218. package/tui/src/ipc/llmTypes.ts +16 -1
  219. package/tui/src/ipc/schema/frame.schema.json +1 -3475
  220. package/tui/src/keybindings/defaultBindings.ts +4 -0
  221. package/tui/src/main.tsx +32 -11
  222. package/tui/src/native-ts/file-index/index.ts +33 -3
  223. package/tui/src/observability/surface.ts +2 -2
  224. package/tui/src/probes/toolRegistryProbe.tsx +3 -1
  225. package/tui/src/projectOnboardingState.ts +7 -6
  226. package/tui/src/query/chatMessageTypes.ts +18 -0
  227. package/tui/src/query/chatMessagesBuilder.ts +1 -1
  228. package/tui/src/query/deps.ts +1 -1
  229. package/tui/src/query/messageGuards.ts +106 -0
  230. package/tui/src/query/publicDataTerminalRepair.ts +384 -0
  231. package/tui/src/query/run.ts +1075 -0
  232. package/tui/src/query/supportBoundary.ts +168 -0
  233. package/tui/src/query/toolResultErrors.ts +103 -0
  234. package/tui/src/query/toolRunner.ts +687 -0
  235. package/tui/src/query/unavailableToolRepair.ts +118 -0
  236. package/tui/src/query.ts +9 -1721
  237. package/tui/src/screens/REPL.tsx +42 -31
  238. package/tui/src/services/api/adapterManifest.ts +4 -0
  239. package/tui/src/services/api/backendChat/events.ts +117 -0
  240. package/tui/src/services/api/backendChat/finalMessage.ts +40 -0
  241. package/tui/src/services/api/backendChat/frame.ts +9 -0
  242. package/tui/src/services/api/backendChat/streaming.ts +430 -0
  243. package/tui/src/services/api/backendChat/types.ts +62 -0
  244. package/tui/src/services/api/backendChat.ts +1 -0
  245. package/tui/src/services/api/client.ts +98 -14
  246. package/tui/src/services/api/errorUtils.ts +5 -5
  247. package/tui/src/services/api/errors.ts +1 -1
  248. package/tui/src/services/api/logging.ts +1 -1
  249. package/tui/src/services/api/ummaya/evidence.ts +194 -0
  250. package/tui/src/services/api/ummaya/messages.ts +255 -0
  251. package/tui/src/services/api/ummaya/nonStreaming.ts +66 -0
  252. package/tui/src/services/api/ummaya/provider.ts +200 -0
  253. package/tui/src/services/api/ummaya/reasoning.ts +24 -0
  254. package/tui/src/services/api/ummaya/request.ts +200 -0
  255. package/tui/src/services/api/ummaya/selectionContext.ts +240 -0
  256. package/tui/src/services/api/ummaya/streaming.ts +365 -0
  257. package/tui/src/services/api/ummaya/streamingPayload.ts +129 -0
  258. package/tui/src/services/api/ummaya/streamingReader.ts +40 -0
  259. package/tui/src/services/api/ummaya/toolSelection.ts +217 -0
  260. package/tui/src/services/api/ummaya/types.ts +110 -0
  261. package/tui/src/services/api/ummaya/usage.ts +30 -0
  262. package/tui/src/services/api/ummaya.ts +26 -364
  263. package/tui/src/services/api/withRetry.ts +1 -1
  264. package/tui/src/services/awaySummary.ts +2 -2
  265. package/tui/src/services/claudeAiLimits.ts +1 -1
  266. package/tui/src/services/compact/autoCompact.ts +1 -1
  267. package/tui/src/services/compact/compact.ts +1 -1
  268. package/tui/src/services/lsp/types.ts +8 -30
  269. package/tui/src/services/tips/types.ts +6 -28
  270. package/tui/src/services/tokenEstimation.ts +1 -1
  271. package/tui/src/services/toolRegistry/bootGuard.ts +5 -5
  272. package/tui/src/services/toolUseSummary/toolUseSummaryGenerator.ts +1 -1
  273. package/tui/src/services/tools/toolExecution.ts +94 -1
  274. package/tui/src/skills/bundled/stuck.ts +12 -12
  275. package/tui/src/state/AppStateStore.ts +7 -0
  276. package/tui/src/store/pendingPermissionSlot.ts +1 -1
  277. package/tui/src/store/session-store.ts +10 -36
  278. package/tui/src/stubs/any-stub.ts +15 -10
  279. package/tui/src/stubs/color-diff-napi.ts +37 -23
  280. package/tui/src/stubs/globals.d.ts +3 -3
  281. package/tui/src/stubs/macro-preload.ts +23 -12
  282. package/tui/src/tools/AdapterTool/AdapterTool.ts +1239 -163
  283. package/tui/src/tools/AdapterTool/routeDiagnostics.ts +75 -0
  284. package/tui/src/tools/AgentTool/AgentTool.tsx +84 -1371
  285. package/tui/src/tools/AgentTool/agentToolHandoff.ts +114 -0
  286. package/tui/src/tools/AgentTool/agentToolPartialResult.ts +16 -0
  287. package/tui/src/tools/AgentTool/agentToolProgress.ts +32 -0
  288. package/tui/src/tools/AgentTool/agentToolResolver.ts +161 -0
  289. package/tui/src/tools/AgentTool/agentToolResult.ts +163 -0
  290. package/tui/src/tools/AgentTool/agentToolUtils.ts +14 -686
  291. package/tui/src/tools/AgentTool/asyncAgentLifecycle.ts +208 -0
  292. package/tui/src/tools/AgentTool/asyncLifecycle.ts +153 -0
  293. package/tui/src/tools/AgentTool/backgroundedCompletion.ts +126 -0
  294. package/tui/src/tools/AgentTool/backgroundedLifecycle.ts +174 -0
  295. package/tui/src/tools/AgentTool/foregroundBackground.ts +83 -0
  296. package/tui/src/tools/AgentTool/foregroundDrain.tsx +133 -0
  297. package/tui/src/tools/AgentTool/foregroundFinalize.ts +98 -0
  298. package/tui/src/tools/AgentTool/foregroundLifecycle.tsx +237 -0
  299. package/tui/src/tools/AgentTool/foregroundProgress.tsx +169 -0
  300. package/tui/src/tools/AgentTool/foregroundTask.ts +89 -0
  301. package/tui/src/tools/AgentTool/forkSubagent.ts +1 -12
  302. package/tui/src/tools/AgentTool/forkSubagentGate.ts +34 -0
  303. package/tui/src/tools/AgentTool/launchRouting.ts +203 -0
  304. package/tui/src/tools/AgentTool/lifecycle.ts +244 -0
  305. package/tui/src/tools/AgentTool/mcpRouting.ts +73 -0
  306. package/tui/src/tools/AgentTool/orchestrationSupport.ts +70 -0
  307. package/tui/src/tools/AgentTool/permissions.ts +39 -0
  308. package/tui/src/tools/AgentTool/promptSetup.ts +181 -0
  309. package/tui/src/tools/AgentTool/remoteRouting.ts +62 -0
  310. package/tui/src/tools/AgentTool/resultMapping.ts +116 -0
  311. package/tui/src/tools/AgentTool/resumeAgent.ts +39 -107
  312. package/tui/src/tools/AgentTool/resumeAgentHelpers.ts +140 -0
  313. package/tui/src/tools/AgentTool/runAgent.ts +1 -1
  314. package/tui/src/tools/AgentTool/runtimeConfig.ts +57 -0
  315. package/tui/src/tools/AgentTool/schemas.ts +196 -0
  316. package/tui/src/tools/AgentTool/sourceVerificationPropagation.ts +263 -0
  317. package/tui/src/tools/AgentTool/worktreeLifecycle.ts +105 -0
  318. package/tui/src/tools/AskUserQuestionTool/AskUserQuestionTool.tsx +174 -202
  319. package/tui/src/tools/BashTool/BashTool.tsx +71 -1072
  320. package/tui/src/tools/BashTool/bashCommandHelpers.ts +12 -12
  321. package/tui/src/tools/BashTool/bashPermissions/astPreflight.ts +173 -0
  322. package/tui/src/tools/BashTool/bashPermissions/classifierChecks.ts +199 -0
  323. package/tui/src/tools/BashTool/bashPermissions/compoundGuards.ts +53 -0
  324. package/tui/src/tools/BashTool/bashPermissions/constants.ts +99 -0
  325. package/tui/src/tools/BashTool/bashPermissions/index.ts +38 -0
  326. package/tui/src/tools/BashTool/bashPermissions/legacyMisparsing.ts +62 -0
  327. package/tui/src/tools/BashTool/bashPermissions/main.ts +135 -0
  328. package/tui/src/tools/BashTool/bashPermissions/normalizedCommands.ts +33 -0
  329. package/tui/src/tools/BashTool/bashPermissions/operatorFlow.ts +98 -0
  330. package/tui/src/tools/BashTool/bashPermissions/permissionChecks.ts +200 -0
  331. package/tui/src/tools/BashTool/bashPermissions/prefixSuggestions.ts +88 -0
  332. package/tui/src/tools/BashTool/bashPermissions/promptClassifierRules.ts +125 -0
  333. package/tui/src/tools/BashTool/bashPermissions/ruleDelegates.ts +19 -0
  334. package/tui/src/tools/BashTool/bashPermissions/ruleMatching.ts +145 -0
  335. package/tui/src/tools/BashTool/bashPermissions/sandboxAutoAllow.ts +75 -0
  336. package/tui/src/tools/BashTool/bashPermissions/subcommandFlow.ts +205 -0
  337. package/tui/src/tools/BashTool/bashPermissions/subcommandGuards.ts +73 -0
  338. package/tui/src/tools/BashTool/bashPermissions/subcommandResultHelpers.ts +116 -0
  339. package/tui/src/tools/BashTool/bashPermissions/types.ts +26 -0
  340. package/tui/src/tools/BashTool/bashPermissions/wrapperStripping.ts +139 -0
  341. package/tui/src/tools/BashTool/bashPermissions.ts +26 -2621
  342. package/tui/src/tools/BashTool/call.ts +202 -0
  343. package/tui/src/tools/BashTool/callLoader.ts +35 -0
  344. package/tui/src/tools/BashTool/commandClassification.ts +151 -0
  345. package/tui/src/tools/BashTool/commandClassificationLoader.ts +40 -0
  346. package/tui/src/tools/BashTool/cwdReset.ts +33 -0
  347. package/tui/src/tools/BashTool/lineTruncation.ts +11 -0
  348. package/tui/src/tools/BashTool/modeValidation.ts +13 -1
  349. package/tui/src/tools/BashTool/outputPersistence.ts +42 -0
  350. package/tui/src/tools/BashTool/permissionClassification.ts +66 -0
  351. package/tui/src/tools/BashTool/permissionLoader.ts +44 -0
  352. package/tui/src/tools/BashTool/resultLoader.ts +29 -0
  353. package/tui/src/tools/BashTool/resultMapping.ts +83 -0
  354. package/tui/src/tools/BashTool/sandboxPolicy.ts +79 -0
  355. package/tui/src/tools/BashTool/schemas.ts +65 -0
  356. package/tui/src/tools/BashTool/sedEditExecution.ts +59 -0
  357. package/tui/src/tools/BashTool/shellExecution.tsx +245 -0
  358. package/tui/src/tools/BashTool/shellOutputUtils.ts +85 -0
  359. package/tui/src/tools/BashTool/shellPermissionGauntlet.ts +97 -0
  360. package/tui/src/tools/BashTool/uiLoader.ts +37 -0
  361. package/tui/src/tools/BriefTool/upload.ts +1 -1
  362. package/tui/src/tools/CalculatorTool/parser.ts +2 -2
  363. package/tui/src/tools/DocumentPrimitive/DocumentPrimitive.ts +262 -0
  364. package/tui/src/tools/DocumentPrimitive/dispatchNormalization.ts +270 -0
  365. package/tui/src/tools/DocumentPrimitive/documentDestinationPath.ts +18 -0
  366. package/tui/src/tools/DocumentPrimitive/documentMutationGuard.ts +22 -0
  367. package/tui/src/tools/DocumentPrimitive/documentPatchNormalization.ts +248 -0
  368. package/tui/src/tools/DocumentPrimitive/documentSourceVerification.ts +245 -0
  369. package/tui/src/tools/DocumentPrimitive/documentSourceVerificationFields.ts +103 -0
  370. package/tui/src/tools/DocumentPrimitive/modelVisibleOutput.ts +40 -0
  371. package/tui/src/tools/DocumentPrimitive/prompt.ts +35 -0
  372. package/tui/src/tools/FileEditTool/FileEditTool.ts +9 -507
  373. package/tui/src/tools/FileEditTool/call.ts +228 -0
  374. package/tui/src/tools/FileEditTool/validateInput.ts +196 -0
  375. package/tui/src/tools/FileReadTool/imageProcessor.ts +13 -0
  376. package/tui/src/tools/FileWriteTool/FileWriteTool.ts +7 -300
  377. package/tui/src/tools/FileWriteTool/call.ts +223 -0
  378. package/tui/src/tools/FileWriteTool/validateInput.ts +80 -0
  379. package/tui/src/tools/ListMcpResourcesTool/ListMcpResourcesTool.ts +19 -3
  380. package/tui/src/tools/LookupPrimitive/LookupPrimitive.ts +48 -29
  381. package/tui/src/tools/LookupPrimitive/prompt.ts +6 -7
  382. package/tui/src/tools/MCPTool/trustPolicy.ts +118 -0
  383. package/tui/src/tools/McpAuthTool/McpAuthTool.ts +21 -3
  384. package/tui/src/tools/NotebookEditTool/NotebookEditTool.ts +7 -326
  385. package/tui/src/tools/NotebookEditTool/call.ts +254 -0
  386. package/tui/src/tools/NotebookEditTool/notebookModel.ts +51 -0
  387. package/tui/src/tools/NotebookEditTool/validateInput.ts +142 -0
  388. package/tui/src/tools/PowerShellTool/PowerShellTool.tsx +46 -937
  389. package/tui/src/tools/PowerShellTool/acceptEditsCommandValidation.ts +162 -0
  390. package/tui/src/tools/PowerShellTool/call.ts +179 -0
  391. package/tui/src/tools/PowerShellTool/callLoader.ts +37 -0
  392. package/tui/src/tools/PowerShellTool/commandClassification.ts +86 -0
  393. package/tui/src/tools/PowerShellTool/modeValidation.ts +25 -332
  394. package/tui/src/tools/PowerShellTool/outputPersistence.ts +42 -0
  395. package/tui/src/tools/PowerShellTool/permissionClassification.ts +28 -0
  396. package/tui/src/tools/PowerShellTool/resultLoader.ts +31 -0
  397. package/tui/src/tools/PowerShellTool/resultMapping.ts +75 -0
  398. package/tui/src/tools/PowerShellTool/schemas.ts +40 -0
  399. package/tui/src/tools/PowerShellTool/shellExecution.tsx +258 -0
  400. package/tui/src/tools/PowerShellTool/symlinkModeValidation.ts +44 -0
  401. package/tui/src/tools/PowerShellTool/uiLoader.ts +37 -0
  402. package/tui/src/tools/PowerShellTool/validation.ts +39 -0
  403. package/tui/src/tools/ReadMcpResourceTool/ReadMcpResourceTool.ts +19 -3
  404. package/tui/src/tools/ResolveLocationPrimitive/ResolveLocationPrimitive.ts +30 -19
  405. package/tui/src/tools/ResolveLocationPrimitive/prompt.ts +2 -6
  406. package/tui/src/tools/SkillTool/SkillTool.ts +2 -2
  407. package/tui/src/tools/SubmitPrimitive/SubmitPrimitive.ts +51 -18
  408. package/tui/src/tools/TaskCreateTool/TaskCreateTool.ts +16 -2
  409. package/tui/src/tools/TaskGetTool/TaskGetTool.ts +23 -3
  410. package/tui/src/tools/TaskListTool/TaskListTool.ts +22 -4
  411. package/tui/src/tools/TaskOutputTool/TaskOutputTool.tsx +46 -547
  412. package/tui/src/tools/TaskOutputTool/lookup.ts +216 -0
  413. package/tui/src/tools/TaskOutputTool/render.tsx +257 -0
  414. package/tui/src/tools/TaskOutputTool/schemas.ts +55 -0
  415. package/tui/src/tools/TaskOutputTool/serialization.ts +36 -0
  416. package/tui/src/tools/TaskStopTool/TaskStopTool.ts +10 -0
  417. package/tui/src/tools/TaskUpdateTool/TaskUpdateTool.ts +14 -364
  418. package/tui/src/tools/TaskUpdateTool/completion.ts +62 -0
  419. package/tui/src/tools/TaskUpdateTool/schemas.ts +62 -0
  420. package/tui/src/tools/TaskUpdateTool/serialization.ts +46 -0
  421. package/tui/src/tools/TaskUpdateTool/statusUpdate.ts +247 -0
  422. package/tui/src/tools/TodoWriteTool/TodoWriteTool.ts +21 -2
  423. package/tui/src/tools/ToolSearchTool/ToolSearchTool.ts +21 -302
  424. package/tui/src/tools/ToolSearchTool/ccSupportTools.ts +223 -0
  425. package/tui/src/tools/ToolSearchTool/descriptionCache.ts +50 -0
  426. package/tui/src/tools/ToolSearchTool/keywordSearch.ts +216 -0
  427. package/tui/src/tools/ToolSearchTool/prompt.ts +10 -4
  428. package/tui/src/tools/ToolSearchTool/resultMapping.ts +30 -0
  429. package/tui/src/tools/ToolSearchTool/schemas.ts +30 -0
  430. package/tui/src/tools/ToolSearchTool/searchPool.ts +47 -0
  431. package/tui/src/tools/ToolSearchTool/supportIntentHints.ts +140 -0
  432. package/tui/src/tools/TranslateTool/TranslateTool.ts +1 -1
  433. package/tui/src/tools/VerifyPrimitive/VerifyPrimitive.ts +27 -10
  434. package/tui/src/tools/WebFetchTool/WebFetchTool.ts +43 -138
  435. package/tui/src/tools/WebFetchTool/call.ts +227 -0
  436. package/tui/src/tools/WebFetchTool/resolvedAddressSafety.ts +78 -0
  437. package/tui/src/tools/WebFetchTool/sourceVerification.ts +204 -0
  438. package/tui/src/tools/WebFetchTool/types.ts +23 -0
  439. package/tui/src/tools/WebFetchTool/urlSafety.ts +181 -0
  440. package/tui/src/tools/WebFetchTool/utils.ts +1 -1
  441. package/tui/src/tools/WebSearchTool/UI.tsx +0 -1
  442. package/tui/src/tools/WebSearchTool/WebSearchTool.ts +9 -313
  443. package/tui/src/tools/WebSearchTool/call.ts +33 -0
  444. package/tui/src/tools/WebSearchTool/responseMapping.ts +190 -0
  445. package/tui/src/tools/WebSearchTool/resultBlock.ts +47 -0
  446. package/tui/src/tools/WebSearchTool/schemas.ts +47 -0
  447. package/tui/src/tools/WebSearchTool/toolSchema.ts +12 -0
  448. package/tui/src/tools/WorkspaceToolAdapter/WorkspaceToolAdapter.ts +79 -0
  449. package/tui/src/tools/WorkspaceToolAdapter/allowedRootPolicy.ts +85 -0
  450. package/tui/src/tools/WorkspaceToolAdapter/documentFormatGuards.ts +73 -0
  451. package/tui/src/tools/WorkspaceToolAdapter/inputNormalization.ts +105 -0
  452. package/tui/src/tools/WorkspaceToolAdapter/mcpExposurePolicy.ts +64 -0
  453. package/tui/src/tools/WorkspaceToolAdapter/toolDefFactory.ts +215 -0
  454. package/tui/src/tools/WorkspaceToolAdapter/toolNames.ts +6 -0
  455. package/tui/src/tools/WorkspaceToolAdapter/workspacePolicy.ts +15 -0
  456. package/tui/src/tools/_shared/citizenUserText.ts +49 -0
  457. package/tui/src/tools/_shared/dispatchPrimitive.ts +6 -6
  458. package/tui/src/tools/_shared/documentChangeToPatch.ts +125 -0
  459. package/tui/src/tools/_shared/documentDispatchArguments.ts +87 -0
  460. package/tui/src/tools/_shared/documentPrimitiveTimeout.ts +13 -0
  461. package/tui/src/tools/_shared/documentToolResultRender.ts +98 -0
  462. package/tui/src/tools/_shared/locationInputRepair.ts +112 -0
  463. package/tui/src/tools/_shared/pendingCallRegistry.ts +1 -6
  464. package/tui/src/tools/_shared/rootPrimitiveInput.ts +68 -0
  465. package/tui/src/tools/_shared/toolChoiceRepair/documentCompletionPatterns.ts +58 -0
  466. package/tui/src/tools/_shared/toolChoiceRepair/documentCompletionPrompt.ts +271 -0
  467. package/tui/src/tools/_shared/toolChoiceRepair/documentRepair.ts +452 -0
  468. package/tui/src/tools/_shared/toolChoiceRepair/messageAccess.ts +80 -0
  469. package/tui/src/tools/_shared/toolChoiceRepair/publicDataRepair.ts +92 -0
  470. package/tui/src/tools/_shared/toolChoiceRepair/supportRepair.ts +135 -0
  471. package/tui/src/tools/_shared/toolChoiceRepair.ts +61 -0
  472. package/tui/src/tools/shared/mockDisclaimer.ts +1 -1
  473. package/tui/src/tools.ts +39 -190
  474. package/tui/src/types/fileSuggestion.ts +4 -26
  475. package/tui/src/types/generated/events_mono/claude_code/v1/claude_code_internal_event.ts +186 -148
  476. package/tui/src/types/generated/events_mono/common/v1/auth.ts +25 -11
  477. package/tui/src/types/generated/events_mono/growthbook/v1/growthbook_experiment_event.ts +47 -30
  478. package/tui/src/types/generated/google/protobuf/timestamp.ts +21 -7
  479. package/tui/src/types/message.ts +80 -102
  480. package/tui/src/types/messageQueueTypes.ts +6 -28
  481. package/tui/src/types/notebook.ts +16 -38
  482. package/tui/src/types/statusLine.ts +4 -26
  483. package/tui/src/types/tools.ts +24 -46
  484. package/tui/src/types/utils.ts +6 -28
  485. package/tui/src/upstreamproxy/relay.ts +7 -3
  486. package/tui/src/upstreamproxy/upstreamproxy.ts +1 -1
  487. package/tui/src/utils/assistantMessageFactories.ts +9 -3
  488. package/tui/src/utils/attachments.ts +1 -1
  489. package/tui/src/utils/auth.ts +129 -139
  490. package/tui/src/utils/bash/ast.ts +23 -23
  491. package/tui/src/utils/bash/bashParser.ts +5 -5
  492. package/tui/src/utils/billing.ts +1 -1
  493. package/tui/src/utils/collapseReadSearch.ts +3 -3
  494. package/tui/src/utils/cronTasks.ts +1 -1
  495. package/tui/src/utils/execFileNoThrow.ts +1 -1
  496. package/tui/src/utils/filePersistence/types.ts +16 -38
  497. package/tui/src/utils/forkedAgent.ts +1 -1
  498. package/tui/src/utils/gracefulShutdown.ts +4 -4
  499. package/tui/src/utils/heapDumpService.ts +12 -8
  500. package/tui/src/utils/hooks/apiQueryHookHelper.ts +1 -1
  501. package/tui/src/utils/hooks/execPromptHook.ts +1 -1
  502. package/tui/src/utils/hooks/skillImprovement.ts +1 -1
  503. package/tui/src/utils/kExaoneReasoning.ts +138 -0
  504. package/tui/src/utils/mcp/dateTimeParser.ts +1 -1
  505. package/tui/src/utils/messages.ts +19 -0
  506. package/tui/src/utils/migrateSessions.ts +3 -3
  507. package/tui/src/utils/model/model.ts +6 -6
  508. package/tui/src/utils/multiToolLayout.ts +13 -0
  509. package/tui/src/utils/permissions/yoloClassifier.ts +1 -1
  510. package/tui/src/utils/plugins/headlessPluginInstall.ts +1 -1
  511. package/tui/src/utils/plugins/mcpPluginIntegration.ts +1 -1
  512. package/tui/src/utils/plugins/mcpbHandler.ts +1 -1
  513. package/tui/src/utils/plugins/pluginLoader.ts +8 -8
  514. package/tui/src/utils/processUserInput/processSlashCommand.tsx +2 -2
  515. package/tui/src/utils/processUserInput/processUserInput.ts +26 -0
  516. package/tui/src/utils/protectedNamespace.ts +5 -3
  517. package/tui/src/utils/rawJsonToolCall.ts +242 -0
  518. package/tui/src/utils/ripgrep.ts +16 -7
  519. package/tui/src/utils/sessionTitle.ts +1 -1
  520. package/tui/src/utils/settings/applySettingsChange.ts +4 -0
  521. package/tui/src/utils/settings/permissionValidation.ts +14 -2
  522. package/tui/src/utils/settings/types.ts +9 -3
  523. package/tui/src/utils/shell/prefix.ts +1 -1
  524. package/tui/src/utils/sideQuery.ts +1 -1
  525. package/tui/src/utils/stats.ts +1 -1
  526. package/tui/src/utils/systemThemeWatcher.ts +13 -3
  527. package/tui/src/utils/teleport.tsx +1 -1
  528. package/uv.lock +394 -22
  529. package/assets/copilot-gate-logo.svg +0 -58
  530. package/assets/govon-logo.svg +0 -40
  531. package/src/ummaya/eval/__init__.py +0 -5
  532. package/src/ummaya/eval/retrieval.py +0 -713
  533. package/tui/src/services/api/claude.ts +0 -3510
  534. 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; use another "
315
- "appropriate adapter or explain that the lookup failed."
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 locate with a locate adapter from"
532
+ " LOCATE FIRST: call a concrete locate adapter from"
484
533
  " <available_adapters>. For a named place use"
485
- " locate({tool_id:'kakao_keyword_search', params:{query:'<지역명>'}}),"
486
- " then call locate({tool_id:'kakao_coord_to_region',"
487
- " params:{lat:<lat>, lon:<lon>}}). Re-invoke this tool with"
488
- " params {mode:'region', q0:region.region_1depth_name,"
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 locate with the appropriate locate adapter"
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 offer to "
570
- "retry or try a different tool."
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
- "offer to retry or try a different tool."
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 in
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.