ummaya 0.2.4 → 0.2.6

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 (482) hide show
  1. package/README.md +15 -2
  2. package/bin/ummaya +10 -1
  3. package/bun.lock +180 -244
  4. package/npm-shrinkwrap.json +760 -1760
  5. package/package.json +39 -22
  6. package/prompts/manifest.yaml +1 -1
  7. package/prompts/system_v1.md +1 -0
  8. package/pyproject.toml +27 -2
  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/_canonical/baselines.yaml +113 -0
  12. package/src/ummaya/engine/engine.py +29 -132
  13. package/src/ummaya/evidence/__init__.py +21 -2
  14. package/src/ummaya/evidence/dataset_contract.py +193 -0
  15. package/src/ummaya/evidence/document_authoring_cases.py +33 -0
  16. package/src/ummaya/evidence/document_harness.py +313 -0
  17. package/src/ummaya/evidence/document_viewer_ux.py +391 -0
  18. package/src/ummaya/evidence/gates.py +70 -0
  19. package/src/ummaya/evidence/json_types.py +20 -0
  20. package/src/ummaya/evidence/models.py +88 -1
  21. package/src/ummaya/evidence/output_payload.py +89 -0
  22. package/src/ummaya/evidence/payload_documents.py +233 -0
  23. package/src/ummaya/evidence/route_contracts.py +224 -0
  24. package/src/ummaya/evidence/route_helpers.py +150 -0
  25. package/src/ummaya/evidence/runner.py +81 -212
  26. package/src/ummaya/evidence/source_provenance.py +246 -0
  27. package/src/ummaya/evidence/source_provenance_redaction.py +176 -0
  28. package/src/ummaya/evidence/tool_layer.py +39 -0
  29. package/src/ummaya/evidence/tool_layer_models.py +151 -0
  30. package/src/ummaya/ipc/adapter_manifest_emitter.py +26 -10
  31. package/src/ummaya/ipc/document_intent_normalization.py +185 -0
  32. package/src/ummaya/ipc/frame_schema.py +5 -5
  33. package/src/ummaya/ipc/route_diagnostics.py +73 -0
  34. package/src/ummaya/ipc/stdio.py +1109 -477
  35. package/src/ummaya/llm/client.py +102 -3
  36. package/src/ummaya/llm/config.py +8 -3
  37. package/src/ummaya/primitives/__init__.py +6 -2
  38. package/src/ummaya/primitives/delegation.py +1 -1
  39. package/src/ummaya/primitives/document.py +28 -0
  40. package/src/ummaya/settings.py +0 -3
  41. package/src/ummaya/tools/discovery_bridge.py +17 -1
  42. package/src/ummaya/tools/documents/__init__.py +297 -0
  43. package/src/ummaya/tools/documents/adapter_registry.py +487 -0
  44. package/src/ummaya/tools/documents/archive_container_probe.py +167 -0
  45. package/src/ummaya/tools/documents/artifact_store.py +454 -0
  46. package/src/ummaya/tools/documents/authoring.py +283 -0
  47. package/src/ummaya/tools/documents/baselines.py +132 -0
  48. package/src/ummaya/tools/documents/capability.py +331 -0
  49. package/src/ummaya/tools/documents/contracts.py +112 -0
  50. package/src/ummaya/tools/documents/conversion.py +521 -0
  51. package/src/ummaya/tools/documents/diff.py +275 -0
  52. package/src/ummaya/tools/documents/engines.py +163 -0
  53. package/src/ummaya/tools/documents/evaluation.py +291 -0
  54. package/src/ummaya/tools/documents/explicit_values.py +108 -0
  55. package/src/ummaya/tools/documents/fixtures.py +174 -0
  56. package/src/ummaya/tools/documents/format_completion_audit.py +471 -0
  57. package/src/ummaya/tools/documents/formats/__init__.py +2 -0
  58. package/src/ummaya/tools/documents/formats/archive.py +528 -0
  59. package/src/ummaya/tools/documents/formats/base.py +41 -0
  60. package/src/ummaya/tools/documents/formats/code_file.py +211 -0
  61. package/src/ummaya/tools/documents/formats/data_file.py +272 -0
  62. package/src/ummaya/tools/documents/formats/hwp.py +284 -0
  63. package/src/ummaya/tools/documents/formats/hwpx.py +1837 -0
  64. package/src/ummaya/tools/documents/formats/odf.py +435 -0
  65. package/src/ummaya/tools/documents/formats/ooxml.py +1030 -0
  66. package/src/ummaya/tools/documents/formats/passive.py +766 -0
  67. package/src/ummaya/tools/documents/formats/pdf.py +702 -0
  68. package/src/ummaya/tools/documents/formats/text_web.py +268 -0
  69. package/src/ummaya/tools/documents/hwp_conversion_probe.py +178 -0
  70. package/src/ummaya/tools/documents/hwp_direct_candidate.py +141 -0
  71. package/src/ummaya/tools/documents/inspection.py +289 -0
  72. package/src/ummaya/tools/documents/intake.py +1079 -0
  73. package/src/ummaya/tools/documents/legacy_office_promotion_probe.py +366 -0
  74. package/src/ummaya/tools/documents/models.py +1598 -0
  75. package/src/ummaya/tools/documents/odf_promotion_probe.py +167 -0
  76. package/src/ummaya/tools/documents/orchestrator.py +96 -0
  77. package/src/ummaya/tools/documents/passive_capability_probe.py +251 -0
  78. package/src/ummaya/tools/documents/patch.py +170 -0
  79. package/src/ummaya/tools/documents/pdfa_conformance.py +284 -0
  80. package/src/ummaya/tools/documents/pdfa_promotion_probe.py +198 -0
  81. package/src/ummaya/tools/documents/permissions.py +110 -0
  82. package/src/ummaya/tools/documents/planner.py +616 -0
  83. package/src/ummaya/tools/documents/registry.py +2733 -0
  84. package/src/ummaya/tools/documents/render.py +978 -0
  85. package/src/ummaya/tools/documents/render_comparison.py +113 -0
  86. package/src/ummaya/tools/documents/render_comparison_models.py +74 -0
  87. package/src/ummaya/tools/documents/render_comparison_regions.py +73 -0
  88. package/src/ummaya/tools/documents/render_comparison_style.py +161 -0
  89. package/src/ummaya/tools/documents/reread.py +157 -0
  90. package/src/ummaya/tools/documents/runtime_authoring.py +244 -0
  91. package/src/ummaya/tools/documents/runtime_authoring_bundle.py +76 -0
  92. package/src/ummaya/tools/documents/scorecard.py +184 -0
  93. package/src/ummaya/tools/documents/socratic_planner.py +193 -0
  94. package/src/ummaya/tools/documents/style.py +48 -0
  95. package/src/ummaya/tools/documents/tool_defs.py +523 -0
  96. package/src/ummaya/tools/documents/validate.py +347 -0
  97. package/src/ummaya/tools/executor.py +29 -0
  98. package/src/ummaya/tools/live_proxy.py +0 -3
  99. package/src/ummaya/tools/models.py +5 -1
  100. package/src/ummaya/tools/register_all.py +8 -0
  101. package/src/ummaya/tools/registry.py +10 -1
  102. package/src/ummaya/tools/routing/__init__.py +59 -0
  103. package/src/ummaya/tools/routing/builder.py +105 -0
  104. package/src/ummaya/tools/routing/cards.py +29 -0
  105. package/src/ummaya/tools/routing/decision_service.py +534 -0
  106. package/src/ummaya/tools/routing/decision_types.py +74 -0
  107. package/src/ummaya/tools/routing/feasibility.py +122 -0
  108. package/src/ummaya/tools/routing/intent.py +17 -0
  109. package/src/ummaya/tools/routing/intent_extractor.py +207 -0
  110. package/src/ummaya/tools/routing/intent_patterns.py +160 -0
  111. package/src/ummaya/tools/routing/intent_public_data.py +150 -0
  112. package/src/ummaya/tools/routing/intent_types.py +48 -0
  113. package/src/ummaya/tools/routing/lint.py +78 -0
  114. package/src/ummaya/tools/routing/metadata.py +174 -0
  115. package/src/ummaya/tools/routing/projection.py +340 -0
  116. package/src/ummaya/tools/routing/retrieval_policy.py +629 -0
  117. package/src/ummaya/tools/routing/schema.py +81 -0
  118. package/src/ummaya/tools/routing/types.py +96 -0
  119. package/src/ummaya/tools/routing_index.py +2 -2
  120. package/src/ummaya/tools/search.py +34 -746
  121. package/tests/fixtures/documents/public_forms/baselines.yaml +113 -0
  122. package/tui/bun.lock +126 -305
  123. package/tui/package.json +35 -22
  124. package/tui/src/.cc-byte-identical-whitelist.yaml +266 -0
  125. package/tui/src/QueryEngine.ts +12 -8
  126. package/tui/src/bridge/inboundAttachments.ts +3 -3
  127. package/tui/src/cli/handlers/auth.ts +3 -12
  128. package/tui/src/cli/handlers/mcp.tsx +0 -1
  129. package/tui/src/cli/print.ts +8 -9
  130. package/tui/src/commands/insights.ts +1 -1
  131. package/tui/src/commands/install-github-app/types.ts +8 -30
  132. package/tui/src/commands/plugin/types.ts +6 -28
  133. package/tui/src/commands/plugin/unifiedTypes.ts +4 -26
  134. package/tui/src/commands/rename/generateSessionName.ts +1 -1
  135. package/tui/src/components/Feedback.tsx +1 -1
  136. package/tui/src/components/LogoV2/EmergencyTip.tsx +11 -2
  137. package/tui/src/components/LogoV2/WelcomeV2.tsx +1 -3
  138. package/tui/src/components/ScrollKeybindingHandler.tsx +6 -6
  139. package/tui/src/components/Spinner/types.ts +6 -28
  140. package/tui/src/components/agents/generateAgent.ts +1 -1
  141. package/tui/src/components/agents/new-agent-creation/types.ts +4 -26
  142. package/tui/src/components/config/EnvSecretIsolatedEditor.tsx +1 -1
  143. package/tui/src/components/mcp/types.ts +16 -38
  144. package/tui/src/components/messages/AssistantToolUseMessage.tsx +3 -2
  145. package/tui/src/components/messages/UserCrossSessionMessage.ts +16 -4
  146. package/tui/src/components/messages/UserForkBoilerplateMessage.ts +16 -4
  147. package/tui/src/components/messages/UserGitHubWebhookMessage.ts +16 -4
  148. package/tui/src/components/messages/UserToolResultMessage/utils.tsx +3 -2
  149. package/tui/src/components/permissions/MonitorPermissionRequest/MonitorPermissionRequest.ts +9 -4
  150. package/tui/src/components/permissions/ReviewArtifactPermissionRequest/ReviewArtifactPermissionRequest.ts +9 -4
  151. package/tui/src/components/primitive/DocumentSocraticReviewBlock.tsx +129 -0
  152. package/tui/src/components/primitive/DocumentToolResultCard.tsx +224 -0
  153. package/tui/src/components/primitive/documentSocraticReview.ts +215 -0
  154. package/tui/src/components/primitive/index.tsx +43 -1
  155. package/tui/src/components/primitive/types.ts +137 -0
  156. package/tui/src/components/ui/option.ts +4 -26
  157. package/tui/src/constants/common.ts +0 -2
  158. package/tui/src/constants/prompts.ts +4 -3
  159. package/tui/src/constants/querySource.ts +4 -26
  160. package/tui/src/entrypoints/sdk/controlTypes.ts +26 -48
  161. package/tui/src/entrypoints/sdk/coreTypes.generated.ts +3 -25
  162. package/tui/src/entrypoints/sdk/runtimeTypes.ts +38 -60
  163. package/tui/src/entrypoints/sdk/sdkUtilityTypes.ts +4 -26
  164. package/tui/src/entrypoints/sdk/settingsTypes.generated.ts +3 -25
  165. package/tui/src/entrypoints/sdk/toolTypes.ts +3 -25
  166. package/tui/src/hooks/toolPermission/handlers/interactiveHandler.ts +10 -0
  167. package/tui/src/hooks/useApiKeyVerification.ts +1 -1
  168. package/tui/src/hooks/useVirtualScroll.ts +1 -1
  169. package/tui/src/ink/ink.tsx +33 -14
  170. package/tui/src/ink/reconciler.ts +2 -3
  171. package/tui/src/ink/render-to-screen.ts +30 -10
  172. package/tui/src/ipc/bridge.ts +62 -15
  173. package/tui/src/ipc/bridgeSingleton.ts +5 -1
  174. package/tui/src/ipc/codec.ts +3 -3
  175. package/tui/src/ipc/frames.generated.ts +12 -12
  176. package/tui/src/ipc/llmClient.ts +151 -27
  177. package/tui/src/ipc/schema/frame.schema.json +1 -1
  178. package/tui/src/keybindings/defaultBindings.ts +4 -0
  179. package/tui/src/main.tsx +32 -15
  180. package/tui/src/native-ts/file-index/index.ts +33 -3
  181. package/tui/src/observability/surface.ts +2 -2
  182. package/tui/src/probes/toolRegistryProbe.tsx +3 -1
  183. package/tui/src/projectOnboardingState.ts +7 -6
  184. package/tui/src/query/chatMessageTypes.ts +18 -0
  185. package/tui/src/query/chatMessagesBuilder.ts +1 -1
  186. package/tui/src/query/deps.ts +1 -1
  187. package/tui/src/query/messageGuards.ts +106 -0
  188. package/tui/src/query/publicDataTerminalRepair.ts +384 -0
  189. package/tui/src/query/run.ts +1075 -0
  190. package/tui/src/query/supportBoundary.ts +168 -0
  191. package/tui/src/query/toolResultErrors.ts +103 -0
  192. package/tui/src/query/toolRunner.ts +687 -0
  193. package/tui/src/query/unavailableToolRepair.ts +118 -0
  194. package/tui/src/query.ts +9 -2186
  195. package/tui/src/screens/REPL.tsx +40 -29
  196. package/tui/src/services/api/adapterManifest.ts +4 -0
  197. package/tui/src/services/api/backendChat/events.ts +117 -0
  198. package/tui/src/services/api/backendChat/finalMessage.ts +40 -0
  199. package/tui/src/services/api/backendChat/frame.ts +9 -0
  200. package/tui/src/services/api/backendChat/streaming.ts +430 -0
  201. package/tui/src/services/api/backendChat/types.ts +62 -0
  202. package/tui/src/services/api/backendChat.ts +1 -0
  203. package/tui/src/services/api/client.ts +65 -2
  204. package/tui/src/services/api/errorUtils.ts +5 -5
  205. package/tui/src/services/api/errors.ts +1 -1
  206. package/tui/src/services/api/logging.ts +1 -1
  207. package/tui/src/services/api/ummaya/evidence.ts +194 -0
  208. package/tui/src/services/api/ummaya/messages.ts +255 -0
  209. package/tui/src/services/api/ummaya/nonStreaming.ts +66 -0
  210. package/tui/src/services/api/ummaya/provider.ts +200 -0
  211. package/tui/src/services/api/ummaya/reasoning.ts +24 -0
  212. package/tui/src/services/api/ummaya/request.ts +200 -0
  213. package/tui/src/services/api/ummaya/selectionContext.ts +240 -0
  214. package/tui/src/services/api/ummaya/streaming.ts +365 -0
  215. package/tui/src/services/api/ummaya/streamingPayload.ts +129 -0
  216. package/tui/src/services/api/ummaya/streamingReader.ts +40 -0
  217. package/tui/src/services/api/ummaya/toolSelection.ts +217 -0
  218. package/tui/src/services/api/ummaya/types.ts +110 -0
  219. package/tui/src/services/api/ummaya/usage.ts +30 -0
  220. package/tui/src/services/api/ummaya.ts +26 -418
  221. package/tui/src/services/api/withRetry.ts +1 -1
  222. package/tui/src/services/awaySummary.ts +2 -2
  223. package/tui/src/services/claudeAiLimits.ts +1 -1
  224. package/tui/src/services/compact/autoCompact.ts +1 -1
  225. package/tui/src/services/compact/compact.ts +1 -1
  226. package/tui/src/services/lsp/types.ts +8 -30
  227. package/tui/src/services/tips/types.ts +6 -28
  228. package/tui/src/services/tokenEstimation.ts +1 -1
  229. package/tui/src/services/toolRegistry/bootGuard.ts +5 -5
  230. package/tui/src/services/toolUseSummary/toolUseSummaryGenerator.ts +1 -1
  231. package/tui/src/services/tools/toolExecution.ts +94 -1
  232. package/tui/src/store/pendingPermissionSlot.ts +1 -1
  233. package/tui/src/store/session-store.ts +10 -36
  234. package/tui/src/stubs/any-stub.ts +15 -10
  235. package/tui/src/stubs/color-diff-napi.ts +37 -23
  236. package/tui/src/stubs/globals.d.ts +3 -3
  237. package/tui/src/stubs/macro-preload.ts +23 -12
  238. package/tui/src/tools/AdapterTool/AdapterTool.ts +1207 -714
  239. package/tui/src/tools/AdapterTool/routeDiagnostics.ts +75 -0
  240. package/tui/src/tools/AgentTool/AgentTool.tsx +84 -1371
  241. package/tui/src/tools/AgentTool/agentToolHandoff.ts +114 -0
  242. package/tui/src/tools/AgentTool/agentToolPartialResult.ts +16 -0
  243. package/tui/src/tools/AgentTool/agentToolProgress.ts +32 -0
  244. package/tui/src/tools/AgentTool/agentToolResolver.ts +161 -0
  245. package/tui/src/tools/AgentTool/agentToolResult.ts +163 -0
  246. package/tui/src/tools/AgentTool/agentToolUtils.ts +14 -686
  247. package/tui/src/tools/AgentTool/asyncAgentLifecycle.ts +208 -0
  248. package/tui/src/tools/AgentTool/asyncLifecycle.ts +153 -0
  249. package/tui/src/tools/AgentTool/backgroundedCompletion.ts +126 -0
  250. package/tui/src/tools/AgentTool/backgroundedLifecycle.ts +174 -0
  251. package/tui/src/tools/AgentTool/foregroundBackground.ts +83 -0
  252. package/tui/src/tools/AgentTool/foregroundDrain.tsx +133 -0
  253. package/tui/src/tools/AgentTool/foregroundFinalize.ts +98 -0
  254. package/tui/src/tools/AgentTool/foregroundLifecycle.tsx +237 -0
  255. package/tui/src/tools/AgentTool/foregroundProgress.tsx +169 -0
  256. package/tui/src/tools/AgentTool/foregroundTask.ts +89 -0
  257. package/tui/src/tools/AgentTool/forkSubagent.ts +1 -12
  258. package/tui/src/tools/AgentTool/forkSubagentGate.ts +34 -0
  259. package/tui/src/tools/AgentTool/launchRouting.ts +203 -0
  260. package/tui/src/tools/AgentTool/lifecycle.ts +244 -0
  261. package/tui/src/tools/AgentTool/mcpRouting.ts +73 -0
  262. package/tui/src/tools/AgentTool/orchestrationSupport.ts +70 -0
  263. package/tui/src/tools/AgentTool/permissions.ts +39 -0
  264. package/tui/src/tools/AgentTool/promptSetup.ts +181 -0
  265. package/tui/src/tools/AgentTool/remoteRouting.ts +62 -0
  266. package/tui/src/tools/AgentTool/resultMapping.ts +116 -0
  267. package/tui/src/tools/AgentTool/resumeAgent.ts +39 -107
  268. package/tui/src/tools/AgentTool/resumeAgentHelpers.ts +140 -0
  269. package/tui/src/tools/AgentTool/runAgent.ts +1 -1
  270. package/tui/src/tools/AgentTool/runtimeConfig.ts +57 -0
  271. package/tui/src/tools/AgentTool/schemas.ts +196 -0
  272. package/tui/src/tools/AgentTool/sourceVerificationPropagation.ts +263 -0
  273. package/tui/src/tools/AgentTool/worktreeLifecycle.ts +105 -0
  274. package/tui/src/tools/AskUserQuestionTool/AskUserQuestionTool.tsx +174 -202
  275. package/tui/src/tools/BashTool/BashTool.tsx +71 -1072
  276. package/tui/src/tools/BashTool/bashCommandHelpers.ts +12 -12
  277. package/tui/src/tools/BashTool/bashPermissions/astPreflight.ts +173 -0
  278. package/tui/src/tools/BashTool/bashPermissions/classifierChecks.ts +199 -0
  279. package/tui/src/tools/BashTool/bashPermissions/compoundGuards.ts +53 -0
  280. package/tui/src/tools/BashTool/bashPermissions/constants.ts +99 -0
  281. package/tui/src/tools/BashTool/bashPermissions/index.ts +38 -0
  282. package/tui/src/tools/BashTool/bashPermissions/legacyMisparsing.ts +62 -0
  283. package/tui/src/tools/BashTool/bashPermissions/main.ts +135 -0
  284. package/tui/src/tools/BashTool/bashPermissions/normalizedCommands.ts +33 -0
  285. package/tui/src/tools/BashTool/bashPermissions/operatorFlow.ts +98 -0
  286. package/tui/src/tools/BashTool/bashPermissions/permissionChecks.ts +200 -0
  287. package/tui/src/tools/BashTool/bashPermissions/prefixSuggestions.ts +88 -0
  288. package/tui/src/tools/BashTool/bashPermissions/promptClassifierRules.ts +125 -0
  289. package/tui/src/tools/BashTool/bashPermissions/ruleDelegates.ts +19 -0
  290. package/tui/src/tools/BashTool/bashPermissions/ruleMatching.ts +145 -0
  291. package/tui/src/tools/BashTool/bashPermissions/sandboxAutoAllow.ts +75 -0
  292. package/tui/src/tools/BashTool/bashPermissions/subcommandFlow.ts +205 -0
  293. package/tui/src/tools/BashTool/bashPermissions/subcommandGuards.ts +73 -0
  294. package/tui/src/tools/BashTool/bashPermissions/subcommandResultHelpers.ts +116 -0
  295. package/tui/src/tools/BashTool/bashPermissions/types.ts +26 -0
  296. package/tui/src/tools/BashTool/bashPermissions/wrapperStripping.ts +139 -0
  297. package/tui/src/tools/BashTool/bashPermissions.ts +26 -2621
  298. package/tui/src/tools/BashTool/call.ts +202 -0
  299. package/tui/src/tools/BashTool/callLoader.ts +35 -0
  300. package/tui/src/tools/BashTool/commandClassification.ts +151 -0
  301. package/tui/src/tools/BashTool/commandClassificationLoader.ts +40 -0
  302. package/tui/src/tools/BashTool/cwdReset.ts +33 -0
  303. package/tui/src/tools/BashTool/lineTruncation.ts +11 -0
  304. package/tui/src/tools/BashTool/modeValidation.ts +13 -1
  305. package/tui/src/tools/BashTool/outputPersistence.ts +42 -0
  306. package/tui/src/tools/BashTool/permissionClassification.ts +66 -0
  307. package/tui/src/tools/BashTool/permissionLoader.ts +44 -0
  308. package/tui/src/tools/BashTool/resultLoader.ts +29 -0
  309. package/tui/src/tools/BashTool/resultMapping.ts +83 -0
  310. package/tui/src/tools/BashTool/sandboxPolicy.ts +79 -0
  311. package/tui/src/tools/BashTool/schemas.ts +65 -0
  312. package/tui/src/tools/BashTool/sedEditExecution.ts +59 -0
  313. package/tui/src/tools/BashTool/shellExecution.tsx +245 -0
  314. package/tui/src/tools/BashTool/shellOutputUtils.ts +85 -0
  315. package/tui/src/tools/BashTool/shellPermissionGauntlet.ts +97 -0
  316. package/tui/src/tools/BashTool/uiLoader.ts +37 -0
  317. package/tui/src/tools/BriefTool/upload.ts +1 -1
  318. package/tui/src/tools/CalculatorTool/parser.ts +2 -2
  319. package/tui/src/tools/DocumentPrimitive/DocumentPrimitive.ts +262 -0
  320. package/tui/src/tools/DocumentPrimitive/dispatchNormalization.ts +270 -0
  321. package/tui/src/tools/DocumentPrimitive/documentDestinationPath.ts +18 -0
  322. package/tui/src/tools/DocumentPrimitive/documentMutationGuard.ts +22 -0
  323. package/tui/src/tools/DocumentPrimitive/documentPatchNormalization.ts +248 -0
  324. package/tui/src/tools/DocumentPrimitive/documentSourceVerification.ts +245 -0
  325. package/tui/src/tools/DocumentPrimitive/documentSourceVerificationFields.ts +103 -0
  326. package/tui/src/tools/DocumentPrimitive/modelVisibleOutput.ts +40 -0
  327. package/tui/src/tools/DocumentPrimitive/prompt.ts +35 -0
  328. package/tui/src/tools/FileEditTool/FileEditTool.ts +9 -507
  329. package/tui/src/tools/FileEditTool/call.ts +228 -0
  330. package/tui/src/tools/FileEditTool/validateInput.ts +196 -0
  331. package/tui/src/tools/FileReadTool/imageProcessor.ts +13 -0
  332. package/tui/src/tools/FileWriteTool/FileWriteTool.ts +7 -300
  333. package/tui/src/tools/FileWriteTool/call.ts +223 -0
  334. package/tui/src/tools/FileWriteTool/validateInput.ts +80 -0
  335. package/tui/src/tools/ListMcpResourcesTool/ListMcpResourcesTool.ts +19 -3
  336. package/tui/src/tools/LookupPrimitive/LookupPrimitive.ts +25 -32
  337. package/tui/src/tools/LookupPrimitive/prompt.ts +0 -2
  338. package/tui/src/tools/MCPTool/trustPolicy.ts +118 -0
  339. package/tui/src/tools/McpAuthTool/McpAuthTool.ts +21 -3
  340. package/tui/src/tools/NotebookEditTool/NotebookEditTool.ts +7 -326
  341. package/tui/src/tools/NotebookEditTool/call.ts +254 -0
  342. package/tui/src/tools/NotebookEditTool/notebookModel.ts +51 -0
  343. package/tui/src/tools/NotebookEditTool/validateInput.ts +142 -0
  344. package/tui/src/tools/PowerShellTool/PowerShellTool.tsx +46 -937
  345. package/tui/src/tools/PowerShellTool/acceptEditsCommandValidation.ts +162 -0
  346. package/tui/src/tools/PowerShellTool/call.ts +179 -0
  347. package/tui/src/tools/PowerShellTool/callLoader.ts +37 -0
  348. package/tui/src/tools/PowerShellTool/commandClassification.ts +86 -0
  349. package/tui/src/tools/PowerShellTool/modeValidation.ts +25 -332
  350. package/tui/src/tools/PowerShellTool/outputPersistence.ts +42 -0
  351. package/tui/src/tools/PowerShellTool/permissionClassification.ts +28 -0
  352. package/tui/src/tools/PowerShellTool/resultLoader.ts +31 -0
  353. package/tui/src/tools/PowerShellTool/resultMapping.ts +75 -0
  354. package/tui/src/tools/PowerShellTool/schemas.ts +40 -0
  355. package/tui/src/tools/PowerShellTool/shellExecution.tsx +258 -0
  356. package/tui/src/tools/PowerShellTool/symlinkModeValidation.ts +44 -0
  357. package/tui/src/tools/PowerShellTool/uiLoader.ts +37 -0
  358. package/tui/src/tools/PowerShellTool/validation.ts +39 -0
  359. package/tui/src/tools/ReadMcpResourceTool/ReadMcpResourceTool.ts +19 -3
  360. package/tui/src/tools/ResolveLocationPrimitive/ResolveLocationPrimitive.ts +1 -11
  361. package/tui/src/tools/ResolveLocationPrimitive/prompt.ts +2 -6
  362. package/tui/src/tools/SkillTool/SkillTool.ts +2 -2
  363. package/tui/src/tools/SubmitPrimitive/SubmitPrimitive.ts +27 -10
  364. package/tui/src/tools/TaskCreateTool/TaskCreateTool.ts +16 -2
  365. package/tui/src/tools/TaskGetTool/TaskGetTool.ts +23 -3
  366. package/tui/src/tools/TaskListTool/TaskListTool.ts +22 -4
  367. package/tui/src/tools/TaskOutputTool/TaskOutputTool.tsx +46 -547
  368. package/tui/src/tools/TaskOutputTool/lookup.ts +216 -0
  369. package/tui/src/tools/TaskOutputTool/render.tsx +257 -0
  370. package/tui/src/tools/TaskOutputTool/schemas.ts +55 -0
  371. package/tui/src/tools/TaskOutputTool/serialization.ts +36 -0
  372. package/tui/src/tools/TaskStopTool/TaskStopTool.ts +10 -0
  373. package/tui/src/tools/TaskUpdateTool/TaskUpdateTool.ts +14 -364
  374. package/tui/src/tools/TaskUpdateTool/completion.ts +62 -0
  375. package/tui/src/tools/TaskUpdateTool/schemas.ts +62 -0
  376. package/tui/src/tools/TaskUpdateTool/serialization.ts +46 -0
  377. package/tui/src/tools/TaskUpdateTool/statusUpdate.ts +247 -0
  378. package/tui/src/tools/TodoWriteTool/TodoWriteTool.ts +21 -2
  379. package/tui/src/tools/ToolSearchTool/ToolSearchTool.ts +21 -302
  380. package/tui/src/tools/ToolSearchTool/ccSupportTools.ts +223 -0
  381. package/tui/src/tools/ToolSearchTool/descriptionCache.ts +50 -0
  382. package/tui/src/tools/ToolSearchTool/keywordSearch.ts +216 -0
  383. package/tui/src/tools/ToolSearchTool/prompt.ts +10 -4
  384. package/tui/src/tools/ToolSearchTool/resultMapping.ts +30 -0
  385. package/tui/src/tools/ToolSearchTool/schemas.ts +30 -0
  386. package/tui/src/tools/ToolSearchTool/searchPool.ts +47 -0
  387. package/tui/src/tools/ToolSearchTool/supportIntentHints.ts +140 -0
  388. package/tui/src/tools/TranslateTool/TranslateTool.ts +1 -1
  389. package/tui/src/tools/VerifyPrimitive/VerifyPrimitive.ts +2 -1
  390. package/tui/src/tools/WebFetchTool/WebFetchTool.ts +43 -138
  391. package/tui/src/tools/WebFetchTool/call.ts +227 -0
  392. package/tui/src/tools/WebFetchTool/resolvedAddressSafety.ts +78 -0
  393. package/tui/src/tools/WebFetchTool/sourceVerification.ts +204 -0
  394. package/tui/src/tools/WebFetchTool/types.ts +23 -0
  395. package/tui/src/tools/WebFetchTool/urlSafety.ts +181 -0
  396. package/tui/src/tools/WebFetchTool/utils.ts +1 -1
  397. package/tui/src/tools/WebSearchTool/UI.tsx +0 -1
  398. package/tui/src/tools/WebSearchTool/WebSearchTool.ts +9 -313
  399. package/tui/src/tools/WebSearchTool/call.ts +33 -0
  400. package/tui/src/tools/WebSearchTool/responseMapping.ts +190 -0
  401. package/tui/src/tools/WebSearchTool/resultBlock.ts +47 -0
  402. package/tui/src/tools/WebSearchTool/schemas.ts +47 -0
  403. package/tui/src/tools/WebSearchTool/toolSchema.ts +12 -0
  404. package/tui/src/tools/WorkspaceToolAdapter/WorkspaceToolAdapter.ts +79 -0
  405. package/tui/src/tools/WorkspaceToolAdapter/allowedRootPolicy.ts +85 -0
  406. package/tui/src/tools/WorkspaceToolAdapter/documentFormatGuards.ts +73 -0
  407. package/tui/src/tools/WorkspaceToolAdapter/inputNormalization.ts +105 -0
  408. package/tui/src/tools/WorkspaceToolAdapter/mcpExposurePolicy.ts +64 -0
  409. package/tui/src/tools/WorkspaceToolAdapter/toolDefFactory.ts +215 -0
  410. package/tui/src/tools/WorkspaceToolAdapter/toolNames.ts +6 -0
  411. package/tui/src/tools/WorkspaceToolAdapter/workspacePolicy.ts +15 -0
  412. package/tui/src/tools/_shared/dispatchPrimitive.ts +6 -6
  413. package/tui/src/tools/_shared/documentChangeToPatch.ts +125 -0
  414. package/tui/src/tools/_shared/documentDispatchArguments.ts +87 -0
  415. package/tui/src/tools/_shared/documentPrimitiveTimeout.ts +13 -0
  416. package/tui/src/tools/_shared/documentToolResultRender.ts +98 -0
  417. package/tui/src/tools/_shared/pendingCallRegistry.ts +1 -6
  418. package/tui/src/tools/_shared/rootPrimitiveInput.ts +1 -0
  419. package/tui/src/tools/_shared/toolChoiceRepair/documentCompletionPatterns.ts +58 -0
  420. package/tui/src/tools/_shared/toolChoiceRepair/documentCompletionPrompt.ts +271 -0
  421. package/tui/src/tools/_shared/toolChoiceRepair/documentRepair.ts +452 -0
  422. package/tui/src/tools/_shared/toolChoiceRepair/messageAccess.ts +80 -0
  423. package/tui/src/tools/_shared/toolChoiceRepair/publicDataRepair.ts +92 -0
  424. package/tui/src/tools/_shared/toolChoiceRepair/supportRepair.ts +135 -0
  425. package/tui/src/tools/_shared/toolChoiceRepair.ts +55 -860
  426. package/tui/src/tools/shared/mockDisclaimer.ts +1 -1
  427. package/tui/src/tools.ts +39 -190
  428. package/tui/src/types/fileSuggestion.ts +4 -26
  429. package/tui/src/types/generated/events_mono/claude_code/v1/claude_code_internal_event.ts +186 -148
  430. package/tui/src/types/generated/events_mono/common/v1/auth.ts +25 -11
  431. package/tui/src/types/generated/events_mono/growthbook/v1/growthbook_experiment_event.ts +47 -30
  432. package/tui/src/types/generated/google/protobuf/timestamp.ts +21 -7
  433. package/tui/src/types/message.ts +80 -102
  434. package/tui/src/types/messageQueueTypes.ts +6 -28
  435. package/tui/src/types/notebook.ts +16 -38
  436. package/tui/src/types/statusLine.ts +4 -26
  437. package/tui/src/types/tools.ts +24 -46
  438. package/tui/src/types/utils.ts +6 -28
  439. package/tui/src/upstreamproxy/relay.ts +7 -3
  440. package/tui/src/upstreamproxy/upstreamproxy.ts +1 -1
  441. package/tui/src/utils/assistantMessageFactories.ts +9 -3
  442. package/tui/src/utils/auth.ts +129 -139
  443. package/tui/src/utils/bash/ast.ts +23 -23
  444. package/tui/src/utils/bash/bashParser.ts +5 -5
  445. package/tui/src/utils/billing.ts +1 -1
  446. package/tui/src/utils/claudeDesktop.ts +4 -4
  447. package/tui/src/utils/collapseReadSearch.ts +3 -3
  448. package/tui/src/utils/cronTasks.ts +1 -1
  449. package/tui/src/utils/execFileNoThrow.ts +1 -1
  450. package/tui/src/utils/filePersistence/types.ts +16 -38
  451. package/tui/src/utils/forkedAgent.ts +1 -1
  452. package/tui/src/utils/gracefulShutdown.ts +4 -4
  453. package/tui/src/utils/heapDumpService.ts +12 -8
  454. package/tui/src/utils/hooks/apiQueryHookHelper.ts +1 -1
  455. package/tui/src/utils/hooks/execPromptHook.ts +1 -1
  456. package/tui/src/utils/hooks/skillImprovement.ts +1 -1
  457. package/tui/src/utils/mcp/dateTimeParser.ts +1 -1
  458. package/tui/src/utils/messages.ts +18 -0
  459. package/tui/src/utils/migrateSessions.ts +3 -3
  460. package/tui/src/utils/model/model.ts +6 -6
  461. package/tui/src/utils/permissions/yoloClassifier.ts +1 -1
  462. package/tui/src/utils/plugins/headlessPluginInstall.ts +1 -1
  463. package/tui/src/utils/plugins/mcpPluginIntegration.ts +1 -1
  464. package/tui/src/utils/plugins/mcpbHandler.ts +1 -1
  465. package/tui/src/utils/plugins/pluginLoader.ts +8 -8
  466. package/tui/src/utils/protectedNamespace.ts +5 -3
  467. package/tui/src/utils/rawJsonToolCall.ts +242 -0
  468. package/tui/src/utils/ripgrep.ts +16 -7
  469. package/tui/src/utils/sessionTitle.ts +1 -1
  470. package/tui/src/utils/settings/permissionValidation.ts +14 -2
  471. package/tui/src/utils/shell/prefix.ts +1 -1
  472. package/tui/src/utils/sideQuery.ts +1 -1
  473. package/tui/src/utils/systemThemeWatcher.ts +13 -3
  474. package/tui/src/utils/teleport.tsx +1 -1
  475. package/uv.lock +426 -45
  476. package/tui/src/services/api/claude.ts +0 -3540
  477. package/tui/src/tools/_shared/directPublicDataGuard.ts +0 -362
  478. package/tui/src/tools/_shared/kmaAnalysisGuard.ts +0 -197
  479. package/tui/src/tools/_shared/kmaAviationGuard.ts +0 -70
  480. package/tui/src/tools/_shared/nmcAedGuard.ts +0 -234
  481. package/tui/src/tools/_shared/protectedCheckGuard.ts +0 -207
  482. package/tui/src/tools/_shared/textToolCallGuard.ts +0 -91
