cowork-os 0.3.21

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 (526) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1638 -0
  3. package/bin/cowork.js +42 -0
  4. package/build/entitlements.mac.plist +16 -0
  5. package/build/icon.icns +0 -0
  6. package/build/icon.png +0 -0
  7. package/dist/electron/electron/activity/ActivityRepository.js +190 -0
  8. package/dist/electron/electron/agent/browser/browser-service.js +639 -0
  9. package/dist/electron/electron/agent/context-manager.js +225 -0
  10. package/dist/electron/electron/agent/custom-skill-loader.js +566 -0
  11. package/dist/electron/electron/agent/daemon.js +975 -0
  12. package/dist/electron/electron/agent/executor.js +3561 -0
  13. package/dist/electron/electron/agent/llm/anthropic-provider.js +155 -0
  14. package/dist/electron/electron/agent/llm/bedrock-provider.js +202 -0
  15. package/dist/electron/electron/agent/llm/gemini-provider.js +375 -0
  16. package/dist/electron/electron/agent/llm/index.js +34 -0
  17. package/dist/electron/electron/agent/llm/ollama-provider.js +263 -0
  18. package/dist/electron/electron/agent/llm/openai-oauth.js +101 -0
  19. package/dist/electron/electron/agent/llm/openai-provider.js +657 -0
  20. package/dist/electron/electron/agent/llm/openrouter-provider.js +232 -0
  21. package/dist/electron/electron/agent/llm/pricing.js +160 -0
  22. package/dist/electron/electron/agent/llm/provider-factory.js +880 -0
  23. package/dist/electron/electron/agent/llm/types.js +178 -0
  24. package/dist/electron/electron/agent/queue-manager.js +378 -0
  25. package/dist/electron/electron/agent/sandbox/docker-sandbox.js +402 -0
  26. package/dist/electron/electron/agent/sandbox/macos-sandbox.js +407 -0
  27. package/dist/electron/electron/agent/sandbox/runner.js +410 -0
  28. package/dist/electron/electron/agent/sandbox/sandbox-factory.js +228 -0
  29. package/dist/electron/electron/agent/sandbox/security-utils.js +258 -0
  30. package/dist/electron/electron/agent/search/brave-provider.js +119 -0
  31. package/dist/electron/electron/agent/search/google-provider.js +100 -0
  32. package/dist/electron/electron/agent/search/index.js +28 -0
  33. package/dist/electron/electron/agent/search/provider-factory.js +395 -0
  34. package/dist/electron/electron/agent/search/serpapi-provider.js +112 -0
  35. package/dist/electron/electron/agent/search/tavily-provider.js +90 -0
  36. package/dist/electron/electron/agent/search/types.js +40 -0
  37. package/dist/electron/electron/agent/security/index.js +12 -0
  38. package/dist/electron/electron/agent/security/input-sanitizer.js +303 -0
  39. package/dist/electron/electron/agent/security/output-filter.js +217 -0
  40. package/dist/electron/electron/agent/skill-eligibility.js +281 -0
  41. package/dist/electron/electron/agent/skill-registry.js +396 -0
  42. package/dist/electron/electron/agent/skills/document.js +878 -0
  43. package/dist/electron/electron/agent/skills/image-generator.js +225 -0
  44. package/dist/electron/electron/agent/skills/organizer.js +141 -0
  45. package/dist/electron/electron/agent/skills/presentation.js +367 -0
  46. package/dist/electron/electron/agent/skills/spreadsheet.js +165 -0
  47. package/dist/electron/electron/agent/tools/browser-tools.js +523 -0
  48. package/dist/electron/electron/agent/tools/builtin-settings.js +384 -0
  49. package/dist/electron/electron/agent/tools/canvas-tools.js +530 -0
  50. package/dist/electron/electron/agent/tools/cron-tools.js +577 -0
  51. package/dist/electron/electron/agent/tools/edit-tools.js +194 -0
  52. package/dist/electron/electron/agent/tools/file-tools.js +719 -0
  53. package/dist/electron/electron/agent/tools/glob-tools.js +283 -0
  54. package/dist/electron/electron/agent/tools/grep-tools.js +387 -0
  55. package/dist/electron/electron/agent/tools/image-tools.js +111 -0
  56. package/dist/electron/electron/agent/tools/mention-tools.js +282 -0
  57. package/dist/electron/electron/agent/tools/node-tools.js +476 -0
  58. package/dist/electron/electron/agent/tools/registry.js +2719 -0
  59. package/dist/electron/electron/agent/tools/search-tools.js +91 -0
  60. package/dist/electron/electron/agent/tools/shell-tools.js +574 -0
  61. package/dist/electron/electron/agent/tools/skill-tools.js +274 -0
  62. package/dist/electron/electron/agent/tools/system-tools.js +578 -0
  63. package/dist/electron/electron/agent/tools/web-fetch-tools.js +444 -0
  64. package/dist/electron/electron/agent/tools/x-tools.js +264 -0
  65. package/dist/electron/electron/agents/AgentRoleRepository.js +420 -0
  66. package/dist/electron/electron/agents/HeartbeatService.js +356 -0
  67. package/dist/electron/electron/agents/MentionRepository.js +197 -0
  68. package/dist/electron/electron/agents/TaskSubscriptionRepository.js +168 -0
  69. package/dist/electron/electron/agents/WorkingStateRepository.js +229 -0
  70. package/dist/electron/electron/canvas/canvas-manager.js +714 -0
  71. package/dist/electron/electron/canvas/canvas-preload.js +53 -0
  72. package/dist/electron/electron/canvas/canvas-protocol.js +195 -0
  73. package/dist/electron/electron/canvas/canvas-store.js +174 -0
  74. package/dist/electron/electron/canvas/index.js +13 -0
  75. package/dist/electron/electron/control-plane/client.js +364 -0
  76. package/dist/electron/electron/control-plane/handlers.js +572 -0
  77. package/dist/electron/electron/control-plane/index.js +41 -0
  78. package/dist/electron/electron/control-plane/node-manager.js +264 -0
  79. package/dist/electron/electron/control-plane/protocol.js +194 -0
  80. package/dist/electron/electron/control-plane/remote-client.js +437 -0
  81. package/dist/electron/electron/control-plane/server.js +640 -0
  82. package/dist/electron/electron/control-plane/settings.js +369 -0
  83. package/dist/electron/electron/control-plane/ssh-tunnel.js +549 -0
  84. package/dist/electron/electron/cron/index.js +30 -0
  85. package/dist/electron/electron/cron/schedule.js +190 -0
  86. package/dist/electron/electron/cron/service.js +614 -0
  87. package/dist/electron/electron/cron/store.js +155 -0
  88. package/dist/electron/electron/cron/types.js +82 -0
  89. package/dist/electron/electron/cron/webhook.js +258 -0
  90. package/dist/electron/electron/database/SecureSettingsRepository.js +444 -0
  91. package/dist/electron/electron/database/TaskLabelRepository.js +120 -0
  92. package/dist/electron/electron/database/repositories.js +1781 -0
  93. package/dist/electron/electron/database/schema.js +978 -0
  94. package/dist/electron/electron/extensions/index.js +33 -0
  95. package/dist/electron/electron/extensions/loader.js +313 -0
  96. package/dist/electron/electron/extensions/registry.js +485 -0
  97. package/dist/electron/electron/extensions/types.js +11 -0
  98. package/dist/electron/electron/gateway/channel-registry.js +1102 -0
  99. package/dist/electron/electron/gateway/channels/bluebubbles-client.js +479 -0
  100. package/dist/electron/electron/gateway/channels/bluebubbles.js +432 -0
  101. package/dist/electron/electron/gateway/channels/discord.js +975 -0
  102. package/dist/electron/electron/gateway/channels/email-client.js +593 -0
  103. package/dist/electron/electron/gateway/channels/email.js +443 -0
  104. package/dist/electron/electron/gateway/channels/google-chat.js +631 -0
  105. package/dist/electron/electron/gateway/channels/imessage-client.js +363 -0
  106. package/dist/electron/electron/gateway/channels/imessage.js +465 -0
  107. package/dist/electron/electron/gateway/channels/index.js +36 -0
  108. package/dist/electron/electron/gateway/channels/line-client.js +470 -0
  109. package/dist/electron/electron/gateway/channels/line.js +479 -0
  110. package/dist/electron/electron/gateway/channels/matrix-client.js +432 -0
  111. package/dist/electron/electron/gateway/channels/matrix.js +592 -0
  112. package/dist/electron/electron/gateway/channels/mattermost-client.js +394 -0
  113. package/dist/electron/electron/gateway/channels/mattermost.js +496 -0
  114. package/dist/electron/electron/gateway/channels/signal-client.js +500 -0
  115. package/dist/electron/electron/gateway/channels/signal.js +582 -0
  116. package/dist/electron/electron/gateway/channels/slack.js +415 -0
  117. package/dist/electron/electron/gateway/channels/teams.js +596 -0
  118. package/dist/electron/electron/gateway/channels/telegram.js +1390 -0
  119. package/dist/electron/electron/gateway/channels/twitch-client.js +502 -0
  120. package/dist/electron/electron/gateway/channels/twitch.js +396 -0
  121. package/dist/electron/electron/gateway/channels/types.js +8 -0
  122. package/dist/electron/electron/gateway/channels/whatsapp.js +953 -0
  123. package/dist/electron/electron/gateway/context-policy.js +268 -0
  124. package/dist/electron/electron/gateway/index.js +1063 -0
  125. package/dist/electron/electron/gateway/infrastructure.js +496 -0
  126. package/dist/electron/electron/gateway/router.js +2700 -0
  127. package/dist/electron/electron/gateway/security.js +375 -0
  128. package/dist/electron/electron/gateway/session.js +115 -0
  129. package/dist/electron/electron/gateway/tunnel.js +503 -0
  130. package/dist/electron/electron/guardrails/guardrail-manager.js +348 -0
  131. package/dist/electron/electron/hooks/gmail-watcher.js +300 -0
  132. package/dist/electron/electron/hooks/index.js +46 -0
  133. package/dist/electron/electron/hooks/mappings.js +381 -0
  134. package/dist/electron/electron/hooks/server.js +480 -0
  135. package/dist/electron/electron/hooks/settings.js +447 -0
  136. package/dist/electron/electron/hooks/types.js +41 -0
  137. package/dist/electron/electron/ipc/canvas-handlers.js +158 -0
  138. package/dist/electron/electron/ipc/handlers.js +3138 -0
  139. package/dist/electron/electron/ipc/mission-control-handlers.js +141 -0
  140. package/dist/electron/electron/main.js +448 -0
  141. package/dist/electron/electron/mcp/client/MCPClientManager.js +330 -0
  142. package/dist/electron/electron/mcp/client/MCPServerConnection.js +437 -0
  143. package/dist/electron/electron/mcp/client/transports/SSETransport.js +304 -0
  144. package/dist/electron/electron/mcp/client/transports/StdioTransport.js +307 -0
  145. package/dist/electron/electron/mcp/client/transports/WebSocketTransport.js +329 -0
  146. package/dist/electron/electron/mcp/host/MCPHostServer.js +354 -0
  147. package/dist/electron/electron/mcp/host/ToolAdapter.js +100 -0
  148. package/dist/electron/electron/mcp/registry/MCPRegistryManager.js +497 -0
  149. package/dist/electron/electron/mcp/settings.js +446 -0
  150. package/dist/electron/electron/mcp/types.js +59 -0
  151. package/dist/electron/electron/memory/MemoryService.js +435 -0
  152. package/dist/electron/electron/notifications/index.js +17 -0
  153. package/dist/electron/electron/notifications/service.js +118 -0
  154. package/dist/electron/electron/notifications/store.js +144 -0
  155. package/dist/electron/electron/preload.js +842 -0
  156. package/dist/electron/electron/reports/StandupReportService.js +272 -0
  157. package/dist/electron/electron/security/concurrency.js +293 -0
  158. package/dist/electron/electron/security/index.js +15 -0
  159. package/dist/electron/electron/security/policy-manager.js +435 -0
  160. package/dist/electron/electron/settings/appearance-manager.js +193 -0
  161. package/dist/electron/electron/settings/personality-manager.js +724 -0
  162. package/dist/electron/electron/settings/x-manager.js +58 -0
  163. package/dist/electron/electron/tailscale/exposure.js +188 -0
  164. package/dist/electron/electron/tailscale/index.js +28 -0
  165. package/dist/electron/electron/tailscale/settings.js +205 -0
  166. package/dist/electron/electron/tailscale/tailscale.js +355 -0
  167. package/dist/electron/electron/tray/QuickInputWindow.js +568 -0
  168. package/dist/electron/electron/tray/TrayManager.js +895 -0
  169. package/dist/electron/electron/tray/index.js +9 -0
  170. package/dist/electron/electron/updater/index.js +6 -0
  171. package/dist/electron/electron/updater/update-manager.js +418 -0
  172. package/dist/electron/electron/utils/env-migration.js +209 -0
  173. package/dist/electron/electron/utils/process.js +102 -0
  174. package/dist/electron/electron/utils/rate-limiter.js +104 -0
  175. package/dist/electron/electron/utils/validation.js +419 -0
  176. package/dist/electron/electron/utils/x-cli.js +177 -0
  177. package/dist/electron/electron/voice/VoiceService.js +507 -0
  178. package/dist/electron/electron/voice/index.js +14 -0
  179. package/dist/electron/electron/voice/voice-settings-manager.js +359 -0
  180. package/dist/electron/shared/channelMessages.js +170 -0
  181. package/dist/electron/shared/types.js +1185 -0
  182. package/package.json +159 -0
  183. package/resources/skills/1password.json +10 -0
  184. package/resources/skills/add-documentation.json +31 -0
  185. package/resources/skills/analyze-csv.json +17 -0
  186. package/resources/skills/apple-notes.json +10 -0
  187. package/resources/skills/apple-reminders.json +10 -0
  188. package/resources/skills/auto-commenter.json +10 -0
  189. package/resources/skills/bear-notes.json +10 -0
  190. package/resources/skills/bird.json +35 -0
  191. package/resources/skills/blogwatcher.json +10 -0
  192. package/resources/skills/blucli.json +10 -0
  193. package/resources/skills/bluebubbles.json +10 -0
  194. package/resources/skills/camsnap.json +10 -0
  195. package/resources/skills/clean-imports.json +18 -0
  196. package/resources/skills/code-review.json +18 -0
  197. package/resources/skills/coding-agent.json +10 -0
  198. package/resources/skills/compare-files.json +23 -0
  199. package/resources/skills/convert-code.json +34 -0
  200. package/resources/skills/create-changelog.json +24 -0
  201. package/resources/skills/debug-error.json +17 -0
  202. package/resources/skills/dependency-check.json +10 -0
  203. package/resources/skills/discord.json +10 -0
  204. package/resources/skills/eightctl.json +10 -0
  205. package/resources/skills/explain-code.json +29 -0
  206. package/resources/skills/extract-todos.json +18 -0
  207. package/resources/skills/food-order.json +10 -0
  208. package/resources/skills/gemini.json +10 -0
  209. package/resources/skills/generate-readme.json +10 -0
  210. package/resources/skills/gifgrep.json +10 -0
  211. package/resources/skills/git-commit.json +10 -0
  212. package/resources/skills/github.json +10 -0
  213. package/resources/skills/gog.json +10 -0
  214. package/resources/skills/goplaces.json +10 -0
  215. package/resources/skills/himalaya.json +10 -0
  216. package/resources/skills/imsg.json +10 -0
  217. package/resources/skills/karpathy-guidelines.json +12 -0
  218. package/resources/skills/last30days.json +26 -0
  219. package/resources/skills/local-places.json +10 -0
  220. package/resources/skills/mcporter.json +10 -0
  221. package/resources/skills/model-usage.json +10 -0
  222. package/resources/skills/nano-banana-pro.json +10 -0
  223. package/resources/skills/nano-pdf.json +10 -0
  224. package/resources/skills/notion.json +10 -0
  225. package/resources/skills/obsidian.json +10 -0
  226. package/resources/skills/openai-image-gen.json +10 -0
  227. package/resources/skills/openai-whisper-api.json +10 -0
  228. package/resources/skills/openai-whisper.json +10 -0
  229. package/resources/skills/openhue.json +10 -0
  230. package/resources/skills/oracle.json +10 -0
  231. package/resources/skills/ordercli.json +10 -0
  232. package/resources/skills/peekaboo.json +10 -0
  233. package/resources/skills/project-structure.json +10 -0
  234. package/resources/skills/proofread.json +17 -0
  235. package/resources/skills/refactor-code.json +31 -0
  236. package/resources/skills/rename-symbol.json +23 -0
  237. package/resources/skills/sag.json +10 -0
  238. package/resources/skills/security-audit.json +18 -0
  239. package/resources/skills/session-logs.json +10 -0
  240. package/resources/skills/sherpa-onnx-tts.json +10 -0
  241. package/resources/skills/skill-creator.json +15 -0
  242. package/resources/skills/skill-hub.json +29 -0
  243. package/resources/skills/slack.json +10 -0
  244. package/resources/skills/songsee.json +10 -0
  245. package/resources/skills/sonoscli.json +10 -0
  246. package/resources/skills/spotify-player.json +10 -0
  247. package/resources/skills/startup-cfo.json +55 -0
  248. package/resources/skills/summarize-folder.json +18 -0
  249. package/resources/skills/summarize.json +10 -0
  250. package/resources/skills/things-mac.json +10 -0
  251. package/resources/skills/tmux.json +10 -0
  252. package/resources/skills/translate.json +36 -0
  253. package/resources/skills/trello.json +10 -0
  254. package/resources/skills/video-frames.json +10 -0
  255. package/resources/skills/voice-call.json +10 -0
  256. package/resources/skills/wacli.json +10 -0
  257. package/resources/skills/weather.json +10 -0
  258. package/resources/skills/write-tests.json +31 -0
  259. package/src/electron/activity/ActivityRepository.ts +238 -0
  260. package/src/electron/agent/browser/browser-service.ts +721 -0
  261. package/src/electron/agent/context-manager.ts +257 -0
  262. package/src/electron/agent/custom-skill-loader.ts +634 -0
  263. package/src/electron/agent/daemon.ts +1097 -0
  264. package/src/electron/agent/executor.ts +4017 -0
  265. package/src/electron/agent/llm/anthropic-provider.ts +175 -0
  266. package/src/electron/agent/llm/bedrock-provider.ts +236 -0
  267. package/src/electron/agent/llm/gemini-provider.ts +422 -0
  268. package/src/electron/agent/llm/index.ts +9 -0
  269. package/src/electron/agent/llm/ollama-provider.ts +347 -0
  270. package/src/electron/agent/llm/openai-oauth.ts +127 -0
  271. package/src/electron/agent/llm/openai-provider.ts +686 -0
  272. package/src/electron/agent/llm/openrouter-provider.ts +273 -0
  273. package/src/electron/agent/llm/pricing.ts +180 -0
  274. package/src/electron/agent/llm/provider-factory.ts +971 -0
  275. package/src/electron/agent/llm/types.ts +291 -0
  276. package/src/electron/agent/queue-manager.ts +408 -0
  277. package/src/electron/agent/sandbox/docker-sandbox.ts +453 -0
  278. package/src/electron/agent/sandbox/macos-sandbox.ts +426 -0
  279. package/src/electron/agent/sandbox/runner.ts +453 -0
  280. package/src/electron/agent/sandbox/sandbox-factory.ts +337 -0
  281. package/src/electron/agent/sandbox/security-utils.ts +251 -0
  282. package/src/electron/agent/search/brave-provider.ts +141 -0
  283. package/src/electron/agent/search/google-provider.ts +131 -0
  284. package/src/electron/agent/search/index.ts +6 -0
  285. package/src/electron/agent/search/provider-factory.ts +450 -0
  286. package/src/electron/agent/search/serpapi-provider.ts +138 -0
  287. package/src/electron/agent/search/tavily-provider.ts +108 -0
  288. package/src/electron/agent/search/types.ts +118 -0
  289. package/src/electron/agent/security/index.ts +20 -0
  290. package/src/electron/agent/security/input-sanitizer.ts +380 -0
  291. package/src/electron/agent/security/output-filter.ts +259 -0
  292. package/src/electron/agent/skill-eligibility.ts +334 -0
  293. package/src/electron/agent/skill-registry.ts +457 -0
  294. package/src/electron/agent/skills/document.ts +1070 -0
  295. package/src/electron/agent/skills/image-generator.ts +272 -0
  296. package/src/electron/agent/skills/organizer.ts +131 -0
  297. package/src/electron/agent/skills/presentation.ts +418 -0
  298. package/src/electron/agent/skills/spreadsheet.ts +166 -0
  299. package/src/electron/agent/tools/browser-tools.ts +546 -0
  300. package/src/electron/agent/tools/builtin-settings.ts +422 -0
  301. package/src/electron/agent/tools/canvas-tools.ts +572 -0
  302. package/src/electron/agent/tools/cron-tools.ts +723 -0
  303. package/src/electron/agent/tools/edit-tools.ts +196 -0
  304. package/src/electron/agent/tools/file-tools.ts +811 -0
  305. package/src/electron/agent/tools/glob-tools.ts +303 -0
  306. package/src/electron/agent/tools/grep-tools.ts +432 -0
  307. package/src/electron/agent/tools/image-tools.ts +126 -0
  308. package/src/electron/agent/tools/mention-tools.ts +371 -0
  309. package/src/electron/agent/tools/node-tools.ts +550 -0
  310. package/src/electron/agent/tools/registry.ts +3052 -0
  311. package/src/electron/agent/tools/search-tools.ts +111 -0
  312. package/src/electron/agent/tools/shell-tools.ts +651 -0
  313. package/src/electron/agent/tools/skill-tools.ts +340 -0
  314. package/src/electron/agent/tools/system-tools.ts +665 -0
  315. package/src/electron/agent/tools/web-fetch-tools.ts +528 -0
  316. package/src/electron/agent/tools/x-tools.ts +267 -0
  317. package/src/electron/agents/AgentRoleRepository.ts +557 -0
  318. package/src/electron/agents/HeartbeatService.ts +469 -0
  319. package/src/electron/agents/MentionRepository.ts +242 -0
  320. package/src/electron/agents/TaskSubscriptionRepository.ts +231 -0
  321. package/src/electron/agents/WorkingStateRepository.ts +278 -0
  322. package/src/electron/canvas/canvas-manager.ts +818 -0
  323. package/src/electron/canvas/canvas-preload.ts +102 -0
  324. package/src/electron/canvas/canvas-protocol.ts +174 -0
  325. package/src/electron/canvas/canvas-store.ts +200 -0
  326. package/src/electron/canvas/index.ts +8 -0
  327. package/src/electron/control-plane/client.ts +527 -0
  328. package/src/electron/control-plane/handlers.ts +723 -0
  329. package/src/electron/control-plane/index.ts +51 -0
  330. package/src/electron/control-plane/node-manager.ts +322 -0
  331. package/src/electron/control-plane/protocol.ts +269 -0
  332. package/src/electron/control-plane/remote-client.ts +517 -0
  333. package/src/electron/control-plane/server.ts +853 -0
  334. package/src/electron/control-plane/settings.ts +401 -0
  335. package/src/electron/control-plane/ssh-tunnel.ts +624 -0
  336. package/src/electron/cron/index.ts +9 -0
  337. package/src/electron/cron/schedule.ts +217 -0
  338. package/src/electron/cron/service.ts +743 -0
  339. package/src/electron/cron/store.ts +165 -0
  340. package/src/electron/cron/types.ts +291 -0
  341. package/src/electron/cron/webhook.ts +303 -0
  342. package/src/electron/database/SecureSettingsRepository.ts +514 -0
  343. package/src/electron/database/TaskLabelRepository.ts +148 -0
  344. package/src/electron/database/repositories.ts +2397 -0
  345. package/src/electron/database/schema.ts +1017 -0
  346. package/src/electron/extensions/index.ts +18 -0
  347. package/src/electron/extensions/loader.ts +336 -0
  348. package/src/electron/extensions/registry.ts +546 -0
  349. package/src/electron/extensions/types.ts +372 -0
  350. package/src/electron/gateway/channel-registry.ts +1267 -0
  351. package/src/electron/gateway/channels/bluebubbles-client.ts +641 -0
  352. package/src/electron/gateway/channels/bluebubbles.ts +509 -0
  353. package/src/electron/gateway/channels/discord.ts +1150 -0
  354. package/src/electron/gateway/channels/email-client.ts +708 -0
  355. package/src/electron/gateway/channels/email.ts +516 -0
  356. package/src/electron/gateway/channels/google-chat.ts +760 -0
  357. package/src/electron/gateway/channels/imessage-client.ts +473 -0
  358. package/src/electron/gateway/channels/imessage.ts +520 -0
  359. package/src/electron/gateway/channels/index.ts +21 -0
  360. package/src/electron/gateway/channels/line-client.ts +598 -0
  361. package/src/electron/gateway/channels/line.ts +559 -0
  362. package/src/electron/gateway/channels/matrix-client.ts +632 -0
  363. package/src/electron/gateway/channels/matrix.ts +655 -0
  364. package/src/electron/gateway/channels/mattermost-client.ts +526 -0
  365. package/src/electron/gateway/channels/mattermost.ts +550 -0
  366. package/src/electron/gateway/channels/signal-client.ts +722 -0
  367. package/src/electron/gateway/channels/signal.ts +666 -0
  368. package/src/electron/gateway/channels/slack.ts +458 -0
  369. package/src/electron/gateway/channels/teams.ts +681 -0
  370. package/src/electron/gateway/channels/telegram.ts +1727 -0
  371. package/src/electron/gateway/channels/twitch-client.ts +665 -0
  372. package/src/electron/gateway/channels/twitch.ts +468 -0
  373. package/src/electron/gateway/channels/types.ts +1002 -0
  374. package/src/electron/gateway/channels/whatsapp.ts +1101 -0
  375. package/src/electron/gateway/context-policy.ts +382 -0
  376. package/src/electron/gateway/index.ts +1274 -0
  377. package/src/electron/gateway/infrastructure.ts +645 -0
  378. package/src/electron/gateway/router.ts +3206 -0
  379. package/src/electron/gateway/security.ts +422 -0
  380. package/src/electron/gateway/session.ts +144 -0
  381. package/src/electron/gateway/tunnel.ts +626 -0
  382. package/src/electron/guardrails/guardrail-manager.ts +380 -0
  383. package/src/electron/hooks/gmail-watcher.ts +355 -0
  384. package/src/electron/hooks/index.ts +30 -0
  385. package/src/electron/hooks/mappings.ts +404 -0
  386. package/src/electron/hooks/server.ts +574 -0
  387. package/src/electron/hooks/settings.ts +466 -0
  388. package/src/electron/hooks/types.ts +245 -0
  389. package/src/electron/ipc/canvas-handlers.ts +223 -0
  390. package/src/electron/ipc/handlers.ts +3661 -0
  391. package/src/electron/ipc/mission-control-handlers.ts +182 -0
  392. package/src/electron/main.ts +496 -0
  393. package/src/electron/mcp/client/MCPClientManager.ts +406 -0
  394. package/src/electron/mcp/client/MCPServerConnection.ts +514 -0
  395. package/src/electron/mcp/client/transports/SSETransport.ts +360 -0
  396. package/src/electron/mcp/client/transports/StdioTransport.ts +355 -0
  397. package/src/electron/mcp/client/transports/WebSocketTransport.ts +384 -0
  398. package/src/electron/mcp/host/MCPHostServer.ts +388 -0
  399. package/src/electron/mcp/host/ToolAdapter.ts +140 -0
  400. package/src/electron/mcp/registry/MCPRegistryManager.ts +565 -0
  401. package/src/electron/mcp/settings.ts +468 -0
  402. package/src/electron/mcp/types.ts +371 -0
  403. package/src/electron/memory/MemoryService.ts +523 -0
  404. package/src/electron/notifications/index.ts +16 -0
  405. package/src/electron/notifications/service.ts +161 -0
  406. package/src/electron/notifications/store.ts +163 -0
  407. package/src/electron/preload.ts +2845 -0
  408. package/src/electron/reports/StandupReportService.ts +356 -0
  409. package/src/electron/security/concurrency.ts +333 -0
  410. package/src/electron/security/index.ts +17 -0
  411. package/src/electron/security/policy-manager.ts +539 -0
  412. package/src/electron/settings/appearance-manager.ts +182 -0
  413. package/src/electron/settings/personality-manager.ts +800 -0
  414. package/src/electron/settings/x-manager.ts +62 -0
  415. package/src/electron/tailscale/exposure.ts +262 -0
  416. package/src/electron/tailscale/index.ts +34 -0
  417. package/src/electron/tailscale/settings.ts +218 -0
  418. package/src/electron/tailscale/tailscale.ts +379 -0
  419. package/src/electron/tray/QuickInputWindow.ts +609 -0
  420. package/src/electron/tray/TrayManager.ts +1005 -0
  421. package/src/electron/tray/index.ts +6 -0
  422. package/src/electron/updater/index.ts +1 -0
  423. package/src/electron/updater/update-manager.ts +447 -0
  424. package/src/electron/utils/env-migration.ts +203 -0
  425. package/src/electron/utils/process.ts +124 -0
  426. package/src/electron/utils/rate-limiter.ts +130 -0
  427. package/src/electron/utils/validation.ts +493 -0
  428. package/src/electron/utils/x-cli.ts +198 -0
  429. package/src/electron/voice/VoiceService.ts +583 -0
  430. package/src/electron/voice/index.ts +9 -0
  431. package/src/electron/voice/voice-settings-manager.ts +403 -0
  432. package/src/renderer/App.tsx +775 -0
  433. package/src/renderer/components/ActivityFeed.tsx +407 -0
  434. package/src/renderer/components/ActivityFeedItem.tsx +285 -0
  435. package/src/renderer/components/AgentRoleCard.tsx +343 -0
  436. package/src/renderer/components/AgentRoleEditor.tsx +805 -0
  437. package/src/renderer/components/AgentSquadSettings.tsx +295 -0
  438. package/src/renderer/components/AgentWorkingStatePanel.tsx +411 -0
  439. package/src/renderer/components/AppearanceSettings.tsx +122 -0
  440. package/src/renderer/components/ApprovalDialog.tsx +100 -0
  441. package/src/renderer/components/BlueBubblesSettings.tsx +505 -0
  442. package/src/renderer/components/BuiltinToolsSettings.tsx +307 -0
  443. package/src/renderer/components/CanvasPreview.tsx +1189 -0
  444. package/src/renderer/components/CommandOutput.tsx +202 -0
  445. package/src/renderer/components/ContextPolicySettings.tsx +523 -0
  446. package/src/renderer/components/ControlPlaneSettings.tsx +1134 -0
  447. package/src/renderer/components/DisclaimerModal.tsx +124 -0
  448. package/src/renderer/components/DiscordSettings.tsx +436 -0
  449. package/src/renderer/components/EmailSettings.tsx +606 -0
  450. package/src/renderer/components/ExtensionsSettings.tsx +542 -0
  451. package/src/renderer/components/FileViewer.tsx +224 -0
  452. package/src/renderer/components/GoogleChatSettings.tsx +535 -0
  453. package/src/renderer/components/GuardrailSettings.tsx +487 -0
  454. package/src/renderer/components/HooksSettings.tsx +581 -0
  455. package/src/renderer/components/ImessageSettings.tsx +484 -0
  456. package/src/renderer/components/LineSettings.tsx +483 -0
  457. package/src/renderer/components/MCPRegistryBrowser.tsx +386 -0
  458. package/src/renderer/components/MCPSettings.tsx +943 -0
  459. package/src/renderer/components/MainContent.tsx +2433 -0
  460. package/src/renderer/components/MatrixSettings.tsx +510 -0
  461. package/src/renderer/components/MattermostSettings.tsx +473 -0
  462. package/src/renderer/components/MemorySettings.tsx +247 -0
  463. package/src/renderer/components/MentionBadge.tsx +87 -0
  464. package/src/renderer/components/MentionInput.tsx +409 -0
  465. package/src/renderer/components/MentionList.tsx +476 -0
  466. package/src/renderer/components/MissionControlPanel.tsx +1995 -0
  467. package/src/renderer/components/NodesSettings.tsx +316 -0
  468. package/src/renderer/components/NotificationPanel.tsx +481 -0
  469. package/src/renderer/components/Onboarding/AwakeningOrb.tsx +44 -0
  470. package/src/renderer/components/Onboarding/Onboarding.tsx +443 -0
  471. package/src/renderer/components/Onboarding/TypewriterText.tsx +102 -0
  472. package/src/renderer/components/Onboarding/index.ts +3 -0
  473. package/src/renderer/components/OnboardingModal.tsx +698 -0
  474. package/src/renderer/components/PairingCodeDisplay.tsx +324 -0
  475. package/src/renderer/components/PersonalitySettings.tsx +597 -0
  476. package/src/renderer/components/QueueSettings.tsx +119 -0
  477. package/src/renderer/components/QuickTaskFAB.tsx +71 -0
  478. package/src/renderer/components/RightPanel.tsx +413 -0
  479. package/src/renderer/components/ScheduledTasksSettings.tsx +1328 -0
  480. package/src/renderer/components/SearchSettings.tsx +328 -0
  481. package/src/renderer/components/Settings.tsx +1504 -0
  482. package/src/renderer/components/Sidebar.tsx +344 -0
  483. package/src/renderer/components/SignalSettings.tsx +673 -0
  484. package/src/renderer/components/SkillHubBrowser.tsx +458 -0
  485. package/src/renderer/components/SkillParameterModal.tsx +185 -0
  486. package/src/renderer/components/SkillsSettings.tsx +451 -0
  487. package/src/renderer/components/SlackSettings.tsx +442 -0
  488. package/src/renderer/components/StandupReportViewer.tsx +614 -0
  489. package/src/renderer/components/TaskBoard.tsx +498 -0
  490. package/src/renderer/components/TaskBoardCard.tsx +357 -0
  491. package/src/renderer/components/TaskBoardColumn.tsx +211 -0
  492. package/src/renderer/components/TaskLabelManager.tsx +472 -0
  493. package/src/renderer/components/TaskQueuePanel.tsx +144 -0
  494. package/src/renderer/components/TaskQuickActions.tsx +492 -0
  495. package/src/renderer/components/TaskTimeline.tsx +216 -0
  496. package/src/renderer/components/TaskView.tsx +162 -0
  497. package/src/renderer/components/TeamsSettings.tsx +518 -0
  498. package/src/renderer/components/TelegramSettings.tsx +421 -0
  499. package/src/renderer/components/Toast.tsx +76 -0
  500. package/src/renderer/components/TraySettings.tsx +189 -0
  501. package/src/renderer/components/TwitchSettings.tsx +511 -0
  502. package/src/renderer/components/UpdateSettings.tsx +295 -0
  503. package/src/renderer/components/VoiceIndicator.tsx +270 -0
  504. package/src/renderer/components/VoiceSettings.tsx +867 -0
  505. package/src/renderer/components/WhatsAppSettings.tsx +721 -0
  506. package/src/renderer/components/WorkingStateEditor.tsx +309 -0
  507. package/src/renderer/components/WorkingStateHistory.tsx +481 -0
  508. package/src/renderer/components/WorkspaceSelector.tsx +150 -0
  509. package/src/renderer/components/XSettings.tsx +311 -0
  510. package/src/renderer/global.d.ts +9 -0
  511. package/src/renderer/hooks/useAgentContext.ts +153 -0
  512. package/src/renderer/hooks/useOnboardingFlow.ts +548 -0
  513. package/src/renderer/hooks/useVoiceInput.ts +268 -0
  514. package/src/renderer/index.html +12 -0
  515. package/src/renderer/main.tsx +10 -0
  516. package/src/renderer/public/cowork-os-logo.png +0 -0
  517. package/src/renderer/quick-input.html +164 -0
  518. package/src/renderer/styles/index.css +14504 -0
  519. package/src/renderer/utils/agentMessages.ts +749 -0
  520. package/src/renderer/utils/voice-directives.ts +169 -0
  521. package/src/shared/channelMessages.ts +213 -0
  522. package/src/shared/types.ts +3608 -0
  523. package/tsconfig.electron.json +26 -0
  524. package/tsconfig.json +26 -0
  525. package/tsconfig.node.json +10 -0
  526. package/vite.config.ts +23 -0
