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
@@ -1,158 +1,29 @@
1
- import type {
2
- BetaContentBlock,
3
- BetaWebSearchTool20250305,
4
- } from 'src/sdk-compat.js'
5
1
  import { getAPIProvider } from 'src/utils/model/providers.js'
6
2
  import type { PermissionResult } from 'src/utils/permissions/PermissionResult.js'
7
- import { z } from 'zod/v4'
8
- import { getFeatureValue_CACHED_MAY_BE_STALE } from '../../services/analytics/growthbook.js'
9
- // UMMAYA-original: CC queryModelWithStreaming replaced by FriendliAI IPC client.
10
- const queryModelWithStreaming = async (_opts?: unknown): Promise<never> => { throw new Error('not implemented') }
11
3
  import { buildTool, type ToolDef } from '../../Tool.js'
12
- import { lazySchema } from '../../utils/lazySchema.js'
13
- import { logError } from '../../utils/log.js'
14
- import { createUserMessage } from '../../utils/userMessageFactories.js'
15
- import { getMainLoopModel, getSmallFastModel } from '../../utils/model/model.js'
16
- import { jsonParse, jsonStringify } from '../../utils/slowOperations.js'
17
- import { asSystemPrompt } from '../../utils/systemPromptType.js'
4
+ import { getMainLoopModel } from '../../utils/model/model.js'
5
+ import { callWebSearch } from './call.js'
18
6
  import { getWebSearchPrompt, WEB_SEARCH_TOOL_NAME } from './prompt.js'
7
+ import { mapWebSearchResultToToolResultBlockParam } from './resultBlock.js'
19
8
  import {
20
9
  getToolUseSummary,
21
10
  renderToolResultMessage,
22
11
  renderToolUseMessage,
23
12
  renderToolUseProgressMessage,
24
13
  } from './UI.js'
14
+ import type { InputSchema, Output, OutputSchema, SearchResult } from './schemas.js'
15
+ import { inputSchema, outputSchema } from './schemas.js'
25
16
 
26
- const inputSchema = lazySchema(() =>
27
- z.strictObject({
28
- query: z.string().min(2).describe('The search query to use'),
29
- allowed_domains: z
30
- .array(z.string())
31
- .optional()
32
- .describe('Only include search results from these domains'),
33
- blocked_domains: z
34
- .array(z.string())
35
- .optional()
36
- .describe('Never include search results from these domains'),
37
- }),
38
- )
39
- type InputSchema = ReturnType<typeof inputSchema>
40
-
41
- type Input = z.infer<InputSchema>
42
-
43
- const searchResultSchema = lazySchema(() => {
44
- const searchHitSchema = z.object({
45
- title: z.string().describe('The title of the search result'),
46
- url: z.string().describe('The URL of the search result'),
47
- })
48
-
49
- return z.object({
50
- tool_use_id: z.string().describe('ID of the tool use'),
51
- content: z.array(searchHitSchema).describe('Array of search hits'),
52
- })
53
- })
54
-
55
- export type SearchResult = z.infer<ReturnType<typeof searchResultSchema>>
56
-
57
- const outputSchema = lazySchema(() =>
58
- z.object({
59
- query: z.string().describe('The search query that was executed'),
60
- results: z
61
- .array(z.union([searchResultSchema(), z.string()]))
62
- .describe('Search results and/or text commentary from the model'),
63
- durationSeconds: z
64
- .number()
65
- .describe('Time taken to complete the search operation'),
66
- }),
67
- )
68
- type OutputSchema = ReturnType<typeof outputSchema>
69
-
70
- export type Output = z.infer<OutputSchema>
17
+ export type { Output, SearchResult }
71
18
 
72
19
  // Re-export WebSearchProgress from centralized types to break import cycles
73
20
  export type { WebSearchProgress } from '../../types/tools.js'
74
21
 
75
22
  import type { WebSearchProgress } from '../../types/tools.js'
76
23
 