@@ -0,0 +1,384 @@
1
+ import type { AssistantMessage, Message } from '../types/message.js'
2
+ import {
3
+ buildGenericPendingFinalAnswerRepairPromptIfNeeded,
4
+ shouldWithholdGenericPendingFinalAnswer,
5
+ } from '../tools/_shared/toolChoiceRepair/publicDataRepair.js'
6
+ import {
7
+ contentBlocks,
8
+ isUserMessage,
9
+ latestTextUserMessageIndex,
10
+ messageText,
11
+ toolUseBlocks,
12
+ } from './messageGuards.js'
13
+ import {
14
+ buildUnavailableToolRepairPromptIfNeeded,
15
+ } from './unavailableToolRepair.js'
16
+
17
+ export {
18
+ buildUnavailableToolFinalAnswerBlockedText,
19
+ shouldBlockFinalAnswerAfterUnavailableToolRepair,
20
+ } from './unavailableToolRepair.js'
21
+
22
+ const UNSUPPORTED_ROUTE_REPAIR_MARKER = 'Unsupported route answer repair:'
23
+ const ROUTE_REQUEST_RE =
24
+ /(경로|대중교통|길\s*찾|길찾|어떻게\s*가|가는\s*법|환승|route|transit|directions|public\s+transport)/iu
25
+ const ROUTE_LIMITATION_RE =
26
+ /(실시간\s*(경로|대중교통|교통).*(제한|없|지원하지|연결되지)|경로\s*adapter|대중교통\s*adapter|공식.*(지도|교통|앱)|카카오맵|네이버\s*지도)/iu
27
+ const ROUTE_DETAIL_CLAIM_RE =
28
+ /(\d+\s*호선|[0-90-9]+\s*번\s*버스|승차|하차|환승\s*(하면|후|→|->)|요금[^\n.。]*\d|(?:약|대략)?\s*\d+\s*분(?:입니다|정도|소요)?)/iu
29
+ const EXPLICIT_PRIOR_RESULT_REQUEST_RE =
30
+ /(이전|전에|아까|방금|앞서|지난|다시|그\s*(결과|검색|병원|곳|장소|정보)|prior|previous|again)/iu
31
+ const RELATIVE_LOCATION_FOLLOWUP_RE =
32
+ /(주위|주변|우리\s*동네|여기|이\s*근처|현재\s*위치|내\s*위치|가까운|가까이|인근|근방)/iu
33
+ const LOCATION_SCOPED_PUBLIC_DATA_RE =
34
+ /(응급|응급실|야간\s*진료|야간진료|병원|의료|날씨|비\s*(?:와|오|올|내리)|우산|미세먼지|대기질|공기질|emergency|hospital|weather|rain|umbrella|air\s*quality)/iu
35
+ const PENDING_TOOL_ACTION_RE =
36
+ /(조회하겠습니다|찾아보겠습니다|검색해\s*보겠습니다|검색하겠습니다|확인해\s*보겠습니다|확인하겠습니다|찾기\s*위해|조회하기\s*위해|검색하기\s*위해)/iu
37
+ const PENDING_TOOL_ACTION_REPAIR_MARKER = 'Pending tool action repair:'
38
+ const LOCATION_RESULT_KINDS = new Set([
39
+ 'coords',
40
+ 'address',
41
+ 'adm_cd',
42
+ 'poi',
43
+ 'region',
44
+ 'bundle',
45
+ ])
46
+ const SENSITIVE_SCALAR_KEY_RE =
47
+ /(^|[_\-.])(?:id|no|num|number|code|receipt|ref|reference|token|auth|authorization|approval|confirm|confirmation|certificate|serial|registration|payment|tax|amount|fee|price|cost|total|balance|claim|case|application|tracking|invoice|bill|번호|코드|접수|영수|승인|인증|토큰|증명|증서|등록|납부|결제|세금|세액|금액|요금|합계|잔액|청구|사건|신청|추적|송장)(?:$|[_\-.])/iu
48
+ const CODE_LIKE_SCALAR_RE = /^[0-9A-Za-z][0-9A-Za-z._:-]*$/u
49
+
50
+ type ToolResultBlock = {
51
+ readonly type: 'tool_result'
52
+ readonly tool_use_id: string
53
+ readonly content?: unknown
54
+ readonly is_error?: boolean
55
+ }
56
+
57
+ export function buildPublicDataTerminalRepairPrompt(params: {
58
+ readonly messages: readonly Message[]
59
+ readonly candidate: AssistantMessage
60
+ }): string | undefined {
61
+ const unavailableToolRepairPrompt =
62
+ buildUnavailableToolRepairPromptIfNeeded(params)
63
+ if (unavailableToolRepairPrompt !== undefined) {
64
+ return unavailableToolRepairPrompt
65
+ }
66
+ const pendingToolActionPrompt =
67
+ buildPendingToolActionRepairPromptIfNeeded(params)
68
+ if (pendingToolActionPrompt !== undefined) {
69
+ return pendingToolActionPrompt
70
+ }
71
+ if (
72
+ shouldWithholdGenericPendingFinalAnswer({
73
+ messages: params.messages,
74
+ candidate: params.candidate,
75
+ })
76
+ ) {
77
+ return buildGenericPendingFinalAnswerRepairPromptIfNeeded({
78
+ messages: [...params.messages, params.candidate],
79
+ })
80
+ }
81
+ if (shouldWithholdUnsupportedRouteAnswer(params)) {
82
+ return buildUnsupportedRouteRepairPrompt()
83
+ }
84
+ return undefined
85
+ }
86
+
87
+ export function shouldBlockFinalAnswerAfterUnsupportedRouteRepair(params: {
88
+ readonly messages: readonly Message[]
89
+ readonly candidate: AssistantMessage
90
+ }): boolean {
91
+ return hasUnsupportedRouteRepairPromptAfterLatestUser(params.messages) &&
92
+ toolUseBlocks(params.candidate).length === 0
93
+ }
94
+
95
+ export function shouldBlockUnsupportedRouteDetailAnswer(params: {
96
+ readonly messages: readonly Message[]
97
+ readonly candidate: AssistantMessage
98
+ }): boolean {
99
+ if (toolUseBlocks(params.candidate).length > 0) return false
100
+ if (!isLatestUserRouteRequest(params.messages)) return false
101
+ if (!hasOnlyLocationEvidenceAfterLatestUser(params.messages)) return false
102
+ return ROUTE_DETAIL_CLAIM_RE.test(messageText(params.candidate))
103
+ }
104
+
105
+ export function shouldBlockStalePriorToolResultAnswer(params: {
106
+ readonly messages: readonly Message[]
107
+ readonly candidate: AssistantMessage
108
+ }): boolean {
109
+ if (toolUseBlocks(params.candidate).length > 0) return false
110
+ const latestUserIndex = latestTextUserMessageIndex(params.messages)
111
+ if (latestUserIndex < 0) return false
112
+ const latestUser = params.messages[latestUserIndex]
113
+ if (latestUser === undefined) return false
114
+ const latestUserText = messageText(latestUser)
115
+ if (EXPLICIT_PRIOR_RESULT_REQUEST_RE.test(latestUserText)) return false
116
+
117
+ const currentPhrases = successfulToolResultPhrases(
118
+ params.messages.slice(latestUserIndex + 1),
119
+ )
120
+ const currentEvidenceText = [...currentPhrases, latestUserText]
121
+ .map(normalizePhraseText)
122
+ .join('\n')
123
+ const candidateText = normalizePhraseText(messageText(params.candidate))
124
+ if (candidateText.length === 0) return false
125
+
126
+ for (const phrase of successfulToolResultPhrases(
127
+ params.messages.slice(0, latestUserIndex),
128
+ { excludeLocationResults: RELATIVE_LOCATION_FOLLOWUP_RE.test(latestUserText) },
129
+ )) {
130
+ const normalizedPhrase = normalizePhraseText(phrase)
131
+ if (normalizedPhrase.length === 0) continue
132
+ if (currentEvidenceText.includes(normalizedPhrase)) continue
133
+ if (candidateText.includes(normalizedPhrase)) return true
134
+ }
135
+ return false
136
+ }
137
+
138
+ export function buildUnsupportedRouteFinalAnswerBlockedText(): string {
139
+ return [
140
+ '현재 UMMAYA 실행 도구 표면에는 실시간 경로 adapter 결과가 없습니다.',
141
+ '이번 턴에서 확인된 것은 출발지/도착지 위치 결과뿐이므로 환승역, 버스번호, 요금, 소요시간을 단정하지 않습니다.',
142
+ '실시간 이동 경로는 카카오맵, 네이버지도, 부산교통공사 등 공식 교통 채널에서 확인해야 합니다.',
143
+ ].join('\n\n')
144
+ }
145
+
146
+ export function buildStalePriorToolResultFinalAnswerBlockedText(): string {
147
+ return [
148
+ '이번 턴에서 확인되지 않은 이전 도구 결과를 현재 요청의 근거로 재사용하지 않습니다.',
149
+ '현재 답변은 최신 사용자 요청 이후 실행된 tool_result에 근거해야 하며, 이전 검색 결과를 새 위치나 새 조건의 결과처럼 단정할 수 없습니다.',
150
+ '필요한 정보는 해당 위치와 조건에 맞는 등록 adapter 결과를 다시 받은 뒤 안내해야 합니다.',
151
+ ].join('\n\n')
152
+ }
153
+
154
+ function buildPendingToolActionRepairPromptIfNeeded(params: {
155
+ readonly messages: readonly Message[]
156
+ readonly candidate: AssistantMessage
157
+ }): string | undefined {
158
+ if (toolUseBlocks(params.candidate).length > 0) return undefined
159
+ if (hasPendingToolActionRepairPromptAfterLatestUser(params.messages)) {
160
+ return undefined
161
+ }
162
+ const latestUserIndex = latestTextUserMessageIndex(params.messages)
163
+ if (latestUserIndex < 0) return undefined
164
+ const latestUser = params.messages[latestUserIndex]
165
+ if (latestUser === undefined) return undefined
166
+ const latestUserText = messageText(latestUser)
167
+ if (!RELATIVE_LOCATION_FOLLOWUP_RE.test(latestUserText)) return undefined
168
+ if (!LOCATION_SCOPED_PUBLIC_DATA_RE.test(latestUserText)) return undefined
169
+ if (hasSuccessfulToolResultAfter(params.messages, latestUserIndex)) {
170
+ return undefined
171
+ }
172
+ if (!hasLocationEvidenceBefore(params.messages, latestUserIndex)) {
173
+ return undefined
174
+ }
175
+ if (!PENDING_TOOL_ACTION_RE.test(messageText(params.candidate))) {
176
+ return undefined
177
+ }
178
+ return [
179
+ `${PENDING_TOOL_ACTION_REPAIR_MARKER} the assistant ended with a promise to look up current public-service data, but no tool_result exists for the latest citizen request.`,
180
+ 'Use the prior location context only as input context, then call a registered adapter tool now when one is available in the current tool schema.',
181
+ 'If no registered adapter supports the request, write a Korean fail-closed limitation; do not end with 조회하겠습니다, 확인하겠습니다, 검색하겠습니다, or another promise to answer later.',
182
+ ].join(' ')
183
+ }
184
+
185
+ function hasPendingToolActionRepairPromptAfterLatestUser(
186
+ messages: readonly Message[],
187
+ ): boolean {
188
+ const latestUserIndex = latestTextUserMessageIndex(messages)
189
+ if (latestUserIndex < 0) return false
190
+ return messages.slice(latestUserIndex + 1).some(message =>
191
+ messageText(message).includes(PENDING_TOOL_ACTION_REPAIR_MARKER),
192
+ )
193
+ }
194
+
195
+ function shouldWithholdUnsupportedRouteAnswer(params: {
196
+ readonly messages: readonly Message[]
197
+ readonly candidate: AssistantMessage
198
+ }): boolean {
199
+ if (toolUseBlocks(params.candidate).length > 0) return false
200
+ if (hasUnsupportedRouteRepairPromptAfterLatestUser(params.messages)) return false
201
+ if (!isLatestUserRouteRequest(params.messages)) return false
202
+ if (!hasOnlyLocationEvidenceAfterLatestUser(params.messages)) return false
203
+ return !ROUTE_LIMITATION_RE.test(messageText(params.candidate))
204
+ }
205
+
206
+ function buildUnsupportedRouteRepairPrompt(): string {
207
+ return [
208
+ `${UNSUPPORTED_ROUTE_REPAIR_MARKER} successful tool_result evidence only located places; no routing, realtime transit, fare, or directions adapter returned route data.`,
209
+ 'Do not provide transfer stations, bus numbers, fares, travel times, or step-by-step route instructions from general knowledge.',
210
+ 'Write a Korean limitation/handoff answer grounded only in the location tool_results and tell the citizen to verify realtime route details in official transit/map channels.',
211
+ ].join(' ')
212
+ }
213
+
214
+ function isLatestUserRouteRequest(messages: readonly Message[]): boolean {
215
+ const latestUserIndex = latestTextUserMessageIndex(messages)
216
+ if (latestUserIndex < 0) return false
217
+ const latestUser = messages[latestUserIndex]
218
+ return latestUser !== undefined && ROUTE_REQUEST_RE.test(messageText(latestUser))
219
+ }
220
+
221
+ function hasUnsupportedRouteRepairPromptAfterLatestUser(
222
+ messages: readonly Message[],
223
+ ): boolean {
224
+ const latestUserIndex = latestTextUserMessageIndex(messages)
225
+ if (latestUserIndex < 0) return false
226
+ return messages.slice(latestUserIndex + 1).some(message =>
227
+ messageText(message).includes(UNSUPPORTED_ROUTE_REPAIR_MARKER),
228
+ )
229
+ }
230
+
231
+ function hasOnlyLocationEvidenceAfterLatestUser(messages: readonly Message[]): boolean {
232
+ const latestUserIndex = latestTextUserMessageIndex(messages)
233
+ if (latestUserIndex < 0) return false
234
+ const successfulResults = messages
235
+ .slice(latestUserIndex + 1)
236
+ .flatMap(message => isUserMessage(message) ? toolResultBlocks(message) : [])
237
+ .filter(block => block.is_error !== true)
238
+ return successfulResults.length > 0 &&
239
+ successfulResults.every(block => isLocationToolResult(block.content))
240
+ }
241
+
242
+ function hasLocationEvidenceBefore(
243
+ messages: readonly Message[],
244
+ endIndex: number,
245
+ ): boolean {
246
+ return messages.slice(0, endIndex).some(message =>
247
+ isUserMessage(message) &&
248
+ toolResultBlocks(message).some(block =>
249
+ block.is_error !== true && isLocationToolResult(block.content),
250
+ ),
251
+ )
252
+ }
253
+
254
+ function successfulToolResultPhrases(
255
+ messages: readonly Message[],
256
+ options: { readonly excludeLocationResults?: boolean } = {},
257
+ ): Set<string> {
258
+ const phrases = new Set<string>()
259
+ for (const message of messages) {
260
+ if (!isUserMessage(message)) continue
261
+ for (const block of toolResultBlocks(message)) {
262
+ if (block.is_error === true) continue
263
+ if (options.excludeLocationResults === true && isLocationToolResult(block.content)) {
264
+ continue
265
+ }
266
+ collectSalientPhrases(block.content, phrases)
267
+ }
268
+ }
269
+ return phrases
270
+ }
271
+
272
+ function collectSalientPhrases(
273
+ value: unknown,
274
+ phrases: Set<string>,
275
+ keyHint?: string,
276
+ ): void {
277
+ if (typeof value === 'string') {
278
+ const parsed = parseJsonObject(value)
279
+ if (parsed !== undefined) {
280
+ collectSalientPhrases(parsed, phrases)
281
+ return
282
+ }
283
+ addSalientPhrase(value, phrases, keyHint)
284
+ return
285
+ }
286
+ if (typeof value === 'number') {
287
+ if (Number.isFinite(value)) {
288
+ addSalientPhrase(String(value), phrases, keyHint)
289
+ }
290
+ return
291
+ }
292
+ if (Array.isArray(value)) {
293
+ for (const item of value) collectSalientPhrases(item, phrases, keyHint)
294
+ return
295
+ }
296
+ if (typeof value !== 'object' || value === null) return
297
+ for (const [key, entry] of Object.entries(value)) {
298
+ collectSalientPhrases(entry, phrases, key)
299
+ }
300
+ }
301
+
302
+ function addSalientPhrase(
303
+ value: string,
304
+ phrases: Set<string>,
305
+ keyHint?: string,
306
+ ): void {
307
+ const phrase = normalizePhraseText(value)
308
+ if (
309
+ !isSalientToolResultPhrase(phrase) &&
310
+ !isSensitiveScalarToolResultPhrase(keyHint, phrase)
311
+ ) {
312
+ return
313
+ }
314
+ phrases.add(phrase)
315
+ }
316
+
317
+ function normalizePhraseText(value: string): string {
318
+ return value.replace(/\s+/g, ' ').trim()
319
+ }
320
+
321
+ function isSalientToolResultPhrase(value: string): boolean {
322
+ if (value.length < 3 || value.length > 80) return false
323
+ if (!/[A-Za-z가-힣]/u.test(value)) return false
324
+ if (/^(ok|true|false|null|none|unknown|collection|bundle|coords|address|region|poi|mock_complete)$/iu.test(value)) {
325
+ return false
326
+ }
327
+ return true
328
+ }
329
+
330
+ function isSensitiveScalarToolResultPhrase(
331
+ keyHint: string | undefined,
332
+ value: string,
333
+ ): boolean {
334
+ if (keyHint === undefined) return false
335
+ if (!SENSITIVE_SCALAR_KEY_RE.test(keyHint)) return false
336
+ if (value.length < 3 || value.length > 80) return false
337
+ if (!/[0-9]/u.test(value)) return false
338
+ if (!CODE_LIKE_SCALAR_RE.test(value)) return false
339
+ if (/^(ok|true|false|null|none|unknown|success)$/iu.test(value)) return false
340
+ return true
341
+ }
342
+
343
+ function isLocationToolResult(content: unknown): boolean {
344
+ const parsed = parseJsonObject(content)
345
+ if (parsed === undefined) return false
346
+ const data = parseJsonObject(parsed.data)
347
+ const result = parseJsonObject(parsed.result) ??
348
+ (data !== undefined ? parseJsonObject(data.result) : undefined)
349
+ const kind = result?.kind
350
+ return typeof kind === 'string' && LOCATION_RESULT_KINDS.has(kind)
351
+ }
352
+
353
+ function parseJsonObject(value: unknown): Record<string, unknown> | undefined {
354
+ if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
355
+ return value as Record<string, unknown>
356
+ }
357
+ if (typeof value !== 'string') return undefined
358
+ try {
359
+ const parsed: unknown = JSON.parse(value)
360
+ return typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)
361
+ ? parsed as Record<string, unknown>
362
+ : undefined
363
+ } catch {
364
+ return undefined
365
+ }
366
+ }
367
+
368
+ function hasSuccessfulToolResultAfter(
369
+ messages: readonly Message[],
370
+ startIndex: number,
371
+ ): boolean {
372
+ return messages.slice(startIndex + 1).some(message =>
373
+ isUserMessage(message) &&
374
+ toolResultBlocks(message).some(block => block.is_error !== true),
375
+ )
376
+ }
377
+
378
+ function toolResultBlocks(message: Message): readonly ToolResultBlock[] {
379
+ return contentBlocks(message).filter(
380
+ (block): block is ToolResultBlock =>
381
+ block.type === 'tool_result' &&
382
+ typeof block.tool_use_id === 'string',
383
+ )
384
+ }