flowent 0.0.7 → 0.0.10

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 (386) hide show
  1. package/README.md +0 -3
  2. package/backend/README.md +0 -3
  3. package/backend/pyproject.toml +2 -8
  4. package/backend/src/flowent/__pycache__/__init__.cpython-313.pyc +0 -0
  5. package/backend/src/flowent/__pycache__/agent.cpython-313.pyc +0 -0
  6. package/backend/src/flowent/__pycache__/cli.cpython-313.pyc +0 -0
  7. package/backend/src/flowent/__pycache__/context.cpython-313.pyc +0 -0
  8. package/backend/src/flowent/__pycache__/llm.cpython-313.pyc +0 -0
  9. package/backend/src/flowent/__pycache__/logging.cpython-313.pyc +0 -0
  10. package/backend/src/flowent/__pycache__/main.cpython-313.pyc +0 -0
  11. package/backend/src/flowent/__pycache__/patch.cpython-313.pyc +0 -0
  12. package/backend/src/flowent/__pycache__/paths.cpython-313.pyc +0 -0
  13. package/backend/src/flowent/__pycache__/sandbox.cpython-313.pyc +0 -0
  14. package/backend/src/flowent/__pycache__/storage.cpython-313.pyc +0 -0
  15. package/backend/src/flowent/__pycache__/tools.cpython-313.pyc +0 -0
  16. package/backend/src/flowent/agent.py +213 -3173
  17. package/backend/src/flowent/cli.py +19 -24
  18. package/backend/src/flowent/context.py +127 -0
  19. package/backend/src/flowent/llm.py +256 -0
  20. package/backend/src/flowent/logging.py +170 -129
  21. package/backend/src/flowent/main.py +321 -70
  22. package/backend/src/flowent/patch.py +182 -0
  23. package/backend/src/flowent/paths.py +11 -0
  24. package/backend/src/flowent/sandbox.py +214 -40
  25. package/backend/src/flowent/static/assets/geist-cyrillic-wght-normal-CHSlOQsW.woff2 +0 -0
  26. package/backend/src/flowent/static/assets/geist-latin-ext-wght-normal-DMtmJ5ZE.woff2 +0 -0
  27. package/backend/src/flowent/static/assets/geist-latin-wght-normal-Dm3htQBi.woff2 +0 -0
  28. package/backend/src/flowent/static/assets/index-C76K95ty.js +81 -0
  29. package/backend/src/flowent/static/assets/index-iUMNKvlU.css +2 -0
  30. package/backend/src/flowent/static/flowent.png +0 -0
  31. package/backend/src/flowent/static/index.html +5 -25
  32. package/backend/src/flowent/storage.py +302 -0
  33. package/backend/src/flowent/tools.py +364 -0
  34. package/backend/tests/__pycache__/test_agent_tools.cpython-313-pytest-9.0.3.pyc +0 -0
  35. package/backend/tests/__pycache__/test_health.cpython-313-pytest-9.0.3.pyc +0 -0
  36. package/backend/tests/__pycache__/test_llm_providers.cpython-313-pytest-9.0.3.pyc +0 -0
  37. package/backend/tests/__pycache__/test_logging.cpython-313-pytest-9.0.3.pyc +0 -0
  38. package/backend/tests/__pycache__/test_persistence.cpython-313-pytest-9.0.3.pyc +0 -0
  39. package/backend/tests/__pycache__/test_workspace_chat.cpython-313-pytest-9.0.3.pyc +0 -0
  40. package/backend/tests/test_agent_tools.py +449 -0
  41. package/backend/tests/test_health.py +12 -0
  42. package/backend/tests/test_llm_providers.py +113 -0
  43. package/backend/tests/test_logging.py +182 -0
  44. package/backend/tests/test_persistence.py +125 -0
  45. package/backend/tests/test_workspace_chat.py +578 -0
  46. package/backend/uv.lock +803 -99
  47. package/dist/frontend/assets/geist-cyrillic-wght-normal-CHSlOQsW.woff2 +0 -0
  48. package/dist/frontend/assets/geist-latin-ext-wght-normal-DMtmJ5ZE.woff2 +0 -0
  49. package/dist/frontend/assets/geist-latin-wght-normal-Dm3htQBi.woff2 +0 -0
  50. package/dist/frontend/assets/index-C76K95ty.js +81 -0
  51. package/dist/frontend/assets/index-iUMNKvlU.css +2 -0
  52. package/dist/frontend/flowent.png +0 -0
  53. package/dist/frontend/index.html +5 -25
  54. package/package.json +1 -2
  55. package/backend/src/flowent/__pycache__/_version.cpython-313.pyc +0 -0
  56. package/backend/src/flowent/__pycache__/access.cpython-313.pyc +0 -0
  57. package/backend/src/flowent/__pycache__/assistant_commands.cpython-313.pyc +0 -0
  58. package/backend/src/flowent/__pycache__/config.cpython-313.pyc +0 -0
  59. package/backend/src/flowent/__pycache__/events.cpython-313.pyc +0 -0
  60. package/backend/src/flowent/__pycache__/graph_runtime.cpython-313.pyc +0 -0
  61. package/backend/src/flowent/__pycache__/graph_service.cpython-313.pyc +0 -0
  62. package/backend/src/flowent/__pycache__/image_assets.cpython-313.pyc +0 -0
  63. package/backend/src/flowent/__pycache__/model_metadata.cpython-313.pyc +0 -0
  64. package/backend/src/flowent/__pycache__/network.cpython-313.pyc +0 -0
  65. package/backend/src/flowent/__pycache__/observability_service.cpython-313.pyc +0 -0
  66. package/backend/src/flowent/__pycache__/registry.cpython-313.pyc +0 -0
  67. package/backend/src/flowent/__pycache__/role_management.cpython-313.pyc +0 -0
  68. package/backend/src/flowent/__pycache__/runtime.cpython-313.pyc +0 -0
  69. package/backend/src/flowent/__pycache__/security.cpython-313.pyc +0 -0
  70. package/backend/src/flowent/__pycache__/settings.cpython-313.pyc +0 -0
  71. package/backend/src/flowent/__pycache__/settings_management.cpython-313.pyc +0 -0
  72. package/backend/src/flowent/__pycache__/state_db.cpython-313.pyc +0 -0
  73. package/backend/src/flowent/__pycache__/workspace_store.cpython-313.pyc +0 -0
  74. package/backend/src/flowent/access.py +0 -247
  75. package/backend/src/flowent/assistant_commands.py +0 -115
  76. package/backend/src/flowent/channels/__init__.py +0 -3
  77. package/backend/src/flowent/channels/__pycache__/__init__.cpython-313.pyc +0 -0
  78. package/backend/src/flowent/channels/__pycache__/telegram.cpython-313.pyc +0 -0
  79. package/backend/src/flowent/channels/telegram.py +0 -615
  80. package/backend/src/flowent/config.py +0 -14
  81. package/backend/src/flowent/dev.py +0 -3
  82. package/backend/src/flowent/events.py +0 -157
  83. package/backend/src/flowent/graph_runtime.py +0 -60
  84. package/backend/src/flowent/graph_service.py +0 -2401
  85. package/backend/src/flowent/image_assets.py +0 -356
  86. package/backend/src/flowent/model_metadata.py +0 -102
  87. package/backend/src/flowent/models/__init__.py +0 -125
  88. package/backend/src/flowent/models/__pycache__/__init__.cpython-313.pyc +0 -0
  89. package/backend/src/flowent/models/__pycache__/agent.cpython-313.pyc +0 -0
  90. package/backend/src/flowent/models/__pycache__/base.cpython-313.pyc +0 -0
  91. package/backend/src/flowent/models/__pycache__/blueprint.cpython-313.pyc +0 -0
  92. package/backend/src/flowent/models/__pycache__/content.cpython-313.pyc +0 -0
  93. package/backend/src/flowent/models/__pycache__/delta.cpython-313.pyc +0 -0
  94. package/backend/src/flowent/models/__pycache__/event.cpython-313.pyc +0 -0
  95. package/backend/src/flowent/models/__pycache__/graph.cpython-313.pyc +0 -0
  96. package/backend/src/flowent/models/__pycache__/history.cpython-313.pyc +0 -0
  97. package/backend/src/flowent/models/__pycache__/llm.cpython-313.pyc +0 -0
  98. package/backend/src/flowent/models/__pycache__/message.cpython-313.pyc +0 -0
  99. package/backend/src/flowent/models/__pycache__/tab.cpython-313.pyc +0 -0
  100. package/backend/src/flowent/models/__pycache__/todo.cpython-313.pyc +0 -0
  101. package/backend/src/flowent/models/agent.py +0 -34
  102. package/backend/src/flowent/models/base.py +0 -24
  103. package/backend/src/flowent/models/blueprint.py +0 -176
  104. package/backend/src/flowent/models/content.py +0 -164
  105. package/backend/src/flowent/models/delta.py +0 -44
  106. package/backend/src/flowent/models/event.py +0 -51
  107. package/backend/src/flowent/models/graph.py +0 -472
  108. package/backend/src/flowent/models/history.py +0 -272
  109. package/backend/src/flowent/models/llm.py +0 -62
  110. package/backend/src/flowent/models/message.py +0 -33
  111. package/backend/src/flowent/models/tab.py +0 -85
  112. package/backend/src/flowent/models/todo.py +0 -10
  113. package/backend/src/flowent/network.py +0 -146
  114. package/backend/src/flowent/observability_service.py +0 -218
  115. package/backend/src/flowent/prompts/__init__.py +0 -67
  116. package/backend/src/flowent/prompts/__pycache__/__init__.cpython-313.pyc +0 -0
  117. package/backend/src/flowent/prompts/__pycache__/common.cpython-313.pyc +0 -0
  118. package/backend/src/flowent/prompts/__pycache__/steward.cpython-313.pyc +0 -0
  119. package/backend/src/flowent/prompts/common.py +0 -250
  120. package/backend/src/flowent/prompts/steward.py +0 -64
  121. package/backend/src/flowent/providers/__init__.py +0 -23
  122. package/backend/src/flowent/providers/__pycache__/__init__.cpython-313.pyc +0 -0
  123. package/backend/src/flowent/providers/__pycache__/anthropic.cpython-313.pyc +0 -0
  124. package/backend/src/flowent/providers/__pycache__/base_url.cpython-313.pyc +0 -0
  125. package/backend/src/flowent/providers/__pycache__/configuration.cpython-313.pyc +0 -0
  126. package/backend/src/flowent/providers/__pycache__/content.cpython-313.pyc +0 -0
  127. package/backend/src/flowent/providers/__pycache__/errors.cpython-313.pyc +0 -0
  128. package/backend/src/flowent/providers/__pycache__/gateway.cpython-313.pyc +0 -0
  129. package/backend/src/flowent/providers/__pycache__/headers.cpython-313.pyc +0 -0
  130. package/backend/src/flowent/providers/__pycache__/management.cpython-313.pyc +0 -0
  131. package/backend/src/flowent/providers/__pycache__/openai.cpython-313.pyc +0 -0
  132. package/backend/src/flowent/providers/__pycache__/openai_responses.cpython-313.pyc +0 -0
  133. package/backend/src/flowent/providers/__pycache__/registry.cpython-313.pyc +0 -0
  134. package/backend/src/flowent/providers/__pycache__/sse.cpython-313.pyc +0 -0
  135. package/backend/src/flowent/providers/__pycache__/thinking.cpython-313.pyc +0 -0
  136. package/backend/src/flowent/providers/anthropic.py +0 -468
  137. package/backend/src/flowent/providers/base_url.py +0 -60
  138. package/backend/src/flowent/providers/configuration.py +0 -189
  139. package/backend/src/flowent/providers/content.py +0 -122
  140. package/backend/src/flowent/providers/errors.py +0 -223
  141. package/backend/src/flowent/providers/gateway.py +0 -169
  142. package/backend/src/flowent/providers/gemini.py +0 -447
  143. package/backend/src/flowent/providers/headers.py +0 -20
  144. package/backend/src/flowent/providers/management.py +0 -96
  145. package/backend/src/flowent/providers/ollama.py +0 -293
  146. package/backend/src/flowent/providers/openai.py +0 -422
  147. package/backend/src/flowent/providers/openai_responses.py +0 -655
  148. package/backend/src/flowent/providers/registry.py +0 -144
  149. package/backend/src/flowent/providers/sse.py +0 -31
  150. package/backend/src/flowent/providers/thinking.py +0 -79
  151. package/backend/src/flowent/registry.py +0 -73
  152. package/backend/src/flowent/role_management.py +0 -270
  153. package/backend/src/flowent/routes/__init__.py +0 -26
  154. package/backend/src/flowent/routes/__pycache__/__init__.cpython-313.pyc +0 -0
  155. package/backend/src/flowent/routes/__pycache__/access.cpython-313.pyc +0 -0
  156. package/backend/src/flowent/routes/__pycache__/assistant.cpython-313.pyc +0 -0
  157. package/backend/src/flowent/routes/__pycache__/image_assets.cpython-313.pyc +0 -0
  158. package/backend/src/flowent/routes/__pycache__/meta.cpython-313.pyc +0 -0
  159. package/backend/src/flowent/routes/__pycache__/nodes.cpython-313.pyc +0 -0
  160. package/backend/src/flowent/routes/__pycache__/prompts.cpython-313.pyc +0 -0
  161. package/backend/src/flowent/routes/__pycache__/providers_route.cpython-313.pyc +0 -0
  162. package/backend/src/flowent/routes/__pycache__/roles.cpython-313.pyc +0 -0
  163. package/backend/src/flowent/routes/__pycache__/settings.cpython-313.pyc +0 -0
  164. package/backend/src/flowent/routes/__pycache__/tabs.cpython-313.pyc +0 -0
  165. package/backend/src/flowent/routes/__pycache__/ws.cpython-313.pyc +0 -0
  166. package/backend/src/flowent/routes/access.py +0 -48
  167. package/backend/src/flowent/routes/assistant.py +0 -158
  168. package/backend/src/flowent/routes/image_assets.py +0 -33
  169. package/backend/src/flowent/routes/meta.py +0 -28
  170. package/backend/src/flowent/routes/nodes.py +0 -423
  171. package/backend/src/flowent/routes/prompts.py +0 -46
  172. package/backend/src/flowent/routes/providers_route.py +0 -365
  173. package/backend/src/flowent/routes/roles.py +0 -207
  174. package/backend/src/flowent/routes/settings.py +0 -379
  175. package/backend/src/flowent/routes/tabs.py +0 -298
  176. package/backend/src/flowent/routes/ws.py +0 -33
  177. package/backend/src/flowent/runtime.py +0 -160
  178. package/backend/src/flowent/security.py +0 -37
  179. package/backend/src/flowent/settings.py +0 -2112
  180. package/backend/src/flowent/settings_management.py +0 -394
  181. package/backend/src/flowent/state_db.py +0 -108
  182. package/backend/src/flowent/static/assets/AssistantPage-BW7XAd9I.js +0 -1
  183. package/backend/src/flowent/static/assets/ChannelsPage-tCJHgt6m.js +0 -1
  184. package/backend/src/flowent/static/assets/PageScaffold-f6g2l7XN.js +0 -1
  185. package/backend/src/flowent/static/assets/PromptsPage-C3Sxn2D7.js +0 -1
  186. package/backend/src/flowent/static/assets/ProvidersPage-BfmdXmNt.js +0 -3
  187. package/backend/src/flowent/static/assets/RolesPage-DET8wO4r.js +0 -1
  188. package/backend/src/flowent/static/assets/SettingsPage-D-g3deMm.js +0 -3
  189. package/backend/src/flowent/static/assets/ToolsPage-CDmtE2g4.js +0 -1
  190. package/backend/src/flowent/static/assets/WorkspacePage-AZsJ0sD0.js +0 -3
  191. package/backend/src/flowent/static/assets/WorkspacePanels-CteCjolX.js +0 -1
  192. package/backend/src/flowent/static/assets/alert-dialog-Duorp_S-.js +0 -1
  193. package/backend/src/flowent/static/assets/dialog-C3ixjGjN.js +0 -1
  194. package/backend/src/flowent/static/assets/elk-worker.min-C9JGDOE-.js +0 -6312
  195. package/backend/src/flowent/static/assets/graph-vendor-CHpVij2M.css +0 -1
  196. package/backend/src/flowent/static/assets/graph-vendor-DRq_-6fV.js +0 -7
  197. package/backend/src/flowent/static/assets/index--o_0fv0N.css +0 -1
  198. package/backend/src/flowent/static/assets/index-C9HuekJm.js +0 -10
  199. package/backend/src/flowent/static/assets/layout.worker-jMHqAFbP.js +0 -24
  200. package/backend/src/flowent/static/assets/markdown-vendor-C9RtvaJh.js +0 -29
  201. package/backend/src/flowent/static/assets/modelParams-DmnF2hwR.js +0 -1
  202. package/backend/src/flowent/static/assets/providerTypes-DT3Ahwl_.js +0 -1
  203. package/backend/src/flowent/static/assets/react-vendor-mEs_JJxa.js +0 -9
  204. package/backend/src/flowent/static/assets/roles-CuRT_chR.js +0 -1
  205. package/backend/src/flowent/static/assets/rolldown-runtime-BYbx6iT9.js +0 -1
  206. package/backend/src/flowent/static/assets/select-DCfeNu-F.js +0 -1
  207. package/backend/src/flowent/static/assets/surface-pWwG5ogx.js +0 -1
  208. package/backend/src/flowent/static/assets/ui-vendor-C5pJa8N7.js +0 -51
  209. package/backend/src/flowent/static/assets/useAppRoute-FgSHBKhV.js +0 -1
  210. package/backend/src/flowent/static/favicon.svg +0 -4
  211. package/backend/src/flowent/tools/__init__.py +0 -176
  212. package/backend/src/flowent/tools/__pycache__/__init__.cpython-313.pyc +0 -0
  213. package/backend/src/flowent/tools/__pycache__/connect.cpython-313.pyc +0 -0
  214. package/backend/src/flowent/tools/__pycache__/contacts.cpython-313.pyc +0 -0
  215. package/backend/src/flowent/tools/__pycache__/create_agent.cpython-313.pyc +0 -0
  216. package/backend/src/flowent/tools/__pycache__/create_tab.cpython-313.pyc +0 -0
  217. package/backend/src/flowent/tools/__pycache__/delete_tab.cpython-313.pyc +0 -0
  218. package/backend/src/flowent/tools/__pycache__/edit.cpython-313.pyc +0 -0
  219. package/backend/src/flowent/tools/__pycache__/exec.cpython-313.pyc +0 -0
  220. package/backend/src/flowent/tools/__pycache__/fetch.cpython-313.pyc +0 -0
  221. package/backend/src/flowent/tools/__pycache__/idle.cpython-313.pyc +0 -0
  222. package/backend/src/flowent/tools/__pycache__/list_roles.cpython-313.pyc +0 -0
  223. package/backend/src/flowent/tools/__pycache__/list_tabs.cpython-313.pyc +0 -0
  224. package/backend/src/flowent/tools/__pycache__/list_tools.cpython-313.pyc +0 -0
  225. package/backend/src/flowent/tools/__pycache__/manage_prompts.cpython-313.pyc +0 -0
  226. package/backend/src/flowent/tools/__pycache__/manage_providers.cpython-313.pyc +0 -0
  227. package/backend/src/flowent/tools/__pycache__/manage_roles.cpython-313.pyc +0 -0
  228. package/backend/src/flowent/tools/__pycache__/manage_settings.cpython-313.pyc +0 -0
  229. package/backend/src/flowent/tools/__pycache__/read.cpython-313.pyc +0 -0
  230. package/backend/src/flowent/tools/__pycache__/send.cpython-313.pyc +0 -0
  231. package/backend/src/flowent/tools/__pycache__/set_permissions.cpython-313.pyc +0 -0
  232. package/backend/src/flowent/tools/__pycache__/sleep.cpython-313.pyc +0 -0
  233. package/backend/src/flowent/tools/__pycache__/todo.cpython-313.pyc +0 -0
  234. package/backend/src/flowent/tools/connect.py +0 -100
  235. package/backend/src/flowent/tools/contacts.py +0 -22
  236. package/backend/src/flowent/tools/create_agent.py +0 -191
  237. package/backend/src/flowent/tools/create_tab.py +0 -61
  238. package/backend/src/flowent/tools/delete_tab.py +0 -39
  239. package/backend/src/flowent/tools/edit.py +0 -142
  240. package/backend/src/flowent/tools/exec.py +0 -118
  241. package/backend/src/flowent/tools/fetch.py +0 -85
  242. package/backend/src/flowent/tools/idle.py +0 -27
  243. package/backend/src/flowent/tools/list_roles.py +0 -68
  244. package/backend/src/flowent/tools/list_tabs.py +0 -100
  245. package/backend/src/flowent/tools/list_tools.py +0 -28
  246. package/backend/src/flowent/tools/manage_prompts.py +0 -102
  247. package/backend/src/flowent/tools/manage_providers.py +0 -220
  248. package/backend/src/flowent/tools/manage_roles.py +0 -275
  249. package/backend/src/flowent/tools/manage_settings.py +0 -326
  250. package/backend/src/flowent/tools/read.py +0 -152
  251. package/backend/src/flowent/tools/send.py +0 -68
  252. package/backend/src/flowent/tools/set_permissions.py +0 -99
  253. package/backend/src/flowent/tools/sleep.py +0 -41
  254. package/backend/src/flowent/tools/todo.py +0 -51
  255. package/backend/src/flowent/workspace_store.py +0 -479
  256. package/backend/tests/__init__.py +0 -0
  257. package/backend/tests/__pycache__/__init__.cpython-313.pyc +0 -0
  258. package/backend/tests/__pycache__/conftest.cpython-313-pytest-9.0.3.pyc +0 -0
  259. package/backend/tests/conftest.py +0 -6
  260. package/backend/tests/integration/api/__pycache__/conftest.cpython-313-pytest-9.0.3.pyc +0 -0
  261. package/backend/tests/integration/api/__pycache__/test_access_api.cpython-313-pytest-9.0.3.pyc +0 -0
  262. package/backend/tests/integration/api/__pycache__/test_assistant_api.cpython-313-pytest-9.0.3.pyc +0 -0
  263. package/backend/tests/integration/api/__pycache__/test_frontend_mounting.cpython-313-pytest-9.0.3.pyc +0 -0
  264. package/backend/tests/integration/api/__pycache__/test_meta_api.cpython-313-pytest-9.0.3.pyc +0 -0
  265. package/backend/tests/integration/api/__pycache__/test_nodes_api.cpython-313-pytest-9.0.3.pyc +0 -0
  266. package/backend/tests/integration/api/__pycache__/test_prompts_api.cpython-313-pytest-9.0.3.pyc +0 -0
  267. package/backend/tests/integration/api/__pycache__/test_roles_api.cpython-313-pytest-9.0.3.pyc +0 -0
  268. package/backend/tests/integration/api/__pycache__/test_tabs_api.cpython-313-pytest-9.0.3.pyc +0 -0
  269. package/backend/tests/integration/api/conftest.py +0 -29
  270. package/backend/tests/integration/api/test_access_api.py +0 -182
  271. package/backend/tests/integration/api/test_assistant_api.py +0 -422
  272. package/backend/tests/integration/api/test_frontend_mounting.py +0 -61
  273. package/backend/tests/integration/api/test_meta_api.py +0 -32
  274. package/backend/tests/integration/api/test_nodes_api.py +0 -787
  275. package/backend/tests/integration/api/test_prompts_api.py +0 -47
  276. package/backend/tests/integration/api/test_roles_api.py +0 -228
  277. package/backend/tests/integration/api/test_tabs_api.py +0 -688
  278. package/backend/tests/unit/__pycache__/test_access.cpython-313-pytest-9.0.3.pyc +0 -0
  279. package/backend/tests/unit/__pycache__/test_cli.cpython-313-pytest-9.0.3.pyc +0 -0
  280. package/backend/tests/unit/__pycache__/test_graph_runtime.cpython-313-pytest-9.0.3.pyc +0 -0
  281. package/backend/tests/unit/__pycache__/test_network.cpython-313-pytest-9.0.3.pyc +0 -0
  282. package/backend/tests/unit/__pycache__/test_state_sqlite_storage.cpython-313-pytest-9.0.3.pyc +0 -0
  283. package/backend/tests/unit/__pycache__/test_workspace_store.cpython-313-pytest-9.0.3.pyc +0 -0
  284. package/backend/tests/unit/agent/__pycache__/test_agent_public_api.cpython-313-pytest-9.0.3.pyc +0 -0
  285. package/backend/tests/unit/agent/__pycache__/test_agent_runtime.cpython-313-pytest-9.0.3.pyc +0 -0
  286. package/backend/tests/unit/agent/test_agent_public_api.py +0 -822
  287. package/backend/tests/unit/agent/test_agent_runtime.py +0 -3088
  288. package/backend/tests/unit/channels/__pycache__/test_telegram_channel.cpython-313-pytest-9.0.3.pyc +0 -0
  289. package/backend/tests/unit/channels/test_telegram_channel.py +0 -552
  290. package/backend/tests/unit/logging/__pycache__/test_logging.cpython-313-pytest-9.0.3.pyc +0 -0
  291. package/backend/tests/unit/logging/test_logging.py +0 -132
  292. package/backend/tests/unit/prompts/__pycache__/test_prompts.cpython-313-pytest-9.0.3.pyc +0 -0
  293. package/backend/tests/unit/prompts/test_prompts.py +0 -570
  294. package/backend/tests/unit/providers/__pycache__/test_anthropic_provider.cpython-313-pytest-9.0.3.pyc +0 -0
  295. package/backend/tests/unit/providers/__pycache__/test_errors.cpython-313-pytest-9.0.3.pyc +0 -0
  296. package/backend/tests/unit/providers/__pycache__/test_extract_delta_parts.cpython-313-pytest-9.0.3.pyc +0 -0
  297. package/backend/tests/unit/providers/__pycache__/test_openai_provider.cpython-313-pytest-9.0.3.pyc +0 -0
  298. package/backend/tests/unit/providers/__pycache__/test_openai_responses.cpython-313-pytest-9.0.3.pyc +0 -0
  299. package/backend/tests/unit/providers/__pycache__/test_provider_gateway.cpython-313-pytest-9.0.3.pyc +0 -0
  300. package/backend/tests/unit/providers/__pycache__/test_think_tag_parser.cpython-313-pytest-9.0.3.pyc +0 -0
  301. package/backend/tests/unit/providers/test_anthropic_provider.py +0 -185
  302. package/backend/tests/unit/providers/test_errors.py +0 -68
  303. package/backend/tests/unit/providers/test_extract_delta_parts.py +0 -22
  304. package/backend/tests/unit/providers/test_openai_provider.py +0 -139
  305. package/backend/tests/unit/providers/test_openai_responses.py +0 -402
  306. package/backend/tests/unit/providers/test_provider_gateway.py +0 -359
  307. package/backend/tests/unit/providers/test_think_tag_parser.py +0 -36
  308. package/backend/tests/unit/routes/__pycache__/test_prompts_routes.cpython-313-pytest-9.0.3.pyc +0 -0
  309. package/backend/tests/unit/routes/__pycache__/test_providers_route.cpython-313-pytest-9.0.3.pyc +0 -0
  310. package/backend/tests/unit/routes/__pycache__/test_roles_routes.cpython-313-pytest-9.0.3.pyc +0 -0
  311. package/backend/tests/unit/routes/__pycache__/test_settings_routes.cpython-313-pytest-9.0.3.pyc +0 -0
  312. package/backend/tests/unit/routes/test_prompts_routes.py +0 -82
  313. package/backend/tests/unit/routes/test_providers_route.py +0 -370
  314. package/backend/tests/unit/routes/test_roles_routes.py +0 -539
  315. package/backend/tests/unit/routes/test_settings_routes.py +0 -1123
  316. package/backend/tests/unit/runtime/__pycache__/test_bootstrap_runtime.cpython-313-pytest-9.0.3.pyc +0 -0
  317. package/backend/tests/unit/runtime/test_bootstrap_runtime.py +0 -1002
  318. package/backend/tests/unit/sandbox/__pycache__/test_sandbox_tools.cpython-313-pytest-9.0.3.pyc +0 -0
  319. package/backend/tests/unit/sandbox/test_sandbox_tools.py +0 -78
  320. package/backend/tests/unit/security/__pycache__/test_security.cpython-313-pytest-9.0.3.pyc +0 -0
  321. package/backend/tests/unit/security/test_security.py +0 -124
  322. package/backend/tests/unit/settings/__pycache__/test_settings_roles.cpython-313-pytest-9.0.3.pyc +0 -0
  323. package/backend/tests/unit/settings/test_settings_roles.py +0 -703
  324. package/backend/tests/unit/test_access.py +0 -45
  325. package/backend/tests/unit/test_cli.py +0 -102
  326. package/backend/tests/unit/test_graph_runtime.py +0 -72
  327. package/backend/tests/unit/test_network.py +0 -51
  328. package/backend/tests/unit/test_state_sqlite_storage.py +0 -87
  329. package/backend/tests/unit/test_workspace_store.py +0 -228
  330. package/backend/tests/unit/tools/__pycache__/test_connect_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  331. package/backend/tests/unit/tools/__pycache__/test_create_agent_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  332. package/backend/tests/unit/tools/__pycache__/test_delete_tab_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  333. package/backend/tests/unit/tools/__pycache__/test_edit_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  334. package/backend/tests/unit/tools/__pycache__/test_exec_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  335. package/backend/tests/unit/tools/__pycache__/test_fetch_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  336. package/backend/tests/unit/tools/__pycache__/test_manage_prompts_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  337. package/backend/tests/unit/tools/__pycache__/test_manage_providers_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  338. package/backend/tests/unit/tools/__pycache__/test_manage_roles_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  339. package/backend/tests/unit/tools/__pycache__/test_manage_settings_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  340. package/backend/tests/unit/tools/__pycache__/test_read_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  341. package/backend/tests/unit/tools/__pycache__/test_set_permissions_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  342. package/backend/tests/unit/tools/__pycache__/test_todo_tool.cpython-313-pytest-9.0.3.pyc +0 -0
  343. package/backend/tests/unit/tools/__pycache__/test_tool_registry.cpython-313-pytest-9.0.3.pyc +0 -0
  344. package/backend/tests/unit/tools/test_connect_tool.py +0 -228
  345. package/backend/tests/unit/tools/test_create_agent_tool.py +0 -404
  346. package/backend/tests/unit/tools/test_delete_tab_tool.py +0 -116
  347. package/backend/tests/unit/tools/test_edit_tool.py +0 -115
  348. package/backend/tests/unit/tools/test_exec_tool.py +0 -81
  349. package/backend/tests/unit/tools/test_fetch_tool.py +0 -65
  350. package/backend/tests/unit/tools/test_manage_prompts_tool.py +0 -92
  351. package/backend/tests/unit/tools/test_manage_providers_tool.py +0 -460
  352. package/backend/tests/unit/tools/test_manage_roles_tool.py +0 -411
  353. package/backend/tests/unit/tools/test_manage_settings_tool.py +0 -611
  354. package/backend/tests/unit/tools/test_read_tool.py +0 -33
  355. package/backend/tests/unit/tools/test_set_permissions_tool.py +0 -595
  356. package/backend/tests/unit/tools/test_todo_tool.py +0 -37
  357. package/backend/tests/unit/tools/test_tool_registry.py +0 -199
  358. package/dist/frontend/assets/AssistantPage-BW7XAd9I.js +0 -1
  359. package/dist/frontend/assets/ChannelsPage-tCJHgt6m.js +0 -1
  360. package/dist/frontend/assets/PageScaffold-f6g2l7XN.js +0 -1
  361. package/dist/frontend/assets/PromptsPage-C3Sxn2D7.js +0 -1
  362. package/dist/frontend/assets/ProvidersPage-BfmdXmNt.js +0 -3
  363. package/dist/frontend/assets/RolesPage-DET8wO4r.js +0 -1
  364. package/dist/frontend/assets/SettingsPage-D-g3deMm.js +0 -3
  365. package/dist/frontend/assets/ToolsPage-CDmtE2g4.js +0 -1
  366. package/dist/frontend/assets/WorkspacePage-AZsJ0sD0.js +0 -3
  367. package/dist/frontend/assets/WorkspacePanels-CteCjolX.js +0 -1
  368. package/dist/frontend/assets/alert-dialog-Duorp_S-.js +0 -1
  369. package/dist/frontend/assets/dialog-C3ixjGjN.js +0 -1
  370. package/dist/frontend/assets/elk-worker.min-C9JGDOE-.js +0 -6312
  371. package/dist/frontend/assets/graph-vendor-CHpVij2M.css +0 -1
  372. package/dist/frontend/assets/graph-vendor-DRq_-6fV.js +0 -7
  373. package/dist/frontend/assets/index--o_0fv0N.css +0 -1
  374. package/dist/frontend/assets/index-C9HuekJm.js +0 -10
  375. package/dist/frontend/assets/layout.worker-jMHqAFbP.js +0 -24
  376. package/dist/frontend/assets/markdown-vendor-C9RtvaJh.js +0 -29
  377. package/dist/frontend/assets/modelParams-DmnF2hwR.js +0 -1
  378. package/dist/frontend/assets/providerTypes-DT3Ahwl_.js +0 -1
  379. package/dist/frontend/assets/react-vendor-mEs_JJxa.js +0 -9
  380. package/dist/frontend/assets/roles-CuRT_chR.js +0 -1
  381. package/dist/frontend/assets/rolldown-runtime-BYbx6iT9.js +0 -1
  382. package/dist/frontend/assets/select-DCfeNu-F.js +0 -1
  383. package/dist/frontend/assets/surface-pWwG5ogx.js +0 -1
  384. package/dist/frontend/assets/ui-vendor-C5pJa8N7.js +0 -51
  385. package/dist/frontend/assets/useAppRoute-FgSHBKhV.js +0 -1
  386. package/dist/frontend/favicon.svg +0 -4