77
- function makeToolSchema(input: Input): BetaWebSearchTool20250305 {
78
- return {
79
- type: 'web_search_20250305',
80
- name: 'web_search',
81
- allowed_domains: input.allowed_domains,
82
- blocked_domains: input.blocked_domains,
83
- max_uses: 8, // Hardcoded to 8 searches maximum
84
- }
85
- }
86
-
87
- function makeOutputFromSearchResponse(
88
- result: BetaContentBlock[],
89
- query: string,
90
- durationSeconds: number,
91
- ): Output {
92
- // The result is a sequence of these blocks:
93
- // - text to start -- always?
94
- // [
95
- // - server_tool_use
96
- // - web_search_tool_result
97
- // - text and citation blocks intermingled
98
- // ]+ (this block repeated for each search)
99
-
100
- const results: (SearchResult | string)[] = []
101
- let textAcc = ''
102
- let inText = true
103
-
104
- for (const block of result) {
105
- if (block.type === 'server_tool_use') {
106
- if (inText) {
107
- inText = false
108
- if (textAcc.trim().length > 0) {
109
- results.push(textAcc.trim())
110
- }
111
- textAcc = ''
112
- }
113
- continue
114
- }
115
-
116
- if (block.type === 'web_search_tool_result') {
117
- // Handle error case - content is a WebSearchToolResultError
118
- if (!Array.isArray(block.content)) {
119
- const errorMessage = `Web search error: ${block.content.error_code}`
120
- logError(new Error(errorMessage))
121
- results.push(errorMessage)
122
- continue
123
- }
124
- // Success case - add results to our collection
125
- const hits = block.content.map(r => ({ title: r.title, url: r.url }))
126
- results.push({
127
- tool_use_id: block.tool_use_id,
128
- content: hits,
129
- })
130
- }
131
-
132
- if (block.type === 'text') {
133
- if (inText) {
134
- textAcc += block.text
135
- } else {
136
- inText = true
137
- textAcc = block.text
138
- }
139
- }
140
- }
141
-
142
- if (textAcc.length) {
143
- results.push(textAcc.trim())
144
- }
145
-
146
- return {
147
- query,
148
- results,
149
- durationSeconds,
150
- }
151
- }
152
-
153
24
  export const WebSearchTool = buildTool({
154
25
  name: WEB_SEARCH_TOOL_NAME,
155
- searchHint: 'search the web for current information',
26
+ searchHint: 'search the web for current information and source evidence',
156
27
  maxResultSizeChars: 100_000,
157
28
  shouldDefer: true,
158
29
  async description(input) {
@@ -253,184 +124,9 @@ export const WebSearchTool = buildTool({
253
124
  return { result: true }
254
125
  },
255
126
  async call(input, context, _canUseTool, _parentMessage, onProgress) {
256
- const startTime = performance.now()
257
- const { query } = input
258
- const userMessage = createUserMessage({
259
- content: 'Perform a web search for the query: ' + query,
260
- })
261
- const toolSchema = makeToolSchema(input)
262
-
263
- const useHaiku = getFeatureValue_CACHED_MAY_BE_STALE(
264
- 'tengu_plum_vx3',
265
- false,
266
- )
267
-
268
- const appState = context.getAppState()
269
- const queryStream = queryModelWithStreaming({
270
- messages: [userMessage],
271
- systemPrompt: asSystemPrompt([
272
- 'You are an assistant for performing a web search tool use',
273
- ]),
274
- thinkingConfig: useHaiku
275
- ? { type: 'disabled' as const }
276
- : context.options.thinkingConfig,
277
- tools: [],
278
- signal: context.abortController.signal,
279
- options: {
280
- getToolPermissionContext: async () => appState.toolPermissionContext,
281
- model: useHaiku ? getSmallFastModel() : context.options.mainLoopModel,
282
- toolChoice: useHaiku ? { type: 'tool', name: 'web_search' } : undefined,
283
- isNonInteractiveSession: context.options.isNonInteractiveSession,
284
- hasAppendSystemPrompt: !!context.options.appendSystemPrompt,
285
- extraToolSchemas: [toolSchema],
286
- querySource: 'web_search_tool',
287
- agents: context.options.agentDefinitions.activeAgents,
288
- mcpTools: [],
289
- agentId: context.agentId,
290
- effortValue: appState.effortValue,
291
- },
292
- })
293
-
294
- const allContentBlocks: BetaContentBlock[] = []
295
- let currentToolUseId = null
296
- let currentToolUseJson = ''
297
- let progressCounter = 0
298
- const toolUseQueries = new Map() // Map of tool_use_id to query
299
-
300
- for await (const event of queryStream) {
301
- if (event.type === 'assistant') {
302
- allContentBlocks.push(...event.message.content)
303
- continue
304
- }
305
-
306
- // Track tool use ID when server_tool_use starts
307
- if (
308
- event.type === 'stream_event' &&
309
- event.event?.type === 'content_block_start'
310
- ) {
311
- const contentBlock = event.event.content_block
312
- if (contentBlock && contentBlock.type === 'server_tool_use') {
313
- currentToolUseId = contentBlock.id
314
- currentToolUseJson = ''
315
- // Note: The ServerToolUseBlock doesn't contain input.query
316
- // The actual query comes through input_json_delta events
317
- continue
318
- }
319
- }
320
-
321
- // Accumulate JSON for current tool use
322
- if (
323
- currentToolUseId &&
324
- event.type === 'stream_event' &&
325
- event.event?.type === 'content_block_delta'
326
- ) {
327
- const delta = event.event.delta
328
- if (delta?.type === 'input_json_delta' && delta.partial_json) {
329
- currentToolUseJson += delta.partial_json
330
-
331
- // Try to extract query from partial JSON for progress updates
332
- try {
333
- // Look for a complete query field
334
- const queryMatch = currentToolUseJson.match(
335
- /"query"\s*:\s*"((?:[^"\\]|\\.)*)"/,
336
- )
337
- if (queryMatch && queryMatch[1]) {
338
- // The regex properly handles escaped characters
339
- const query = jsonParse('"' + queryMatch[1] + '"')
340
-
341
- if (
342
- !toolUseQueries.has(currentToolUseId) ||
343
- toolUseQueries.get(currentToolUseId) !== query
344
- ) {
345
- toolUseQueries.set(currentToolUseId, query)
346
- progressCounter++
347
- if (onProgress) {
348
- onProgress({
349
- toolUseID: `search-progress-${progressCounter}`,
350
- data: {
351
- type: 'query_update',
352
- query,
353
- },
354
- })
355
- }
356
- }
357
- }
358
- } catch {
359
- // Ignore parsing errors for partial JSON
360
- }
361
- }
362
- }
363
-
364
- // Yield progress when search results come in
365
- if (
366
- event.type === 'stream_event' &&
367
- event.event?.type === 'content_block_start'
368
- ) {
369
- const contentBlock = event.event.content_block
370
- if (contentBlock && contentBlock.type === 'web_search_tool_result') {
371
- // Get the actual query that was used for this search
372
- const toolUseId = contentBlock.tool_use_id
373
- const actualQuery = toolUseQueries.get(toolUseId) || query
374
- const content = contentBlock.content
375
-
376
- progressCounter++
377
- if (onProgress) {
378
- onProgress({
379
- toolUseID: toolUseId || `search-progress-${progressCounter}`,
380
- data: {
381
- type: 'search_results_received',
382
- resultCount: Array.isArray(content) ? content.length : 0,
383
- query: actualQuery,
384
- },
385
- })
386
- }
387
- }
388
- }
389
- }
390
-
391
- // Process the final result
392
- const endTime = performance.now()
393
- const durationSeconds = (endTime - startTime) / 1000
394
-
395
- const data = makeOutputFromSearchResponse(
396
- allContentBlocks,
397
- query,
398
- durationSeconds,
399
- )
400
- return { data }
127
+ return callWebSearch(input, context, onProgress)
401
128
  },
402
129
  mapToolResultToToolResultBlockParam(output, toolUseID) {
403
- const { query, results } = output
404
-
405
- let formattedOutput = `Web search results for query: "${query}"\n\n`
406
-
407
- // Process the results array - it can contain both string summaries and search result objects.
408
- // Guard against null/undefined entries that can appear after JSON round-tripping
409
- // (e.g., from compaction or transcript deserialization).
410
- ;(results ?? []).forEach(result => {
411
- if (result == null) {
412
- return
413
- }
414
- if (typeof result === 'string') {
415
- // Text summary
416
- formattedOutput += result + '\n\n'
417
- } else {
418
- // Search result with links
419
- if (result.content?.length > 0) {
420
- formattedOutput += `Links: ${jsonStringify(result.content)}\n\n`
421
- } else {
422
- formattedOutput += 'No links found.\n\n'
423
- }
424
- }
425
- })
426
-
427
- formattedOutput +=
428
- '\nREMINDER: You MUST include the sources above in your response to the user using markdown hyperlinks.'
429
-
430
- return {
431
- tool_use_id: toolUseID,
432
- type: 'tool_result',
433
- content: formattedOutput.trim(),
434
- }
130
+ return mapWebSearchResultToToolResultBlockParam(output, toolUseID)
435
131
  },
436
132
  } satisfies ToolDef<InputSchema, Output, WebSearchProgress>)