@@ -0,0 +1,686 @@
1
+ import OpenAI from 'openai';
2
+ import {
3
+ getModel,
4
+ getModels,
5
+ complete as piAiComplete,
6
+ type Model,
7
+ type Message as PiAiMessage,
8
+ type Context as PiAiContext,
9
+ type Tool as PiAiTool,
10
+ } from '@mariozechner/pi-ai';
11
+ import {
12
+ LLMProvider,
13
+ LLMProviderConfig,
14
+ LLMRequest,
15
+ LLMResponse,
16
+ LLMContent,
17
+ LLMMessage,
18
+ LLMTool,
19
+ LLMToolResult,
20
+ } from './types';
21
+ import { OpenAIOAuth, OpenAIOAuthTokens } from './openai-oauth';
22
+
23
+ // Default model for openai-codex (ChatGPT backend)
24
+ const DEFAULT_CODEX_MODEL = 'gpt-5.1-codex-mini';
25
+
26
+ /**
27
+ * OpenAI API provider implementation
28
+ * Supports both API key and OAuth token authentication
29
+ * - API Key: Uses OpenAI SDK directly with api.openai.com
30
+ * - OAuth: Uses pi-ai SDK with ChatGPT backend (chatgpt.com/backend-api/)
31
+ */
32
+ export class OpenAIProvider implements LLMProvider {
33
+ readonly type = 'openai' as const;
34
+ private client: OpenAI | null = null;
35
+ private authMethod: 'api_key' | 'oauth';
36
+ private oauthTokens?: OpenAIOAuthTokens;
37
+ private model: string;
38
+
39
+ constructor(config: LLMProviderConfig) {
40
+ const apiKey = config.openaiApiKey;
41
+ const accessToken = config.openaiAccessToken;
42
+ const refreshToken = config.openaiRefreshToken;
43
+ const tokenExpiresAt = config.openaiTokenExpiresAt;
44
+ this.model = config.model;
45
+
46
+ if (accessToken && refreshToken) {
47
+ // Use OAuth - will use pi-ai SDK for API calls
48
+ this.oauthTokens = {
49
+ access_token: accessToken,
50
+ refresh_token: refreshToken,
51
+ expires_at: tokenExpiresAt || 0, // Use stored expiry or 0 if not available
52
+ };
53
+ this.authMethod = 'oauth';
54
+ console.log(`[OpenAI] Using OAuth authentication with pi-ai SDK (token expires: ${tokenExpiresAt ? new Date(tokenExpiresAt).toISOString() : 'unknown'})`);
55
+ } else if (apiKey) {
56
+ // Use API key - standard OpenAI SDK
57
+ this.client = new OpenAI({ apiKey });
58
+ this.authMethod = 'api_key';
59
+ console.log('[OpenAI] Using API key authentication');
60
+ } else {
61
+ throw new Error('OpenAI authentication required. Use API key or sign in with ChatGPT.');
62
+ }
63
+ }
64
+
65
+ async createMessage(request: LLMRequest): Promise<LLMResponse> {
66
+ if (this.authMethod === 'oauth') {
67
+ return this.createMessageWithOAuth(request);
68
+ } else {
69
+ return this.createMessageWithApiKey(request);
70
+ }
71
+ }
72
+
73
+ /**
74
+ * Create message using API key (standard OpenAI SDK)
75
+ */
76
+ private async createMessageWithApiKey(request: LLMRequest): Promise<LLMResponse> {
77
+ if (!this.client) {
78
+ throw new Error('OpenAI client not initialized');
79
+ }
80
+
81
+ const messages = this.convertMessages(request.messages, request.system);
82
+ const tools = request.tools ? this.convertTools(request.tools) : undefined;
83
+
84
+ try {
85
+ console.log(`[OpenAI] Calling API with model: ${request.model}`);
86
+
87
+ const response = await this.client.chat.completions.create(
88
+ {
89
+ model: request.model,
90
+ max_tokens: request.maxTokens,
91
+ messages,
92
+ ...(tools && tools.length > 0 && { tools }),
93
+ },
94
+ request.signal ? { signal: request.signal } : undefined
95
+ );
96
+
97
+ return this.convertResponse(response);
98
+ } catch (error: any) {
99
+ // Handle abort errors gracefully
100
+ if (error.name === 'AbortError' || error.message?.includes('aborted')) {
101
+ console.log(`[OpenAI] Request aborted`);
102
+ throw new Error('Request cancelled');
103
+ }
104
+
105
+ console.error(`[OpenAI] API error:`, {
106
+ status: error.status,
107
+ message: error.message,
108
+ type: error.type || error.name,
109
+ });
110
+ throw error;
111
+ }
112
+ }
113
+
114
+ /**
115
+ * Map public model names to openai-codex model IDs
116
+ */
117
+ private mapToCodexModel(modelId: string): string {
118
+ // Map common public model names to ChatGPT internal models
119
+ const modelMap: Record<string, string> = {
120
+ // Map gpt-4o models to gpt-5.1
121
+ 'gpt-4o': 'gpt-5.1',
122
+ 'gpt-4o-mini': 'gpt-5.1-codex-mini',
123
+ // Map o1/reasoning models to gpt-5.2
124
+ 'o1': 'gpt-5.2',
125
+ 'o1-mini': 'gpt-5.2-codex',
126
+ 'o1-preview': 'gpt-5.2',
127
+ // Default mappings
128
+ 'gpt-4-turbo': 'gpt-5.1',
129
+ 'gpt-4': 'gpt-5.1',
130
+ 'gpt-3.5-turbo': 'gpt-5.1-codex-mini',
131
+ };
132
+
133
+ return modelMap[modelId] || modelId;
134
+ }
135
+
136
+ /**
137
+ * Create message using OAuth (pi-ai SDK with ChatGPT backend)
138
+ */
139
+ private async createMessageWithOAuth(request: LLMRequest): Promise<LLMResponse> {
140
+ if (!this.oauthTokens) {
141
+ throw new Error('OAuth tokens not available');
142
+ }
143
+
144
+ try {
145
+ // Map model ID to ChatGPT internal model
146
+ const codexModelId = this.mapToCodexModel(request.model);
147
+ console.log(`[OpenAI] Calling ChatGPT backend with model: ${codexModelId} (requested: ${request.model})`);
148
+
149
+ // Get the model object from pi-ai SDK
150
+ let model: Model<any>;
151
+ try {
152
+ // Get available models and find one that matches
153
+ const availableModels = getModels('openai-codex');
154
+ const found = availableModels.find(m => m.id === codexModelId);
155
+ if (found) {
156
+ model = found;
157
+ } else {
158
+ // Use default if not found
159
+ console.log(`[OpenAI] Model ${codexModelId} not found, using default: ${DEFAULT_CODEX_MODEL}`);
160
+ model = availableModels.find(m => m.id === DEFAULT_CODEX_MODEL) || availableModels[0];
161
+ }
162
+ } catch (e) {
163
+ console.error('[OpenAI] Failed to get model from pi-ai SDK:', e);
164
+ throw new Error(`Model not available: ${codexModelId}`);
165
+ }
166
+
167
+ // Convert messages to pi-ai format
168
+ const piAiMessages = this.convertMessagesToPiAi(request.messages);
169
+
170
+ // Convert tools to pi-ai format
171
+ const piAiTools = request.tools ? this.convertToolsToPiAi(request.tools) : undefined;
172
+
173
+ // Get API key from OAuth tokens (with auto-refresh)
174
+ const { apiKey, newTokens } = await OpenAIOAuth.getApiKeyFromTokens(this.oauthTokens);
175
+
176
+ // Update tokens if they were refreshed
177
+ if (newTokens) {
178
+ this.oauthTokens = newTokens;
179
+ }
180
+
181
+ // Build context
182
+ const context: PiAiContext = {
183
+ systemPrompt: request.system,
184
+ messages: piAiMessages,
185
+ tools: piAiTools,
186
+ };
187
+
188
+ // Make the API call using pi-ai SDK
189
+ const response = await piAiComplete(model, context, {
190
+ apiKey,
191
+ maxTokens: request.maxTokens,
192
+ signal: request.signal,
193
+ });
194
+
195
+ // Convert pi-ai response to our format
196
+ return this.convertPiAiResponse(response);
197
+ } catch (error: any) {
198
+ // Handle abort errors gracefully
199
+ if (error.name === 'AbortError' || error.message?.includes('aborted')) {
200
+ console.log(`[OpenAI] Request aborted`);
201
+ throw new Error('Request cancelled');
202
+ }
203
+
204
+ console.error(`[OpenAI] ChatGPT API error:`, {
205
+ message: error.message,
206
+ type: error.type || error.name,
207
+ });
208
+ throw error;
209
+ }
210
+ }
211
+
212
+ async testConnection(): Promise<{ success: boolean; error?: string }> {
213
+ try {
214
+ if (this.authMethod === 'oauth') {
215
+ // For OAuth, try to get the API key and make a simple request
216
+ if (!this.oauthTokens) {
217
+ return { success: false, error: 'OAuth tokens not available' };
218
+ }
219
+
220
+ const { apiKey } = await OpenAIOAuth.getApiKeyFromTokens(this.oauthTokens);
221
+
222
+ // Get a model from the available models
223
+ const availableModels = getModels('openai-codex');
224
+ const model = availableModels.find(m => m.id === DEFAULT_CODEX_MODEL) || availableModels[0];
225
+
226
+ await piAiComplete(
227
+ model,
228
+ {
229
+ messages: [{
230
+ role: 'user',
231
+ content: [{ type: 'text', text: 'Hi' }],
232
+ timestamp: Date.now(),
233
+ }],
234
+ },
235
+ { apiKey, maxTokens: 10 }
236
+ );
237
+
238
+ return { success: true };
239
+ } else {
240
+ // For API key, use standard OpenAI SDK
241
+ if (!this.client) {
242
+ return { success: false, error: 'OpenAI client not initialized' };
243
+ }
244
+
245
+ await this.client.chat.completions.create({
246
+ model: 'gpt-4o-mini',
247
+ max_tokens: 10,
248
+ messages: [{ role: 'user', content: 'Hi' }],
249
+ });
250
+ return { success: true };
251
+ }
252
+ } catch (error: any) {
253
+ return {
254
+ success: false,
255
+ error: error.message || 'Failed to connect to OpenAI API',
256
+ };
257
+ }
258
+ }
259
+
260
+ /**
261
+ * Get available models
262
+ * For API key: uses the models.list API
263
+ * For OAuth: uses pi-ai SDK's model list for openai-codex provider
264
+ */
265
+ async getAvailableModels(): Promise<Array<{ id: string; name: string; description: string }>> {
266
+ // For OAuth authentication, use pi-ai SDK's model list
267
+ if (this.authMethod === 'oauth') {
268
+ console.log('[OpenAI] Using OAuth - fetching models from pi-ai SDK...');
269
+
270
+ try {
271
+ // Get models from pi-ai SDK for openai-codex provider
272
+ const piAiModels = getModels('openai-codex');
273
+
274
+ const models = piAiModels.map((m) => ({
275
+ id: m.id,
276
+ name: m.name || this.formatModelName(m.id),
277
+ description: this.getModelDescription(m.id),
278
+ }));
279
+
280
+ // Sort by priority
281
+ models.sort((a, b) => {
282
+ const priority = (id: string) => {
283
+ if (id.includes('5.1-codex-mini')) return 0;
284
+ if (id.includes('5.1-codex-max')) return 1;
285
+ if (id === 'gpt-5.1') return 2;
286
+ if (id.includes('5.2-codex')) return 3;
287
+ if (id === 'gpt-5.2') return 4;
288
+ return 5;
289
+ };
290
+ return priority(a.id) - priority(b.id);
291
+ });
292
+
293
+ console.log(`[OpenAI] Found ${models.length} models via pi-ai SDK`);
294
+ return models;
295
+ } catch (error) {
296
+ console.error('[OpenAI] Failed to get models from pi-ai SDK:', error);
297
+ // Return defaults on error
298
+ return this.getDefaultCodexModels();
299
+ }
300
+ }
301
+
302
+ // For API key authentication, use the standard models list API
303
+ if (this.client) {
304
+ try {
305
+ const response = await this.client.models.list();
306
+ const models = response.data
307
+ .filter((m) => m.id.startsWith('gpt-') || m.id.startsWith('o1') || m.id.startsWith('o3'))
308
+ .map((m) => ({
309
+ id: m.id,
310
+ name: this.formatModelName(m.id),
311
+ description: this.getModelDescription(m.id),
312
+ }))
313
+ .sort((a, b) => {
314
+ const priority = (id: string) => {
315
+ if (id.includes('gpt-4o')) return 0;
316
+ if (id.includes('gpt-4')) return 1;
317
+ if (id.includes('gpt-3.5')) return 2;
318
+ if (id.includes('o1')) return 3;
319
+ if (id.includes('o3')) return 4;
320
+ return 5;
321
+ };
322
+ return priority(a.id) - priority(b.id);
323
+ });
324
+ return models;
325
+ } catch (error: any) {
326
+ console.error('Failed to fetch OpenAI models:', error);
327
+ }
328
+ }
329
+
330
+ // Return defaults if nothing else works
331
+ return this.getDefaultModels();
332
+ }
333
+
334
+ private getDefaultModels(): Array<{ id: string; name: string; description: string }> {
335
+ return [
336
+ { id: 'gpt-4o', name: 'GPT-4o', description: 'Most capable model for complex tasks' },
337
+ { id: 'gpt-4o-mini', name: 'GPT-4o Mini', description: 'Fast and affordable for most tasks' },
338
+ { id: 'o1', name: 'o1', description: 'Advanced reasoning model' },
339
+ { id: 'o1-mini', name: 'o1 Mini', description: 'Fast reasoning model' },
340
+ { id: 'gpt-4-turbo', name: 'GPT-4 Turbo', description: 'Previous generation flagship' },
341
+ { id: 'gpt-3.5-turbo', name: 'GPT-3.5 Turbo', description: 'Fast and cost-effective' },
342
+ ];
343
+ }
344
+
345
+ private getDefaultCodexModels(): Array<{ id: string; name: string; description: string }> {
346
+ return [
347
+ { id: 'gpt-5.1-codex-mini', name: 'GPT-5.1 Codex Mini', description: 'Fast and efficient for most tasks' },
348
+ { id: 'gpt-5.1-codex-max', name: 'GPT-5.1 Codex Max', description: 'Maximum capability for complex tasks' },
349
+ { id: 'gpt-5.1', name: 'GPT-5.1', description: 'Balanced performance and capability' },
350
+ { id: 'gpt-5.2-codex', name: 'GPT-5.2 Codex', description: 'Advanced reasoning model' },
351
+ { id: 'gpt-5.2', name: 'GPT-5.2', description: 'Most advanced reasoning' },
352
+ ];
353
+ }
354
+
355
+ private formatModelName(modelId: string): string {
356
+ // Format model ID to display name
357
+ if (modelId === 'gpt-4o') return 'GPT-4o';
358
+ if (modelId === 'gpt-4o-mini') return 'GPT-4o Mini';
359
+ if (modelId.includes('gpt-4o-')) return `GPT-4o (${modelId.replace('gpt-4o-', '')})`;
360
+ if (modelId === 'gpt-4-turbo') return 'GPT-4 Turbo';
361
+ if (modelId.includes('gpt-4-turbo-')) return `GPT-4 Turbo (${modelId.replace('gpt-4-turbo-', '')})`;
362
+ if (modelId === 'gpt-4') return 'GPT-4';
363
+ if (modelId.includes('gpt-4-')) return `GPT-4 (${modelId.replace('gpt-4-', '')})`;
364
+ if (modelId === 'gpt-3.5-turbo') return 'GPT-3.5 Turbo';
365
+ if (modelId.includes('gpt-3.5-turbo-')) return `GPT-3.5 Turbo (${modelId.replace('gpt-3.5-turbo-', '')})`;
366
+ if (modelId === 'o1') return 'o1';
367
+ if (modelId === 'o1-mini') return 'o1 Mini';
368
+ if (modelId === 'o1-preview') return 'o1 Preview';
369
+ if (modelId === 'o3-mini') return 'o3 Mini';
370
+ // ChatGPT internal models
371
+ if (modelId === 'gpt-5.1') return 'GPT-5.1';
372
+ if (modelId === 'gpt-5.1-codex-mini') return 'GPT-5.1 Codex Mini';
373
+ if (modelId === 'gpt-5.1-codex-max') return 'GPT-5.1 Codex Max';
374
+ if (modelId === 'gpt-5.2') return 'GPT-5.2';
375
+ if (modelId === 'gpt-5.2-codex') return 'GPT-5.2 Codex';
376
+ return modelId;
377
+ }
378
+
379
+ private getModelDescription(modelId: string): string {
380
+ if (modelId.includes('gpt-4o') && !modelId.includes('mini')) return 'Most capable model for complex tasks';
381
+ if (modelId.includes('gpt-4o-mini')) return 'Fast and affordable for most tasks';
382
+ if (modelId.includes('gpt-4-turbo')) return 'Previous generation flagship';
383
+ if (modelId.includes('gpt-4')) return 'High capability model';
384
+ if (modelId.includes('gpt-3.5')) return 'Fast and cost-effective';
385
+ if (modelId === 'o1' || modelId === 'o1-preview') return 'Advanced reasoning model';
386
+ if (modelId === 'o1-mini') return 'Fast reasoning model';
387
+ if (modelId.includes('o3')) return 'Next generation reasoning';
388
+ // ChatGPT internal models
389
+ if (modelId === 'gpt-5.1') return 'Balanced performance and capability';
390
+ if (modelId === 'gpt-5.1-codex-mini') return 'Fast and efficient for most tasks';
391
+ if (modelId === 'gpt-5.1-codex-max') return 'Maximum capability for complex tasks';
392
+ if (modelId === 'gpt-5.2') return 'Most advanced reasoning';
393
+ if (modelId === 'gpt-5.2-codex') return 'Advanced reasoning model';
394
+ return 'OpenAI model';
395
+ }
396
+
397
+ /**
398
+ * Convert messages to pi-ai SDK format
399
+ */
400
+ private convertMessagesToPiAi(messages: LLMMessage[]): PiAiMessage[] {
401
+ const result: PiAiMessage[] = [];
402
+ const now = Date.now();
403
+
404
+ for (const msg of messages) {
405
+ if (typeof msg.content === 'string') {
406
+ if (msg.role === 'user') {
407
+ result.push({
408
+ role: 'user',
409
+ content: [{ type: 'text', text: msg.content }],
410
+ timestamp: now,
411
+ });
412
+ } else {
413
+ // Assistant message
414
+ result.push({
415
+ role: 'assistant',
416
+ content: [{ type: 'text', text: msg.content }],
417
+ api: 'openai-codex-responses',
418
+ provider: 'openai-codex',
419
+ model: this.model,
420
+ usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, totalTokens: 0, cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 } },
421
+ stopReason: 'stop',
422
+ timestamp: now,
423
+ });
424
+ }
425
+ } else if (Array.isArray(msg.content)) {
426
+ // Check if this is a tool result array
427
+ const toolResults = msg.content.filter((item): item is LLMToolResult => item.type === 'tool_result');
428
+
429
+ if (toolResults.length > 0) {
430
+ // Convert tool results to pi-ai format
431
+ for (const toolResult of toolResults) {
432
+ result.push({
433
+ role: 'toolResult',
434
+ toolCallId: toolResult.tool_use_id,
435
+ toolName: '', // Will be filled by the SDK
436
+ content: [{ type: 'text', text: toolResult.content }],
437
+ isError: toolResult.is_error || false,
438
+ timestamp: now,
439
+ });
440
+ }
441
+ } else {
442
+ // Handle mixed content (text and tool_use)
443
+ if (msg.role === 'user') {
444
+ const textContent = msg.content
445
+ .filter((item) => item.type === 'text')
446
+ .map((item) => ({ type: 'text' as const, text: (item as any).text }));
447
+
448
+ if (textContent.length > 0) {
449
+ result.push({
450
+ role: 'user',
451
+ content: textContent,
452
+ timestamp: now,
453
+ });
454
+ }
455
+ } else {
456
+ // Assistant message with tool calls
457
+ const content: any[] = [];
458
+
459
+ for (const item of msg.content) {
460
+ if (item.type === 'text') {
461
+ content.push({ type: 'text', text: (item as any).text });
462
+ } else if (item.type === 'tool_use') {
463
+ content.push({
464
+ type: 'toolCall',
465
+ id: (item as any).id,
466
+ name: (item as any).name,
467
+ arguments: (item as any).input,
468
+ });
469
+ }
470
+ }
471
+
472
+ if (content.length > 0) {
473
+ result.push({
474
+ role: 'assistant',
475
+ content,
476
+ api: 'openai-codex-responses',
477
+ provider: 'openai-codex',
478
+ model: this.model,
479
+ usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, totalTokens: 0, cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 } },
480
+ stopReason: 'stop',
481
+ timestamp: now,
482
+ });
483
+ }
484
+ }
485
+ }
486
+ }
487
+ }
488
+
489
+ return result;
490
+ }
491
+
492
+ /**
493
+ * Convert tools to pi-ai SDK format
494
+ */
495
+ private convertToolsToPiAi(tools: LLMTool[]): PiAiTool[] {
496
+ return tools.map((tool) => ({
497
+ name: tool.name,
498
+ description: tool.description,
499
+ parameters: tool.input_schema as any,
500
+ }));
501
+ }
502
+
503
+ /**
504
+ * Convert pi-ai response to our format
505
+ */
506
+ private convertPiAiResponse(response: any): LLMResponse {
507
+ const content: LLMContent[] = [];
508
+
509
+ if (response.content) {
510
+ for (const block of response.content) {
511
+ if (block.type === 'text') {
512
+ content.push({
513
+ type: 'text',
514
+ text: block.text,
515
+ });
516
+ } else if (block.type === 'toolCall') {
517
+ content.push({
518
+ type: 'tool_use',
519
+ id: block.id,
520
+ name: block.name,
521
+ input: block.arguments || {},
522
+ });
523
+ }
524
+ }
525
+ }
526
+
527
+ // Map stop reason
528
+ let stopReason: LLMResponse['stopReason'] = 'end_turn';
529
+ if (response.stopReason === 'toolUse') {
530
+ stopReason = 'tool_use';
531
+ } else if (response.stopReason === 'length') {
532
+ stopReason = 'max_tokens';
533
+ }
534
+
535
+ return {
536
+ content,
537
+ stopReason,
538
+ usage: response.usage
539
+ ? {
540
+ inputTokens: response.usage.input || 0,
541
+ outputTokens: response.usage.output || 0,
542
+ }
543
+ : undefined,
544
+ };
545
+ }
546
+
547
+ /**
548
+ * Convert messages to OpenAI format (for API key auth)
549
+ */
550
+ private convertMessages(messages: LLMMessage[], system?: string): OpenAI.ChatCompletionMessageParam[] {
551
+ const result: OpenAI.ChatCompletionMessageParam[] = [];
552
+
553
+ // Add system message first if provided
554
+ if (system) {
555
+ result.push({
556
+ role: 'system',
557
+ content: system,
558
+ });
559
+ }
560
+
561
+ for (const msg of messages) {
562
+ if (typeof msg.content === 'string') {
563
+ result.push({
564
+ role: msg.role,
565
+ content: msg.content,
566
+ });
567
+ } else if (Array.isArray(msg.content)) {
568
+ // Check if this is a tool result array
569
+ const toolResults = msg.content.filter((item): item is LLMToolResult => item.type === 'tool_result');
570
+
571
+ if (toolResults.length > 0) {
572
+ // Convert tool results to OpenAI format
573
+ for (const toolResult of toolResults) {
574
+ result.push({
575
+ role: 'tool',
576
+ tool_call_id: toolResult.tool_use_id,
577
+ content: toolResult.content,
578
+ });
579
+ }
580
+ } else {
581
+ // Handle mixed content (text and tool_use)
582
+ const textContent = msg.content
583
+ .filter((item) => item.type === 'text')
584
+ .map((item) => (item as { type: 'text'; text: string }).text)
585
+ .join('\n');
586
+
587
+ const toolUses = msg.content.filter((item) => item.type === 'tool_use');
588
+
589
+ if (msg.role === 'assistant') {
590
+ const assistantMsg: OpenAI.ChatCompletionAssistantMessageParam = {
591
+ role: 'assistant',
592
+ content: textContent || null,
593
+ };
594
+
595
+ if (toolUses.length > 0) {
596
+ assistantMsg.tool_calls = toolUses.map((tool) => ({
597
+ id: (tool as any).id,
598
+ type: 'function' as const,
599
+ function: {
600
+ name: (tool as any).name,
601
+ arguments: JSON.stringify((tool as any).input),
602
+ },
603
+ }));
604
+ }
605
+
606
+ result.push(assistantMsg);
607
+ } else {
608
+ result.push({
609
+ role: msg.role,
610
+ content: textContent,
611
+ });
612
+ }
613
+ }
614
+ }
615
+ }
616
+
617
+ return result;
618
+ }
619
+
620
+ private convertTools(tools: LLMTool[]): OpenAI.ChatCompletionTool[] {
621
+ return tools.map((tool) => ({
622
+ type: 'function' as const,
623
+ function: {
624
+ name: tool.name,
625
+ description: tool.description,
626
+ parameters: tool.input_schema,
627
+ },
628
+ }));
629
+ }
630
+
631
+ private convertResponse(response: OpenAI.ChatCompletion): LLMResponse {
632
+ const choice = response.choices[0];
633
+ const content: LLMContent[] = [];
634
+
635
+ // Add text content if present
636
+ if (choice.message.content) {
637
+ content.push({
638
+ type: 'text',
639
+ text: choice.message.content,
640
+ });
641
+ }
642
+
643
+ // Add tool calls if present
644
+ if (choice.message.tool_calls) {
645
+ for (const toolCall of choice.message.tool_calls) {
646
+ // Only handle function-type tool calls
647
+ if (toolCall.type === 'function') {
648
+ content.push({
649
+ type: 'tool_use',
650
+ id: toolCall.id,
651
+ name: toolCall.function.name,
652
+ input: JSON.parse(toolCall.function.arguments || '{}'),
653
+ });
654
+ }
655
+ }
656
+ }
657
+
658
+ return {
659
+ content,
660
+ stopReason: this.mapStopReason(choice.finish_reason),
661
+ usage: response.usage
662
+ ? {
663
+ inputTokens: response.usage.prompt_tokens,
664
+ outputTokens: response.usage.completion_tokens,
665
+ }
666
+ : undefined,
667
+ };
668
+ }
669
+
670
+ private mapStopReason(
671
+ reason: OpenAI.ChatCompletion.Choice['finish_reason']
672
+ ): LLMResponse['stopReason'] {
673
+ switch (reason) {
674
+ case 'stop':
675
+ return 'end_turn';
676
+ case 'tool_calls':
677
+ return 'tool_use';
678
+ case 'length':
679
+ return 'max_tokens';
680
+ case 'content_filter':
681
+ return 'stop_sequence';
682
+ default:
683
+ return 'end_turn';
684
+ }
685
+ }
686
+ }