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,629 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+
3
+ from __future__ import annotations
4
+
5
+ from ummaya.tools.routing.intent import ToolSelectionIntent, extract_tool_selection_intent
6
+
7
+ _KCUE_TOOL_IDS = frozenset(
8
+ {
9
+ "kcue_finance_regional_tuition",
10
+ "kcue_student_regional_foreign",
11
+ }
12
+ )
13
+ _DOCUMENT_TOOL_IDS = frozenset({"document"})
14
+ _KMA_URL_AIR_TOOL_IDS = frozenset(
15
+ {
16
+ "kma_apihub_url_air_amos_minute",
17
+ "kma_apihub_url_air_metar_decoded",
18
+ }
19
+ )
20
+ _KMA_ANALYSIS_TOOL_IDS = frozenset(
21
+ {
22
+ "kma_apihub_url_high_resolution_grid_point",
23
+ "kma_apihub_url_aws_objective_analysis_grid",
24
+ "kma_apihub_url_analysis_weather_chart_image",
25
+ }
26
+ )
27
+ _KMA_LIFESTYLE_WEATHER_TOOL_IDS = frozenset(
28
+ {
29
+ "kma_current_observation",
30
+ "kma_ultra_short_term_forecast",
31
+ "kma_short_term_forecast",
32
+ }
33
+ )
34
+ _LOCATION_TOOL_IDS = frozenset(
35
+ {
36
+ "locate",
37
+ "kakao_address_search",
38
+ "kakao_keyword_search",
39
+ "kakao_coord_to_region",
40
+ "juso_adm_cd_lookup",
41
+ "sgis_adm_cd_lookup",
42
+ }
43
+ )
44
+ _AIRKOREA_TOOL_IDS = frozenset({"airkorea_ctprvn_air_quality"})
45
+
46
+
47
+ def expand_query_for_adapter_retrieval(query: str) -> str:
48
+ intent = extract_tool_selection_intent(query)
49
+ return expand_query_for_intent(query, intent)
50
+
51
+
52
+ def expand_query_for_intent(query: str, intent: ToolSelectionIntent) -> str:
53
+ additions: list[str] = []
54
+ is_airport_aviation_query = intent.has_public_data_ref("kma_airport_aviation")
55
+ if is_airport_aviation_query:
56
+ additions.extend(_airport_aviation_additions(intent))
57
+ if intent.has_public_data_ref("kma_analysis_data"):
58
+ additions.extend(_kma_analysis_data_additions())
59
+ if intent.has_public_data_ref("kma_lifestyle_weather"):
60
+ additions.extend(_kma_lifestyle_weather_additions())
61
+ if intent.has_location_ref("poi") and not is_airport_aviation_query:
62
+ additions.extend(["장소", "키워드", "POI", "랜드마크", "역", "keyword"])
63
+ if intent.has_location_ref("admin"):
64
+ additions.extend(["주소", "행정동", "법정동", "도로명", "지번", "address"])
65
+ if intent.has_public_data_ref("emergency_medical"):
66
+ additions.extend(["응급실", "응급의료", "NMC", "emergency"])
67
+ if intent.has_public_data_ref("aed"):
68
+ additions.extend(["AED", "자동심장충격기", "자동제세동기", "국립중앙의료원"])
69
+ additions.extend(_emergency_chain_additions(intent))
70
+ additions.extend(_pps_bid_additions(intent))
71
+ additions.extend(_airkorea_air_quality_additions(intent))
72
+ additions.extend(_kcue_regional_additions(intent))
73
+ additions.extend(_ocean_water_quality_additions(intent))
74
+ additions.extend(_health_detail_additions(intent))
75
+ additions.extend(_document_harness_additions(intent))
76
+ additions.extend(_public_safety_location_additions(intent))
77
+ if intent.has_public_data_ref("traffic_hazard"):
78
+ additions.extend(_traffic_hazard_additions())
79
+ if not additions:
80
+ return query
81
+ return f"{query} {' '.join(additions)}"
82
+
83
+
84
+ def filter_special_case_scores(
85
+ intent: ToolSelectionIntent,
86
+ scored: list[tuple[str, float]],
87
+ ) -> list[tuple[str, float]]:
88
+ is_airport_aviation_query = intent.has_public_data_ref("kma_airport_aviation")
89
+ is_analysis_query = intent.has_public_data_ref("kma_analysis_data")
90
+ is_analysis_map_query = intent.has_public_data_ref("kma_analysis_map")
91
+ is_analysis_point_query = (
92
+ intent.has_public_data_ref("kma_analysis_point") and not is_analysis_map_query
93
+ )
94
+ is_lifestyle_weather_query = intent.has_public_data_ref("kma_lifestyle_weather")
95
+ scored = _filter_initial_special_scores(intent, scored)
96
+ if is_analysis_query:
97
+ scored = _filter_kma_analysis_scores(
98
+ scored,
99
+ is_analysis_map_query=is_analysis_map_query,
100
+ is_analysis_point_query=is_analysis_point_query,
101
+ prefer_poi_location=intent.has_location_ref("poi"),
102
+ )
103
+ if is_lifestyle_weather_query:
104
+ scored = _filter_kma_lifestyle_weather_scores(scored)
105
+ scored = _filter_document_harness_scores(intent, scored)
106
+ scored = _filter_emergency_chain_scores(intent, scored)
107
+ scored = _filter_pps_bid_scores(intent, scored)
108
+ scored = _filter_airkorea_air_quality_scores(intent, scored)
109
+ scored = _filter_kcue_regional_scores(intent, scored)
110
+ scored = _filter_health_detail_scores(intent, scored)
111
+ scored = _filter_public_safety_location_scores(intent, scored)
112
+ scored = _filter_ocean_water_quality_scores(intent, scored)
113
+ scored = _filter_kma_aviation_scores(
114
+ intent, scored, is_airport_aviation_query=is_airport_aviation_query
115
+ )
116
+ scored = _boost_aed_scores(intent, scored)
117
+
118
+ return [
119
+ (tool_id, score + 1000.0 if tool_id in intent.explicit_tool_ids else score)
120
+ for tool_id, score in scored
121
+ ]
122
+
123
+
124
+ def is_document_harness_query(query: str) -> bool:
125
+ return extract_tool_selection_intent(query).has_document_ref("document_harness")
126
+
127
+
128
+ def _filter_kma_analysis_scores(
129
+ scored: list[tuple[str, float]],
130
+ *,
131
+ is_analysis_map_query: bool,
132
+ is_analysis_point_query: bool,
133
+ prefer_poi_location: bool,
134
+ ) -> list[tuple[str, float]]:
135
+ chart_boost = 900.0 if is_analysis_map_query else 150.0
136
+ if is_analysis_point_query and not is_analysis_map_query:
137
+ chart_boost = -20.0
138
+ analysis_boosts = {
139
+ "kma_apihub_url_analysis_weather_chart_image": chart_boost,
140
+ "kma_apihub_url_high_resolution_grid_point": (900.0 if is_analysis_point_query else 450.0),
141
+ "kma_apihub_url_aws_objective_analysis_grid": (800.0 if is_analysis_point_query else 400.0),
142
+ }
143
+ allowed_location_ids = _LOCATION_TOOL_IDS if is_analysis_point_query else frozenset()
144
+ adjusted: list[tuple[str, float]] = []
145
+ for tool_id, score in scored:
146
+ if tool_id in _KMA_ANALYSIS_TOOL_IDS:
147
+ adjusted.append((tool_id, score + analysis_boosts.get(tool_id, 0.0)))
148
+ continue
149
+ if tool_id in allowed_location_ids:
150
+ location_score = max(1.0, score - 10.0)
151
+ if prefer_poi_location and tool_id == "kakao_keyword_search":
152
+ location_score += 30.0
153
+ elif prefer_poi_location and tool_id == "kakao_address_search":
154
+ location_score = max(1.0, location_score - 15.0)
155
+ adjusted.append((tool_id, location_score))
156
+ return adjusted
157
+
158
+
159
+ def _kma_lifestyle_weather_additions() -> list[str]:
160
+ return [
161
+ "기상청",
162
+ "KMA",
163
+ "현재날씨",
164
+ "초단기실황",
165
+ "초단기예보",
166
+ "단기예보",
167
+ "강수",
168
+ "우산",
169
+ "nx",
170
+ "ny",
171
+ "base_date",
172
+ "base_time",
173
+ "current",
174
+ "observation",
175
+ "forecast",
176
+ "precipitation",
177
+ ]
178
+
179
+
180
+ def _airport_aviation_additions(intent: ToolSelectionIntent) -> list[str]:
181
+ additions = [
182
+ "METAR",
183
+ "SPECI",
184
+ "AMOS",
185
+ "항공기상",
186
+ "공항기상",
187
+ "항공",
188
+ "비행기",
189
+ "항공편",
190
+ "운항",
191
+ "이륙",
192
+ "시정",
193
+ "RVR",
194
+ "wind",
195
+ "visibility",
196
+ ]
197
+ if intent.has_public_data_ref("kma_gimpo_airport") and intent.has_public_data_ref(
198
+ "kma_runway_area"
199
+ ):
200
+ additions.extend(["AMOS", "공항기상관측", "매분자료", "활주로", "김포공항", "stn110"])
201
+ return additions
202
+
203
+
204
+ def _kma_analysis_data_additions() -> list[str]:
205
+ return [
206
+ "분석자료",
207
+ "고해상도",
208
+ "격자자료",
209
+ "객관분석",
210
+ "AWS",
211
+ "분석일기도",
212
+ "지도",
213
+ "비구름",
214
+ "바람흐름",
215
+ "objective",
216
+ "analysis",
217
+ "grid",
218
+ "chart",
219
+ ]
220
+
221
+
222
+ def _traffic_hazard_additions() -> list[str]:
223
+ return [
224
+ "교통사고",
225
+ "사고다발구역",
226
+ "위험지점",
227
+ "도로위험구역",
228
+ "어린이보호구역",
229
+ "행정동코드",
230
+ "KOROAD",
231
+ "accident",
232
+ "hazard",
233
+ ]
234
+
235
+
236
+ def _emergency_chain_additions(intent: ToolSelectionIntent) -> list[str]:
237
+ if not intent.has_public_data_ref("emergency_medical"):
238
+ return []
239
+ additions = [
240
+ "응급실",
241
+ "응급의료",
242
+ "자동심장충격기",
243
+ "AED",
244
+ "국립중앙의료원",
245
+ "NMC",
246
+ "nearby",
247
+ "emergency",
248
+ "hospital",
249
+ ]
250
+ if intent.has_location_ref("poi"):
251
+ additions.extend(["장소", "키워드", "POI", "랜드마크", "역", "keyword"])
252
+ return additions
253
+
254
+
255
+ def _public_safety_location_additions(intent: ToolSelectionIntent) -> list[str]:
256
+ additions: list[str] = []
257
+ if intent.has_public_data_ref("mois_emergency_call_box"):
258
+ additions.extend(
259
+ [
260
+ "안전비상벨",
261
+ "비상벨",
262
+ "긴급신고함",
263
+ "방범",
264
+ "행정안전부",
265
+ "MOIS",
266
+ "emergency",
267
+ "call",
268
+ "box",
269
+ ]
270
+ )
271
+ if intent.has_public_data_ref("gyeryong_assistive_charger"):
272
+ additions.extend(
273
+ [
274
+ "계룡시",
275
+ "전동보장구",
276
+ "전동휠체어",
277
+ "장애인",
278
+ "충전소",
279
+ "충전장소",
280
+ "accessibility",
281
+ "charger",
282
+ ]
283
+ )
284
+ return additions
285
+
286
+
287
+ def _ocean_water_quality_additions(intent: ToolSelectionIntent) -> list[str]:
288
+ if not intent.has_public_data_ref("mof_ocean_water_quality"):
289
+ return []
290
+ return [
291
+ "해양수산부",
292
+ "해양수질",
293
+ "수질자동측정망",
294
+ "관측소",
295
+ "SEA3003",
296
+ "용존산소",
297
+ "water",
298
+ "quality",
299
+ "ocean",
300
+ ]
301
+
302
+
303
+ def _pps_bid_additions(intent: ToolSelectionIntent) -> list[str]:
304
+ if not intent.has_public_data_ref("pps_bid"):
305
+ return []
306
+ return [
307
+ "조달청",
308
+ "나라장터",
309
+ "입찰공고",
310
+ "공사입찰",
311
+ "bidNtceNm",
312
+ "inqryBgnDt",
313
+ "inqryEndDt",
314
+ "PPS",
315
+ "bid",
316
+ "procurement",
317
+ ]
318
+
319
+
320
+ def _airkorea_air_quality_additions(intent: ToolSelectionIntent) -> list[str]:
321
+ if not intent.has_public_data_ref("airkorea_air_quality"):
322
+ return []
323
+ return [
324
+ "에어코리아",
325
+ "AirKorea",
326
+ "미세먼지",
327
+ "초미세먼지",
328
+ "대기질",
329
+ "대기오염",
330
+ "공기질",
331
+ "PM10",
332
+ "PM2.5",
333
+ "sido_name",
334
+ "city province air quality",
335
+ ]
336
+
337
+
338
+ def _kcue_regional_additions(intent: ToolSelectionIntent) -> list[str]:
339
+ if not intent.has_public_data_ref("kcue_regional"):
340
+ return []
341
+ additions = [
342
+ "한국대학교육협의회",
343
+ "대학알리미",
344
+ "대학정보공시",
345
+ "학교구분코드",
346
+ "schlDivCd",
347
+ "지역별통계",
348
+ "KCUE",
349
+ ]
350
+ if intent.has_public_data_ref("kcue_regional_finance"):
351
+ additions.extend(["재정현황", "등록금", "FinancesService", "regional tuition"])
352
+ if intent.has_public_data_ref("kcue_regional_foreign_student"):
353
+ additions.extend(["학생현황", "외국인유학생", "regional foreign student"])
354
+ return additions
355
+
356
+
357
+ def _health_detail_additions(intent: ToolSelectionIntent) -> list[str]:
358
+ if not intent.has_public_data_ref("hira_medical_detail"):
359
+ return []
360
+ return [
361
+ "의료기관",
362
+ "상세정보",
363
+ "진료과목",
364
+ "진료시간",
365
+ "주차",
366
+ "요양기호",
367
+ "ykiho",
368
+ "HIRA",
369
+ "hospital",
370
+ "detail",
371
+ ]
372
+
373
+
374
+ def _document_harness_additions(intent: ToolSelectionIntent) -> list[str]:
375
+ if not intent.has_document_ref("document_harness"):
376
+ return []
377
+ return [
378
+ "document",
379
+ "document.path",
380
+ "local",
381
+ "file",
382
+ "path",
383
+ "artifact_refs",
384
+ "public",
385
+ "document",
386
+ "harness",
387
+ "form",
388
+ "render",
389
+ "diff",
390
+ "save",
391
+ ]
392
+
393
+
394
+ def _filter_kma_lifestyle_weather_scores(
395
+ scored: list[tuple[str, float]],
396
+ ) -> list[tuple[str, float]]:
397
+ allowed_tool_ids = _KMA_LIFESTYLE_WEATHER_TOOL_IDS | _LOCATION_TOOL_IDS
398
+ if any(tool_id in allowed_tool_ids for tool_id, _ in scored):
399
+ scored = [(tool_id, score) for tool_id, score in scored if tool_id in allowed_tool_ids]
400
+ boosts = {
401
+ "kakao_keyword_search": 1100.0,
402
+ "kakao_address_search": 1000.0,
403
+ "kma_current_observation": 900.0,
404
+ "kma_ultra_short_term_forecast": 800.0,
405
+ "kma_short_term_forecast": 650.0,
406
+ "kakao_coord_to_region": 260.0,
407
+ "juso_adm_cd_lookup": 260.0,
408
+ "sgis_adm_cd_lookup": 260.0,
409
+ }
410
+ return [(tool_id, score + boosts.get(tool_id, 0.0)) for tool_id, score in scored]
411
+
412
+
413
+ def _filter_public_safety_location_scores(
414
+ intent: ToolSelectionIntent, scored: list[tuple[str, float]]
415
+ ) -> list[tuple[str, float]]:
416
+ boosts = {}
417
+ if intent.has_public_data_ref("mois_emergency_call_box"):
418
+ boosts["mois_emergency_call_box_lookup"] = 1000.0
419
+ if intent.has_public_data_ref("gyeryong_assistive_charger"):
420
+ boosts["gyeryong_assistive_device_charging_place_locate"] = 1000.0
421
+ if not boosts:
422
+ return scored
423
+ return [(tool_id, score + boosts.get(tool_id, 0.0)) for tool_id, score in scored]
424
+
425
+
426
+ def _filter_emergency_chain_scores(
427
+ intent: ToolSelectionIntent, scored: list[tuple[str, float]]
428
+ ) -> list[tuple[str, float]]:
429
+ if not intent.has_public_data_ref("emergency_medical"):
430
+ return scored
431
+ emergency_tool_ids = {
432
+ "nmc_emergency_search",
433
+ "nmc_aed_site_locate",
434
+ "hira_hospital_search",
435
+ "hira_medical_institution_detail",
436
+ }
437
+ allowed_tool_ids = emergency_tool_ids | _LOCATION_TOOL_IDS
438
+ if any(tool_id in emergency_tool_ids for tool_id, _ in scored):
439
+ scored = [(tool_id, score) for tool_id, score in scored if tool_id in allowed_tool_ids]
440
+ implicit_collapse = intent.has_public_data_ref("implicit_emergency")
441
+ boosts = {
442
+ "nmc_emergency_search": 1200.0,
443
+ "nmc_aed_site_locate": 1150.0 if implicit_collapse else 950.0,
444
+ "kakao_keyword_search": 1100.0 if implicit_collapse else 900.0,
445
+ "kakao_address_search": 800.0,
446
+ "kakao_coord_to_region": 500.0,
447
+ "juso_adm_cd_lookup": 300.0,
448
+ "sgis_adm_cd_lookup": 300.0,
449
+ "hira_hospital_search": 250.0,
450
+ "hira_medical_institution_detail": 200.0,
451
+ }
452
+ return [(tool_id, score + boosts.get(tool_id, 0.0)) for tool_id, score in scored]
453
+
454
+
455
+ def _filter_ocean_water_quality_scores(
456
+ intent: ToolSelectionIntent, scored: list[tuple[str, float]]
457
+ ) -> list[tuple[str, float]]:
458
+ if not intent.has_public_data_ref("mof_ocean_water_quality"):
459
+ return scored
460
+ return [
461
+ (
462
+ tool_id,
463
+ score + (1000.0 if tool_id == "mof_ocean_water_quality_check" else 0.0),
464
+ )
465
+ for tool_id, score in scored
466
+ ]
467
+
468
+
469
+ def _filter_pps_bid_scores(
470
+ intent: ToolSelectionIntent, scored: list[tuple[str, float]]
471
+ ) -> list[tuple[str, float]]:
472
+ if not intent.has_public_data_ref("pps_bid"):
473
+ return scored
474
+ has_pps_bid = any(tool_id == "pps_bid_public_info" for tool_id, _ in scored)
475
+ if not has_pps_bid:
476
+ return scored
477
+ return [
478
+ (tool_id, score + 1000.0) for tool_id, score in scored if tool_id == "pps_bid_public_info"
479
+ ]
480
+
481
+
482
+ def _filter_airkorea_air_quality_scores(
483
+ intent: ToolSelectionIntent, scored: list[tuple[str, float]]
484
+ ) -> list[tuple[str, float]]:
485
+ if not intent.has_public_data_ref("airkorea_air_quality"):
486
+ return scored
487
+ has_airkorea = any(tool_id in _AIRKOREA_TOOL_IDS for tool_id, _ in scored)
488
+ if not has_airkorea:
489
+ return scored
490
+ return [(tool_id, score + 1200.0) for tool_id, score in scored if tool_id in _AIRKOREA_TOOL_IDS]
491
+
492
+
493
+ def _filter_kcue_regional_scores(
494
+ intent: ToolSelectionIntent, scored: list[tuple[str, float]]
495
+ ) -> list[tuple[str, float]]:
496
+ if not intent.has_public_data_ref("kcue_regional"):
497
+ return scored
498
+ has_kcue = any(tool_id in _KCUE_TOOL_IDS for tool_id, _ in scored)
499
+ if not has_kcue:
500
+ return scored
501
+
502
+ prefer_finance = intent.has_public_data_ref("kcue_regional_finance")
503
+ prefer_foreign_student = intent.has_public_data_ref("kcue_regional_foreign_student")
504
+ boosts = {
505
+ "kcue_finance_regional_tuition": 1000.0 if prefer_finance else 700.0,
506
+ "kcue_student_regional_foreign": 1000.0 if prefer_foreign_student else 700.0,
507
+ }
508
+ return [
509
+ (tool_id, score + boosts[tool_id]) for tool_id, score in scored if tool_id in _KCUE_TOOL_IDS
510
+ ]
511
+
512
+
513
+ def _filter_health_detail_scores(
514
+ intent: ToolSelectionIntent, scored: list[tuple[str, float]]
515
+ ) -> list[tuple[str, float]]:
516
+ if not intent.has_public_data_ref("hira_medical_detail"):
517
+ return scored
518
+ return [
519
+ (
520
+ tool_id,
521
+ score + (650.0 if tool_id == "hira_medical_institution_detail" else 0.0),
522
+ )
523
+ for tool_id, score in scored
524
+ ]
525
+
526
+
527
+ def _filter_document_harness_scores(
528
+ intent: ToolSelectionIntent,
529
+ scored: list[tuple[str, float]],
530
+ ) -> list[tuple[str, float]]:
531
+ if not intent.has_document_ref("document_harness"):
532
+ return scored
533
+ if not any(tool_id in _DOCUMENT_TOOL_IDS for tool_id, _score in scored):
534
+ return scored
535
+ boosts = {"document": 1600.0}
536
+ return [
537
+ (tool_id, score + boosts[tool_id])
538
+ for tool_id, score in scored
539
+ if tool_id in _DOCUMENT_TOOL_IDS
540
+ ]
541
+
542
+
543
+ def _filter_initial_special_scores(
544
+ intent: ToolSelectionIntent, scored: list[tuple[str, float]]
545
+ ) -> list[tuple[str, float]]:
546
+ if intent.has_public_data_ref("traffic_hazard_specific"):
547
+ scored = [
548
+ (tool_id, score) for tool_id, score in scored if tool_id != "koroad_accident_search"
549
+ ]
550
+ if intent.has_public_data_ref("kma_analysis_chart"):
551
+ return [
552
+ (tool_id, score)
553
+ for tool_id, score in scored
554
+ if tool_id == "kma_apihub_url_analysis_weather_chart_image"
555
+ ]
556
+ return scored
557
+
558
+
559
+ def _filter_kma_aviation_scores(
560
+ intent: ToolSelectionIntent,
561
+ scored: list[tuple[str, float]],
562
+ *,
563
+ is_airport_aviation_query: bool,
564
+ ) -> list[tuple[str, float]]:
565
+ if intent.has_public_data_ref("kma_gimhae_airport") and is_airport_aviation_query:
566
+ scored = [
567
+ (tool_id, score)
568
+ for tool_id, score in scored
569
+ if tool_id != "kma_apihub_url_air_amos_minute"
570
+ ]
571
+ if (
572
+ intent.has_public_data_ref("kma_gimpo_airport")
573
+ and intent.has_public_data_ref("kma_runway_area")
574
+ and is_airport_aviation_query
575
+ ):
576
+ scored = [
577
+ (tool_id, score + 500.0 if tool_id == "kma_apihub_url_air_amos_minute" else score)
578
+ for tool_id, score in scored
579
+ ]
580
+ if not is_airport_aviation_query:
581
+ return scored
582
+
583
+ has_air_url_candidate = any(tool_id in _KMA_URL_AIR_TOOL_IDS for tool_id, _ in scored)
584
+ if not has_air_url_candidate:
585
+ return scored
586
+ if intent.has_public_data_ref("kma_explicit_metar"):
587
+ blocked_tool_ids = (
588
+ _LOCATION_TOOL_IDS | _KMA_LIFESTYLE_WEATHER_TOOL_IDS | {"kma_forecast_fetch"}
589
+ )
590
+ scored = [(tool_id, score) for tool_id, score in scored if tool_id not in blocked_tool_ids]
591
+ else:
592
+ scored = [(tool_id, score) for tool_id, score in scored if tool_id in _KMA_URL_AIR_TOOL_IDS]
593
+ prefer_amos = bool(
594
+ intent.has_public_data_ref("kma_gimpo_airport")
595
+ and intent.has_public_data_ref("kma_runway_area")
596
+ and not intent.has_public_data_ref("kma_gimhae_airport")
597
+ )
598
+ return [
599
+ (
600
+ tool_id,
601
+ score
602
+ + (
603
+ 800.0
604
+ if tool_id == "kma_apihub_url_air_amos_minute" and prefer_amos
605
+ else 700.0
606
+ if tool_id == "kma_apihub_url_air_metar_decoded"
607
+ else 0.0
608
+ ),
609
+ )
610
+ for tool_id, score in scored
611
+ ]
612
+
613
+
614
+ def _boost_aed_scores(
615
+ intent: ToolSelectionIntent, scored: list[tuple[str, float]]
616
+ ) -> list[tuple[str, float]]:
617
+ if not intent.has_public_data_ref("aed"):
618
+ return scored
619
+ return [
620
+ (
621
+ tool_id,
622
+ score + 900.0
623
+ if tool_id == "nmc_aed_site_locate"
624
+ else score + 700.0
625
+ if tool_id == "nmc_emergency_search" and intent.has_public_data_ref("emergency_medical")
626
+ else score,
627
+ )
628
+ for tool_id, score in scored
629
+ ]
@@ -0,0 +1,81 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+
3
+ from __future__ import annotations
4
+
5
+ import hashlib
6
+ import json
7
+ from collections.abc import Iterable, Mapping
8
+
9
+ from pydantic import BaseModel
10
+
11
+ from ummaya.tools.routing.types import SchemaFieldSummary
12
+
13
+
14
+ def model_json_schema(model: type[BaseModel]) -> dict[str, object]:
15
+ return {str(key): value for key, value in model.model_json_schema().items()}
16
+
17
+
18
+ def schema_summary(schema: Mapping[str, object]) -> tuple[SchemaFieldSummary, ...]:
19
+ raw_properties = schema.get("properties")
20
+ if not isinstance(raw_properties, Mapping):
21
+ return ()
22
+ required = required_names(schema)
23
+ summaries: list[SchemaFieldSummary] = []
24
+ for raw_name, raw_spec in raw_properties.items():
25
+ name = str(raw_name)
26
+ spec = raw_spec if isinstance(raw_spec, Mapping) else {}
27
+ summaries.append(
28
+ SchemaFieldSummary(
29
+ name=name,
30
+ type=schema_type(spec),
31
+ required=name in required,
32
+ description=schema_description(spec),
33
+ )
34
+ )
35
+ return tuple(summaries)
36
+
37
+
38
+ def required_names(schema: Mapping[str, object]) -> frozenset[str]:
39
+ raw_required = schema.get("required")
40
+ if not isinstance(raw_required, list):
41
+ return frozenset()
42
+ return frozenset(str(item) for item in raw_required if isinstance(item, str))
43
+
44
+
45
+ def schema_type(spec: Mapping[str, object]) -> str:
46
+ raw_type = spec.get("type")
47
+ if isinstance(raw_type, str):
48
+ return raw_type
49
+ if isinstance(raw_type, list):
50
+ return "|".join(str(item) for item in raw_type)
51
+ if "$ref" in spec:
52
+ return "ref"
53
+ if "anyOf" in spec:
54
+ return "anyOf"
55
+ if "oneOf" in spec:
56
+ return "oneOf"
57
+ return "unknown"
58
+
59
+
60
+ def schema_description(spec: Mapping[str, object]) -> str | None:
61
+ value = spec.get("description")
62
+ return value if isinstance(value, str) and value.strip() else None
63
+
64
+
65
+ def sha256(value: object) -> str:
66
+ return hashlib.sha256(canonical_json(value).encode("utf-8")).hexdigest()
67
+
68
+
69
+ def canonical_json(value: object) -> str:
70
+ return json.dumps(value, sort_keys=True, separators=(",", ":"), ensure_ascii=True)
71
+
72
+
73
+ def unique(values: Iterable[str]) -> list[str]:
74
+ seen: set[str] = set()
75
+ result: list[str] = []
76
+ for value in values:
77
+ item = str(value).strip()
78
+ if item and item not in seen:
79
+ result.append(item)
80
+ seen.add(item)
81
+ return result