@@ -1,199 +0,0 @@
1
- from flowent.agent import Agent
2
- from flowent.models import NodeConfig, NodeType
3
- from flowent.tools import build_tool_registry
4
-
5
-
6
- def test_empty_tools_list_grants_minimum_tools():
7
- agent = Agent(NodeConfig(node_type=NodeType.AGENT, tools=[]))
8
-
9
- tools = build_tool_registry().get_tools_for_agent(agent)
10
-
11
- assert [tool.name for tool in tools] == [
12
- "idle",
13
- "sleep",
14
- "todo",
15
- "contacts",
16
- "send",
17
- ]
18
-
19
-
20
- def test_tool_registry_merges_explicit_allow_list_with_minimum_tools():
21
- agent = Agent(NodeConfig(node_type=NodeType.AGENT, tools=["idle", "todo"]))
22
-
23
- tools = build_tool_registry().get_tools_for_agent(agent)
24
-
25
- assert [tool.name for tool in tools] == [
26
- "idle",
27
- "sleep",
28
- "todo",
29
- "contacts",
30
- "send",
31
- ]
32
-
33
-
34
- def test_tool_registry_registers_management_and_workflow_tools():
35
- tool_names = [tool.name for tool in build_tool_registry().list_tools()]
36
-
37
- assert "create_workflow" in tool_names
38
- assert "delete_workflow" in tool_names
39
- assert "set_permissions" in tool_names
40
- assert "create_agent" in tool_names
41
- assert "connect" in tool_names
42
- assert "send" in tool_names
43
- assert "list_workflows" in tool_names
44
- assert "manage_providers" in tool_names
45
- assert "manage_roles" in tool_names
46
- assert "manage_settings" in tool_names
47
- assert "manage_prompts" in tool_names
48
-
49
-
50
- def test_tool_registry_grants_workflow_graph_tools_when_explicitly_allowed():
51
- agent = Agent(
52
- NodeConfig(
53
- node_type=NodeType.ASSISTANT,
54
- tools=[
55
- "create_workflow",
56
- "delete_workflow",
57
- "create_agent",
58
- "connect",
59
- "list_workflows",
60
- ],
61
- )
62
- )
63
-
64
- tools = build_tool_registry().get_tools_for_agent(agent)
65
-
66
- assert [tool.name for tool in tools] == [
67
- "idle",
68
- "sleep",
69
- "todo",
70
- "contacts",
71
- "send",
72
- "create_workflow",
73
- "delete_workflow",
74
- "create_agent",
75
- "connect",
76
- "list_workflows",
77
- ]
78
-
79
-
80
- def test_tool_registry_filters_assistant_only_tools_for_workflow_nodes():
81
- agent = Agent(
82
- NodeConfig(
83
- node_type=NodeType.AGENT,
84
- role_name="Conductor",
85
- tools=[
86
- "create_workflow",
87
- "delete_workflow",
88
- "set_permissions",
89
- "create_agent",
90
- "connect",
91
- "list_workflows",
92
- "manage_settings",
93
- ],
94
- )
95
- )
96
-
97
- tools = build_tool_registry().get_tools_for_agent(agent)
98
-
99
- assert [tool.name for tool in tools] == [
100
- "idle",
101
- "sleep",
102
- "todo",
103
- "contacts",
104
- "send",
105
- "set_permissions",
106
- "create_agent",
107
- "connect",
108
- ]
109
-
110
-
111
- def test_tool_registry_ignores_mcp_prefixed_tools_for_workflow_nodes():
112
- agent = Agent(
113
- NodeConfig(
114
- node_type=NodeType.AGENT,
115
- role_name="Worker",
116
- tools=[
117
- "mcp__external__search_notes",
118
- "mcp__external__lookup",
119
- ],
120
- )
121
- )
122
-
123
- tools = build_tool_registry().get_tools_for_agent(agent)
124
-
125
- assert "mcp__external__search_notes" not in {tool.name for tool in tools}
126
- assert "mcp__external__lookup" not in {tool.name for tool in tools}
127
-
128
-
129
- def test_tool_registry_ignores_mcp_prefixed_tools_for_assistant():
130
- agent = Agent(
131
- NodeConfig(
132
- node_type=NodeType.ASSISTANT,
133
- tools=[
134
- "mcp__external__summarize",
135
- "mcp__external__lookup",
136
- ],
137
- )
138
- )
139
-
140
- tools = build_tool_registry().get_tools_for_agent(agent)
141
-
142
- assert "mcp__external__summarize" not in {tool.name for tool in tools}
143
- assert "mcp__external__lookup" not in {tool.name for tool in tools}
144
-
145
-
146
- def test_build_tools_for_role_filters_mcp_prefixed_tools(monkeypatch):
147
- from flowent.graph_service import build_tools_for_role
148
- from flowent.settings import RoleConfig, Settings
149
-
150
- monkeypatch.setattr(
151
- "flowent.settings.get_settings",
152
- lambda: Settings(
153
- roles=[
154
- RoleConfig(
155
- name="Worker",
156
- system_prompt="Do work.",
157
- included_tools=["mcp__external__search_notes", "read"],
158
- )
159
- ]
160
- ),
161
- )
162
-
163
- tools = build_tools_for_role(
164
- "Worker",
165
- requested_tools=[
166
- "mcp__external__lookup",
167
- "mcp__external__summarize",
168
- "mcp__external__classify",
169
- "mcp__external__search_notes",
170
- ],
171
- )
172
-
173
- assert "mcp__external__lookup" not in tools
174
- assert "mcp__external__summarize" not in tools
175
- assert "mcp__external__classify" not in tools
176
- assert "mcp__external__search_notes" not in tools
177
-
178
-
179
- def test_list_agent_visible_tool_descriptors_excludes_external_tools():
180
- from flowent.tools import list_agent_visible_tool_descriptors
181
-
182
- tool_names = {
183
- descriptor["name"] for descriptor in list_agent_visible_tool_descriptors()
184
- }
185
-
186
- assert all(not tool_name.startswith("mcp__") for tool_name in tool_names)
187
-
188
-
189
- def test_tool_registry_shows_management_tools_in_agent_visible_list():
190
- visible_tool_names = {
191
- tool.name for tool in build_tool_registry().list_tools(agent_visible_only=True)
192
- }
193
-
194
- assert "manage_providers" in visible_tool_names
195
- assert "manage_roles" in visible_tool_names
196
- assert "manage_settings" in visible_tool_names
197
- assert "manage_prompts" in visible_tool_names
198
- assert "set_permissions" in visible_tool_names
199
- assert "send" in visible_tool_names
@@ -1 +0,0 @@
1
- import{a as e}from"./rolldown-runtime-BYbx6iT9.js";import{d as t,l as n}from"./graph-vendor-DRq_-6fV.js";import{q as r}from"./ui-vendor-C5pJa8N7.js";import{A as i,C as a,D as o,E as s,M as c,N as l,O as u,S as d,T as ee,_ as te,b as ne,g as re,h as ie,j as ae,k as oe,m as f,t as p,v as se,w as ce,x as m,y as le}from"./WorkspacePanels-CteCjolX.js";import{A as h,K as g,M as ue,U as de,Y as _,ft as v,g as y,h as fe,j as b,m as pe,p as me,q as he,ut as x}from"./index-C9HuekJm.js";async function ge(e){return _(`/api/assistant/message`,{method:`POST`,body:e,errorMessage:`Failed to send Assistant message`})}async function _e(e){return _(`/api/assistant/messages/${e}/retry`,{method:`POST`,errorMessage:`Failed to retry Assistant message`})}var S=e(t(),1);function C(e){for(let t of e.values())if(t.node_type===`assistant`)return t;return null}function ve(e){return C(e)?.id??null}var w=`assistant`;function ye(){return s(w)}function be(e){return o(w,e)}function xe(e){ee(w,e)}function T(e={}){let{bottomInset:t=0}=e,{agents:n}=y(),{connected:i}=pe(),{agentHistories:o,clearAgentHistory:s,clearHistorySnapshot:c,historyInvalidatedAt:ee,historyClearedAt:ae,historySnapshots:p,streamingDeltas:_}=fe(),{activeToolCalls:v}=me(),[x,C]=(0,S.useState)(null),[w,T]=(0,S.useState)(0),[E,D]=(0,S.useState)(``),[O,k]=(0,S.useState)([]),[A,j]=(0,S.useState)(null),[Se,Ce]=(0,S.useState)(!1),[we,Te]=(0,S.useState)(null),[M,Ee]=(0,S.useState)(!1),[N,P]=(0,S.useState)([]),[F,I]=(0,S.useState)(null),De=(0,S.useRef)(null),Oe=(0,S.useRef)(!0),ke=(0,S.useRef)([]),L=(0,S.useRef)(null),R=(0,S.useRef)(!1),z=(0,S.useMemo)(()=>ve(n),[n]),B=(0,S.useMemo)(()=>z?n.get(z)??null:null,[n,z]),V=B?.capabilities?.input_image??!1,H=z?ae.get(z)??0:0,U=z?ee.get(z)??0:0,W=z?p.get(z)??null:null,Ae=O.some(e=>e.status===`uploading`),je=O.filter(le),G=(0,S.useSyncExternalStore)(be,ye,ye),K=A===null?null:G[A]??null,q=K!==null&&E===K.text&&se(O,K),J=B?.state??x?.state??null,Y=(0,S.useCallback)(async e=>{let t=e.pendingMessageTimestamp??Date.now(),n=ie(e.content,e.parts,t);Ee(!0),P(e=>[...e,n]);try{let n=await ge({content:e.content,parts:e.parts});return n.status===`command_executed`?P(n=>h(n,{content:e.content,timestamp:t})):n.message_id&&P(r=>r.map(r=>r.timestamp===t&&r.content===e.content?{...r,message_id:n.message_id}:r)),xe(e.history),e.restoreDraft&&d(e.restoreDraft.images),!0}catch(n){return P(n=>h(n,{content:e.content,timestamp:t})),e.restoreDraft&&(D(e.restoreDraft.input),k(e.restoreDraft.images),j(e.restoreDraft.historyCursor)),r.error(n instanceof Error?n.message:`Failed to send message`),!1}finally{Ee(!1)}},[]),X=(0,S.useCallback)((e,t)=>{j(t),D(e?.text??``),k(e?a(e):[])},[]),Me=(0,S.useCallback)(e=>{j(null),D(e)},[]);(0,S.useEffect)(()=>{ke.current=O},[O]),(0,S.useEffect)(()=>{L.current=F},[F]),(0,S.useEffect)(()=>()=>{d(ke.current)},[]),(0,S.useEffect)(()=>{H&&(P([]),I(null),C(e=>e&&{...e,history:u(e.history)}),T(Date.now()))},[H]),(0,S.useEffect)(()=>{U&&(P([]),W&&(C(e=>e&&{...e,history:W}),T(Date.now())))},[U,W]),(0,S.useEffect)(()=>{let e=L.current;!e||e.send_failed||e.target_id!==z||J!==e.target_state&&I({...e,target_state:J})},[z,J]),(0,S.useEffect)(()=>{let e=L.current;!e||e.send_failed||!z||e.target_id!==z||J!==`idle`||M||R.current||(R.current=!0,I(null),Y({content:e.content,parts:e.parts??[],history:e.history_entry,pendingMessageTimestamp:e.timestamp}).then(t=>{R.current=!1,t||I({...e,send_failed:!0,target_state:`error`})}).catch(()=>{R.current=!1,I({...e,send_failed:!0,target_state:`error`})}))},[z,J,M,Y]),(0,S.useEffect)(()=>{if(!i||!z){C(null);return}let e=new AbortController,t=!1;return(async()=>{s(z);try{let n=await g(z,e.signal);if(t||!n)return;C(n),T(Date.now()),c(z)}catch{!t&&!e.signal.aborted&&r.error(`Failed to load Assistant history`)}})(),()=>{t=!0,e.abort()}},[H,U,z,s,c,i]);let Z=(0,S.useMemo)(()=>z?oe({history:W??x?.history??[],incremental:o.get(z),deltas:_.get(z),fetchedAt:w||Date.now()}):[],[o,W,x,w,_,z]);(0,S.useEffect)(()=>{if(!z||N.length===0)return;let e=Z.filter(e=>e.type===`ReceivedMessage`&&e.from_id===`human`&&(!!e.content||!!e.message_id||!!e.parts?.length));e.length!==0&&P(t=>e.reduce((e,t)=>h(e,{content:t.content??b(t.parts,t.content),messageId:t.message_id}),t))},[z,Z,N.length]);let Q=(0,S.useMemo)(()=>[...Z,...F?[{...F}]:[],...N.map(e=>({...e}))],[Z,N,F]),$=(0,S.useMemo)(()=>{let e=N.length+ +!!F,t=z?_.get(z)??[]:[],n=i&&(e>0||B?.state===`running`||B?.state===`sleeping`||v.has(z??``)||t.length>0),r=[...Q].map((e,t)=>({item:e,index:t})).reverse().find(({item:e})=>e.type===`PendingHumanMessage`?!0:e.type===`ReceivedMessage`&&e.from_id===`human`&&ue(e.parts,e.content).length>0)?.index,a=r===void 0?[]:Q.slice(r+1),o=a.some(e=>e.type===`AssistantText`&&ue(e.parts,e.content).length>0),s=[...a].reverse().find(e=>e.type===`ToolCall`&&e.streaming===!0),c=(z?v.get(z)??null:null)??s?.tool_name??null;return{running:n,runningHint:n&&r!==void 0&&!o?{label:c?`Running tools...`:`Thinking...`,toolName:c}:null}},[v,z,B?.state,i,N.length,F,_,Q]);(0,S.useLayoutEffect)(()=>{let e=De.current;!e||!Oe.current||(e.scrollTop=e.scrollHeight)},[t,$.runningHint?`${$.runningHint.label}:${$.runningHint.toolName??``}`:``,Q]),(0,S.useLayoutEffect)(()=>{let e=De.current;if(!e||typeof ResizeObserver>`u`)return;let t=new ResizeObserver(()=>{Oe.current&&(e.scrollTop=e.scrollHeight)});return t.observe(e),()=>{t.disconnect()}},[]);let Ne=e=>{Oe.current=ne(e.currentTarget)},Pe=async(e={})=>{let t=E.trim();if(!t&&je.length===0||Ae||M)return;let n=f(t,je),i=E,a=O,o=A,s=Date.now(),c=t||b(n),l={text:i,images:ce(a),timestamp:s},u=e.deferWhenBusy&&z&&L.current?.target_id===z&&(J===`error`||J===`terminated`);if(e.deferWhenBusy&&z&&(J===`running`||J===`sleeping`||u)){I(re({content:c,historyEntry:l,historyScope:`assistant`,parts:n,targetId:z,targetState:J,timestamp:s})),j(null),D(``),k([]),d(a);return}if(J===`terminated`){r.error(`Resolve the current chat before sending`);return}j(null),D(``),k([]),await Y({content:c,parts:n,history:l,pendingMessageTimestamp:s,restoreDraft:{input:i,images:a,historyCursor:o}})},Fe=(0,S.useCallback)(async e=>{if(j(null),!V){r.error(`Current model does not support image input`);return}let t=Array.from(e).filter(e=>e.type.startsWith(`image/`));if(t.length===0)return;let n=await te(t);k(e=>[...e,...n]),await Promise.all(n.map(async(e,n)=>{let i=t[n];if(i)try{let t=await l(i);k(n=>n.map(n=>n.id===e.id?{...n,assetId:t.id,mimeType:t.mime_type,width:typeof t.width==`number`?t.width:n.width,height:typeof t.height==`number`?t.height:n.height,status:`ready`}:n))}catch(t){m(e),k(t=>t.filter(t=>t.id!==e.id)),r.error(t instanceof Error?t.message:`Failed to upload image`)}}))},[V]),Ie=(0,S.useCallback)(e=>{j(null),k(t=>{let n=t.find(t=>t.id===e);return n&&m(n),t.filter(t=>t.id!==e)})},[]),Le=(0,S.useCallback)((e,t)=>{if(G.length===0)return!1;let n=t.start,r=t.end,i=E.length===0&&O.length===0,a=typeof n==`number`&&typeof r==`number`&&n===r&&(n===0||n===E.length);if(!i&&!(K!==null&&q&&a))return!1;if(A===null){if(e!==-1)return!1;let t=G.length-1;return X(G[t]??null,t),!0}if(e===-1){let e=Math.max(A-1,0);return X(G[e]??null,e),!0}if(A>=G.length-1)return X(null,null),!0;let o=A+1;return X(G[o]??null,o),!0},[K,O,A,E,G,q,X]),Re=async()=>{if(!(!z||Se)){Ce(!0);try{await de(z),P([]),I(null),s(z),C(await g(z)),T(Date.now()),c(z)}catch(e){r.error(e instanceof Error?e.message:`Failed to clear assistant chat`)}finally{Ce(!1)}}},ze=(0,S.useCallback)(async()=>{if(z&&!(B?.state!==`running`&&B?.state!==`sleeping`)){await he(z);for(let e=0;e<25;e+=1){let e=await g(z);if(!e)break;if(C(e),T(Date.now()),e.state!==`running`&&e.state!==`sleeping`)return;await new Promise(e=>window.setTimeout(e,120))}throw Error(`Assistant did not stop in time`)}},[z,B?.state]),Be=async e=>{if(!(!z||!e||we)){Te(e);try{try{await ze(),await _e(e)}catch(e){r.error(e instanceof Error?e.message:`Failed to retry Assistant message`);return}s(z);try{let e=await g(z);e&&(C(e),T(Date.now()),c(z))}catch{return}}finally{Te(null)}}},Ve=(0,S.useCallback)(async()=>{if(!z)return;await he(z),P([]),s(z);let e=await g(z);e&&(C(e),T(Date.now()),c(z))},[z,s,c]);return{addImages:Fe,connected:i,draftImages:O,handleKeyDown:e=>{if(e.key===`Tab`&&!e.shiftKey){(E.trim()||je.length>0)&&(e.preventDefault(),Pe({deferWhenBusy:!0}));return}e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),Pe())},hasUploadingImages:Ae,input:E,isBrowsingInputHistory:q,navigateInputHistory:Le,onMessagesScroll:Ne,removeImage:Ie,retryMessage:Be,retryingMessageId:we,scrollRef:De,clearing:Se,sending:M,clearChat:Re,cancelPendingSend:(0,S.useCallback)(e=>{I(t=>t?.id===e?null:t)},[]),sendPendingSend:(0,S.useCallback)(async e=>{let t=L.current;!t||t.id!==e||!z||t.target_id!==z||M||R.current||J===`terminated`||(I(null),await Y({content:t.content,parts:t.parts??[],history:t.history_entry,pendingMessageTimestamp:t.timestamp})||I({...t,send_failed:!0,target_state:`error`}))},[z,J,M,Y]),sendMessage:Pe,setInput:Me,stopAssistant:Ve,supportsInputImage:V,timelineItems:Q,assistantActivity:$}}var E=n();function D({onOpenDetails:e}){let{agents:t}=y(),[n,a]=(0,S.useState)(!1),{height:o,ref:s}=i(),{addImages:l=async()=>{},assistantActivity:u={running:!1,runningHint:null},clearChat:d,cancelPendingSend:ee,clearing:te=!1,connected:ne,draftImages:re=[],handleKeyDown:ie,hasUploadingImages:oe=!1,input:f,isBrowsingInputHistory:p,navigateInputHistory:se,onMessagesScroll:ce,removeImage:m=()=>{},retryMessage:le,retryingMessageId:h,scrollRef:g,sending:ue,sendMessage:de,sendPendingSend:_,setInput:fe,stopAssistant:b,supportsInputImage:pe=!1,timelineItems:me}=T({bottomInset:o}),he=Array.from(t.values()).find(e=>e.node_type===`assistant`)?.role_name??null;return(0,E.jsxs)(`div`,{className:v(`relative flex h-full flex-col overflow-hidden bg-surface-overlay text-foreground`),children:[(0,E.jsx)(`div`,{"aria-hidden":`true`,className:`pointer-events-none absolute inset-0`,style:{background:`var(--shell-surface-sweep)`}}),(0,E.jsx)(`div`,{"aria-hidden":`true`,className:`pointer-events-none absolute inset-x-0 top-0 h-px`,style:{background:`var(--shell-hairline)`}}),(0,E.jsx)(`div`,{"aria-hidden":`true`,className:v(`pointer-events-none absolute inset-0 z-20 border transition-[opacity,border-color,box-shadow] duration-300`,u.running?`animate-pulse shadow-lg shadow-ring/5`:`opacity-0`,u.running&&`border-ring/25 opacity-100 shadow-ring/10`)}),(0,E.jsx)(O,{connected:ne,onClearChat:()=>void d(),onOpenDetails:e,roleName:he,clearing:te}),(0,E.jsxs)(`div`,{className:`relative flex min-h-0 flex-1 flex-col`,children:[(0,E.jsx)(ae,{allowHumanMessageRetry:!0,bottomInset:o,items:me,nodes:t,onRetryHumanMessage:e=>void le(e),onCancelPendingSend:ee,onSendPendingSend:e=>void _(e),onScroll:ce,retryImageInputEnabled:pe,retryingMessageId:h,runningHint:u.runningHint,scrollRef:g}),(0,E.jsx)(`div`,{ref:s,style:{paddingBottom:`calc(10px + env(safe-area-inset-bottom, 0px))`},className:`pointer-events-none absolute inset-x-0 bottom-0 z-10 bg-gradient-to-b from-transparent via-background/70 to-background/95 px-2.5 pt-8`,children:(0,E.jsx)(`div`,{className:`mx-auto w-full max-w-3xl`,children:(0,E.jsx)(c,{busy:u.running,disabled:!f.trim()&&re.length===0||oe||ue,commandsEnabled:!0,images:re,imageInputEnabled:pe,input:f,onAddImages:e=>void l(e),onChange:fe,onNavigateHistory:se,onKeyDown:ie,onRemoveImage:m,onSend:()=>void de(),onStop:()=>{a(!0),b().catch(e=>{r.error(e instanceof Error?e.message:`Failed to stop Assistant`)}).finally(()=>{a(!1)})},overlay:!0,stopping:n,suppressCommandNavigation:p,targetLabel:`Assistant`})})})]})]})}function O({clearing:e,connected:t,onClearChat:n,onOpenDetails:r,roleName:i}){return(0,E.jsxs)(`div`,{className:`relative z-10 flex flex-wrap items-center gap-2.5 border-b border-border px-3.5 py-2.5`,children:[(0,E.jsxs)(`div`,{className:`flex min-w-[220px] flex-1 items-center gap-2`,children:[(0,E.jsx)(`div`,{className:`shrink-0 text-[14px] font-semibold leading-6 text-foreground`,children:`Assistant`}),i?(0,E.jsxs)(`span`,{className:`min-w-0 truncate rounded-full border border-border bg-accent/35 px-2 py-0.5 text-[10px] font-medium leading-4 text-muted-foreground/78`,children:[`Role: `,i]}):null,(0,E.jsx)(k,{connected:t})]}),(0,E.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,E.jsx)(x,{type:`button`,size:`sm`,variant:`outline`,disabled:e,onClick:n,children:e?`Clearing...`:`Clear Chat`}),(0,E.jsx)(x,{type:`button`,size:`sm`,variant:`outline`,disabled:!r,onClick:r,children:`Assistant Details`})]})]})}function k({connected:e}){return(0,E.jsx)(`span`,{className:v(`rounded-full border px-2.5 py-0.5 text-[9px] font-medium transition-colors`,e?`border-graph-status-running/18 bg-graph-status-running/[0.12] text-graph-status-running`:`border-graph-status-idle/18 bg-graph-status-idle/[0.12] text-graph-status-idle`),children:e?`Online`:`Connecting...`})}function A(){let{agents:e}=y(),t=C(e),[n,r]=(0,S.useState)(!1);return(0,E.jsx)(`div`,{className:`flex h-full flex-col min-h-0`,children:n&&t?(0,E.jsx)(`div`,{className:`h-full overflow-hidden p-6`,children:(0,E.jsx)(`div`,{className:`h-full overflow-hidden rounded-xl border border-border bg-surface-overlay/90 shadow-md`,children:(0,E.jsx)(p,{agent:t,onClose:()=>r(!1)})})}):(0,E.jsx)(D,{onOpenDetails:t?()=>r(!0):void 0})})}export{A as AssistantPage};
@@ -1 +0,0 @@
1
- import{a as e}from"./rolldown-runtime-BYbx6iT9.js";import{d as t,l as n}from"./graph-vendor-DRq_-6fV.js";import{en as r,et as i,q as a,ut as o}from"./ui-vendor-C5pJa8N7.js";import{Y as s,r as c,rt as l,ut as u}from"./index-C9HuekJm.js";import{a as d,o as f}from"./surface-pWwG5ogx.js";import{c as p,n as m,r as h,s as g}from"./PageScaffold-f6g2l7XN.js";async function _(){return s(`/api/settings/telegram`,{errorMessage:`Failed to fetch Telegram settings`})}async function v(e){return s(`/api/settings/telegram`,{method:`PATCH`,body:e,errorMessage:`Failed to save Telegram settings`})}async function y(e){return s(`/api/settings/telegram/approve/${e}`,{method:`POST`,errorMessage:`Failed to approve Telegram chat`})}async function b(e){return s(`/api/settings/telegram/pending/${e}`,{method:`DELETE`,errorMessage:`Failed to remove pending Telegram chat`})}async function x(e){return s(`/api/settings/telegram/chat/${e}`,{method:`DELETE`,errorMessage:`Failed to remove Telegram chat`})}var S=e(t(),1);function C(e,t=`auto`){return typeof e!=`number`||!Number.isFinite(e)?null:t===`milliseconds`?e:t===`seconds`?e*1e3:e>0xe8d4a51000?e:e*1e3}function w(e,t={}){let{fallback:n=`Unknown`,format:r,unit:i=`auto`}=t,a=C(e,i);if(a===null)return n;let o=new Date(a);return r?new Intl.DateTimeFormat(void 0,r).format(o):o.toLocaleString()}var T=n();function E(e){return e?w(e,{fallback:`—`,unit:`seconds`}):`—`}function D(e){return e.display_name.trim()?e.display_name.trim():e.username?.trim()?`@${e.username.trim()}`:`Unknown chat`}function O(){let{data:e,isLoading:t,mutate:n}=p(`telegramSettings`,_),[s,C]=(0,S.useState)(!1),[w,O]=(0,S.useState)(``),[k,A]=(0,S.useState)(!1),j=(0,S.useMemo)(()=>!!e?.bot_token,[e?.bot_token]),M=async()=>{if(e){C(!0);try{let e={};k&&(e.bot_token=w.trim()),n((await v(e)).telegram,!1),O(``),A(!1),a.success(`Telegram settings saved`)}catch{a.error(`Failed to save Telegram settings`)}finally{C(!1)}}},N=async e=>{try{n((await y(e)).telegram,!1),a.success(`Telegram chat approved`)}catch{a.error(`Failed to approve Telegram chat`)}},P=async e=>{try{n((await b(e)).telegram,!1),a.success(`Pending Telegram chat removed`)}catch{a.error(`Failed to remove pending Telegram chat`)}},F=async e=>{try{n((await x(e)).telegram,!1),a.success(`Approved Telegram chat removed`)}catch{a.error(`Failed to remove approved Telegram chat`)}};return t||!e?(0,T.jsx)(c,{label:`Loading channels...`,textClassName:`text-[13px]`}):(0,T.jsx)(m,{children:(0,T.jsx)(`div`,{className:`h-full min-h-0 overflow-y-auto pr-2 scrollbar-none pt-6`,children:(0,T.jsxs)(`div`,{className:`mx-auto max-w-[680px] pb-10`,children:[(0,T.jsx)(h,{title:`Channels`}),(0,T.jsxs)(g,{className:`mt-6 space-y-8`,children:[(0,T.jsxs)(`div`,{className:`flex items-start justify-between gap-4`,children:[(0,T.jsx)(`div`,{children:(0,T.jsx)(`h2`,{className:`text-lg font-medium text-foreground`,children:`Telegram`})}),(0,T.jsx)(f,{tone:j?`running`:`idle`,children:j?`Configured`:`Not configured`})]}),(0,T.jsxs)(`section`,{children:[(0,T.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3`,children:[(0,T.jsx)(`label`,{className:`text-[13px] font-medium text-foreground/80`,children:`Bot Token`}),(0,T.jsx)(f,{tone:j?`running`:`idle`,children:j?`Saved`:`Missing`})]}),(0,T.jsxs)(`div`,{className:`mt-3`,children:[(0,T.jsx)(l,{value:w,onChange:e=>{O(e.target.value),A(!0)},placeholder:e.bot_token||`Enter Telegram bot token`,mono:!0,showLabel:`Show Telegram bot token`,hideLabel:`Hide Telegram bot token`}),j&&!k?(0,T.jsx)(`p`,{className:`mt-2 text-[11px] text-muted-foreground`,children:`Leave empty to keep the current token.`}):null]})]}),(0,T.jsxs)(`section`,{className:`border-t border-border pt-8`,children:[(0,T.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3`,children:[(0,T.jsx)(`label`,{className:`text-[13px] font-medium text-foreground/80`,children:`Pending Private Chats`}),(0,T.jsxs)(f,{tone:`muted`,className:`px-2 py-0.5`,children:[e.pending_chats.length,` waiting`]})]}),e.pending_chats.length===0?(0,T.jsx)(`p`,{className:`mt-4 text-[13px] text-muted-foreground`,children:`No pending chats.`}):(0,T.jsx)(`div`,{className:`mt-4 space-y-2`,children:e.pending_chats.map(e=>(0,T.jsx)(d,{as:`div`,padding:`sm`,className:`px-4 py-3.5 transition-colors hover:bg-accent/20`,children:(0,T.jsxs)(`div`,{className:`flex items-center justify-between gap-4`,children:[(0,T.jsxs)(`div`,{className:`min-w-0`,children:[(0,T.jsx)(`p`,{className:`text-[13px] font-medium text-foreground`,children:D(e)}),(0,T.jsxs)(`div`,{className:`mt-1 flex items-center gap-3 text-[11px] text-muted-foreground`,children:[(0,T.jsxs)(`span`,{className:`font-mono`,children:[`ID: `,e.chat_id]}),e.username?(0,T.jsxs)(`span`,{children:[`@`,e.username]}):null,(0,T.jsxs)(`span`,{children:[`First seen: `,E(e.first_seen_at)]})]})]}),(0,T.jsxs)(`div`,{className:`flex shrink-0 items-center gap-1.5`,children:[(0,T.jsxs)(u,{type:`button`,variant:`outline`,size:`xs`,onClick:()=>void N(e.chat_id),children:[(0,T.jsx)(r,{className:`size-3.5`}),`Approve`]}),(0,T.jsx)(u,{type:`button`,variant:`ghost`,size:`icon-xs`,onClick:()=>void P(e.chat_id),className:`text-muted-foreground hover:bg-destructive/10 hover:text-destructive`,children:(0,T.jsx)(i,{className:`size-3.5`})})]})]})},e.chat_id))})]}),(0,T.jsxs)(`section`,{className:`border-t border-border pt-8`,children:[(0,T.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3`,children:[(0,T.jsx)(`label`,{className:`text-[13px] font-medium text-foreground/80`,children:`Approved Private Chats`}),(0,T.jsxs)(f,{tone:`muted`,className:`px-2 py-0.5`,children:[e.approved_chats.length,` active`]})]}),e.approved_chats.length===0?(0,T.jsx)(`p`,{className:`mt-4 text-[13px] text-muted-foreground`,children:`No approved chats yet.`}):(0,T.jsx)(`div`,{className:`mt-4 space-y-2`,children:e.approved_chats.map(e=>(0,T.jsx)(d,{as:`div`,padding:`sm`,className:`group px-4 py-3.5 transition-colors hover:bg-accent/20`,children:(0,T.jsxs)(`div`,{className:`flex items-center justify-between gap-4`,children:[(0,T.jsxs)(`div`,{className:`min-w-0`,children:[(0,T.jsx)(`p`,{className:`text-[13px] font-medium text-foreground`,children:D(e)}),(0,T.jsxs)(`div`,{className:`mt-1 flex items-center gap-3 text-[11px] text-muted-foreground`,children:[(0,T.jsxs)(`span`,{className:`font-mono`,children:[`ID: `,e.chat_id]}),e.username?(0,T.jsxs)(`span`,{children:[`@`,e.username]}):null,(0,T.jsxs)(`span`,{children:[`Approved: `,E(e.approved_at)]})]})]}),(0,T.jsx)(u,{type:`button`,variant:`ghost`,size:`icon-xs`,onClick:()=>void F(e.chat_id),className:`shrink-0 text-muted-foreground opacity-0 transition-all hover:bg-destructive/10 hover:text-destructive group-hover:opacity-100 focus:opacity-100`,children:(0,T.jsx)(i,{className:`size-3.5`})})]})},e.chat_id))})]}),(0,T.jsx)(`div`,{className:`flex justify-end border-t border-border pt-6`,children:(0,T.jsxs)(u,{type:`button`,size:`sm`,onClick:()=>void M(),disabled:s,className:`text-[13px]`,children:[(0,T.jsx)(o,{className:`size-4`}),s?`Saving...`:`Save Changes`]})})]})]})})})}export{O as ChannelsPage};
@@ -1 +0,0 @@
1
- import{a as e}from"./rolldown-runtime-BYbx6iT9.js";import{c as t,d as n,l as r}from"./graph-vendor-DRq_-6fV.js";import{Ft as i}from"./ui-vendor-C5pJa8N7.js";import{a,ft as o,i as s,o as c,s as l,ut as u}from"./index-C9HuekJm.js";import{a as d}from"./surface-pWwG5ogx.js";var f=e(n(),1),p=t(),m=Object.prototype.hasOwnProperty;function h(e,t){var n,r;if(e===t)return!0;if(e&&t&&(n=e.constructor)===t.constructor){if(n===Date)return e.getTime()===t.getTime();if(n===RegExp)return e.toString()===t.toString();if(n===Array){if((r=e.length)===t.length)for(;r--&&h(e[r],t[r]););return r===-1}if(!n||typeof e==`object`){for(n in r=0,e)if(m.call(e,n)&&++r&&!m.call(t,n)||!(n in t)||!h(e[n],t[n]))return!1;return Object.keys(t).length===r}}return e!==e&&t!==t}var g=new WeakMap,_=()=>{},v=void 0,y=Object,b=e=>e===v,x=e=>typeof e==`function`,S=(e,t)=>({...e,...t}),ee=e=>x(e.then),C={},w={},T=`undefined`,E=typeof window!=T,D=typeof document!=T,O=E&&`Deno`in window,k=()=>E&&typeof window.requestAnimationFrame!=T,te=(e,t)=>{let n=g.get(e);return[()=>!b(t)&&e.get(t)||C,r=>{if(!b(t)){let i=e.get(t);t in w||(w[t]=i),n[5](t,S(i,r),i||C)}},n[6],()=>!b(t)&&t in w?w[t]:!b(t)&&e.get(t)||C]},A=!0,j=()=>A,[M,N]=E&&window.addEventListener?[window.addEventListener.bind(window),window.removeEventListener.bind(window)]:[_,_],P=()=>{let e=D&&document.visibilityState;return b(e)||e!==`hidden`},ne=e=>(D&&document.addEventListener(`visibilitychange`,e),M(`focus`,e),()=>{D&&document.removeEventListener(`visibilitychange`,e),N(`focus`,e)}),re=e=>{let t=()=>{A=!0,e()},n=()=>{A=!1};return M(`online`,t),M(`offline`,n),()=>{N(`online`,t),N(`offline`,n)}},ie={isOnline:j,isVisible:P},F={initFocus:ne,initReconnect:re},ae=!f.useId,I=!E||O,oe=e=>k()?window.requestAnimationFrame(e):setTimeout(e,1),L=I?f.useEffect:f.useLayoutEffect,R=typeof navigator<`u`&&navigator.connection,z=!I&&R&&([`slow-2g`,`2g`].includes(R.effectiveType)||R.saveData),B=new WeakMap,se=e=>y.prototype.toString.call(e),V=(e,t)=>e===`[object ${t}]`,ce=0,H=e=>{let t=typeof e,n=se(e),r=V(n,`Date`),i=V(n,`RegExp`),a=V(n,`Object`),o,s;if(y(e)===e&&!r&&!i){if(o=B.get(e),o)return o;if(o=++ce+`~`,B.set(e,o),Array.isArray(e)){for(o=`@`,s=0;s<e.length;s++)o+=H(e[s])+`,`;B.set(e,o)}if(a){o=`#`;let t=y.keys(e).sort();for(;!b(s=t.pop());)b(e[s])||(o+=s+`:`+H(e[s])+`,`);B.set(e,o)}}else o=r?e.toJSON():t==`symbol`?e.toString():t==`string`?JSON.stringify(e):``+e;return o},le=e=>{if(x(e))try{e=e()}catch{e=``}let t=e;return e=typeof e==`string`?e:(Array.isArray(e)?e.length:e)?H(e):``,[e,t]},U=0,ue=()=>++U;async function de(...e){let[t,n,r,i]=e,a=S({populateCache:!0,throwOnError:!0},typeof i==`boolean`?{revalidate:i}:i||{}),o=a.populateCache,s=a.rollbackOnError,c=a.optimisticData,l=e=>typeof s==`function`?s(e):s!==!1,u=a.throwOnError;if(x(n)){let e=n,r=[],i=t.keys();for(let n of i)!/^\$(inf|sub)\$/.test(n)&&e(t.get(n)._k)&&r.push(n);return Promise.all(r.map(d))}return d(n);async function d(n){let[i]=le(n);if(!i)return;let[s,d]=te(t,i),[f,p,m,h]=g.get(t),_=()=>{let e=f[i];return(x(a.revalidate)?a.revalidate(s().data,n):a.revalidate!==!1)&&(delete m[i],delete h[i],e&&e[0])?e[0](2).then(()=>s().data):s().data};if(e.length<3)return _();let y=r,S,C=!1,w=ue();p[i]=[w,0];let T=!b(c),E=s(),D=E.data,O=E._c,k=b(O)?D:O;if(T&&(c=x(c)?c(k,D):c,d({data:c,_c:k})),x(y))try{y=y(k)}catch(e){S=e,C=!0}if(y&&ee(y))if(y=await y.catch(e=>{S=e,C=!0}),w!==p[i][0]){if(C)throw S;return y}else C&&T&&l(S)&&(o=!0,d({data:k,_c:v}));if(o&&(C||(x(o)?d({data:o(y,k),error:v,_c:v}):d({data:y,error:v,_c:v}))),p[i][1]=ue(),Promise.resolve(_()).then(()=>{d({_c:v})}),C){if(u)throw S;return}return y}}var W=(e,t)=>{for(let n in e)e[n][0]&&e[n][0](t)},G=(e,t)=>{if(!g.has(e)){let n=S(F,t),r=Object.create(null),i=de.bind(v,e),a=_,o=Object.create(null),s=(e,t)=>{let n=o[e]||[];return o[e]=n,n.push(t),()=>n.splice(n.indexOf(t),1)},c=(t,n,r)=>{e.set(t,n);let i=o[t];if(i)for(let e of i)e(n,r)},l=()=>{if(!g.has(e)&&(g.set(e,[r,Object.create(null),Object.create(null),Object.create(null),i,c,s]),!I)){let t=n.initFocus(setTimeout.bind(v,W.bind(v,r,0))),i=n.initReconnect(setTimeout.bind(v,W.bind(v,r,1)));a=()=>{t&&t(),i&&i(),g.delete(e)}}};return l(),[e,i,l,a]}return[e,g.get(e)[4]]},K=(e,t,n,r,i)=>{let a=n.errorRetryCount,o=i.retryCount,s=~~((Math.random()+.5)*(1<<(o<8?o:8)))*n.errorRetryInterval;!b(a)&&o>a||setTimeout(r,s,i)},q=h,[J,fe]=G(new Map),Y=S({onLoadingSlow:_,onSuccess:_,onError:_,onErrorRetry:K,onDiscarded:_,revalidateOnFocus:!0,revalidateOnReconnect:!0,revalidateIfStale:!0,shouldRetryOnError:!0,errorRetryInterval:z?1e4:5e3,focusThrottleInterval:5*1e3,dedupingInterval:2*1e3,loadingTimeout:z?5e3:3e3,compare:q,isPaused:()=>!1,cache:J,mutate:fe,fallback:{}},ie),X=(e,t)=>{let n=S(e,t);if(t){let{use:r,fallback:i}=e,{use:a,fallback:o}=t;r&&a&&(n.use=r.concat(a)),i&&o&&(n.fallback=S(i,o))}return n},Z=(0,f.createContext)({}),pe=e=>{let{value:t}=e,n=(0,f.useContext)(Z),r=x(t),i=(0,f.useMemo)(()=>r?t(n):t,[r,n,t]),a=(0,f.useMemo)(()=>r?i:X(n,i),[r,n,i]),o=i&&i.provider,s=(0,f.useRef)(v);o&&!s.current&&(s.current=G(o(a.cache||J),i));let c=s.current;return c&&(a.cache=c[0],a.mutate=c[1]),L(()=>{if(c)return c[2]&&c[2](),c[3]},[]),(0,f.createElement)(Z.Provider,S(e,{value:a}))},Q=E&&window.__SWR_DEVTOOLS_USE__,me=Q?window.__SWR_DEVTOOLS_USE__:[],he=()=>{Q&&(window.__SWR_DEVTOOLS_REACT__=f.default)},ge=e=>x(e[1])?[e[0],e[1],e[2]||{}]:[e[0],null,(e[1]===null?e[2]:e[1])||{}],_e=()=>{let e=(0,f.useContext)(Z);return(0,f.useMemo)(()=>S(Y,e),[e])},ve=me.concat(e=>(t,n,r)=>e(t,n&&((...e)=>{let[r]=le(t),[,,,i]=g.get(J);if(r.startsWith(`$inf$`))return n(...e);let a=i[r];return b(a)?n(...e):(delete i[r],a)}),r)),ye=e=>function(...t){let n=_e(),[r,i,a]=ge(t),o=X(n,a),s=e,{use:c}=o,l=(c||[]).concat(ve);for(let e=l.length;e--;)s=l[e](s);return s(r,i||o.fetcher||null,o)},be=(e,t,n)=>{let r=t[e]||(t[e]=[]);return r.push(n),()=>{let e=r.indexOf(n);e>=0&&(r[e]=r[r.length-1],r.pop())}};he();var xe=f.use||(e=>{switch(e.status){case`pending`:throw e;case`fulfilled`:return e.value;case`rejected`:throw e.reason;default:throw e.status=`pending`,e.then(t=>{e.status=`fulfilled`,e.value=t},t=>{e.status=`rejected`,e.reason=t}),e}}),Se={dedupe:!0},Ce=Promise.resolve(v),we=()=>_,Te=(e,t,n)=>{let{cache:r,compare:i,suspense:a,fallbackData:o,revalidateOnMount:s,revalidateIfStale:c,refreshInterval:l,refreshWhenHidden:u,refreshWhenOffline:d,keepPreviousData:m,strictServerPrefetchWarning:h}=n,[_,y,C,w]=g.get(r),[T,E]=le(e),D=(0,f.useRef)(!1),O=(0,f.useRef)(!1),k=(0,f.useRef)(T),A=(0,f.useRef)(t),j=(0,f.useRef)(n),M=()=>j.current,N=()=>M().isVisible()&&M().isOnline(),[P,ne,re,ie]=te(r,T),F=(0,f.useRef)({}).current,R=b(o)?b(n.fallback)?v:n.fallback[T]:o,z=(e,t)=>{for(let n in F){let r=n;if(r===`data`){if(!i(e[r],t[r])&&(!b(e[r])||!i(K,t[r])))return!1}else if(t[r]!==e[r])return!1}return!0},B=!D.current,se=(0,f.useMemo)(()=>{let e=P(),n=ie(),r=e=>{let n=S(e);return delete n._k,!(!T||!t||M().isPaused())&&(B&&!b(s)?s:b(b(R)?n.data:R)||c)?{isValidating:!0,isLoading:!0,...n}:n},i=r(e),a=e===n?i:r(n),o=i;return[()=>{let e=r(P());return z(e,o)?(o.data=e.data,o.isLoading=e.isLoading,o.isValidating=e.isValidating,o.error=e.error,o):(o=e,e)},()=>a]},[r,T]),V=(0,p.useSyncExternalStore)((0,f.useCallback)(e=>re(T,(t,n)=>{z(n,t)||e()}),[r,T]),se[0],se[1]),ce=_[T]&&_[T].length>0,H=V.data,U=b(H)?R&&ee(R)?xe(R):R:H,W=V.error,G=(0,f.useRef)(U),K=m?b(H)?b(G.current)?U:G.current:H:U,q=T&&b(U),J=(0,f.useRef)(null);!I&&(0,p.useSyncExternalStore)(we,()=>(J.current=!1,J),()=>(J.current=!0,J));let fe=J.current;h&&fe&&!a&&q&&console.warn(`Missing pre-initiated data for serialized key "${T}" during server-side rendering. Data fetching should be initiated on the server and provided to SWR via fallback data. You can set "strictServerPrefetchWarning: false" to disable this warning.`);let Y=!T||!t||M().isPaused()||ce&&!b(W)?!1:B&&!b(s)?s:a?b(U)?!1:c:b(U)||c,X=B&&Y,Z=b(V.isValidating)?X:V.isValidating,pe=b(V.isLoading)?X:V.isLoading,Q=(0,f.useCallback)(async e=>{let t=A.current;if(!T||!t||O.current||M().isPaused())return!1;let r,a,o=!0,s=e||{},c=!C[T]||!s.dedupe,l=()=>ae?!O.current&&T===k.current&&D.current:T===k.current,u={isValidating:!1,isLoading:!1},d=()=>{ne(u)},f=()=>{let e=C[T];e&&e[1]===a&&delete C[T]},p={isValidating:!0};b(P().data)&&(p.isLoading=!0);try{if(c&&(ne(p),n.loadingTimeout&&b(P().data)&&setTimeout(()=>{o&&l()&&M().onLoadingSlow(T,n)},n.loadingTimeout),C[T]=[t(E),ue()]),[r,a]=C[T],r=await r,c&&setTimeout(f,n.dedupingInterval),!C[T]||C[T][1]!==a)return c&&l()&&M().onDiscarded(T),!1;u.error=v;let e=y[T];if(!b(e)&&(a<=e[0]||a<=e[1]||e[1]===0))return d(),c&&l()&&M().onDiscarded(T),!1;let s=P().data;u.data=i(s,r)?s:r,c&&l()&&M().onSuccess(r,T,n)}catch(e){f();let t=M(),{shouldRetryOnError:n}=t;t.isPaused()||(u.error=e,c&&l()&&(t.onError(e,T,t),(n===!0||x(n)&&n(e))&&(!M().revalidateOnFocus||!M().revalidateOnReconnect||N())&&t.onErrorRetry(e,T,t,e=>{let t=_[T];t&&t[0]&&t[0](3,e)},{retryCount:(s.retryCount||0)+1,dedupe:!0})))}return o=!1,d(),!0},[T,r]),me=(0,f.useCallback)((...e)=>de(r,k.current,...e),[]);if(L(()=>{A.current=t,j.current=n,b(H)||(G.current=H)}),L(()=>{if(!T)return;let e=Q.bind(v,Se),t=0;M().revalidateOnFocus&&(t=Date.now()+M().focusThrottleInterval);let n=be(T,_,(n,r={})=>{if(n==0){let n=Date.now();M().revalidateOnFocus&&n>t&&N()&&(t=n+M().focusThrottleInterval,e())}else if(n==1)M().revalidateOnReconnect&&N()&&e();else if(n==2)return Q();else if(n==3)return Q(r)});return O.current=!1,k.current=T,D.current=!0,ne({_k:E}),Y&&(C[T]||(b(U)||I?e():oe(e))),()=>{O.current=!0,n()}},[T]),L(()=>{let e;function t(){let t=x(l)?l(P().data):l;t&&e!==-1&&(e=setTimeout(n,t))}function n(){!P().error&&(u||M().isVisible())&&(d||M().isOnline())?Q(Se).then(t):t()}return t(),()=>{e&&=(clearTimeout(e),-1)}},[l,u,d,T]),(0,f.useDebugValue)(K),a){if(!ae&&I&&q)throw Error(`Fallback data is required when using Suspense in SSR.`);q&&(A.current=t,j.current=n,O.current=!1);let e=w[T];if(xe(!b(e)&&q?me(e):Ce),!b(W)&&q)throw W;let r=q?Q(Se):Ce;!b(K)&&q&&(r.status=`fulfilled`,r.value=!0),xe(r)}return{mutate:me,get data(){return F.data=!0,K},get error(){return F.error=!0,W},get isValidating(){return F.isValidating=!0,Z},get isLoading(){return F.isLoading=!0,pe}}};y.defineProperty(pe,`defaultValue`,{value:Y});var Ee=ye(Te),$=r();function De({children:e,className:t}){return(0,$.jsx)(`div`,{className:o(`flex h-full flex-col min-h-0 overflow-hidden`,t),children:e})}function Oe({children:e,className:t}){return(0,$.jsx)(d,{as:`section`,padding:`md`,className:o(`border-transparent bg-card/[0.18] ring-1 ring-white/[0.04]`,t),children:e})}function ke({actions:e,className:t,hint:n,title:r}){return(0,$.jsx)(`div`,{className:o(`border-b border-border/70 pb-4`,t),children:(0,$.jsxs)(`div`,{className:`flex flex-wrap items-start justify-between gap-4`,children:[(0,$.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[(0,$.jsx)(`h1`,{className:`text-[28px] font-medium tracking-[-0.04em] text-foreground`,children:r}),n?(0,$.jsx)(c,{delayDuration:150,children:(0,$.jsxs)(s,{children:[(0,$.jsx)(l,{asChild:!0,children:(0,$.jsx)(u,{type:`button`,variant:`ghost`,size:`icon-sm`,className:`inline-flex size-7 items-center justify-center rounded-full border border-border/70 bg-card/20 text-muted-foreground transition-colors hover:bg-accent/35 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/50`,"aria-label":`${r} details`,children:(0,$.jsx)(i,{className:`size-3.5`})})}),(0,$.jsx)(a,{side:`right`,className:`max-w-xs px-3 py-2`,children:n})]})}):null]}),e?(0,$.jsx)(`div`,{className:`flex shrink-0 flex-wrap items-center gap-2`,children:e}):null]})})}function Ae({title:e}){return(0,$.jsx)(`div`,{className:`mb-4`,children:(0,$.jsx)(`h2`,{className:`text-[14px] font-medium tracking-tight text-foreground/90`,children:e})})}function je({children:e,className:t,contentClassName:n,separated:r=!1,title:i}){return(0,$.jsxs)(`section`,{className:o(r?`border-t border-border pt-8`:`mb-10`,t),children:[(0,$.jsx)(Ae,{title:i}),(0,$.jsx)(`div`,{className:o(`rounded-xl border border-white/[0.04] bg-card/[0.03] shadow-sm px-5 transition-colors`,n),children:e})]})}function Me({label:e,description:t,children:n,valueClassName:r}){return(0,$.jsxs)(`div`,{className:`flex flex-col gap-2 border-b border-border/40 py-5 last:border-b-0 md:flex-row md:items-start md:justify-between md:gap-8 hover:bg-muted/10 transition-colors`,children:[(0,$.jsxs)(`div`,{className:`min-w-0 shrink-0 md:w-[35%] pt-1`,children:[(0,$.jsx)(`label`,{className:`block text-[13px] font-medium text-foreground/80 tracking-tight`,children:e}),t&&(0,$.jsx)(`p`,{className:`mt-1 text-[12px] text-muted-foreground/70 leading-relaxed pr-4`,children:t})]}),(0,$.jsx)(`div`,{className:o(`w-full min-w-0 flex-1 md:w-[65%] flex md:justify-end`,r),children:(0,$.jsx)(`div`,{className:`w-full md:max-w-md space-y-3`,children:n})})]})}function Ne({label:e,description:t,children:n}){return(0,$.jsxs)(`div`,{className:`flex flex-col gap-3 border-b border-border/40 py-5 last:border-b-0 hover:bg-muted/10 transition-colors`,children:[(0,$.jsxs)(`div`,{className:`min-w-0 pt-1`,children:[(0,$.jsx)(`label`,{className:`block text-[13px] font-medium text-foreground/80 tracking-tight`,children:e}),t&&(0,$.jsx)(`p`,{className:`mt-1.5 text-[12px] text-muted-foreground/70 leading-relaxed max-w-2xl`,children:t})]}),(0,$.jsx)(`div`,{className:`w-full mt-1`,children:n})]})}function Pe({children:e,className:t}){return(0,$.jsx)(`div`,{className:o(`mt-3 flex flex-col gap-3 rounded-lg border border-border/40 bg-background/30 p-4`,t),children:e})}export{Me as a,Ee as c,Pe as i,De as n,Ne as o,ke as r,Oe as s,je as t};
@@ -1 +0,0 @@
1
- import{a as e}from"./rolldown-runtime-BYbx6iT9.js";import{d as t,l as n}from"./graph-vendor-DRq_-6fV.js";import{Ft as r,q as i,ut as a}from"./ui-vendor-C5pJa8N7.js";import{Y as o,a as s,i as c,nt as l,o as u,r as d,s as f,ut as p}from"./index-C9HuekJm.js";import{a as m,o as h}from"./surface-pWwG5ogx.js";import{c as g,n as _,r as v}from"./PageScaffold-f6g2l7XN.js";async function y(){return o(`/api/prompts`,{errorMessage:`Failed to fetch prompts`})}async function b(e){return o(`/api/prompts`,{method:`PUT`,body:e,errorMessage:`Failed to save prompts`})}var x=e(t(),1),S=n(),C=`min-h-0 w-full flex-1 resize-none select-text rounded-md bg-transparent p-3 font-mono text-[13px] leading-relaxed text-foreground placeholder:text-muted-foreground transition-colors focus:bg-background/35 focus:outline-none scrollbar-none`;function w(){let{data:e,isLoading:t,mutate:n}=g(`promptSettings`,y),[r,o]=(0,x.useState)(``),[s,c]=(0,x.useState)(``),[u,f]=(0,x.useState)(!1);(0,x.useEffect)(()=>{e&&(o(e.custom_prompt),c(e.custom_post_prompt))},[e]);let w=async()=>{f(!0);try{n(await b({custom_prompt:r,custom_post_prompt:s}),!1),i.success(`Prompts saved`)}catch{i.error(`Failed to save prompts`)}finally{f(!1)}};return t?(0,S.jsx)(d,{label:`Loading prompts...`,textClassName:`text-[13px]`}):(0,S.jsx)(_,{children:(0,S.jsxs)(`div`,{className:`mx-auto flex h-full w-full max-w-[800px] flex-col px-4 pb-10 pt-6`,children:[(0,S.jsx)(v,{title:`Prompts`,hint:`Custom Prompt is appended to the global system prompt layer. Custom Post Prompt is appended after the built-in runtime post prompt.`,actions:(0,S.jsxs)(p,{type:`button`,onClick:()=>void w(),disabled:u,size:`sm`,className:`text-[13px]`,children:[(0,S.jsx)(a,{className:`size-4`}),u?`Saving...`:`Save Changes`]})}),(0,S.jsxs)(`div`,{className:`grid min-h-0 flex-1 gap-8 pt-6`,children:[(0,S.jsxs)(`div`,{className:`flex min-h-0 flex-col`,children:[(0,S.jsx)(`div`,{className:`mb-3 flex items-center justify-between px-1`,children:(0,S.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,S.jsx)(`h2`,{className:`text-[15px] font-medium text-foreground`,children:`Custom Prompt`}),T(`Custom Prompt details`,`Appended to every node's system prompt.`),(0,S.jsxs)(h,{tone:`neutral`,className:`px-2 py-0.5`,children:[r.length,` chars`]})]})}),(0,S.jsx)(m,{as:`div`,padding:`none`,className:`relative flex min-h-0 flex-1 p-1`,children:(0,S.jsx)(l,{"aria-label":`Custom Prompt`,value:r,onChange:e=>o(e.target.value),placeholder:`Appended to every node's system prompt...`,className:C,mono:!0})})]}),(0,S.jsxs)(`div`,{className:`flex min-h-0 flex-col`,children:[(0,S.jsx)(`div`,{className:`mb-3 flex items-center justify-between px-1`,children:(0,S.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,S.jsx)(`h2`,{className:`text-[15px] font-medium text-foreground`,children:`Custom Post Prompt`}),T(`Custom Post Prompt details`,`Appended after the built-in runtime post prompt.`),(0,S.jsxs)(h,{tone:`neutral`,className:`px-2 py-0.5`,children:[s.length,` chars`]})]})}),(0,S.jsx)(m,{as:`div`,padding:`none`,className:`relative flex min-h-0 flex-1 p-1`,children:(0,S.jsx)(l,{"aria-label":`Custom Post Prompt`,value:s,onChange:e=>c(e.target.value),placeholder:`Appended after the built-in runtime post prompt...`,className:C,mono:!0})})]})]})]})})}var T=(e,t)=>(0,S.jsx)(u,{delayDuration:150,children:(0,S.jsxs)(c,{children:[(0,S.jsx)(f,{asChild:!0,children:(0,S.jsx)(p,{type:`button`,variant:`ghost`,size:`icon-xs`,"aria-label":e,className:`rounded-full text-muted-foreground hover:bg-accent/35 hover:text-foreground`,children:(0,S.jsx)(r,{className:`size-3.5`})})}),(0,S.jsx)(s,{className:`max-w-xs`,children:t})]})});export{w as PromptsPage};
@@ -1,3 +0,0 @@
1
- import{a as e}from"./rolldown-runtime-BYbx6iT9.js";import{d as t,l as n}from"./graph-vendor-DRq_-6fV.js";import{an as r,en as i,et as a,ft as o,gt as s,ot as c,q as l,vt as u,yt as d}from"./ui-vendor-C5pJa8N7.js";import{$ as f,C as p,O as m,S as h,X as g,Y as _,d as v,et as y,f as b,ft as x,k as S,l as C,nt as w,rt as T,st as E,ut as D}from"./index-C9HuekJm.js";import{a as O,i as k,o as A}from"./surface-pWwG5ogx.js";import{a as j,c as ee,n as M,r as te,t as N}from"./PageScaffold-f6g2l7XN.js";import{a as P,c as F,i as I,n as L,o as R,r as z,s as B,t as V}from"./alert-dialog-Duorp_S-.js";import{i as H,n as ne,r as U,t as re}from"./providerTypes-DT3Ahwl_.js";import{a as W,i as G,n as K,r as q,t as J}from"./select-DCfeNu-F.js";import{a as Y,i as ie,o as ae,r as oe,s as se,t as ce}from"./dialog-C3ixjGjN.js";import{t as le}from"./useAppRoute-FgSHBKhV.js";async function ue(){return _(`/api/providers`,{errorMessage:`Failed to fetch providers`,fallback:[],map:e=>e?.providers??[]})}async function de(e){return _(`/api/providers`,{method:`POST`,body:e,errorMessage:`Failed to create provider`})}async function fe(e,t){return _(`/api/providers/${e}`,{method:`PUT`,body:t,errorMessage:`Failed to update provider`})}async function pe(e){await g(`/api/providers/${e}`,{method:`DELETE`,errorMessage:`Failed to delete provider`})}async function me(e){return _(`/api/providers/models`,{method:`POST`,body:e,errorMessage:`Failed to fetch provider models`,fallback:[],map:e=>e?.models??[]})}async function he(e){return _(`/api/providers/models/test`,{method:`POST`,body:e,errorMessage:`Failed to test provider model`})}var X=n();function ge({clearModelsConfirmOpen:e,onCancelClearModels:t,onCancelDeleteProvider:n,onClearModels:r,onDeleteProvider:i,providerToDelete:a}){return(0,X.jsxs)(X.Fragment,{children:[(0,X.jsx)(V,{open:e,onOpenChange:e=>{e||t()},children:(0,X.jsxs)(I,{children:[(0,X.jsxs)(B,{children:[(0,X.jsx)(F,{children:`Clear all models?`}),(0,X.jsx)(P,{children:`This removes every model from this provider, including discovered and manual entries. Save the provider to keep the cleared list.`})]}),(0,X.jsxs)(R,{children:[(0,X.jsx)(z,{asChild:!0,children:(0,X.jsx)(D,{type:`button`,variant:`ghost`,children:`Cancel`})}),(0,X.jsx)(L,{asChild:!0,children:(0,X.jsx)(D,{type:`button`,variant:`destructive`,onClick:r,children:`Clear Models`})})]})]})}),(0,X.jsx)(V,{open:a!==null,onOpenChange:e=>{e||n()},children:(0,X.jsxs)(I,{children:[(0,X.jsxs)(B,{children:[(0,X.jsx)(F,{children:`Delete provider?`}),(0,X.jsx)(P,{children:a?`This will permanently remove ${a.name}.`:`This will permanently remove the selected provider.`})]}),(0,X.jsxs)(R,{children:[(0,X.jsx)(z,{asChild:!0,children:(0,X.jsx)(D,{variant:`ghost`,children:`Cancel`})}),(0,X.jsx)(L,{asChild:!0,children:(0,X.jsx)(D,{variant:`destructive`,onClick:i,children:`Delete`})})]})]})})]})}function _e(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function ve(e){return!e||Object.keys(e).length===0?``:JSON.stringify(e,null,2)}function ye(e){if(!e.trim())return{headers:{},error:null};let t;try{t=JSON.parse(e)}catch{return{headers:{},error:`Headers must be valid JSON`}}if(!_e(t))return{headers:{},error:`Headers must be a JSON object`};let n={};for(let[e,r]of Object.entries(t)){if(typeof r!=`string`)return{headers:{},error:`Headers values must all be strings`};n[e]=r}return{headers:n,error:null}}function Z(e){return e?{name:e.name,type:e.type,base_url:e.base_url,api_key:e.api_key,headers_text:ve(e.headers),retry_429_delay_seconds:e.retry_429_delay_seconds,models:e.models.map(e=>({...e}))}:{name:``,type:`openai_compatible`,base_url:``,api_key:``,headers_text:``,retry_429_delay_seconds:0,models:[]}}function Q(e){return{model:e?.model??``,context_window_tokens:e?.context_window_tokens===null||e?.context_window_tokens===void 0?``:String(e.context_window_tokens),input_image:H(e?.input_image??null),output_image:H(e?.output_image??null),structured_output:H(e?.structured_output??null),source:e?.source??`manual`}}function be(e){return JSON.stringify({name:e.name,type:e.type,base_url:e.base_url,api_key:e.api_key,headers_text:e.headers_text,retry_429_delay_seconds:e.retry_429_delay_seconds,models:e.models})}function xe(e,t){return{name:e.name,type:e.type,base_url:e.base_url,api_key:e.api_key,headers:t,retry_429_delay_seconds:e.retry_429_delay_seconds,models:e.models}}function Se(e,t,n){return{provider_id:n,name:e.name,type:e.type,base_url:e.base_url,api_key:e.api_key,headers:t,retry_429_delay_seconds:e.retry_429_delay_seconds}}function Ce(e,t){let n=new Map(e.map(e=>[e.model,e])),r=new Map(t.map(e=>[e.model,e])),i=[];for(let t of e){let e=r.get(t.model);if(!e){i.push(t);continue}if(t.source===`manual`){i.push({...t,context_window_tokens:t.context_window_tokens??e.context_window_tokens,input_image:t.input_image??e.input_image,output_image:t.output_image??e.output_image,structured_output:t.structured_output??e.structured_output}),r.delete(t.model);continue}i.push(e),r.delete(t.model)}for(let e of t)n.has(e.model)||i.push(e);return i}function we(e){let t=[];return e.context_window_tokens!==null&&t.push(`${e.context_window_tokens.toLocaleString()} tokens`),e.input_image!==null&&t.push(e.input_image?`Image input`:`No image input`),e.output_image!==null&&t.push(e.output_image?`Image output`:`No image output`),e.structured_output!==null&&e.structured_output!==void 0&&t.push(e.structured_output?`Structured output`:`No structured output`),t.length>0?t.join(` · `):`No capability metadata`}function Te(e){let t=new Set;for(let n of e){let e=n.model.trim();if(t.has(e))return e;t.add(e)}return null}function Ee(e){let t=e.trim();if(!/^\d+$/.test(t))return null;let n=Number.parseInt(t,10);return Number.isSafeInteger(n)&&n>=0?n:null}function De(e){return e.model.trim()?e.context_window_tokens&&!/^\d+$/.test(e.context_window_tokens)?`Context Window must be a positive integer`:null:`Model ID is required`}function Oe(e){let t=U(e.structured_output??`auto`);return{model:e.model.trim(),source:e.source,context_window_tokens:e.context_window_tokens?Number.parseInt(e.context_window_tokens,10):null,input_image:U(e.input_image),output_image:U(e.output_image),...t===null?{}:{structured_output:t}}}function ke({draft:e,endpointPreview:t,onUpdateDraft:n,parsedHeaders:r}){return(0,X.jsxs)(N,{title:`Connection`,separated:!0,contentClassName:`rounded-lg border-dashed bg-card/30`,children:[(0,X.jsx)(j,{label:`Base URL`,children:(0,X.jsx)(y,{value:e.base_url,onChange:t=>n({...e,base_url:t.target.value}),placeholder:`https://api.openai.com/v1`})}),(0,X.jsx)(j,{label:`Request Preview`,children:(0,X.jsx)(`div`,{className:x(`w-full select-text rounded-md border px-3 py-2 text-[12px]`,t.error?`border-destructive/20 bg-destructive/8 text-destructive`:`border-border bg-card/30 text-foreground/80`),children:t.error?t.error:t.previewUrl?(0,X.jsx)(`code`,{className:`select-text font-mono`,children:t.previewUrl}):(0,X.jsx)(`span`,{className:`text-muted-foreground`,children:`Enter a base URL to preview`})})}),(0,X.jsx)(j,{label:`Access Key`,children:(0,X.jsx)(T,{value:e.api_key,onChange:t=>n({...e,api_key:t.target.value}),placeholder:`sk-...`,mono:!0,showLabel:`Show access key`,hideLabel:`Hide access key`})}),(0,X.jsx)(j,{label:`Headers`,children:(0,X.jsxs)(`div`,{className:`space-y-2`,children:[(0,X.jsx)(w,{value:e.headers_text,onChange:t=>n({...e,headers_text:t.target.value}),placeholder:`{
2
- "Authorization": "Bearer ..."
3
- }`,spellCheck:!1,className:x(`min-h-[140px]`,r.error?`border-destructive/30 text-destructive focus-visible:border-destructive/50 focus-visible:ring-destructive/20`:``),mono:!0}),r.error?(0,X.jsx)(`p`,{className:`text-[11px] text-destructive`,children:r.error}):null]})}),(0,X.jsx)(j,{label:`429 Retry Delay`,children:(0,X.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,X.jsx)(y,{"aria-label":`429 Retry Delay`,inputMode:`numeric`,pattern:`[0-9]*`,value:String(e.retry_429_delay_seconds),onChange:t=>{let r=Ee(t.target.value);r!==null&&n({...e,retry_429_delay_seconds:r})},mono:!0}),(0,X.jsx)(`span`,{className:`text-[13px] font-medium text-muted-foreground`,children:`s`})]})})]})}function Ae({draft:e,onUpdateDraft:t}){return(0,X.jsxs)(N,{title:`Identity`,className:`mb-10`,contentClassName:`rounded-lg border-dashed bg-card/30`,children:[(0,X.jsx)(j,{label:`Name`,children:(0,X.jsx)(y,{value:e.name,onChange:n=>t({...e,name:n.target.value}),placeholder:`e.g., OpenAI Production`})}),(0,X.jsx)(j,{label:`Type`,children:(0,X.jsxs)(J,{value:e.type,onValueChange:n=>t({...e,type:n}),children:[(0,X.jsx)(G,{className:E,children:(0,X.jsx)(W,{})}),(0,X.jsx)(K,{className:`rounded-xl border-border bg-popover`,children:ne.map(e=>(0,X.jsx)(q,{value:e.value,className:`text-[13px]`,children:e.label},e.value))})]})})]})}function je({fetchingModels:e,modelTestResults:t,models:n,onAddModel:r,onClearModels:i,onDeleteModel:c,onEditModel:l,onFetchModels:u,onTestModel:d}){return(0,X.jsx)(`div`,{className:`border-t border-border pt-8`,children:(0,X.jsxs)(N,{title:`Models`,contentClassName:`space-y-4 bg-card/30 p-5`,children:[(0,X.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3`,children:[(0,X.jsxs)(`p`,{className:`text-[13px] font-medium text-foreground/80`,children:[n.length,` model`,n.length===1?``:`s`]}),(0,X.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,X.jsxs)(D,{type:`button`,variant:`ghost`,size:`sm`,disabled:e,onClick:u,children:[(0,X.jsx)(o,{className:x(`size-3.5`,e&&`animate-spin`)}),`Fetch Models`]}),(0,X.jsxs)(D,{type:`button`,variant:`outline`,size:`sm`,onClick:r,children:[(0,X.jsx)(s,{className:`size-3.5`}),`Add Model`]}),(0,X.jsxs)(D,{type:`button`,variant:`ghost`,size:`sm`,disabled:n.length===0||e,onClick:i,children:[(0,X.jsx)(a,{className:`size-3.5`}),`Clear Models`]})]})]}),n.length===0?(0,X.jsxs)(O,{as:`div`,padding:`sm`,className:`border-dashed bg-background/35 py-5 text-center`,children:[(0,X.jsx)(`p`,{className:`text-[13px] font-medium text-foreground/80`,children:`No models in this provider draft`}),(0,X.jsx)(`p`,{className:`mt-1 text-[11px] leading-relaxed text-muted-foreground`,children:`Fetch models or add a manual entry.`})]}):(0,X.jsx)(`div`,{className:`space-y-2`,children:n.map(e=>(0,X.jsx)(Me,{model:e,onDeleteModel:c,onEditModel:l,onTestModel:d,testResult:t[e.model]},e.model))})]})})}function Me({model:e,onDeleteModel:t,onEditModel:n,onTestModel:r,testResult:i}){return(0,X.jsx)(O,{as:`div`,padding:`sm`,className:`bg-background/35`,children:(0,X.jsxs)(`div`,{className:`flex flex-wrap items-start justify-between gap-3`,children:[(0,X.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,X.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,X.jsx)(`p`,{className:`truncate select-text font-mono text-[13px] text-foreground/85`,children:e.model}),(0,X.jsx)(A,{tone:e.source===`manual`?`idle`:`running`,className:`px-2 py-0.5`,children:e.source===`manual`?`Manual`:`Discovered`})]}),(0,X.jsx)(`p`,{className:`mt-1 select-text text-[11px] leading-relaxed text-muted-foreground`,children:we(e)}),(0,X.jsx)(Ne,{testResult:i})]}),(0,X.jsxs)(`div`,{className:`flex shrink-0 items-center gap-1.5`,children:[(0,X.jsxs)(D,{type:`button`,variant:`ghost`,size:`sm`,disabled:i?.state===`running`,onClick:()=>r(e),children:[(0,X.jsx)(u,{className:`size-3.5`}),`Test`]}),(0,X.jsxs)(D,{type:`button`,variant:`ghost`,size:`sm`,onClick:()=>n(e),children:[(0,X.jsx)(d,{className:`size-3.5`}),`Edit`]}),(0,X.jsxs)(D,{type:`button`,variant:`ghost`,size:`sm`,onClick:()=>t(e.model),children:[(0,X.jsx)(a,{className:`size-3.5`}),`Delete`]})]})]})})}function Ne({testResult:e}){return e?.state===`running`?(0,X.jsx)(`p`,{className:`mt-2 select-text text-[11px] text-muted-foreground`,children:`Testing this model against the current draft provider...`}):e?.state===`success`?(0,X.jsxs)(`p`,{className:`mt-2 select-text text-[11px] text-graph-status-running`,children:[`Test succeeded in `,e.duration_ms,`ms`]}):e?.state===`error`?(0,X.jsx)(`p`,{className:`mt-2 select-text text-[11px] text-destructive`,children:e.error_summary}):null}function Pe({draft:e,endpointPreview:t,fetchingModels:n,hasChanges:a,isCreating:o,modelTestResults:s,onAddModel:l,onCancelChanges:u,onClearModels:d,onDeleteModel:f,onEditModel:p,onFetchModels:m,onSaveProvider:h,onTestModel:g,onUpdateDraft:_,parsedHeaders:v,saving:y,selectedProvider:b}){return!o&&!b?(0,X.jsx)(r.div,{initial:{opacity:0},animate:{opacity:1},className:`flex h-full flex-col items-center justify-center px-6 text-center`,children:(0,X.jsx)(k,{icon:c,title:`No provider selected`,className:`border-transparent bg-transparent`})}):(0,X.jsxs)(`div`,{className:`flex min-h-full flex-col px-8 py-8 md:px-12 md:py-10`,children:[(0,X.jsxs)(`div`,{className:`mb-8 flex items-center justify-between`,children:[(0,X.jsxs)(`div`,{children:[(0,X.jsx)(`h2`,{className:`text-xl font-medium text-foreground`,children:o?`New Provider`:b?.name}),o?null:(0,X.jsx)(`p`,{className:`mt-1 select-text font-mono text-[12px] text-muted-foreground`,children:b?.id})]}),a?(0,X.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,X.jsx)(D,{type:`button`,variant:`ghost`,size:`sm`,onClick:u,disabled:y,children:`Cancel`}),(0,X.jsxs)(D,{type:`button`,size:`sm`,onClick:h,disabled:y,children:[(0,X.jsx)(i,{className:`size-3.5`}),y?`Saving...`:`Save Provider`]})]}):null]}),(0,X.jsxs)(`div`,{className:`mx-auto w-full max-w-[720px] flex-1`,children:[(0,X.jsx)(Ae,{draft:e,onUpdateDraft:_}),(0,X.jsx)(ke,{draft:e,endpointPreview:t,onUpdateDraft:_,parsedHeaders:v}),(0,X.jsx)(je,{fetchingModels:n,modelTestResults:s,models:e.models,onAddModel:l,onClearModels:d,onDeleteModel:f,onEditModel:p,onFetchModels:m,onTestModel:g}),!o&&b?(0,X.jsx)(`div`,{className:`border-t border-border pt-8`,children:(0,X.jsx)(N,{title:`Provider`,contentClassName:`rounded-lg border-dashed bg-card/30`,children:(0,X.jsx)(j,{label:`Provider ID`,children:(0,X.jsx)(`div`,{className:`select-text rounded-md border border-border bg-card/30 px-3 py-2 font-mono text-[12px] text-foreground/80`,children:b.id})})})}):null]})]})}function Fe({draft:e,onClose:t,onDraftChange:n,onSave:r,state:i}){return(0,X.jsx)(ce,{open:i!==null,onOpenChange:e=>{e||t()},children:(0,X.jsxs)(oe,{children:[(0,X.jsxs)(ae,{children:[(0,X.jsx)(se,{children:i?.mode===`edit`?`Edit Model`:`Add Model`}),(0,X.jsx)(ie,{className:`sr-only`,children:i?.mode===`edit`?`Edit Model`:`Add Model`})]}),(0,X.jsxs)(`div`,{className:`space-y-4 px-5 py-4`,children:[(0,X.jsxs)(`div`,{className:`space-y-2`,children:[(0,X.jsx)(`label`,{className:`text-[13px] font-medium text-foreground/80`,children:`Model ID`}),(0,X.jsx)(y,{"aria-label":`Model ID`,value:e.model,onChange:t=>n({...e,model:t.target.value}),placeholder:`gpt-5`,mono:!0})]}),(0,X.jsxs)(`div`,{className:`space-y-2`,children:[(0,X.jsx)(`label`,{className:`text-[13px] font-medium text-foreground/80`,children:`Source`}),(0,X.jsx)(`div`,{className:`rounded-md border border-border bg-card/30 px-3 py-2 text-[13px] text-foreground/80`,children:e.source===`manual`?`Manual`:`Discovered`})]}),(0,X.jsxs)(`div`,{className:`space-y-2`,children:[(0,X.jsx)(`label`,{className:`text-[13px] font-medium text-foreground/80`,children:`Context Window`}),(0,X.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,X.jsx)(y,{"aria-label":`Context Window`,inputMode:`numeric`,pattern:`[0-9]*`,value:e.context_window_tokens,onChange:t=>{let r=t.target.value.trim();/^\d*$/.test(r)&&n({...e,context_window_tokens:r})},placeholder:`Optional`,mono:!0}),(0,X.jsx)(`span`,{className:`text-[13px] font-medium text-muted-foreground`,children:`tokens`})]})]}),(0,X.jsxs)(`div`,{className:`grid gap-4 sm:grid-cols-3`,children:[(0,X.jsxs)(`div`,{className:`space-y-2`,children:[(0,X.jsx)(`label`,{className:`text-[13px] font-medium text-foreground/80`,children:`Input Image`}),(0,X.jsxs)(J,{value:e.input_image,onValueChange:t=>n({...e,input_image:t}),children:[(0,X.jsx)(G,{className:E,children:(0,X.jsx)(W,{})}),(0,X.jsxs)(K,{className:`rounded-xl border-border bg-popover`,children:[(0,X.jsx)(q,{value:`auto`,children:`Auto`}),(0,X.jsx)(q,{value:`enabled`,children:`Enabled`}),(0,X.jsx)(q,{value:`disabled`,children:`Disabled`})]})]})]}),(0,X.jsxs)(`div`,{className:`space-y-2`,children:[(0,X.jsx)(`label`,{className:`text-[13px] font-medium text-foreground/80`,children:`Output Image`}),(0,X.jsxs)(J,{value:e.output_image,onValueChange:t=>n({...e,output_image:t}),children:[(0,X.jsx)(G,{className:E,children:(0,X.jsx)(W,{})}),(0,X.jsxs)(K,{className:`rounded-xl border-border bg-popover`,children:[(0,X.jsx)(q,{value:`auto`,children:`Auto`}),(0,X.jsx)(q,{value:`enabled`,children:`Enabled`}),(0,X.jsx)(q,{value:`disabled`,children:`Disabled`})]})]})]}),(0,X.jsxs)(`div`,{className:`space-y-2`,children:[(0,X.jsx)(`label`,{className:`text-[13px] font-medium text-foreground/80`,children:`Structured Output`}),(0,X.jsxs)(J,{value:e.structured_output??`auto`,onValueChange:t=>n({...e,structured_output:t}),children:[(0,X.jsx)(G,{className:E,children:(0,X.jsx)(W,{})}),(0,X.jsxs)(K,{className:`rounded-xl border-border bg-popover`,children:[(0,X.jsx)(q,{value:`auto`,children:`Auto`}),(0,X.jsx)(q,{value:`enabled`,children:`Enabled`}),(0,X.jsx)(q,{value:`disabled`,children:`Disabled`})]})]})]})]})]}),(0,X.jsxs)(Y,{className:`px-5 pb-5`,children:[(0,X.jsx)(D,{variant:`ghost`,onClick:t,children:`Cancel`}),(0,X.jsx)(D,{onClick:r,children:i?.mode===`edit`?`Save Model`:`Add Model`})]})]})})}function Ie({isDragging:e,loading:t,onCreate:n,onDelete:i,onRefresh:l,onResizeStart:u,onSelect:d,panelWidth:p,providers:m,selectedId:h}){return(0,X.jsxs)(`div`,{style:{width:`${p}px`},className:`relative flex shrink-0 flex-col border-r border-border bg-card/20 pt-8 pl-8`,children:[(0,X.jsxs)(`div`,{className:`flex shrink-0 items-center justify-between px-5 py-4`,children:[(0,X.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,X.jsx)(c,{className:`size-4 text-muted-foreground`}),(0,X.jsx)(`span`,{className:`text-[13px] font-medium text-foreground/80`,children:`Providers`})]}),(0,X.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,X.jsx)(f,{onClick:l,disabled:t,className:`size-7`,children:(0,X.jsx)(o,{className:x(`size-3.5`,t&&`animate-spin`)})}),(0,X.jsx)(f,{onClick:n,className:`size-7`,children:(0,X.jsx)(s,{className:`size-3.5`})})]})]}),(0,X.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto px-3 pb-4`,children:t?(0,X.jsx)(`div`,{className:`space-y-1`,children:[...[,,,]].map((e,t)=>(0,X.jsx)(`div`,{className:`h-10 w-full animate-pulse rounded-lg bg-accent/20`},t))}):m.length===0?(0,X.jsxs)(r.div,{initial:{opacity:0},animate:{opacity:1},className:`py-10 text-center`,children:[(0,X.jsx)(`p`,{className:`text-[13px] text-muted-foreground`,children:`No providers`}),(0,X.jsxs)(D,{type:`button`,size:`sm`,onClick:n,className:`mt-4`,children:[(0,X.jsx)(s,{className:`size-3`}),`Add your first provider`]})]}):(0,X.jsx)(`div`,{className:`space-y-0.5`,children:m.map((e,t)=>(0,X.jsxs)(r.div,{initial:{opacity:0,x:-4},animate:{opacity:1,x:0},transition:{delay:t*.03},className:x(`group relative flex w-full items-center justify-between rounded-lg transition-all`,h===e.id?`bg-accent/55 text-foreground`:`text-muted-foreground hover:bg-accent/30 hover:text-foreground`),children:[(0,X.jsx)(`div`,{className:x(`absolute inset-y-1 left-0 w-px rounded-full bg-ring/60 transition-opacity`,h===e.id?`opacity-100`:`opacity-0`)}),(0,X.jsx)(D,{type:`button`,variant:`ghost`,onClick:()=>d(e),className:`h-auto min-w-0 flex-1 justify-start rounded-lg bg-transparent px-3 py-2.5 text-left text-inherit shadow-none hover:bg-transparent hover:text-inherit focus-visible:ring-2 focus-visible:ring-ring/50`,children:(0,X.jsxs)(`span`,{className:`min-w-0 flex-1 pl-2`,children:[(0,X.jsx)(`span`,{className:`block truncate text-[13px] font-medium`,children:e.name}),(0,X.jsx)(`span`,{className:`block truncate text-[11px] text-muted-foreground`,children:re(e.type)})]})}),(0,X.jsx)(f,{onClick:()=>{i(e)},className:`mr-2 size-6 shrink-0 border-transparent bg-transparent opacity-0 transition-opacity hover:bg-destructive/10 hover:text-destructive group-hover:opacity-100`,children:(0,X.jsx)(a,{className:`size-3`})})]},e.id))})}),(0,X.jsx)(C,{position:`right`,isDragging:e,onMouseDown:u})]})}var $=e(t(),1),Le={openai_compatible:`/v1`,openai_responses:`/v1`,anthropic:`/v1`,gemini:`/v1beta`},Re={openai_compatible:`/chat/completions`,openai_responses:`/responses`,anthropic:`/messages`,gemini:`/models/{model}:streamGenerateContent`},ze=Array.from(new Set(Object.values(Le))).sort((e,t)=>t.length-e.length);function Be(e){return e.trim().toLowerCase()}function Ve(e){return e.trim().replace(/\/+$/,``)}function He(e,t){let n=Be(e),r=Le[n],i=Ve(t);if(!r||!i)return{resolvedBaseUrl:null,error:null};let a=i.toLowerCase();for(let e of ze)if(a.endsWith(e))return e===r?{resolvedBaseUrl:i,error:null}:{resolvedBaseUrl:null,error:`Base URL suffix '${e}' does not match type '${n}' (expected '${r}')`};return{resolvedBaseUrl:`${i}${r}`,error:null}}function Ue(e,t){let n=Be(e),r=Re[n],{resolvedBaseUrl:i,error:a}=He(n,t);return a?{previewUrl:null,error:a}:!i||!r?{previewUrl:null,error:null}:{previewUrl:`${i}${r}`,error:null}}function We(){let e=le(),[t,n]=(0,$.useState)(e.providerId),[r,i]=(0,$.useState)(e.providerMode===`create`),[a,o]=(0,$.useState)(()=>Z()),[s,c]=(0,$.useState)(!1),[u,d]=(0,$.useState)(null),[f,g]=(0,$.useState)(!1),[_,y]=(0,$.useState)(!1),[x,C]=(0,$.useState)(null),[w,T]=(0,$.useState)(Q()),[E,D]=(0,$.useState)({}),O=(0,$.useRef)(null),{data:k=[],isLoading:A,mutate:j}=ee(`providers`,ue,{onSuccess:e=>{!t||e.find(e=>e.id===t)||(n(null),i(!1),o(Z()),D({}),g(!1))}}),[M,te]=b(`providers-panel-width`,300,200,500),{isDragging:N,startDrag:P}=v(M,te,`right`),F=(0,$.useMemo)(()=>k.find(e=>e.id===t),[k,t]);(0,$.useEffect)(()=>{if(e.page!==`providers`)return;let t=e.providerMode===`create`?`create`:e.providerId?`detail:${e.providerId}`:`list`;if(O.current!==t){if(e.providerMode===`create`){O.current=t,i(!0),n(null),o(Z()),D({}),C(null),g(!1);return}if(e.providerId){let r=k.find(t=>t.id===e.providerId);if(!r){A||(O.current=`list`,n(null),i(!1),o(Z()),D({}),C(null),g(!1),S(h(null)));return}O.current=t,n(r.id),i(!1),o(Z(r)),D({}),C(null),g(!1);return}O.current=t,n(null),i(!1),o(Z()),D({}),C(null),g(!1)}},[A,k,e.page,e.providerId,e.providerMode]);let I=(0,$.useMemo)(()=>Ue(a.type,a.base_url),[a.base_url,a.type]),L=(0,$.useMemo)(()=>ye(a.headers_text),[a.headers_text]),R=(0,$.useMemo)(()=>{let e=r?Z():Z(F);return be(a)!==be(e)},[a,r,F]),z=(0,$.useCallback)(e=>{o(e)},[]),B=(0,$.useCallback)(e=>{T(e)},[]),V=(0,$.useCallback)(e=>{d(e)},[]),H=(0,$.useCallback)(()=>{d(null)},[]),ne=(0,$.useCallback)(async()=>{await j()},[j]),U=(0,$.useCallback)(e=>{O.current=`detail:${e.id}`,n(e.id),i(!1),o(Z(e)),D({}),C(null),g(!1),m(h(e.id))},[]),re=(0,$.useCallback)(()=>{O.current=`create`,i(!0),n(null),o(Z()),D({}),C(null),g(!1),m(p())},[]),W=(0,$.useCallback)(()=>{r?(O.current=`list`,i(!1),o(Z()),m(h(null))):o(Z(F)),D({}),C(null),g(!1)},[r,F]),G=(0,$.useCallback)(async()=>{if(!a.name.trim()){l.error(`Provider name is required`);return}if(!a.base_url.trim()){l.error(`Provider base URL is required`);return}if(I.error){l.error(I.error);return}if(L.error){l.error(L.error);return}let e=Te(a.models);if(e){l.error(`Model ID '${e}' is duplicated`);return}let s=xe(a,L.headers);c(!0);try{if(r){let e=await de(s);j([...k,e],!1),O.current=`detail:${e.id}`,i(!1),n(e.id),o(Z(e)),S(h(e.id)),l.success(`Provider created`)}else if(t){let e=await fe(t,s);j(k.map(n=>n.id===t?e:n),!1),o(Z(e)),l.success(`Provider updated`)}D({}),g(!1)}catch{l.error(r?`Failed to create provider`:`Failed to update provider`)}finally{c(!1)}},[a,I.error,r,j,L.error,L.headers,k,t]),K=(0,$.useCallback)(async()=>{if(!u)return;let e=u.id;d(null),g(!1);try{await pe(e),j(k.filter(t=>t.id!==e),!1),t===e&&(O.current=`list`,n(null),o(Z()),S(h(null))),D({}),l.success(`Provider deleted`)}catch{l.error(`Failed to delete provider`)}},[j,u,k,t]),q=(0,$.useCallback)(()=>{C({mode:`create`,originalModel:null}),T(Q())},[]),J=(0,$.useCallback)(e=>{C({mode:`edit`,originalModel:e.model}),T(Q(e))},[]),Y=(0,$.useCallback)(()=>{C(null),T(Q())},[]),ie=(0,$.useCallback)(()=>{let e=De(w);if(e){l.error(e);return}let t=w.model.trim();if(a.models.some(e=>e.model===t&&e.model!==x?.originalModel)){l.error(`Model ID '${t}' already exists in this provider`);return}let n=Oe(w);o(e=>x?.mode===`edit`&&x.originalModel?{...e,models:e.models.map(e=>e.model===x.originalModel?n:e)}:{...e,models:[...e.models,n]}),D(e=>{let n={...e};return x?.originalModel&&x.originalModel!==t&&delete n[x.originalModel],n}),Y()},[Y,a.models,w,x]),ae=(0,$.useCallback)(e=>{o(t=>({...t,models:t.models.filter(t=>t.model!==e)})),D(t=>{let n={...t};return delete n[e],n})},[]),oe=(0,$.useCallback)(()=>{a.models.length!==0&&g(!0)},[a.models.length]);return{cancelClearModels:(0,$.useCallback)(()=>{g(!1)},[]),clearModelsConfirmOpen:f,draft:a,endpointPreview:I,fetchingModels:_,handleCancel:W,handleClearModels:(0,$.useCallback)(()=>{o(e=>({...e,models:[]})),D({}),g(!1)},[]),handleCreateNew:re,handleDelete:K,handleDeleteModel:ae,handleFetchModels:(0,$.useCallback)(async()=>{if(!a.type.trim()||!a.base_url.trim()){l.error(`Provider type and base URL are required before fetching models`);return}if(I.error){l.error(I.error);return}if(L.error){l.error(L.error);return}y(!0);try{let e=await me(Se(a,L.headers,t??void 0));o(t=>({...t,models:Ce(t.models,e)})),l.success(`Provider models fetched`)}catch(e){l.error(e instanceof Error?e.message:`Failed to fetch provider models`)}finally{y(!1)}},[a,I.error,L.error,L.headers,t]),handleSave:G,handleSaveModel:ie,handleSelect:U,handleTestModel:(0,$.useCallback)(async e=>{if(I.error){l.error(I.error);return}if(L.error){l.error(L.error);return}D(t=>({...t,[e.model]:{state:`running`}}));try{let n=await he({...Se(a,L.headers,t??void 0),model:e.model});D(t=>({...t,[e.model]:n.ok?{state:`success`,duration_ms:n.duration_ms??0}:{state:`error`,error_summary:n.error_summary??`Provider test failed`}}))}catch(t){D(n=>({...n,[e.model]:{state:`error`,error_summary:t instanceof Error?t.message:`Provider test failed`}}))}},[a,I.error,L.error,L.headers,t]),hasChanges:R,isCreating:r,isDragging:N,loading:A,modelEditorDraft:w,modelEditorState:x,modelTestResults:E,openCreateModelDialog:q,openEditModelDialog:J,panelWidth:M,parsedHeaders:L,providerToDelete:u,providers:k,refreshProviders:ne,requestClearModels:oe,saving:s,selectedId:t,selectedProvider:F,updateProviderDraft:z,updateProviderModelDraft:B,requestDeleteProvider:V,cancelDeleteProvider:H,startDrag:P,closeModelDialog:Y}}function Ge(){let{cancelClearModels:e,cancelDeleteProvider:t,clearModelsConfirmOpen:n,draft:r,endpointPreview:i,fetchingModels:a,handleCancel:o,handleClearModels:s,handleCreateNew:c,handleDelete:l,handleDeleteModel:u,handleFetchModels:d,handleSave:f,handleSaveModel:p,handleSelect:m,handleTestModel:h,hasChanges:g,isCreating:_,isDragging:v,loading:y,modelEditorDraft:b,modelEditorState:x,modelTestResults:S,openCreateModelDialog:C,openEditModelDialog:w,panelWidth:T,parsedHeaders:E,providerToDelete:D,providers:k,refreshProviders:A,requestClearModels:j,requestDeleteProvider:ee,saving:N,selectedId:P,selectedProvider:F,updateProviderDraft:I,updateProviderModelDraft:L,startDrag:R,closeModelDialog:z}=We();return(0,X.jsx)(M,{className:`overflow-hidden px-4 pt-6 sm:px-5`,children:(0,X.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col`,children:[(0,X.jsx)(te,{title:`Providers`}),(0,X.jsxs)(O,{as:`div`,padding:`none`,className:`mt-6 flex min-h-0 flex-1 overflow-hidden border-border/60 bg-card/[0.14]`,children:[(0,X.jsx)(Ie,{isDragging:v,loading:y,onCreate:c,onDelete:ee,onRefresh:()=>{A()},onResizeStart:R,onSelect:m,panelWidth:T,providers:k,selectedId:P}),(0,X.jsx)(`div`,{className:`min-w-0 flex-1 overflow-y-auto bg-transparent`,children:(0,X.jsx)(Pe,{draft:r,endpointPreview:i,fetchingModels:a,hasChanges:g,isCreating:_,modelTestResults:S,onAddModel:C,onCancelChanges:o,onClearModels:j,onDeleteModel:u,onEditModel:w,onFetchModels:()=>{d()},onSaveProvider:()=>{f()},onTestModel:e=>{h(e)},onUpdateDraft:I,parsedHeaders:E,saving:N,selectedProvider:F})})]}),(0,X.jsx)(Fe,{draft:b,onClose:z,onDraftChange:L,onSave:p,state:x}),(0,X.jsx)(ge,{clearModelsConfirmOpen:n,onCancelClearModels:e,onCancelDeleteProvider:t,onClearModels:s,onDeleteProvider:()=>{l()},providerToDelete:D})]})})}export{Ge as ProvidersPage};
@@ -1 +0,0 @@
1
- import{a as e}from"./rolldown-runtime-BYbx6iT9.js";import{d as t,l as n}from"./graph-vendor-DRq_-6fV.js";import{Ft as r,Gt as i,J as a,X as o,an as s,bt as c,et as l,ft as u,gt as d,q as f}from"./ui-vendor-C5pJa8N7.js";import{a as p,i as m,n as h,t as g}from"./roles-CuRT_chR.js";import{$ as _,O as v,T as y,a as b,et as x,ft as S,i as C,k as w,nt as T,o as ee,ot as E,r as D,s as O,st as k,ut as A,w as j,x as M,y as N}from"./index-C9HuekJm.js";import{a as P,i as te,o as F}from"./surface-pWwG5ogx.js";import{a as I,c as ne,n as re,r as ie,t as L}from"./PageScaffold-f6g2l7XN.js";import{a as ae,c as oe,i as R,n as z,o as B,r as V,s as H,t as U}from"./alert-dialog-Duorp_S-.js";import{a as W,i as G,n as K,r as q,t as J}from"./select-DCfeNu-F.js";import{t as se}from"./useAppRoute-FgSHBKhV.js";import{i as ce,n as le,r as ue,t as Y}from"./modelParams-DmnF2hwR.js";var X=n();function de({onConfirmDelete:e,onOpenChange:t,roleToDelete:n}){return(0,X.jsx)(U,{open:n!==null,onOpenChange:t,children:(0,X.jsxs)(R,{children:[(0,X.jsxs)(H,{children:[(0,X.jsx)(oe,{children:`Delete role?`}),(0,X.jsx)(ae,{children:n?`This will permanently remove ${n.name}.`:`This will permanently remove the selected role.`})]}),(0,X.jsxs)(B,{children:[(0,X.jsx)(V,{asChild:!0,children:(0,X.jsx)(A,{variant:`ghost`,children:`Cancel`})}),(0,X.jsx)(z,{asChild:!0,children:(0,X.jsx)(A,{variant:`destructive`,onClick:()=>void e(),children:`Delete`})})]})]})})}function fe({activeRole:e,draft:t,isReadOnly:n,onUpdateDraft:r,shouldLockIdentityFields:i}){let a=n||i;return(0,X.jsxs)(L,{title:`Identity`,className:`mb-10`,contentClassName:`rounded-lg border-dashed bg-card/30`,children:[(0,X.jsx)(I,{label:`Role Name`,children:(0,X.jsx)(x,{value:t.name,onChange:e=>r(t=>({...t,name:e.target.value})),readOnly:a,placeholder:`e.g., Code Reviewer`,className:S(a?E:``)})}),(0,X.jsx)(I,{label:`Description`,children:(0,X.jsx)(T,{value:t.description,onChange:e=>r(t=>({...t,description:e.target.value})),readOnly:a,placeholder:`Briefly explain what this role is best suited for`,rows:3,className:S(`resize-y`,a?E:``)})}),(0,X.jsx)(I,{label:`System Prompt`,children:(0,X.jsxs)(`div`,{className:`space-y-2`,children:[(0,X.jsx)(T,{value:t.system_prompt,onChange:e=>r(t=>({...t,system_prompt:e.target.value})),readOnly:a,placeholder:`You are a helpful assistant that...`,rows:12,className:S(`resize-y`,a?E:``),mono:!0}),a?(0,X.jsx)(`p`,{className:`text-[11px] text-muted-foreground`,children:e?.is_builtin||i?`Built-in role fields are locked.`:`View only.`}):null]})})]})}function pe({disabled:e,isDefaultSelected:t,onSelectDefault:n,onSelectOverride:r,overrideLabel:i}){return(0,X.jsxs)(X.Fragment,{children:[(0,X.jsx)(A,{type:`button`,variant:`ghost`,size:`sm`,disabled:e,onClick:n,className:S(`h-8 rounded-md border px-3 text-[13px] font-medium transition-colors`,t?`border-border bg-accent/45 text-foreground`:`border-transparent bg-card/20 text-muted-foreground hover:bg-accent/25`,e&&`cursor-default`),children:`Use Settings Default`}),(0,X.jsx)(A,{type:`button`,variant:`ghost`,size:`sm`,disabled:e,onClick:r,className:S(`h-8 rounded-md border px-3 text-[13px] font-medium transition-colors`,t?`border-transparent bg-card/20 text-muted-foreground hover:bg-accent/25`:`border-border bg-accent/45 text-foreground`,e&&`cursor-default`),children:i}),t?(0,X.jsx)(F,{tone:`muted`,children:`Settings default`}):null]})}function me({draft:e,isReadOnly:t,onModelParamsModeChange:n,onUpdateDraft:r}){let i=!le(e.model_params);return(0,X.jsx)(L,{title:`Model Parameters`,className:`mb-10`,separated:!0,contentClassName:`border-transparent bg-transparent p-0 shadow-none`,children:(0,X.jsxs)(`div`,{className:`space-y-6`,children:[(0,X.jsxs)(`div`,{className:`flex flex-wrap gap-3`,children:[(0,X.jsx)(pe,{disabled:t,isDefaultSelected:!i,onSelectDefault:()=>n(!1),onSelectOverride:()=>n(!0),overrideLabel:`Set Parameter Overrides`}),i?null:(0,X.jsx)(he,{})]}),i?(0,X.jsx)(P,{children:(0,X.jsx)(ce,{value:Y(e.model_params),onChange:e=>r(t=>({...t,model_params:e})),disabled:t,emptyLabel:`Inherit settings default`,numberPlaceholder:`Inherit settings default`,reasoningDisableLabel:`Disable`})}):(0,X.jsx)(F,{tone:`muted`,children:`Settings default`})]})})}function he(){return(0,X.jsx)(ee,{delayDuration:150,children:(0,X.jsxs)(C,{children:[(0,X.jsx)(O,{asChild:!0,children:(0,X.jsx)(A,{type:`button`,variant:`ghost`,size:`icon-xs`,className:`rounded-full text-muted-foreground hover:bg-accent/35 hover:text-foreground`,"aria-label":`Parameter override details`,children:(0,X.jsx)(r,{className:`size-3.5`})})}),(0,X.jsx)(b,{className:`max-w-xs`,children:`Overrides affect this role only. Unsupported fields may be ignored.`})]})})}function ge({availableProviderModels:e,draft:t,isReadOnly:n,onModelModeChange:r,onOpenProvidersPage:i,onProviderChange:a,onUpdateDraft:o,providers:s}){return(0,X.jsx)(L,{title:`Model Configuration`,className:`mb-10`,separated:!0,contentClassName:`border-transparent bg-transparent p-0 shadow-none`,children:(0,X.jsxs)(`div`,{className:`space-y-6`,children:[(0,X.jsx)(pe,{disabled:n,isDefaultSelected:t.model===null,onSelectDefault:()=>r(!1),onSelectOverride:()=>r(!0),overrideLabel:`Set Role Override`}),t.model?(0,X.jsx)(P,{children:(0,X.jsxs)(`div`,{className:`grid gap-6 md:grid-cols-2`,children:[(0,X.jsxs)(`div`,{className:`space-y-2`,children:[(0,X.jsx)(`label`,{className:`text-[13px] font-medium text-foreground/80`,children:`Provider`}),(0,X.jsxs)(J,{value:t.model.provider_id||void 0,onValueChange:a,disabled:n,children:[(0,X.jsx)(G,{className:k,children:(0,X.jsx)(W,{placeholder:`Select a provider`})}),(0,X.jsx)(K,{className:`rounded-xl border-border bg-popover`,children:s.map(e=>(0,X.jsx)(q,{value:e.id,className:`text-[13px]`,children:e.name},e.id))})]})]}),(0,X.jsx)(_e,{availableProviderModels:e,draft:t,isReadOnly:n,onOpenProvidersPage:i,onUpdateDraft:o}),(0,X.jsxs)(`div`,{className:`space-y-2 md:col-span-2`,children:[(0,X.jsx)(`label`,{className:`text-[13px] font-medium text-foreground/80`,children:`Model ID`}),(0,X.jsx)(x,{value:t.model.model,onChange:e=>o(t=>({...t,model:t.model?{...t.model,model:e.target.value}:null})),readOnly:n,placeholder:`e.g., gpt-4o-mini`,className:S(n?E:``),mono:!0}),(0,X.jsx)(`p`,{className:`text-[11px] text-muted-foreground`,children:`Catalog or manual ID`})]})]})}):(0,X.jsx)(F,{tone:`muted`,children:`Settings default`})]})})}function _e({availableProviderModels:e,draft:t,isReadOnly:n,onOpenProvidersPage:r,onUpdateDraft:i}){let a=e.some(e=>e.model===t.model?.model)?t.model?.model:void 0;return(0,X.jsxs)(`div`,{className:`space-y-2`,children:[(0,X.jsx)(`label`,{className:`text-[13px] font-medium text-foreground/80`,children:`Provider Models`}),(0,X.jsxs)(J,{value:a,onValueChange:e=>i(t=>({...t,model:t.model?{...t.model,model:e}:null})),disabled:n||!t.model?.provider_id||e.length===0,children:[(0,X.jsx)(G,{className:k,children:(0,X.jsx)(W,{placeholder:e.length>0?`Pick a provider model`:`No saved provider models`})}),(0,X.jsx)(K,{className:`max-h-[300px] rounded-xl border-border bg-popover`,children:e.map(e=>(0,X.jsx)(q,{value:e.model,className:`text-[13px]`,children:e.model},e.model))})]}),e.length===0?(0,X.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2 text-[11px] text-muted-foreground`,children:[(0,X.jsx)(`span`,{children:`No saved provider models.`}),(0,X.jsx)(A,{type:`button`,variant:`outline`,size:`xs`,onClick:r,children:`Open Providers`})]}):null]})}function ve({configurableTools:e,getToolState:t,isReadOnly:n,onToolStateCycle:r,shouldLockIdentityFields:i}){return(0,X.jsx)(L,{title:`Tool Configuration`,className:`mb-10`,separated:!0,contentClassName:`bg-card/30`,children:e.map(e=>(0,X.jsx)(ye,{isDisabled:n||i,onToolStateCycle:r,state:t(e.name),tool:e},e.name))})}function ye({isDisabled:e,onToolStateCycle:t,state:n,tool:r}){return(0,X.jsxs)(`div`,{className:`flex items-center justify-between gap-4 border-b border-border px-5 py-4 last:border-b-0`,children:[(0,X.jsxs)(`div`,{className:`min-w-0 flex-1`,title:r.description,children:[(0,X.jsx)(`p`,{className:`font-mono text-[13px] text-foreground/80`,children:r.name}),(0,X.jsx)(`p`,{className:`mt-1 truncate text-[12px] text-muted-foreground`,children:r.description})]}),(0,X.jsx)(A,{type:`button`,variant:`ghost`,size:`xs`,onClick:()=>t(r.name),disabled:e,className:S(`shrink-0 rounded-full px-3 py-1 text-xs font-medium transition-colors`,n===`included`&&`bg-accent/50 text-foreground`,n===`excluded`&&`bg-transparent text-muted-foreground line-through`,n===`allowed`&&`bg-accent/20 text-muted-foreground hover:bg-accent/35`,e&&`cursor-default hover:bg-inherit opacity-60`),children:n===`allowed`?`Allowed`:n===`included`?`Included`:`Excluded`})]})}function be({activeRole:e,availableProviderModels:t,canSave:n,configurableTools:r,draft:i,getToolState:a,isReadOnly:o,onClosePanel:s,onEditRole:c,onModelModeChange:l,onModelParamsModeChange:u,onOpenProvidersPage:d,onProviderChange:f,onSaveRole:p,onToolStateCycle:m,onUpdateDraft:h,panelBadgeLabel:g,panelMode:_,panelTitle:v,providers:y,saving:b,shouldLockIdentityFields:x}){return(0,X.jsx)(`div`,{className:`h-full min-h-0 overflow-y-auto pr-2 scrollbar-none`,children:(0,X.jsxs)(`div`,{className:`mx-auto max-w-3xl pb-10`,children:[(0,X.jsx)(xe,{badgeLabel:g,onClosePanel:s,title:v}),(0,X.jsx)(fe,{activeRole:e,draft:i,isReadOnly:o,onUpdateDraft:h,shouldLockIdentityFields:x}),(0,X.jsx)(ge,{availableProviderModels:t,draft:i,isReadOnly:o,onModelModeChange:l,onOpenProvidersPage:d,onProviderChange:f,onUpdateDraft:h,providers:y}),(0,X.jsx)(me,{draft:i,isReadOnly:o,onModelParamsModeChange:u,onUpdateDraft:h}),(0,X.jsx)(ve,{configurableTools:r,getToolState:a,isReadOnly:o,onToolStateCycle:m,shouldLockIdentityFields:x}),(0,X.jsx)(Se,{activeRole:e,canSave:n,isReadOnly:o,onClosePanel:s,onEditRole:c,onSaveRole:p,panelMode:_,saving:b})]})})}function xe({badgeLabel:e,onClosePanel:t,title:n}){return(0,X.jsxs)(P,{as:`div`,padding:`sm`,className:`mb-8 flex items-center justify-between px-5 py-4`,children:[(0,X.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,X.jsx)(F,{tone:`neutral`,className:`py-0.5 text-[11px]`,children:e}),(0,X.jsx)(`h2`,{className:`text-[15px] font-medium text-foreground`,children:n})]}),(0,X.jsx)(A,{type:`button`,variant:`ghost`,size:`icon-xs`,onClick:t,className:`text-muted-foreground hover:bg-accent/45 hover:text-foreground`,children:(0,X.jsx)(a,{className:`size-3.5`})})]})}function Se({activeRole:e,canSave:t,isReadOnly:n,onClosePanel:r,onEditRole:i,onSaveRole:a,panelMode:o,saving:s}){return(0,X.jsxs)(`div`,{className:`flex items-center justify-end gap-3 border-t border-border pt-6`,children:[(0,X.jsx)(A,{type:`button`,variant:`ghost`,size:`sm`,onClick:r,disabled:s,children:`Cancel`}),n?null:(0,X.jsx)(A,{type:`button`,size:`sm`,onClick:()=>void a(),disabled:!t,children:s?`Saving...`:o===`create`?`Create Role`:`Save Changes`}),n&&e&&!e.is_builtin?(0,X.jsx)(A,{type:`button`,variant:`secondary`,size:`sm`,onClick:()=>i(e),children:`Edit Role`}):null]})}var Ce=new Set([`idle`,`sleep`,`todo`,`contacts`]);function Z(){return{name:``,description:``,system_prompt:``,model:null,model_params:null,included_tools:[],excluded_tools:[]}}function Q(e){return e?{name:e.name,description:e.description,system_prompt:e.system_prompt,model:e.model?{provider_id:e.model.provider_id,model:e.model.model}:null,model_params:e.model_params?Y(e.model_params):null,included_tools:[...e.included_tools],excluded_tools:[...e.excluded_tools]}:Z()}function we(e){return e.filter(e=>!Ce.has(e.name))}function Te(e){return Object.fromEntries(e.map(e=>[e.id,e]))}function Ee(e,t){return e.included_tools.includes(t)?`included`:e.excluded_tools.includes(t)?`excluded`:`allowed`}function De(e,t){let n=Ee(e,t);return n===`allowed`?{...e,included_tools:[...e.included_tools,t],excluded_tools:e.excluded_tools.filter(e=>e!==t)}:n===`included`?{...e,included_tools:e.included_tools.filter(e=>e!==t),excluded_tools:[...e.excluded_tools,t]}:{...e,included_tools:e.included_tools.filter(e=>e!==t),excluded_tools:e.excluded_tools.filter(e=>e!==t)}}function Oe(e){return e.length===0?null:{provider_id:e[0]?.id??``,model:``}}function ke(e){let{activeRoleName:t,draft:n,roles:r}=e,i=n.name.trim();if(!i)return`Role name is required`;if(!n.description.trim())return`Role description is required`;if(!n.system_prompt.trim())return`System prompt is required`;if(n.model){if(!n.model.provider_id.trim())return`Provider is required for a role model override`;if(!n.model.model.trim())return`Model is required for a role model override`}return r.some(e=>e.name===i&&e.name!==t)?`Role name already exists`:null}function Ae(e){return{name:e.name.trim(),description:e.description.trim(),system_prompt:e.system_prompt,model:e.model?{provider_id:e.model.provider_id.trim(),model:e.model.model.trim()}:null,model_params:ue(e.model_params),included_tools:e.included_tools,excluded_tools:e.excluded_tools}}function je(e){return e===`view`}function Me(e,t){return e!==`create`&&e!==null&&t?.is_builtin===!0}function Ne(e,t){return e===`create`?`New Role`:t?.is_builtin?`Built-in`:`Custom`}function Pe(e,t){return e===`create`?`Create Role`:t?.is_builtin?`Role Details`:t?.name??`Role Details`}function Fe(e,t){return!(t||!e.name.trim()||!e.description.trim()||!e.system_prompt.trim())}function Ie(e,t){return e.model?`${t[e.model.provider_id]?.name??e.model.provider_id} / ${e.model.model}`:`Settings default`}function Le(e){let t=e.included_tools.length,n=e.excluded_tools.length;return t===0&&n===0?`Default`:[t>0?`+${t}`:null,n>0?`-${n}`:null].filter(Boolean).join(` `)}function Re({activeRole:e,onCreateRole:t,onDeleteRole:n,onEditRole:r,onViewRole:i,providersById:a,roles:c}){return c.length===0?(0,X.jsx)(s.div,{initial:{opacity:0},animate:{opacity:1},className:`flex h-full flex-col items-center justify-center text-center`,children:(0,X.jsx)(te,{icon:o,title:`No roles yet`,action:(0,X.jsxs)(A,{type:`button`,size:`sm`,onClick:t,children:[(0,X.jsx)(d,{className:`size-4`}),`New Role`]}),className:`border-transparent bg-transparent`})}):(0,X.jsx)(`div`,{className:`h-full min-h-0 overflow-y-auto pr-2 scrollbar-none`,children:(0,X.jsxs)(`div`,{className:`mx-auto w-full max-w-5xl`,children:[(0,X.jsxs)(`div`,{className:`mb-2 grid grid-cols-[260px_1fr_120px_100px] gap-4 px-4 pb-3`,children:[(0,X.jsx)(`span`,{className:`text-[11px] font-medium text-muted-foreground`,children:`Name`}),(0,X.jsx)(`span`,{className:`text-[11px] font-medium text-muted-foreground`,children:`Model`}),(0,X.jsx)(`span`,{className:`text-[11px] font-medium text-muted-foreground`,children:`Tools`}),(0,X.jsx)(`span`,{})]}),(0,X.jsx)(`div`,{className:`space-y-1`,children:c.map((t,o)=>(0,X.jsx)(ze,{activeRoleName:e?.name??null,index:o,onDeleteRole:n,onEditRole:r,onViewRole:i,providersById:a,role:t},t.name))})]})})}function ze({activeRoleName:e,index:t,onDeleteRole:n,onEditRole:r,onViewRole:a,providersById:o,role:u}){return(0,X.jsxs)(s.div,{initial:{opacity:0,y:4},animate:{opacity:1,y:0},transition:{delay:t*.03},className:S(`group grid grid-cols-[220px_1fr_100px_80px] items-center gap-4 rounded-xl px-4 py-3.5 transition-colors`,e===u.name?`bg-accent/25`:`hover:bg-accent/15`),children:[(0,X.jsxs)(`div`,{className:`min-w-0 pr-2`,children:[(0,X.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,X.jsx)(`span`,{className:`truncate text-[13px] font-medium text-foreground`,children:u.name}),u.is_builtin?(0,X.jsx)(F,{tone:`muted`,className:`px-1.5 py-0.5 text-[9px]`,children:`Built-in`}):null]}),(0,X.jsx)(`p`,{className:`mt-1 line-clamp-2 text-[12px] leading-relaxed text-muted-foreground`,children:u.description})]}),(0,X.jsx)(`div`,{className:`min-w-0 pr-2`,children:(0,X.jsx)(`span`,{className:`block truncate text-[13px] text-muted-foreground`,children:Ie(u,o)})}),(0,X.jsx)(`div`,{className:`pr-2`,children:(0,X.jsx)(`span`,{className:`font-mono text-[13px] text-muted-foreground`,children:Le(u)})}),(0,X.jsxs)(`div`,{className:`flex items-center justify-end gap-0.5 opacity-0 transition-opacity group-hover:opacity-100 focus-within:opacity-100`,children:[(0,X.jsx)(_,{onClick:()=>a(u),"aria-label":`View ${u.name}`,title:`View ${u.name}`,className:`size-7`,children:(0,X.jsx)(i,{className:`size-3.5`})}),(0,X.jsx)(_,{onClick:()=>r(u),"aria-label":`Edit ${u.name}`,title:`Edit ${u.name}`,className:`size-7`,children:(0,X.jsx)(c,{className:`size-3.5`})}),u.is_builtin?null:(0,X.jsx)(_,{onClick:()=>n(u),"aria-label":`Delete ${u.name}`,title:`Delete ${u.name}`,className:`flex size-7 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-destructive/10 hover:text-destructive`,children:(0,X.jsx)(l,{className:`size-3.5`})})]})]})}var $=e(t(),1);function Be(){let e=se(),[t,n]=(0,$.useState)(e.roleMode),[r,i]=(0,$.useState)(e.roleName),[a,o]=(0,$.useState)(Z()),[s,c]=(0,$.useState)(!1),[l,u]=(0,$.useState)(null),d=(0,$.useRef)(null),{data:_,isLoading:b,mutate:x}=ne(`rolesBootstrap`,m),S=(0,$.useMemo)(()=>_?.roles??[],[_?.roles]),C=(0,$.useMemo)(()=>_?.tools??[],[_?.tools]),T=(0,$.useMemo)(()=>_?.providers??[],[_?.providers]),ee=(0,$.useMemo)(()=>we(C),[C]),E=(0,$.useMemo)(()=>Te(T),[T]),D=(0,$.useMemo)(()=>r?S.find(e=>e.name===r)??null:null,[r,S]),O=a.model?.provider_id??``,k=(0,$.useMemo)(()=>O?E[O]?.models??[]:[],[O,E]),A=t!==null,M=je(t),N=Me(t,D),P=Ne(t,D),te=Pe(t,D),F=Fe(a,s);(0,$.useEffect)(()=>{if(e.page!==`roles`)return;let t=e.roleMode===`create`?`create`:e.roleName?`${e.roleMode??`view`}:${e.roleName}`:`list`;if(d.current!==t){if(e.roleMode===`create`){d.current=t,n(`create`),i(null),o(Z());return}if(e.roleName){let r=S.find(t=>t.name===e.roleName);if(!r){b||(d.current=`list`,n(null),i(null),o(Z()),w(j(null)));return}d.current=t,n(e.roleMode===`edit`?`edit`:`view`),i(r.name),o(Q(r));return}d.current=t,n(null),i(null),o(Z())}},[b,S,e.page,e.roleMode,e.roleName]);let I=(0,$.useCallback)(e=>{x({roles:e,tools:C,providers:T},!1)},[x,T,C]),re=(0,$.useCallback)(async()=>{await x()},[x]),ie=(0,$.useCallback)(()=>{d.current=`list`,n(null),i(null),o(Z()),v(j(null))},[]),L=(0,$.useCallback)(()=>{d.current=`create`,n(`create`),i(null),o(Z()),v(y())},[]),ae=(0,$.useCallback)(e=>{d.current=`view:${e.name}`,n(`view`),i(e.name),o(Q(e)),v(j(e.name,`view`))},[]),oe=(0,$.useCallback)(e=>{d.current=`edit:${e.name}`,n(`edit`),i(e.name),o(Q(e)),v(j(e.name,`edit`))},[]),R=(0,$.useCallback)(e=>{o(t=>e(t))},[]),z=(0,$.useCallback)(e=>{if(!e){R(e=>({...e,model:null}));return}if(T.length===0){f.error(`Create a provider before setting a role model`);return}R(e=>({...e,model:e.model??Oe(T)}))},[T,R]),B=(0,$.useCallback)(e=>{R(t=>({...t,model:t.model?{provider_id:e,model:``}:null}))},[R]),V=(0,$.useCallback)(e=>{R(t=>({...t,model_params:e?Y(t.model_params):null}))},[R]),H=(0,$.useCallback)(async()=>{let e=ke({activeRoleName:r,draft:a,roles:S});if(e){f.error(e);return}c(!0);try{let e=Ae(a);if(t===`edit`&&r){let t=await p(r,D?.is_builtin?{model:e.model,model_params:e.model_params}:e);I(S.map(e=>e.name===r?t:e)),d.current=`view:${t.name}`,n(`view`),i(t.name),o(Q(t)),w(j(t.name,`view`)),f.success(`Role updated`)}else{let t=await g(e);I([t,...S]),d.current=`view:${t.name}`,n(`view`),i(t.name),o(Q(t)),w(j(t.name,`view`)),f.success(`Role created`)}}catch(e){f.error(e instanceof Error?e.message:`Failed to save role`)}finally{c(!1)}},[D,r,a,t,S,I]),U=(0,$.useCallback)(e=>{u(e)},[]),W=(0,$.useCallback)(()=>{u(null)},[]),G=(0,$.useCallback)(async()=>{if(!l)return;let e=l.name;u(null);try{await h(e),I(S.filter(t=>t.name!==e)),r===e&&(d.current=`list`,n(null),i(null),o(Z()),w(j(null))),f.success(`Role deleted`)}catch(e){f.error(e instanceof Error?e.message:`Failed to delete role`)}},[r,l,S,I]);return{activeRole:D,activeRoleName:r,availableActiveProviderModelOptions:k,canSave:F,configurableTools:ee,draft:a,isPanelOpen:A,isReadOnly:M,loading:b,panelBadgeLabel:P,panelMode:t,panelTitle:te,providers:T,providersById:E,refreshRoles:re,roleToDelete:l,roles:S,saving:s,shouldLockIdentityFields:N,actions:{clearRoleToDelete:W,closePanel:ie,cycleRoleToolState:(0,$.useCallback)(e=>{R(t=>De(t,e))},[R]),handleDelete:G,handleModelModeChange:z,handleModelParamsModeChange:V,handleProviderChange:B,handleSave:H,openCreate:L,openEdit:oe,openView:ae,requestDeleteRole:U,updateDraft:R},getToolState:e=>Ee(a,e)}}function Ve(){let e=N(),{activeRole:t,availableActiveProviderModelOptions:n,canSave:r,configurableTools:i,draft:a,getToolState:o,isPanelOpen:s,isReadOnly:c,loading:l,panelBadgeLabel:f,panelMode:p,panelTitle:m,providers:h,providersById:g,refreshRoles:_,roleToDelete:y,roles:b,saving:x,shouldLockIdentityFields:C,actions:w}=Be(),T={...w,openProvidersPage:()=>{e?.navigateToPage(`providers`),e||v(M(`providers`))}};return l&&!s?(0,X.jsx)(D,{label:`Loading roles...`}):(0,X.jsxs)(re,{className:`px-4 pt-6 sm:px-5`,children:[(0,X.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col`,children:[(0,X.jsx)(ie,{title:`Roles`,actions:(0,X.jsxs)(X.Fragment,{children:[(0,X.jsx)(A,{type:`button`,variant:`outline`,size:`icon-sm`,onClick:()=>void _(),disabled:l,className:`bg-accent/20 text-muted-foreground hover:bg-accent/45 hover:text-foreground`,children:(0,X.jsx)(u,{className:S(`size-4`,l&&`animate-spin`)})}),s?null:(0,X.jsxs)(A,{type:`button`,size:`sm`,onClick:w.openCreate,children:[(0,X.jsx)(d,{className:`size-4`}),`New Role`]})]})}),(0,X.jsx)(`div`,{className:`mt-6 min-h-0 flex-1`,children:s?(0,X.jsx)(be,{activeRole:t,availableProviderModels:n,canSave:r,configurableTools:i,draft:a,getToolState:o,isReadOnly:c,onClosePanel:w.closePanel,onEditRole:w.openEdit,onModelModeChange:w.handleModelModeChange,onModelParamsModeChange:w.handleModelParamsModeChange,onOpenProvidersPage:T.openProvidersPage,onProviderChange:w.handleProviderChange,onSaveRole:w.handleSave,onToolStateCycle:w.cycleRoleToolState,onUpdateDraft:w.updateDraft,panelBadgeLabel:f,panelMode:p,panelTitle:m,providers:h,saving:x,shouldLockIdentityFields:C}):(0,X.jsx)(Re,{activeRole:t,onCreateRole:w.openCreate,onDeleteRole:w.requestDeleteRole,onEditRole:w.openEdit,onViewRole:w.openView,providersById:g,roles:b})})]}),(0,X.jsx)(de,{roleToDelete:y,onConfirmDelete:w.handleDelete,onOpenChange:e=>{e||w.clearRoleToDelete()}})]})}export{Ve as RolesPage};
@@ -1,3 +0,0 @@
1
- import{a as e}from"./rolldown-runtime-BYbx6iT9.js";import{d as t,l as n}from"./graph-vendor-DRq_-6fV.js";import{c as r,d as i,l as a,q as o,u as s,ut as c}from"./ui-vendor-C5pJa8N7.js";import{E as l,O as u,Q as d,Y as f,at as p,et as m,ft as h,it as g,nt as _,r as v,rt as y,st as b,tt as x,ut as S}from"./index-C9HuekJm.js";import{a as C,c as w,i as T,n as E,o as D,r as O,t as k}from"./PageScaffold-f6g2l7XN.js";import{i as A,r as j,t as M}from"./providerTypes-DT3Ahwl_.js";import{a as N,i as P,n as F,r as I,t as L}from"./select-DCfeNu-F.js";import{t as R}from"./useAppRoute-FgSHBKhV.js";import{i as z,t as B}from"./modelParams-DmnF2hwR.js";async function V(){return f(`/api/settings/bootstrap`,{errorMessage:`Failed to fetch settings bootstrap`})}async function ee(e){return f(`/api/settings`,{method:`POST`,body:e,errorMessage:`Failed to save settings`,map:e=>{if(!e)throw Error(`Failed to save settings`);return{settings:e.settings,reauthRequired:e.reauth_required===!0}}})}var H=e(t(),1),U=n(),W=s,G=H.forwardRef(({className:e,...t},n)=>(0,U.jsx)(a,{ref:n,className:h(`inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground`,e),...t}));G.displayName=a.displayName;var K=H.forwardRef(({className:e,...t},n)=>(0,U.jsx)(i,{ref:n,className:h(`inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow`,e),...t}));K.displayName=i.displayName;var q=H.forwardRef(({className:e,...t},n)=>(0,U.jsx)(r,{ref:n,className:h(`mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2`,e),...t}));q.displayName=r.displayName;var J=1024;function Y(e){let t=[],n=new Set;for(let r of e){let e=r.trim();if(!e)continue;let i=e.replace(/\/+$/u,``)||`/`;n.has(i)||(n.add(i),t.push(i))}return t}function X(e,t){return e.find(e=>e.id===t)??null}function Z(e,t){return e.find(e=>e.name===t)??null}function Q(e){return e?.models??[]}function te(e,t){return t?e.find(e=>e.model===t)??null:null}function ne(e,t){return e.model.context_window_tokens??t?.context_window_tokens??e.model.resolved_context_window_tokens??null}function re(e,t){return{input_image:e.model.input_image??t?.input_image??e.model.capabilities?.input_image??!1,output_image:e.model.output_image??t?.output_image??e.model.capabilities?.output_image??!1,structured_output:e.model.structured_output??t?.structured_output??e.model.capabilities?.structured_output??!1}}function ie(e,t){if(!e)return null;let n=t.max_output_tokens??1024;return Math.max(1,e-n-J)}function ae(e,t){return e!==null&&t!==null&&e>=t?`Automatic Compact token limit must stay below the known safe input window`:null}function oe(e,t){let n=t&&(t.newCode||t.confirmCode)?{new_code:t.newCode,confirm_code:t.confirmCode}:void 0;return{...n?{access:n}:{},working_dir:e.working_dir.trim(),assistant:{role_name:e.assistant.role_name,allow_network:e.assistant.allow_network,write_dirs:Y(e.assistant.write_dirs)},leader:e.leader,model:{active_provider_id:e.model.active_provider_id,active_model:e.model.active_model,input_image:e.model.input_image,output_image:e.model.output_image,structured_output:e.model.structured_output,context_window_tokens:e.model.context_window_tokens,timeout_ms:e.model.timeout_ms,retry_policy:e.model.retry_policy,max_retries:e.model.max_retries,retry_initial_delay_seconds:e.model.retry_initial_delay_seconds,retry_max_delay_seconds:e.model.retry_max_delay_seconds,retry_backoff_cap_retries:e.model.retry_backoff_cap_retries,auto_compact_token_limit:e.model.auto_compact_token_limit,params:e.model.params}}}var $=[{value:`no_retry`,label:`No retry`},{value:`limited`,label:`Limited`},{value:`unlimited`,label:`Unlimited`}];function se({accessDraftError:e,onSave:t,saving:n,settings:r}){return(0,U.jsx)(O,{title:`Settings`,actions:(0,U.jsxs)(S,{type:`button`,size:`sm`,onClick:t,disabled:n||!!e||!r.working_dir.trim(),className:`text-[13px]`,children:[(0,U.jsx)(c,{className:`size-4`}),n?`Saving...`:`Save Changes`]}),className:`mb-8`})}function ce({accessDraft:e,accessDraftError:t,onAccessDraftChange:n}){let r=!!(e.newCode.trim()||e.confirmCode.trim());return(0,U.jsxs)(k,{title:`Access Configuration`,className:`mt-8 first:mt-0`,children:[(0,U.jsx)(D,{label:`New Access Code`,children:(0,U.jsxs)(`div`,{className:`space-y-2 w-full max-w-lg`,children:[(0,U.jsx)(y,{id:`new-access-code`,value:e.newCode,onChange:e=>n(t=>({...t,newCode:e.target.value})),placeholder:`Leave empty to keep`,showLabel:`Show new access code`,hideLabel:`Hide new access code`,buttonSize:`default`}),r?(0,U.jsx)(`p`,{className:g,children:`Saving signs you out; use the new code to return.`}):null]})}),(0,U.jsx)(D,{label:`Confirm Access Code`,children:(0,U.jsxs)(`div`,{className:`space-y-2 w-full max-w-lg`,children:[(0,U.jsx)(y,{id:`confirm-access-code`,value:e.confirmCode,onChange:e=>n(t=>({...t,confirmCode:e.target.value})),placeholder:`Repeat the new access code`,showLabel:`Show confirmed access code`,hideLabel:`Hide confirmed access code`,buttonSize:`default`}),t?(0,U.jsx)(`p`,{className:h(`text-destructive font-medium pt-1`,g),children:t}):null]})})]})}function le({onSettingsChange:e,settings:t}){return(0,U.jsxs)(k,{title:`Path Configuration`,className:`mt-10`,children:[(0,U.jsx)(D,{label:`App Data Directory`,children:(0,U.jsxs)(`div`,{className:`space-y-2 max-w-lg`,children:[(0,U.jsx)(m,{"aria-label":`App Data Directory`,value:t.app_data_dir,readOnly:!0,mono:!0}),(0,U.jsx)(`p`,{className:g,children:`Read-only while Flowent is running.`})]})}),(0,U.jsx)(D,{label:`Working Directory`,children:(0,U.jsxs)(`div`,{className:`space-y-2 max-w-lg`,children:[(0,U.jsx)(m,{"aria-label":`Working Directory`,value:t.working_dir,onChange:t=>e(e=>({...e,working_dir:t.target.value})),placeholder:`/workspace/project`,mono:!0}),(0,U.jsx)(`p`,{className:g,children:`Changing this does not expand saved allowed folders.`}),(0,U.jsx)(`div`,{className:h(`space-y-2`,g),children:t.working_dir.trim()?null:(0,U.jsx)(`p`,{className:`text-destructive`,children:`Working Directory must not be empty.`})})]})})]})}function ue({assistantRole:e,onSettingsChange:t,roles:n,settings:r}){return(0,U.jsxs)(k,{title:`Assistant Configuration`,children:[(0,U.jsx)(C,{label:`Assistant Role`,children:(0,U.jsxs)(`div`,{className:`w-full`,children:[(0,U.jsxs)(L,{value:r.assistant.role_name,onValueChange:e=>t(t=>({...t,assistant:{...t.assistant,role_name:e}})),children:[(0,U.jsx)(P,{className:b,children:(0,U.jsx)(N,{placeholder:`Select a role`})}),(0,U.jsx)(F,{children:n.map(e=>(0,U.jsx)(I,{value:e.name,children:(0,U.jsxs)(`div`,{className:`flex min-w-0 flex-col items-start`,children:[(0,U.jsx)(`span`,{children:e.name}),(0,U.jsx)(`span`,{className:`text-[11px] text-muted-foreground`,children:e.description})]})},e.name))})]}),e?(0,U.jsx)(`div`,{"data-testid":`assistant-role-guidance`,className:h(`mt-2`,g),children:(0,U.jsx)(`p`,{children:e.description})}):null]})}),(0,U.jsx)(C,{label:`Network Access`,children:(0,U.jsxs)(`div`,{className:`space-y-2`,children:[(0,U.jsx)(x,{checked:r.assistant.allow_network,label:`Network Access`,onCheckedChange:e=>t(t=>({...t,assistant:{...t.assistant,allow_network:e}})),showStateText:!0}),r.assistant.allow_network?null:(0,U.jsx)(`p`,{className:g,children:`Assistant cannot connect to the web.`})]})}),(0,U.jsx)(D,{label:`Write Directories`,children:(0,U.jsxs)(`div`,{className:`space-y-2 max-w-xl`,children:[(0,U.jsx)(_,{"aria-label":`Write Dirs`,value:r.assistant.write_dirs.join(`
2
- `),onChange:e=>t(t=>({...t,assistant:{...t.assistant,write_dirs:e.target.value.split(`
3
- `)}})),rows:4,spellCheck:!1,placeholder:`/workspace/output`,className:`min-h-[108px]`,mono:!0}),(0,U.jsx)(`p`,{className:g,children:`One absolute folder path per line.`})]})})]})}function de({leaderRole:e,onSettingsChange:t,roles:n,settings:r}){return(0,U.jsx)(k,{title:`Leader Configuration`,className:`mt-10`,children:(0,U.jsx)(C,{label:`Leader Role`,children:(0,U.jsxs)(`div`,{className:`w-full`,children:[(0,U.jsxs)(L,{value:r.leader.role_name,onValueChange:e=>t(t=>({...t,leader:{role_name:e}})),children:[(0,U.jsx)(P,{className:b,children:(0,U.jsx)(N,{placeholder:`Select a role`})}),(0,U.jsx)(F,{children:n.map(e=>(0,U.jsx)(I,{value:e.name,children:(0,U.jsxs)(`div`,{className:`flex min-w-0 flex-col items-start`,children:[(0,U.jsx)(`span`,{children:e.name}),(0,U.jsx)(`span`,{className:`text-[11px] text-muted-foreground`,children:e.description})]})},e.name))})]}),e?(0,U.jsx)(`p`,{className:h(`mt-2`,g),children:e.description}):null]})})})}function fe({activeProvider:e,activeProviderModels:t,availableActiveProviderModels:n,effectiveContextWindowTokens:r,effectiveModelCapabilities:i,knownSafeInputTokens:a,onSettingsChange:o,providers:s,settings:c}){return(0,U.jsxs)(k,{title:`Model Configuration`,className:`mt-10`,children:[(0,U.jsxs)(C,{label:`Active Provider`,children:[(0,U.jsxs)(L,{value:c.model.active_provider_id,onValueChange:e=>{o(t=>({...t,model:{...t.model,active_provider_id:e,active_model:``}}))},children:[(0,U.jsx)(P,{className:b,children:(0,U.jsx)(N,{placeholder:`Select a provider`})}),(0,U.jsx)(F,{children:s.map(e=>(0,U.jsxs)(I,{value:e.id,children:[e.name,` (`,M(e.type),`)`]},e.id))})]}),e?(0,U.jsxs)(`p`,{className:`mt-2 text-xs text-muted-foreground`,children:[`Using `,e.name,` (`,e.base_url,`)`]}):null]}),(0,U.jsxs)(C,{label:`Model`,children:[(0,U.jsxs)(`div`,{className:`space-y-3`,children:[c.model.active_provider_id?t.length>0?(0,U.jsxs)(`div`,{className:`space-y-2`,children:[(0,U.jsx)(`label`,{className:p,children:`Provider Models`}),(0,U.jsxs)(L,{value:n.some(e=>e.model===c.model.active_model)?c.model.active_model:void 0,onValueChange:e=>o(t=>({...t,model:{...t.model,active_model:e}})),children:[(0,U.jsx)(P,{className:b,children:(0,U.jsx)(N,{placeholder:`Select a provider model`})}),(0,U.jsx)(F,{children:n.map(e=>(0,U.jsx)(I,{value:e.model,children:e.model},e.model))})]})]}):(0,U.jsx)(`p`,{className:g,children:`No saved provider models.`}):null,(0,U.jsx)(m,{value:c.model.active_model,onChange:e=>o(t=>({...t,model:{...t.model,active_model:e.target.value}})),placeholder:c.model.active_provider_id?`Enter model ID manually`:`Select a provider first`})]}),c.model.active_model?(0,U.jsxs)(`div`,{className:h(`mt-2 space-y-1`,g),children:[(0,U.jsxs)(`p`,{children:[`Context window:`,` `,r?r.toLocaleString():`Not resolved`]}),(0,U.jsxs)(`p`,{children:[`Capabilities: input_image=`,i.input_image?`true`:`false`,`, output_image=`,i.output_image?`true`:`false`,`, structured_output=`,i.structured_output?`true`:`false`]})]}):null]}),(0,U.jsx)(D,{label:`Model Metadata Overrides`,children:(0,U.jsx)(`div`,{className:`space-y-3 w-full`,children:(0,U.jsxs)(`div`,{className:`grid gap-3 md:grid-cols-4`,children:[(0,U.jsxs)(`div`,{className:`space-y-1`,children:[(0,U.jsx)(`label`,{htmlFor:`model-context-window`,className:p,children:`Context Window`}),(0,U.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,U.jsx)(m,{id:`model-context-window`,"aria-label":`Context Window`,inputMode:`numeric`,pattern:`[0-9]*`,value:c.model.context_window_tokens===null?``:String(c.model.context_window_tokens),onChange:e=>{let t=e.target.value.trim();/^\d*$/.test(t)&&(t&&Number.parseInt(t,10)<=0||o(e=>({...e,model:{...e.model,context_window_tokens:t?Number.parseInt(t,10):null}})))},placeholder:`Auto`,mono:!0}),(0,U.jsx)(`span`,{className:`text-[13px] font-medium text-muted-foreground`,children:`tokens`})]})]}),(0,U.jsxs)(`div`,{className:`space-y-1`,children:[(0,U.jsx)(`label`,{className:p,children:`Input Image`}),(0,U.jsxs)(L,{value:A(c.model.input_image),onValueChange:e=>o(t=>({...t,model:{...t.model,input_image:j(e)}})),children:[(0,U.jsx)(P,{"aria-label":`Input Image`,className:b,children:(0,U.jsx)(N,{placeholder:`Auto`})}),(0,U.jsxs)(F,{children:[(0,U.jsx)(I,{value:`auto`,children:`Auto`}),(0,U.jsx)(I,{value:`enabled`,children:`Enabled`}),(0,U.jsx)(I,{value:`disabled`,children:`Disabled`})]})]})]}),(0,U.jsxs)(`div`,{className:`space-y-1`,children:[(0,U.jsx)(`label`,{className:p,children:`Output Image`}),(0,U.jsxs)(L,{value:A(c.model.output_image),onValueChange:e=>o(t=>({...t,model:{...t.model,output_image:j(e)}})),children:[(0,U.jsx)(P,{"aria-label":`Output Image`,className:b,children:(0,U.jsx)(N,{placeholder:`Auto`})}),(0,U.jsxs)(F,{children:[(0,U.jsx)(I,{value:`auto`,children:`Auto`}),(0,U.jsx)(I,{value:`enabled`,children:`Enabled`}),(0,U.jsx)(I,{value:`disabled`,children:`Disabled`})]})]})]}),(0,U.jsxs)(`div`,{className:`space-y-1`,children:[(0,U.jsx)(`label`,{className:p,children:`Structured Output`}),(0,U.jsxs)(L,{value:A(c.model.structured_output??null),onValueChange:e=>o(t=>({...t,model:{...t.model,structured_output:j(e)}})),children:[(0,U.jsx)(P,{"aria-label":`Structured Output`,className:b,children:(0,U.jsx)(N,{placeholder:`Auto`})}),(0,U.jsxs)(F,{children:[(0,U.jsx)(I,{value:`auto`,children:`Auto`}),(0,U.jsx)(I,{value:`enabled`,children:`Enabled`}),(0,U.jsx)(I,{value:`disabled`,children:`Disabled`})]})]})]})]})})}),(0,U.jsx)(D,{label:`Default Model Parameters`,children:(0,U.jsx)(`div`,{className:`rounded-xl border border-border bg-card/30 p-5`,children:(0,U.jsx)(z,{className:`w-full`,value:B(c.model.params),onChange:e=>o(t=>({...t,model:{...t.model,params:e}})),emptyLabel:`Not set`,numberPlaceholder:`Not set`,reasoningDisableLabel:null})})}),(0,U.jsx)(C,{label:`Request Timeout`,children:(0,U.jsx)(`div`,{className:`space-y-2 w-full max-w-xs`,children:(0,U.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,U.jsx)(m,{"aria-label":`Request Timeout`,inputMode:`numeric`,pattern:`[0-9]*`,value:String(c.model.timeout_ms),onChange:e=>{let t=e.target.value.trim();if(!/^\d+$/.test(t))return;let n=Number.parseInt(t,10);!Number.isSafeInteger(n)||n<=0||o(e=>({...e,model:{...e.model,timeout_ms:n}}))},mono:!0}),(0,U.jsx)(`span`,{className:`text-[13px] font-medium text-muted-foreground`,children:`ms`})]})})}),(0,U.jsx)(D,{label:`Retry Strategy`,children:(0,U.jsxs)(T,{className:`max-w-3xl`,children:[(0,U.jsxs)(`div`,{className:`grid gap-6 md:grid-cols-[1fr_2fr]`,children:[(0,U.jsxs)(`div`,{className:`space-y-1`,children:[(0,U.jsx)(`label`,{className:p,children:`Policy`}),(0,U.jsxs)(L,{value:c.model.retry_policy,onValueChange:e=>o(t=>({...t,model:{...t.model,retry_policy:e}})),children:[(0,U.jsx)(P,{className:b,children:(0,U.jsx)(N,{placeholder:`Select a retry policy`})}),(0,U.jsx)(F,{children:$.map(e=>(0,U.jsx)(I,{value:e.value,children:e.label},e.value))})]})]}),c.model.retry_policy===`limited`?(0,U.jsxs)(`div`,{className:`space-y-1`,children:[(0,U.jsx)(`label`,{htmlFor:`retry-attempts`,className:p,children:`Max Attempts`}),(0,U.jsx)(m,{id:`retry-attempts`,"aria-label":`Retry Attempts`,inputMode:`numeric`,pattern:`[0-9]*`,value:String(c.model.max_retries),onChange:e=>{let t=e.target.value.trim();if(!/^\d+$/.test(t))return;let n=Number.parseInt(t,10);!Number.isSafeInteger(n)||n<=0||o(e=>({...e,model:{...e.model,max_retries:n}}))},mono:!0})]}):(0,U.jsx)(`div`,{})]}),(0,U.jsxs)(`div`,{className:`grid gap-3 md:grid-cols-3 mt-2 border-t border-border/40 pt-4`,children:[(0,U.jsxs)(`div`,{className:`space-y-1`,children:[(0,U.jsx)(`label`,{htmlFor:`retry-initial-delay`,className:p,children:`Initial Delay`}),(0,U.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,U.jsx)(m,{id:`retry-initial-delay`,"aria-label":`Initial Delay`,inputMode:`decimal`,value:String(c.model.retry_initial_delay_seconds),onChange:e=>{let t=e.target.value.trim();if(!/^\d+(\.\d+)?$/.test(t))return;let n=Number.parseFloat(t);!Number.isFinite(n)||n<=0||o(e=>({...e,model:{...e.model,retry_initial_delay_seconds:n}}))},mono:!0}),(0,U.jsx)(`span`,{className:`text-[13px] font-medium text-muted-foreground`,children:`s`})]})]}),(0,U.jsxs)(`div`,{className:`space-y-1`,children:[(0,U.jsx)(`label`,{htmlFor:`retry-max-delay`,className:p,children:`Max Delay`}),(0,U.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,U.jsx)(m,{id:`retry-max-delay`,"aria-label":`Max Delay`,inputMode:`decimal`,value:String(c.model.retry_max_delay_seconds),onChange:e=>{let t=e.target.value.trim();if(!/^\d+(\.\d+)?$/.test(t))return;let n=Number.parseFloat(t);!Number.isFinite(n)||n<=0||o(e=>({...e,model:{...e.model,retry_max_delay_seconds:n}}))},mono:!0}),(0,U.jsx)(`span`,{className:`text-[13px] font-medium text-muted-foreground`,children:`s`})]})]}),(0,U.jsxs)(`div`,{className:`space-y-1`,children:[(0,U.jsx)(`label`,{htmlFor:`retry-backoff-cap-retries`,className:p,children:`Cap Retries`}),(0,U.jsx)(m,{id:`retry-backoff-cap-retries`,"aria-label":`Cap Retries`,inputMode:`numeric`,pattern:`[0-9]*`,value:String(c.model.retry_backoff_cap_retries),onChange:e=>{let t=e.target.value.trim();if(!/^\d+$/.test(t))return;let n=Number.parseInt(t,10);!Number.isSafeInteger(n)||n<=0||o(e=>({...e,model:{...e.model,retry_backoff_cap_retries:n}}))},mono:!0})]})]})]})}),(0,U.jsx)(D,{label:`Automatic Compact`,children:(0,U.jsxs)(`div`,{className:`space-y-3 w-full max-w-sm`,children:[(0,U.jsxs)(`div`,{className:`space-y-1`,children:[(0,U.jsx)(`label`,{htmlFor:`auto-compact-token-limit`,className:p,children:`Token Limit`}),(0,U.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,U.jsx)(m,{id:`auto-compact-token-limit`,"aria-label":`Automatic Compact Token Limit`,inputMode:`numeric`,pattern:`[0-9]*`,value:c.model.auto_compact_token_limit===null?``:String(c.model.auto_compact_token_limit),onChange:e=>{let t=e.target.value.trim();/^\d*$/.test(t)&&(t&&Number.parseInt(t,10)<=0||o(e=>({...e,model:{...e.model,auto_compact_token_limit:t?Number.parseInt(t,10):null}})))},placeholder:`Disabled`,mono:!0}),(0,U.jsx)(`span`,{className:`text-[13px] font-medium text-muted-foreground`,children:`tokens`})]})]}),a===null?c.model.auto_compact_token_limit===null?null:(0,U.jsx)(`p`,{className:`text-[11px] leading-relaxed text-graph-status-idle`,children:`The current model window is not resolved, so this token limit can be saved but cannot be fully validated yet.`}):(0,U.jsxs)(`p`,{className:g,children:[`Known safe input window: `,a.toLocaleString(),` `,`tokens.`,c.model.auto_compact_token_limit!==null&&c.model.auto_compact_token_limit>=a?` Save is blocked until the token limit is lower than this window.`:null]})]})})]})}function pe({appVersion:e}){return(0,U.jsx)(`div`,{className:`mt-12 flex flex-col items-center pt-2 pb-6 text-center`,children:(0,U.jsxs)(`p`,{className:`text-[11px] font-medium text-muted-foreground`,children:[`Flowent Agent Studio v`,e??`—`]})})}function me(){let{requireReauth:e}=d(),{data:t,isLoading:n,mutate:r}=w(`settingsBootstrap`,()=>V()),[i,a]=(0,H.useState)(null),[s,c]=(0,H.useState)(!1),[l,u]=(0,H.useState)({newCode:``,confirmCode:``}),f=(0,H.useMemo)(()=>t?.providers??[],[t?.providers]),p=(0,H.useMemo)(()=>t?.roles??[],[t?.roles]),m=t?.version??null;(0,H.useEffect)(()=>{t?.settings&&!i&&a(t.settings)},[t?.settings,i]);let h=i??t?.settings??null,g=(0,H.useCallback)(e=>{a(n=>{let r=n??t?.settings??null;return r?e(r):n})},[t?.settings]),_=(0,H.useCallback)(e=>{u(t=>e(t))},[]),v=(0,H.useMemo)(()=>h?X(f,h.model.active_provider_id):null,[f,h]),y=(0,H.useMemo)(()=>h?Z(p,h.assistant.role_name):null,[p,h]),b=(0,H.useMemo)(()=>Q(v),[v]),x=b,S=(0,H.useMemo)(()=>h?te(b,h.model.active_model):null,[b,h]),C=(0,H.useMemo)(()=>h?ne(h,S):null,[S,h]),T=(0,H.useMemo)(()=>h?re(h,S):{input_image:!1,output_image:!1,structured_output:!1},[S,h]),E=(0,H.useMemo)(()=>h?ie(C,h.model.params):null,[C,h]),D=(0,H.useMemo)(()=>h?Z(p,h.leader.role_name):null,[p,h]),O=(0,H.useMemo)(()=>!l.newCode&&!l.confirmCode?null:l.newCode.trim()?l.confirmCode===l.newCode?null:`Confirm Access Code must exactly match New Access Code.`:`New Access Code must not be empty.`,[l.confirmCode,l.newCode]);return{accessDraft:l,accessDraftError:O,activeProvider:v,activeProviderModels:b,availableActiveProviderModels:x,appVersion:m,assistantRole:y,effectiveContextWindowTokens:C,effectiveModelCapabilities:T,handleSave:(0,H.useCallback)(async()=>{if(!h)return;if(O){o.error(O);return}if(!h.working_dir.trim()){o.error(`Working Directory must not be empty`);return}if(h.model.retry_max_delay_seconds<h.model.retry_initial_delay_seconds){o.error(`Max Delay must be greater than or equal to Initial Delay`);return}let t=ae(h.model.auto_compact_token_limit,E);if(t){o.error(t);return}c(!0);try{let t=await ee(oe(h,l)),n=t.settings;if(a(n),u({newCode:``,confirmCode:``}),r(e=>e&&{...e,settings:n},!1),t.reauthRequired){o.success(`Access code updated. Sign in again with the new code.`),e();return}o.success(`Settings saved`)}catch(e){o.error(e instanceof Error?e.message:`Failed to save settings`)}finally{c(!1)}},[l,O,E,r,e,h]),knownSafeInputTokens:E,leaderRole:D,loading:n,providers:f,roles:p,saving:s,settings:h,updateAccessDraft:_,updateSettings:g}}var he=[`model`,`assistant`,`leader`,`access`,`path`];function ge(){let e=R(),{accessDraft:t,accessDraftError:n,activeProvider:r,activeProviderModels:i,availableActiveProviderModels:a,appVersion:o,assistantRole:s,effectiveContextWindowTokens:c,effectiveModelCapabilities:d,handleSave:f,knownSafeInputTokens:p,leaderRole:m,loading:h,providers:g,roles:_,saving:y,settings:b,updateAccessDraft:x,updateSettings:S}=me();return h||!b?(0,U.jsx)(v,{label:`Loading settings...`,textClassName:`text-[13px]`}):(0,U.jsx)(E,{children:(0,U.jsx)(`div`,{className:`h-full min-h-0 overflow-y-auto pr-2 scrollbar-none pb-20`,children:(0,U.jsxs)(`div`,{className:`mx-auto max-w-[680px] pb-10 pt-6`,children:[(0,U.jsx)(se,{accessDraftError:n,onSave:()=>{f()},saving:y,settings:b}),(0,U.jsxs)(W,{value:e.settingsSection,onValueChange:e=>{u(l(e))},className:`w-full`,children:[(0,U.jsx)(G,{className:`mb-8 w-full justify-start h-auto flex-wrap bg-transparent p-0 gap-6 border-b border-border/40 rounded-none`,children:he.map(e=>(0,U.jsx)(K,{value:e,className:`data-[state=active]:bg-transparent data-[state=active]:shadow-none bg-transparent border-b-2 border-transparent data-[state=active]:border-primary data-[state=active]:text-foreground text-muted-foreground rounded-none px-1 pb-2.5 pt-2 hover:text-foreground transition-colors`,children:e.charAt(0).toUpperCase()+e.slice(1)},e))}),(0,U.jsx)(q,{value:`model`,className:`mt-0`,children:(0,U.jsx)(fe,{activeProvider:r,activeProviderModels:i,availableActiveProviderModels:a,effectiveContextWindowTokens:c,effectiveModelCapabilities:d,knownSafeInputTokens:p,onSettingsChange:S,providers:g,settings:b})}),(0,U.jsx)(q,{value:`assistant`,className:`mt-0`,children:(0,U.jsx)(ue,{assistantRole:s,onSettingsChange:S,roles:_,settings:b})}),(0,U.jsx)(q,{value:`leader`,className:`mt-0`,children:(0,U.jsx)(de,{leaderRole:m,onSettingsChange:S,roles:_,settings:b})}),(0,U.jsx)(q,{value:`access`,className:`mt-0`,children:(0,U.jsx)(ce,{accessDraft:t,accessDraftError:n,onAccessDraftChange:x})}),(0,U.jsx)(q,{value:`path`,className:`mt-0`,children:(0,U.jsx)(le,{onSettingsChange:S,settings:b})})]}),(0,U.jsx)(pe,{appVersion:o})]})})})}export{ge as SettingsPage};
@@ -1 +0,0 @@
1
- import{a as e}from"./rolldown-runtime-BYbx6iT9.js";import{d as t,l as n}from"./graph-vendor-DRq_-6fV.js";import{Bt as r,Ht as i,J as a,Lt as o,Mt as s,Pt as c,Q as l,Tt as u,Ut as d,Vt as f,X as p,Y as m,Yt as h,_t as g,an as _,at as v,it as y,jt as b,lt as x,st as S,tt as C,zt as w}from"./ui-vendor-C5pJa8N7.js";import{Y as T,ft as E,ht as D,lt as O,ut as k}from"./index-C9HuekJm.js";import{a as A,i as j,o as M,r as N,t as P}from"./surface-pWwG5ogx.js";import{c as F,n as I,r as L}from"./PageScaffold-f6g2l7XN.js";async function R(){return T(`/api/tools`,{errorMessage:`Failed to fetch tools`,fallback:[],map:e=>e?.tools??[]})}var z=e(t(),1),B=n(),V={send:S,idle:h,sleep:h,todo:b,contacts:u,list_tools:m,list_roles:p,list_workflows:c,exec:C,read:f,edit:i,fetch:o,create_workflow:r,create_agent:w,connect:s,set_permissions:y,manage_providers:g,manage_roles:l,manage_settings:v,manage_prompts:d};function H(e){let t=e.trim();return t.length<=96?t:`${t.slice(0,93).trimEnd()}...`}function U({expanded:e,onToggle:t,tool:n}){let r=V[n.name]??m;return(0,B.jsxs)(A,{as:`div`,padding:`md`,onClick:t,className:E(`group cursor-pointer transition-colors duration-300 hover:border-ring/25 hover:bg-accent/20 hover:shadow-sm`,e&&`border-border bg-accent/20 shadow-sm`),children:[(0,B.jsx)(N,{icon:r,size:`sm`,className:`mb-4 transition-colors group-hover:bg-accent/40`}),(0,B.jsx)(`code`,{className:`block text-[13px] font-mono font-medium text-foreground`,children:n.name}),(0,B.jsx)(`p`,{className:`mt-2 text-[10px] text-muted-foreground/75`,children:`Built-in`}),(0,B.jsx)(`p`,{className:`mt-2 line-clamp-1 text-[12px] leading-relaxed text-muted-foreground`,children:H(n.description)}),(0,B.jsx)(D,{initial:!1,children:e?(0,B.jsx)(_.div,{initial:{height:0,opacity:0},animate:{height:`auto`,opacity:1},exit:{height:0,opacity:0},transition:{duration:.2,ease:[.22,1,.36,1]},className:`overflow-hidden`,onClick:e=>e.stopPropagation(),children:(0,B.jsxs)(`div`,{className:`mt-4 border-t border-border pt-4`,children:[(0,B.jsx)(`p`,{className:`mb-2 text-[10px] font-medium text-muted-foreground/75`,children:`Parameters`}),(0,B.jsx)(P,{className:`max-h-48 p-3.5 text-foreground/70`,children:JSON.stringify(n.parameters??{},null,2)})]})}):null})]})}function W(){let{data:e=[],isLoading:t}=F(`tools`,R),[n,r]=(0,z.useState)(new Set),[i,o]=(0,z.useState)(``),s=i.trim().toLowerCase(),c=(0,z.useMemo)(()=>s?e.filter(e=>[e.name,e.description,e.source??``].join(` `).toLowerCase().includes(s)):e,[s,e]),l=e=>{r(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})};return(0,B.jsx)(I,{children:(0,B.jsxs)(`div`,{className:`flex h-full flex-col px-8 pt-6`,children:[(0,B.jsx)(L,{title:`Tools`}),(0,B.jsxs)(`div`,{className:`mb-6 mt-6 flex items-center justify-between gap-4`,children:[(0,B.jsxs)(`div`,{className:`relative w-full max-w-sm`,children:[(0,B.jsx)(x,{className:`pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground`}),(0,B.jsx)(O,{value:i,onChange:e=>o(e.target.value),placeholder:`Search tools`,className:`h-9 rounded-full bg-background/45 pl-9 pr-9 text-[13px]`}),i?(0,B.jsx)(k,{type:`button`,variant:`ghost`,size:`icon-xs`,"aria-label":`Clear search`,className:`absolute right-2 top-1/2 -translate-y-1/2 rounded-full text-muted-foreground hover:bg-accent/35 hover:text-foreground`,onClick:()=>o(``),children:(0,B.jsx)(a,{className:`size-3.5`})}):null]}),(0,B.jsxs)(M,{tone:`neutral`,className:`h-5 text-[11px]`,children:[c.length,` tools`]})]}),(0,B.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto pr-2 scrollbar-none`,children:t?(0,B.jsx)(`div`,{className:`grid grid-cols-2 gap-4 lg:grid-cols-3`,children:[...[,,,,,,]].map((e,t)=>(0,B.jsx)(A,{as:`div`,className:`h-36 animate-pulse bg-accent/20`},t))}):e.length===0?(0,B.jsx)(_.div,{initial:{opacity:0},animate:{opacity:1},className:`flex h-full flex-col items-center justify-center text-center`,children:(0,B.jsx)(j,{icon:m,title:`No tools available`,className:`border-transparent bg-transparent`})}):c.length===0?(0,B.jsx)(_.div,{initial:{opacity:0},animate:{opacity:1},className:`flex h-full flex-col items-center justify-center text-center`,children:(0,B.jsx)(j,{icon:x,title:`No tools found`,action:(0,B.jsxs)(k,{type:`button`,variant:`outline`,size:`sm`,onClick:()=>o(``),children:[(0,B.jsx)(a,{className:`size-4`}),`Clear Search`]}),className:`border-transparent bg-transparent`})}):(0,B.jsx)(`div`,{className:`grid grid-cols-2 gap-4 lg:grid-cols-3 pb-8`,children:c.map((e,t)=>(0,B.jsx)(_.div,{initial:{opacity:0,y:8},animate:{opacity:1,y:0},transition:{delay:t*.03},children:(0,B.jsx)(U,{tool:e,expanded:n.has(e.name),onToggle:()=>l(e.name)})},e.name))})})]})})}export{W as ToolsPage};