@@ -0,0 +1,33 @@
1
+ import type {
2
+ ToolCallProgress,
3
+ ToolResult,
4
+ ToolUseContext,
5
+ } from '../../Tool.js'
6
+ import type { WebSearchProgress } from '../../types/tools.js'
7
+ import type { Input, Output } from './schemas.js'
8
+ import { makeBlockedOutputFromProviderError } from './responseMapping.js'
9
+
10
+ class WebSearchProviderUnavailableError extends Error {
11
+ readonly name = 'WebSearchProviderUnavailableError'
12
+
13
+ constructor() {
14
+ super(
15
+ 'WebSearch is blocked: UMMAYA does not currently expose a policy-approved server-side web search provider for the FriendliAI execution path. Use WebFetch with an explicit public URL or a registered live adapter instead.',
16
+ )
17
+ }
18
+ }
19
+
20
+ export async function callWebSearch(
21
+ input: Input,
22
+ _context: ToolUseContext,
23
+ _onProgress?: ToolCallProgress<WebSearchProgress>,
24
+ ): Promise<ToolResult<Output>> {
25
+ const startTime = performance.now()
26
+ return {
27
+ data: makeBlockedOutputFromProviderError(
28
+ input.query,
29
+ startTime,
30
+ new WebSearchProviderUnavailableError(),
31
+ ),
32
+ }
33
+ }
@@ -0,0 +1,190 @@
1
+ import type { BetaContentBlock } from 'src/sdk-compat.js'
2
+ import { logError } from '../../utils/log.js'
3
+ import { errorMessage } from '../../utils/errors.js'
4
+ import {
5
+ buildSourceEvidence,
6
+ buildSourceVerification,
7
+ redactSourceVerificationText,
8
+ type SourceVerificationEvidence,
9
+ } from '../WebFetchTool/sourceVerification.js'
10
+ import { WEB_SEARCH_TOOL_NAME } from './prompt.js'
11
+ import type { Output, SearchResult } from './schemas.js'
12
+
13
+ type WebSearchResultBlock = {
14
+ readonly type: 'web_search_tool_result'
15
+ readonly tool_use_id: string
16
+ readonly content: unknown
17
+ }
18
+
19
+ type TextBlock = {
20
+ readonly type: 'text'
21
+ readonly text: string
22
+ }
23
+
24
+ type ServerToolUseBlock = {
25
+ readonly type: 'server_tool_use'
26
+ }
27
+
28
+ function isWebSearchResultBlock(
29
+ block: BetaContentBlock,
30
+ ): block is WebSearchResultBlock {
31
+ return block.type === 'web_search_tool_result'
32
+ }
33
+
34
+ function isTextBlock(block: BetaContentBlock): block is TextBlock {
35
+ return block.type === 'text' && 'text' in block && typeof block.text === 'string'
36
+ }
37
+
38
+ function isServerToolUseBlock(
39
+ block: BetaContentBlock,
40
+ ): block is ServerToolUseBlock {
41
+ return block.type === 'server_tool_use'
42
+ }
43
+
44
+ function isSearchHit(value: unknown): value is { readonly title: string; readonly url: string } {
45
+ return (
46
+ typeof value === 'object' &&
47
+ value !== null &&
48
+ 'title' in value &&
49
+ typeof value.title === 'string' &&
50
+ 'url' in value &&
51
+ typeof value.url === 'string'
52
+ )
53
+ }
54
+
55
+ function providerErrorCode(content: unknown): string {
56
+ if (
57
+ typeof content === 'object' &&
58
+ content !== null &&
59
+ 'error_code' in content &&
60
+ typeof content.error_code === 'string'
61
+ ) {
62
+ return content.error_code
63
+ }
64
+ return 'provider_error'
65
+ }
66
+
67
+ function appendSearchResultEvidence(
68
+ block: WebSearchResultBlock,
69
+ results: (SearchResult | string)[],
70
+ evidence: SourceVerificationEvidence[],
71
+ ): void {
72
+ if (!Array.isArray(block.content)) {
73
+ const message = `Web search error: ${providerErrorCode(block.content)}`
74
+ logError(new Error(message))
75
+ results.push(message)
76
+ evidence.push(
77
+ buildSourceEvidence({
78
+ toolId: WEB_SEARCH_TOOL_NAME,
79
+ sourceUrl: null,
80
+ title: 'Provider error',
81
+ blockedOrUsed: 'blocked',
82
+ rawText: message,
83
+ }),
84
+ )
85
+ return
86
+ }
87
+
88
+ const hits = block.content.filter(isSearchHit).map(hit => ({
89
+ title: hit.title,
90
+ url: hit.url,
91
+ }))
92
+ for (const hit of hits) {
93
+ evidence.push(
94
+ buildSourceEvidence({
95
+ toolId: WEB_SEARCH_TOOL_NAME,
96
+ sourceUrl: hit.url,
97
+ title: hit.title,
98
+ blockedOrUsed: 'needs_input',
99
+ rawText: `${hit.title}\n${hit.url}`,
100
+ }),
101
+ )
102
+ }
103
+ results.push({
104
+ tool_use_id: block.tool_use_id,
105
+ content: hits,
106
+ })
107
+ }
108
+
109
+ export function makeOutputFromSearchResponse(
110
+ result: readonly BetaContentBlock[],
111
+ query: string,
112
+ durationSeconds: number,
113
+ ): Output {
114
+ const results: (SearchResult | string)[] = []
115
+ const evidence: SourceVerificationEvidence[] = []
116
+ let textAcc = ''
117
+ let inText = true
118
+
119
+ for (const block of result) {
120
+ if (isServerToolUseBlock(block)) {
121
+ if (inText) {
122
+ inText = false
123
+ if (textAcc.trim().length > 0) {
124
+ results.push(textAcc.trim())
125
+ }
126
+ textAcc = ''
127
+ }
128
+ continue
129
+ }
130
+
131
+ if (isWebSearchResultBlock(block)) {
132
+ appendSearchResultEvidence(block, results, evidence)
133
+ }
134
+
135
+ if (isTextBlock(block)) {
136
+ if (inText) {
137
+ textAcc += block.text
138
+ } else {
139
+ inText = true
140
+ textAcc = block.text
141
+ }
142
+ }
143
+ }
144
+
145
+ if (textAcc.length) {
146
+ results.push(redactSourceVerificationText(textAcc.trim()))
147
+ }
148
+ if (evidence.length === 0) {
149
+ evidence.push(
150
+ buildSourceEvidence({
151
+ toolId: WEB_SEARCH_TOOL_NAME,
152
+ sourceUrl: null,
153
+ title: 'No source URL returned',
154
+ blockedOrUsed: 'needs_input',
155
+ rawText: query,
156
+ }),
157
+ )
158
+ }
159
+
160
+ return {
161
+ query,
162
+ results,
163
+ durationSeconds,
164
+ sourceVerification: buildSourceVerification(evidence),
165
+ }
166
+ }
167
+
168
+ export function makeBlockedOutputFromProviderError(
169
+ query: string,
170
+ startTime: number,
171
+ error: unknown,
172
+ ): Output {
173
+ const message = `Source verification blocked: ${errorMessage(error)}`
174
+ const safeMessage = redactSourceVerificationText(message)
175
+ logError(new Error(message))
176
+ return {
177
+ query,
178
+ results: [safeMessage],
179
+ durationSeconds: (performance.now() - startTime) / 1000,
180
+ sourceVerification: buildSourceVerification([
181
+ buildSourceEvidence({
182
+ toolId: WEB_SEARCH_TOOL_NAME,
183
+ sourceUrl: null,
184
+ title: 'Provider error',
185
+ blockedOrUsed: 'blocked',
186
+ rawText: message,
187
+ }),
188
+ ]),
189
+ }
190
+ }
@@ -0,0 +1,47 @@
1
+ import { jsonStringify } from '../../utils/slowOperations.js'
2
+ import {
3
+ formatSourceVerifiedToolResult,
4
+ redactSourceVerificationText,
5
+ redactSourceVerificationUrl,
6
+ } from '../WebFetchTool/sourceVerification.js'
7
+ import type { Output } from './schemas.js'
8
+
9
+ export function mapWebSearchResultToToolResultBlockParam(
10
+ output: Output,
11
+ toolUseID: string,
12
+ ): {
13
+ readonly tool_use_id: string
14
+ readonly type: 'tool_result'
15
+ readonly content: string
16
+ } {
17
+ const { query, results, sourceVerification } = output
18
+ let formattedOutput = `Web search results for query: "${redactSourceVerificationText(query)}"\n\n`
19
+
20
+ for (const result of results) {
21
+ if (typeof result === 'string') {
22
+ formattedOutput += `${redactSourceVerificationText(result)}\n\n`
23
+ continue
24
+ }
25
+ if (result.content.length > 0) {
26
+ const safeContent = result.content.map(hit => ({
27
+ title: redactSourceVerificationText(hit.title),
28
+ url: redactSourceVerificationUrl(hit.url) ?? 'none',
29
+ }))
30
+ formattedOutput += `Links: ${jsonStringify(safeContent)}\n\n`
31
+ } else {
32
+ formattedOutput += 'No links found.\n\n'
33
+ }
34
+ }
35
+
36
+ formattedOutput +=
37
+ '\nREMINDER: You MUST include the sources above in your response to the user using markdown hyperlinks.'
38
+
39
+ return {
40
+ tool_use_id: toolUseID,
41
+ type: 'tool_result',
42
+ content: formatSourceVerifiedToolResult({
43
+ result: formattedOutput.trim(),
44
+ sourceVerification,
45
+ }),
46
+ }
47
+ }
@@ -0,0 +1,47 @@
1
+ import { z } from 'zod/v4'
2
+ import { lazySchema } from '../../utils/lazySchema.js'
3
+ import { sourceVerificationSchema } from '../WebFetchTool/sourceVerification.js'
4
+
5
+ export const inputSchema = lazySchema(() =>
6
+ z.strictObject({
7
+ query: z.string().min(2).describe('The search query to use'),
8
+ allowed_domains: z
9
+ .array(z.string())
10
+ .optional()
11
+ .describe('Only include search results from these domains'),
12
+ blocked_domains: z
13
+ .array(z.string())
14
+ .optional()
15
+ .describe('Never include search results from these domains'),
16
+ }),
17
+ )
18
+ export type InputSchema = ReturnType<typeof inputSchema>
19
+ export type Input = z.infer<InputSchema>
20
+
21
+ const searchHitSchema = z.object({
22
+ title: z.string().describe('The title of the search result'),
23
+ url: z.string().describe('The URL of the search result'),
24
+ })
25
+
26
+ export const searchResultSchema = lazySchema(() =>
27
+ z.object({
28
+ tool_use_id: z.string().describe('ID of the tool use'),
29
+ content: z.array(searchHitSchema).describe('Array of search hits'),
30
+ }),
31
+ )
32
+ export type SearchResult = z.infer<ReturnType<typeof searchResultSchema>>
33
+
34
+ export const outputSchema = lazySchema(() =>
35
+ z.object({
36
+ query: z.string().describe('The search query that was executed'),
37
+ results: z
38
+ .array(z.union([searchResultSchema(), z.string()]))
39
+ .describe('Search results and/or text commentary from the model'),
40
+ durationSeconds: z
41
+ .number()
42
+ .describe('Time taken to complete the search operation'),
43
+ sourceVerification: sourceVerificationSchema.optional(),
44
+ }),
45
+ )
46
+ export type OutputSchema = ReturnType<typeof outputSchema>
47
+ export type Output = z.infer<OutputSchema>
@@ -0,0 +1,12 @@
1
+ import type { BetaWebSearchTool20250305 } from 'src/sdk-compat.js'
2
+ import type { Input } from './schemas.js'
3
+
4
+ export function makeToolSchema(input: Input): BetaWebSearchTool20250305 {
5
+ return {
6
+ type: 'web_search_20250305',
7
+ name: 'web_search',
8
+ allowed_domains: input.allowed_domains,
9
+ blocked_domains: input.blocked_domains,
10
+ max_uses: 8,
11
+ }
12
+ }