@agent-spaces/server 0.3.65 → 0.4.0

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 (278) hide show
  1. package/dist/adapters/agent-runtime.js +8 -0
  2. package/dist/adapters/codex-function-tool-bridge.js +152 -0
  3. package/dist/adapters/codex-runtime.js +23 -4
  4. package/dist/adapters/git.js +25 -3
  5. package/dist/adapters/hermes-runtime.js +813 -0
  6. package/dist/adapters/langchain-runtime.js +384 -21
  7. package/dist/adapters/oh-my-pi-runtime.js +858 -0
  8. package/dist/adapters/open-agent-sdk-runtime.js +202 -5
  9. package/dist/adapters/open-agent-sdk-runtime.test.js +35 -0
  10. package/dist/agents/agent-message-parts.js +52 -2
  11. package/dist/agents/issue-task-controller.js +71 -2
  12. package/dist/agents/pull-request-agent.js +115 -0
  13. package/dist/agents/scheduler-agent.js +1 -1
  14. package/dist/agents/title-generator-agent.js +120 -0
  15. package/dist/app.js +61 -4
  16. package/dist/middleware/auth.js +1 -1
  17. package/dist/package.json +2 -1
  18. package/dist/routes/agent-sse.js +70 -6
  19. package/dist/routes/channel.js +23 -2
  20. package/dist/routes/chat-run.js +191 -0
  21. package/dist/routes/chat.js +142 -0
  22. package/dist/routes/command.js +16 -0
  23. package/dist/routes/data.js +189 -0
  24. package/dist/routes/git.js +10 -1
  25. package/dist/routes/import.js +199 -0
  26. package/dist/routes/issue.js +17 -5
  27. package/dist/routes/notification.js +10 -0
  28. package/dist/routes/plugin.js +69 -0
  29. package/dist/routes/version.js +95 -0
  30. package/dist/routes/workflow-hook.js +71 -0
  31. package/dist/routes/workflow.js +282 -7
  32. package/dist/routes/workspace.js +13 -4
  33. package/dist/routes/worktree.js +93 -0
  34. package/dist/services/agent.js +123 -36
  35. package/dist/services/ai-text.js +185 -0
  36. package/dist/services/builtin-tools/index.js +1 -0
  37. package/dist/services/builtin-tools/workflow-editor-tools.js +509 -0
  38. package/dist/services/builtin-tools/workflow-exec-tools.js +320 -0
  39. package/dist/services/chat.js +134 -0
  40. package/dist/services/command-process-manager.js +16 -0
  41. package/dist/services/execution-manager.js +1346 -0
  42. package/dist/services/generated-title.js +59 -0
  43. package/dist/services/gitignore.js +22 -18
  44. package/dist/services/interaction-manager.js +114 -0
  45. package/dist/services/issue-retry.js +25 -0
  46. package/dist/services/notification-center.js +9 -0
  47. package/dist/services/output-style.js +8 -1
  48. package/dist/services/plugin.js +257 -0
  49. package/dist/services/prompt-template.js +8 -1
  50. package/dist/services/pty.js +20 -0
  51. package/dist/services/search.js +16 -6
  52. package/dist/services/skill.js +2 -0
  53. package/dist/services/version.js +69 -0
  54. package/dist/services/workflow-command-runner.js +24 -0
  55. package/dist/services/workflow-trigger-service.js +137 -0
  56. package/dist/services/workflow.js +219 -39
  57. package/dist/services/workspace.js +23 -1
  58. package/dist/services/worktree.js +207 -0
  59. package/dist/storage/agent-store.js +8 -0
  60. package/dist/storage/chat-store.js +151 -0
  61. package/dist/storage/database-store.js +6 -0
  62. package/dist/storage/json-store.js +2 -1
  63. package/dist/storage/kanban-store.js +6 -0
  64. package/dist/storage/workflow-store.js +386 -22
  65. package/dist/storage/worktree-store.js +33 -0
  66. package/dist/web/404.html +1 -1
  67. package/dist/web/__next.__PAGE__.txt +4 -4
  68. package/dist/web/__next._full.txt +21 -21
  69. package/dist/web/__next._head.txt +4 -4
  70. package/dist/web/__next._index.txt +13 -13
  71. package/dist/web/__next._tree.txt +2 -2
  72. package/dist/web/_next/static/chunks/{08x85faoz58i7.js → 0-92u-tiuy40a.js} +4 -4
  73. package/dist/web/_next/static/chunks/{0db14450oqzhg.js → 0-yizd8osmas2.js} +1 -1
  74. package/dist/web/_next/static/chunks/0.ln~3mnv8.69.js +1 -0
  75. package/dist/web/_next/static/chunks/{11cchuwoupmbf.js → 01y3e9pemva7b.js} +10 -10
  76. package/dist/web/_next/static/chunks/02l~tmzrgny.~.js +1 -0
  77. package/dist/web/_next/static/chunks/03f1bwuynjdmk.js +1 -0
  78. package/dist/web/_next/static/chunks/04cb4kc9r2pd1.js +1 -0
  79. package/dist/web/_next/static/chunks/04de6ha5_e3pp.js +1 -0
  80. package/dist/web/_next/static/chunks/09he0p79ov1rn.js +1 -0
  81. package/dist/web/_next/static/chunks/09vpocs4zuc8h.js +1 -0
  82. package/dist/web/_next/static/chunks/0_o2exgr0e_nh.js +1 -0
  83. package/dist/web/_next/static/chunks/{0xbaakj0dfc0..js → 0_y9nskc-xt2k.js} +1 -1
  84. package/dist/web/_next/static/chunks/0clnj-1fi6u8j.js +3 -0
  85. package/dist/web/_next/static/chunks/0gv40by0zzxs_.js +1 -0
  86. package/dist/web/_next/static/chunks/0iusr8y88.kjg.js +1 -0
  87. package/dist/web/_next/static/chunks/{0-a.-hl3wv99k.js → 0j-8418fxvkd1.js} +1 -1
  88. package/dist/web/_next/static/chunks/0j.wxxyoclma5.js +1 -0
  89. package/dist/web/_next/static/chunks/{0.6b64sy0g5.3.js → 0jq.16sozqik..js} +1 -1
  90. package/dist/web/_next/static/chunks/0jw8xdk_fpnp0.css +1 -0
  91. package/dist/web/_next/static/chunks/0l1lkd-wcotma.js +1 -0
  92. package/dist/web/_next/static/chunks/{0u6h-hqc_i52e.js → 0ncxf_zr4n839.js} +1 -1
  93. package/dist/web/_next/static/chunks/0ndo7um~v7vco.js +1 -0
  94. package/dist/web/_next/static/chunks/0ngk.~kan8wq_.js +1 -0
  95. package/dist/web/_next/static/chunks/0ppr271hz0xoq.js +1 -0
  96. package/dist/web/_next/static/chunks/0rt9bofnn6qvn.js +1 -0
  97. package/dist/web/_next/static/chunks/0t64.9jd00hio.js +3 -0
  98. package/dist/web/_next/static/chunks/0taui9--5n6-5.js +1 -0
  99. package/dist/web/_next/static/chunks/0ty39169lh~z3.js +1 -0
  100. package/dist/web/_next/static/chunks/0v8nof~waedlu.js +1 -0
  101. package/dist/web/_next/static/chunks/{0-pi.67w.ymsr.js → 0vcfoagnpf.aw.js} +1 -1
  102. package/dist/web/_next/static/chunks/{0vis~lx0nxgn-.js → 0wwwq.gyyz0vg.js} +3 -3
  103. package/dist/web/_next/static/chunks/0x5lak8yz7pm7.js +1 -0
  104. package/dist/web/_next/static/chunks/0xon_.4-o0_zq.js +7 -0
  105. package/dist/web/_next/static/chunks/0zjnrbt7inime.js +1 -0
  106. package/dist/web/_next/static/chunks/0zwebpitvpuv1.js +1 -0
  107. package/dist/web/_next/static/chunks/0~02o4g-o6n~m.js +1 -0
  108. package/dist/web/_next/static/chunks/{0w7.tb29958zj.js → 0~fjezp.k4qk3.js} +1 -1
  109. package/dist/web/_next/static/chunks/0~sh93re1-_rp.js +1 -0
  110. package/dist/web/_next/static/chunks/10_niiq0k6o-p.js +5 -0
  111. package/dist/web/_next/static/chunks/12tjr0_2ccrtq.js +2 -0
  112. package/dist/web/_next/static/chunks/12x5.go_x9mfk.js +1 -0
  113. package/dist/web/_next/static/chunks/{0l2w0qz1ea7ql.js → 12~5dk9i9d16t.js} +2 -2
  114. package/dist/web/_next/static/chunks/13iye4rv5p31b.js +1 -0
  115. package/dist/web/_next/static/chunks/{01~quun6sefgl.js → 13~y-b.b9rrw4.js} +1 -1
  116. package/dist/web/_next/static/chunks/151wzhb5q0lo5.js +1 -0
  117. package/dist/web/_not-found/__next._full.txt +19 -19
  118. package/dist/web/_not-found/__next._head.txt +4 -4
  119. package/dist/web/_not-found/__next._index.txt +13 -13
  120. package/dist/web/_not-found/__next._not-found.__PAGE__.txt +2 -2
  121. package/dist/web/_not-found/__next._not-found.txt +3 -3
  122. package/dist/web/_not-found/__next._tree.txt +2 -2
  123. package/dist/web/_not-found.html +1 -1
  124. package/dist/web/_not-found.txt +19 -19
  125. package/dist/web/index.html +1 -1
  126. package/dist/web/index.txt +21 -21
  127. package/dist/web/login/__next._full.txt +21 -21
  128. package/dist/web/login/__next._head.txt +4 -4
  129. package/dist/web/login/__next._index.txt +13 -13
  130. package/dist/web/login/__next._tree.txt +2 -2
  131. package/dist/web/login/__next.login.__PAGE__.txt +4 -4
  132. package/dist/web/login/__next.login.txt +3 -3
  133. package/dist/web/login.html +1 -1
  134. package/dist/web/login.txt +21 -21
  135. package/dist/web/settings/__next._full.txt +23 -23
  136. package/dist/web/settings/__next._head.txt +4 -4
  137. package/dist/web/settings/__next._index.txt +13 -13
  138. package/dist/web/settings/__next._tree.txt +2 -2
  139. package/dist/web/settings/__next.settings.__PAGE__.txt +4 -4
  140. package/dist/web/settings/__next.settings.txt +5 -5
  141. package/dist/web/settings/agents/__next._full.txt +23 -23
  142. package/dist/web/settings/agents/__next._head.txt +4 -4
  143. package/dist/web/settings/agents/__next._index.txt +13 -13
  144. package/dist/web/settings/agents/__next._tree.txt +2 -2
  145. package/dist/web/settings/agents/__next.settings.agents.__PAGE__.txt +4 -4
  146. package/dist/web/settings/agents/__next.settings.agents.txt +3 -3
  147. package/dist/web/settings/agents/__next.settings.txt +5 -5
  148. package/dist/web/settings/agents.html +1 -1
  149. package/dist/web/settings/agents.txt +23 -23
  150. package/dist/web/settings/mcps/__next._full.txt +23 -23
  151. package/dist/web/settings/mcps/__next._head.txt +4 -4
  152. package/dist/web/settings/mcps/__next._index.txt +13 -13
  153. package/dist/web/settings/mcps/__next._tree.txt +2 -2
  154. package/dist/web/settings/mcps/__next.settings.mcps.__PAGE__.txt +4 -4
  155. package/dist/web/settings/mcps/__next.settings.mcps.txt +3 -3
  156. package/dist/web/settings/mcps/__next.settings.txt +5 -5
  157. package/dist/web/settings/mcps.html +1 -1
  158. package/dist/web/settings/mcps.txt +23 -23
  159. package/dist/web/settings/models/__next._full.txt +23 -23
  160. package/dist/web/settings/models/__next._head.txt +4 -4
  161. package/dist/web/settings/models/__next._index.txt +13 -13
  162. package/dist/web/settings/models/__next._tree.txt +2 -2
  163. package/dist/web/settings/models/__next.settings.models.__PAGE__.txt +4 -4
  164. package/dist/web/settings/models/__next.settings.models.txt +3 -3
  165. package/dist/web/settings/models/__next.settings.txt +5 -5
  166. package/dist/web/settings/models.html +1 -1
  167. package/dist/web/settings/models.txt +23 -23
  168. package/dist/web/settings/output-styles/__next._full.txt +23 -23
  169. package/dist/web/settings/output-styles/__next._head.txt +4 -4
  170. package/dist/web/settings/output-styles/__next._index.txt +13 -13
  171. package/dist/web/settings/output-styles/__next._tree.txt +2 -2
  172. package/dist/web/settings/output-styles/__next.settings.output-styles.__PAGE__.txt +4 -4
  173. package/dist/web/settings/output-styles/__next.settings.output-styles.txt +3 -3
  174. package/dist/web/settings/output-styles/__next.settings.txt +5 -5
  175. package/dist/web/settings/output-styles.html +1 -1
  176. package/dist/web/settings/output-styles.txt +23 -23
  177. package/dist/web/settings/prompts/__next._full.txt +23 -23
  178. package/dist/web/settings/prompts/__next._head.txt +4 -4
  179. package/dist/web/settings/prompts/__next._index.txt +13 -13
  180. package/dist/web/settings/prompts/__next._tree.txt +2 -2
  181. package/dist/web/settings/prompts/__next.settings.prompts.__PAGE__.txt +4 -4
  182. package/dist/web/settings/prompts/__next.settings.prompts.txt +3 -3
  183. package/dist/web/settings/prompts/__next.settings.txt +5 -5
  184. package/dist/web/settings/prompts.html +1 -1
  185. package/dist/web/settings/prompts.txt +23 -23
  186. package/dist/web/settings/providers/__next._full.txt +23 -23
  187. package/dist/web/settings/providers/__next._head.txt +4 -4
  188. package/dist/web/settings/providers/__next._index.txt +13 -13
  189. package/dist/web/settings/providers/__next._tree.txt +2 -2
  190. package/dist/web/settings/providers/__next.settings.providers.__PAGE__.txt +4 -4
  191. package/dist/web/settings/providers/__next.settings.providers.txt +3 -3
  192. package/dist/web/settings/providers/__next.settings.txt +5 -5
  193. package/dist/web/settings/providers.html +1 -1
  194. package/dist/web/settings/providers.txt +23 -23
  195. package/dist/web/settings/skills/__next._full.txt +23 -23
  196. package/dist/web/settings/skills/__next._head.txt +4 -4
  197. package/dist/web/settings/skills/__next._index.txt +13 -13
  198. package/dist/web/settings/skills/__next._tree.txt +2 -2
  199. package/dist/web/settings/skills/__next.settings.skills.__PAGE__.txt +4 -4
  200. package/dist/web/settings/skills/__next.settings.skills.txt +3 -3
  201. package/dist/web/settings/skills/__next.settings.txt +5 -5
  202. package/dist/web/settings/skills.html +1 -1
  203. package/dist/web/settings/skills.txt +23 -23
  204. package/dist/web/settings/tools/__next._full.txt +23 -23
  205. package/dist/web/settings/tools/__next._head.txt +4 -4
  206. package/dist/web/settings/tools/__next._index.txt +13 -13
  207. package/dist/web/settings/tools/__next._tree.txt +2 -2
  208. package/dist/web/settings/tools/__next.settings.tools.__PAGE__.txt +4 -4
  209. package/dist/web/settings/tools/__next.settings.tools.txt +3 -3
  210. package/dist/web/settings/tools/__next.settings.txt +5 -5
  211. package/dist/web/settings/tools.html +1 -1
  212. package/dist/web/settings/tools.txt +23 -23
  213. package/dist/web/settings.html +1 -1
  214. package/dist/web/settings.txt +23 -23
  215. package/dist/web/workflows/__next._full.txt +22 -22
  216. package/dist/web/workflows/__next._head.txt +4 -4
  217. package/dist/web/workflows/__next._index.txt +13 -13
  218. package/dist/web/workflows/__next._tree.txt +2 -2
  219. package/dist/web/workflows/__next.workflows.__PAGE__.txt +4 -4
  220. package/dist/web/workflows/__next.workflows.txt +3 -3
  221. package/dist/web/workflows.html +1 -1
  222. package/dist/web/workflows.txt +22 -22
  223. package/dist/web/workspace/_/__next._full.txt +20 -20
  224. package/dist/web/workspace/_/__next._head.txt +4 -4
  225. package/dist/web/workspace/_/__next._index.txt +13 -13
  226. package/dist/web/workspace/_/__next._tree.txt +2 -2
  227. package/dist/web/workspace/_/__next.workspace.$d$id.__PAGE__.txt +3 -3
  228. package/dist/web/workspace/_/__next.workspace.$d$id.txt +3 -3
  229. package/dist/web/workspace/_/__next.workspace.txt +3 -3
  230. package/dist/web/workspace/_.html +1 -1
  231. package/dist/web/workspace/_.txt +20 -20
  232. package/dist/web/workspaces/__next._full.txt +21 -21
  233. package/dist/web/workspaces/__next._head.txt +4 -4
  234. package/dist/web/workspaces/__next._index.txt +13 -13
  235. package/dist/web/workspaces/__next._tree.txt +2 -2
  236. package/dist/web/workspaces/__next.workspaces.__PAGE__.txt +4 -4
  237. package/dist/web/workspaces/__next.workspaces.txt +3 -3
  238. package/dist/web/workspaces.html +1 -1
  239. package/dist/web/workspaces.txt +21 -21
  240. package/dist/ws/agent-prompt.js +36 -3
  241. package/dist/ws/agent-runner.js +30 -18
  242. package/dist/ws/chat-handler.js +89 -0
  243. package/dist/ws/connection-manager.js +49 -2
  244. package/dist/ws/execution-channels.js +88 -0
  245. package/dist/ws/handler.js +32 -5
  246. package/dist/ws/message-parts.js +130 -12
  247. package/dist/ws/terminal-handler.js +26 -0
  248. package/package.json +13 -1
  249. package/public/avatars/user.jpg +0 -0
  250. package/dist/web/_next/static/chunks/0-v_p6j5u3_9l.js +0 -1
  251. package/dist/web/_next/static/chunks/0.-x29t-8gk0r.js +0 -1
  252. package/dist/web/_next/static/chunks/0.l5e8~r7_0~p.js +0 -1
  253. package/dist/web/_next/static/chunks/0.n~yfwf4~6w-.js +0 -1
  254. package/dist/web/_next/static/chunks/00-syqzi-6zxr.js +0 -1
  255. package/dist/web/_next/static/chunks/02j4sr9psucf-.js +0 -1
  256. package/dist/web/_next/static/chunks/06si8l0doqe8p.js +0 -1
  257. package/dist/web/_next/static/chunks/08kfx8on9oty~.js +0 -1
  258. package/dist/web/_next/static/chunks/08ugbvzr20drp.js +0 -2
  259. package/dist/web/_next/static/chunks/0_cqojbge48kq.js +0 -5
  260. package/dist/web/_next/static/chunks/0d6~~lv0-6kex.js +0 -3
  261. package/dist/web/_next/static/chunks/0gdwop9cnpmtu.js +0 -1
  262. package/dist/web/_next/static/chunks/0ghx3j_.-gdyd.js +0 -1
  263. package/dist/web/_next/static/chunks/0kbvoxla7f751.js +0 -1
  264. package/dist/web/_next/static/chunks/0paaat8y96ayc.js +0 -7
  265. package/dist/web/_next/static/chunks/0pq318f8xgafg.js +0 -1
  266. package/dist/web/_next/static/chunks/0t6s8of0qr6nc.js +0 -1
  267. package/dist/web/_next/static/chunks/0xt-8wk21gs7g.js +0 -1
  268. package/dist/web/_next/static/chunks/0yd.m1afqg.2t.js +0 -3
  269. package/dist/web/_next/static/chunks/0yhbr8hl09b-5.js +0 -1
  270. package/dist/web/_next/static/chunks/0z~vqzbm_q371.js +0 -1
  271. package/dist/web/_next/static/chunks/0~~_ltu6dx_ch.js +0 -1
  272. package/dist/web/_next/static/chunks/12oxcgyhpaxw~.js +0 -1
  273. package/dist/web/_next/static/chunks/1452eibz62gs6.css +0 -1
  274. package/dist/web/_next/static/chunks/16zlreiems5cn.js +0 -1
  275. package/dist/web/_next/static/chunks/18awqjk9-o5m0.js +0 -1
  276. /package/dist/web/_next/static/{x4-CsKe6qUQyFDWVtfvUg → rGXyAK8rgod1NjF3bLZAY}/_buildManifest.js +0 -0
  277. /package/dist/web/_next/static/{x4-CsKe6qUQyFDWVtfvUg → rGXyAK8rgod1NjF3bLZAY}/_clientMiddlewareManifest.js +0 -0
  278. /package/dist/web/_next/static/{x4-CsKe6qUQyFDWVtfvUg → rGXyAK8rgod1NjF3bLZAY}/_ssgManifest.js +0 -0
@@ -3,11 +3,15 @@
3
3
  */
4
4
  import { ClaudeCodeRuntime } from './claude-code-runtime/index.js';
5
5
  import { CodexRuntime } from './codex-runtime.js';
6
+ import { HermesRuntime } from './hermes-runtime.js';
6
7
  import { LangChainRuntime } from './langchain-runtime.js';
8
+ import { OhMyPiRuntime } from './oh-my-pi-runtime.js';
7
9
  import { OpenAgentSdkRuntime } from './open-agent-sdk-runtime.js';
8
10
  export { ClaudeCodeRuntime } from './claude-code-runtime/index.js';
9
11
  export { CodexRuntime } from './codex-runtime.js';
12
+ export { HermesRuntime } from './hermes-runtime.js';
10
13
  export { LangChainRuntime } from './langchain-runtime.js';
14
+ export { OhMyPiRuntime } from './oh-my-pi-runtime.js';
11
15
  export { OpenAgentSdkRuntime } from './open-agent-sdk-runtime.js';
12
16
  export function createAgentRuntime(configOrProvider = {}, model) {
13
17
  const config = typeof configOrProvider === 'string'
@@ -22,6 +26,10 @@ export function createAgentRuntime(configOrProvider = {}, model) {
22
26
  return new CodexRuntime(config);
23
27
  case 'langchain':
24
28
  return new LangChainRuntime(config);
29
+ case 'hermes':
30
+ return new HermesRuntime(config);
31
+ case 'oh-my-pi':
32
+ return new OhMyPiRuntime(config);
25
33
  }
26
34
  }
27
35
  //# sourceMappingURL=agent-runtime.js.map
@@ -0,0 +1,152 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { createServer } from 'node:http';
3
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
4
+ import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
5
+ import { CallToolRequestSchema, ErrorCode, ListToolsRequestSchema, McpError, } from '@modelcontextprotocol/sdk/types.js';
6
+ const AGENT_SPACES_MCP_SERVER_NAME = 'agent-spaces';
7
+ export async function startCodexFunctionToolBridge(functionTools, log) {
8
+ if (!functionTools?.length)
9
+ return undefined;
10
+ const toolsByName = new Map(functionTools.map((functionTool) => [functionTool.name, functionTool]));
11
+ const mcpServer = new Server({ name: AGENT_SPACES_MCP_SERVER_NAME, version: '0.1.0' }, {
12
+ capabilities: {
13
+ tools: { listChanged: false },
14
+ },
15
+ instructions: 'Agent Spaces built-in runtime tools for workspace data.',
16
+ });
17
+ const transport = new StreamableHTTPServerTransport({
18
+ sessionIdGenerator: randomUUID,
19
+ enableJsonResponse: true,
20
+ });
21
+ mcpServer.setRequestHandler(ListToolsRequestSchema, () => ({
22
+ tools: functionTools.map(toMcpTool),
23
+ }));
24
+ mcpServer.setRequestHandler(CallToolRequestSchema, async (request) => {
25
+ const functionTool = toolsByName.get(normalizeFunctionToolCallName(request.params.name));
26
+ if (!functionTool) {
27
+ throw new McpError(ErrorCode.InvalidParams, `Tool ${request.params.name} not found`);
28
+ }
29
+ const result = await functionTool.execute(request.params.arguments ?? {});
30
+ return {
31
+ content: [
32
+ {
33
+ type: 'text',
34
+ text: stringifyToolResult(result),
35
+ },
36
+ ],
37
+ ...(isRecord(result) ? { structuredContent: result } : {}),
38
+ };
39
+ });
40
+ await mcpServer.connect(transport);
41
+ const httpServer = createServer(async (req, res) => {
42
+ try {
43
+ const url = new URL(req.url ?? '/', 'http://127.0.0.1');
44
+ if (url.pathname !== '/mcp') {
45
+ res.writeHead(404).end('Not found');
46
+ return;
47
+ }
48
+ log?.(`function tool bridge request | method=${req.method ?? '-'} path=${url.pathname}`);
49
+ await transport.handleRequest(req, res);
50
+ }
51
+ catch (err) {
52
+ const message = err instanceof Error ? err.message : String(err);
53
+ log?.(`function tool bridge request failed | ${message}`);
54
+ if (!res.headersSent)
55
+ res.writeHead(500, { 'content-type': 'text/plain; charset=utf-8' });
56
+ if (!res.writableEnded)
57
+ res.end(message);
58
+ }
59
+ });
60
+ await listen(httpServer);
61
+ const address = httpServer.address();
62
+ if (!address || typeof address === 'string') {
63
+ await closeHttpServer(httpServer);
64
+ await mcpServer.close();
65
+ throw new Error('Failed to start Codex function tool bridge');
66
+ }
67
+ const url = `http://127.0.0.1:${address.port}/mcp`;
68
+ log?.(`function tool bridge started | url=${url} tools=${functionTools.map((tool) => tool.name).join(',')}`);
69
+ return {
70
+ name: AGENT_SPACES_MCP_SERVER_NAME,
71
+ url,
72
+ close: async () => {
73
+ await mcpServer.close();
74
+ await closeHttpServer(httpServer);
75
+ log?.('function tool bridge stopped');
76
+ },
77
+ };
78
+ }
79
+ function toMcpTool(functionTool) {
80
+ return {
81
+ name: functionTool.name,
82
+ description: functionTool.description,
83
+ inputSchema: normalizeToolInputSchema(functionTool.inputSchema),
84
+ annotations: toMcpToolAnnotations(functionTool),
85
+ };
86
+ }
87
+ function normalizeFunctionToolCallName(name) {
88
+ const prefixedName = agentSpacesMcpToolNamePrefix();
89
+ return name.startsWith(prefixedName) ? name.slice(prefixedName.length) : name;
90
+ }
91
+ function agentSpacesMcpToolNamePrefix() {
92
+ return `mcp__${AGENT_SPACES_MCP_SERVER_NAME}__`;
93
+ }
94
+ function normalizeToolInputSchema(schema) {
95
+ if (schema.type === 'object')
96
+ return schema;
97
+ return {
98
+ type: 'object',
99
+ properties: normalizeSchemaProperties(schema.properties),
100
+ required: Array.isArray(schema.required) ? schema.required.map(String) : [],
101
+ };
102
+ }
103
+ function toMcpToolAnnotations(functionTool) {
104
+ if (!functionTool.annotations)
105
+ return undefined;
106
+ return {
107
+ readOnlyHint: functionTool.annotations.readOnly,
108
+ destructiveHint: functionTool.annotations.destructive,
109
+ openWorldHint: functionTool.annotations.openWorld,
110
+ };
111
+ }
112
+ function stringifyToolResult(result) {
113
+ if (result === undefined)
114
+ return 'null';
115
+ return JSON.stringify(result, null, 2) ?? String(result);
116
+ }
117
+ function normalizeSchemaProperties(properties) {
118
+ if (!isRecord(properties))
119
+ return {};
120
+ return Object.fromEntries(Object.entries(properties).filter((entry) => isRecord(entry[1])));
121
+ }
122
+ function listen(server) {
123
+ return new Promise((resolve, reject) => {
124
+ const onError = (err) => {
125
+ server.off('listening', onListening);
126
+ reject(err);
127
+ };
128
+ const onListening = () => {
129
+ server.off('error', onError);
130
+ resolve();
131
+ };
132
+ server.once('error', onError);
133
+ server.once('listening', onListening);
134
+ server.listen(0, '127.0.0.1');
135
+ });
136
+ }
137
+ function closeHttpServer(server) {
138
+ if (!server.listening)
139
+ return Promise.resolve();
140
+ return new Promise((resolve, reject) => {
141
+ server.close((err) => {
142
+ if (err)
143
+ reject(err);
144
+ else
145
+ resolve();
146
+ });
147
+ });
148
+ }
149
+ function isRecord(value) {
150
+ return Boolean(value && typeof value === 'object' && !Array.isArray(value));
151
+ }
152
+ //# sourceMappingURL=codex-function-tool-bridge.js.map
@@ -2,6 +2,7 @@ import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, wri
2
2
  import { basename, extname, join } from 'node:path';
3
3
  import { Codex } from '@openai/codex-sdk';
4
4
  import { appendOutputStyleToPrompt, summarizeResult } from './agent-runtime-types.js';
5
+ import { startCodexFunctionToolBridge } from './codex-function-tool-bridge.js';
5
6
  /**
6
7
  * Runtime backed by OpenAI's Codex SDK.
7
8
  * Spawns the bundled Codex CLI and consumes its structured JSONL event stream.
@@ -23,12 +24,15 @@ export class CodexRuntime {
23
24
  if (codexHome)
24
25
  prepareCodexHome(codexHome, agentDir);
25
26
  const skillNames = normalizeSkillNames(options?.skills, codexHome);
26
- const configOverrides = buildCodexConfig(this.config, options, skillNames);
27
27
  const sandboxMode = normalizeSandboxMode(this.config.permissionMode);
28
28
  const approvalPolicy = normalizeApprovalPolicy(this.config.permissionMode);
29
- d(`starting | cwd=${cwd} model=${this.config.model ?? 'default'} sandboxMode=${sandboxMode} approvalPolicy=${approvalPolicy} maxTurns=${options?.maxTurns ?? '∞'} mcpServers=${Object.keys(options?.mcpServers ?? {}).join(',') || '-'} skills=${skillNames.join(',') || '-'} codexHome=${codexHome ?? 'default'} sandboxDirs=${options?.sandboxDirs?.join(',') ?? '-'}`);
29
+ let functionToolBridge;
30
+ d(`starting | cwd=${cwd} model=${this.config.model ?? 'default'} sandboxMode=${sandboxMode} approvalPolicy=${approvalPolicy} maxTurns=${options?.maxTurns ?? '∞'} mcpServers=${Object.keys(options?.mcpServers ?? {}).join(',') || '-'} functionTools=${options?.functionTools?.map((tool) => tool.name).join(',') || '-'} skills=${skillNames.join(',') || '-'} codexHome=${codexHome ?? 'default'} sandboxDirs=${options?.sandboxDirs?.join(',') ?? '-'}`);
30
31
  d(`prompt: ${prompt.slice(0, 300)}${prompt.length > 300 ? '...' : ''}`);
31
32
  try {
33
+ functionToolBridge = await startCodexFunctionToolBridge(options?.functionTools, d);
34
+ const mcpServers = withFunctionToolBridge(options?.mcpServers, functionToolBridge);
35
+ const configOverrides = buildCodexConfig(this.config, mcpServers, skillNames);
32
36
  const codex = new Codex({
33
37
  apiKey: this.config.apiKey,
34
38
  baseUrl: shouldUseCodexOpenAIBaseUrl(this.config) ? this.config.baseURL : undefined,
@@ -127,6 +131,13 @@ export class CodexRuntime {
127
131
  return { success: false, summary: 'Codex execution failed', artifacts: [], error: message, output, sessionId: options?.resumeSessionId };
128
132
  }
129
133
  finally {
134
+ try {
135
+ await functionToolBridge?.close();
136
+ }
137
+ catch (err) {
138
+ const message = err instanceof Error ? err.message : String(err);
139
+ d(`function tool bridge close failed | ${message}`);
140
+ }
130
141
  this.abortController = null;
131
142
  }
132
143
  }
@@ -143,13 +154,13 @@ function buildEnv(config, codexHome) {
143
154
  CODEX_INTERNAL_ORIGINATOR_OVERRIDE: process.env.CODEX_INTERNAL_ORIGINATOR_OVERRIDE || 'agent-spaces/server',
144
155
  });
145
156
  }
146
- function buildCodexConfig(runtimeConfig, options, skillNames) {
157
+ function buildCodexConfig(runtimeConfig, rawMcpServers, skillNames) {
147
158
  const config = {};
148
159
  Object.assign(config, buildCodexProviderConfig(runtimeConfig));
149
160
  if (runtimeConfig.thinkingEnabled !== false) {
150
161
  config.model_reasoning_effort = runtimeConfig.thinkingEffort ?? 'medium';
151
162
  }
152
- const mcpServers = normalizeMcpServers(options?.mcpServers);
163
+ const mcpServers = normalizeMcpServers(rawMcpServers);
153
164
  if (mcpServers)
154
165
  config.mcp_servers = mcpServers;
155
166
  if (skillNames.length > 0) {
@@ -157,6 +168,14 @@ function buildCodexConfig(runtimeConfig, options, skillNames) {
157
168
  }
158
169
  return removeUndefined(config);
159
170
  }
171
+ function withFunctionToolBridge(mcpServers, bridge) {
172
+ if (!bridge)
173
+ return mcpServers;
174
+ return {
175
+ ...(mcpServers ?? {}),
176
+ [bridge.name]: { url: bridge.url },
177
+ };
178
+ }
160
179
  function buildCodexProviderConfig(runtimeConfig) {
161
180
  if (!runtimeConfig.baseURL || shouldUseCodexOpenAIBaseUrl(runtimeConfig))
162
181
  return {};
@@ -170,6 +170,12 @@ export async function gitStatus(workspaceId) {
170
170
  try {
171
171
  const upstream = await getUpstreamRef(git, result.branch);
172
172
  if (upstream) {
173
+ const counts = await git.raw(['rev-list', '--left-right', '--count', `HEAD...${upstream}`]);
174
+ const [ahead, behind] = counts.trim().split(/\s+/).map((value) => Number(value));
175
+ if (Number.isFinite(ahead))
176
+ result.ahead = ahead;
177
+ if (Number.isFinite(behind))
178
+ result.behind = behind;
173
179
  const remoteHeadHash = await git.revparse(['--short', upstream]);
174
180
  result.remoteHeadHash = remoteHeadHash.trim();
175
181
  }
@@ -267,7 +273,7 @@ export async function gitLog(workspaceId, maxCount = 50) {
267
273
  const status = await git.status();
268
274
  const upstream = await getUpstreamRef(git, status.current || 'HEAD');
269
275
  const refs = upstream ? ['HEAD', upstream] : ['HEAD'];
270
- const pretty = '%H%x1f%s%x1f%an%x1f%aI%x1e';
276
+ const pretty = '%H%x1f%P%x1f%s%x1f%an%x1f%aI%x1f%D%x1e';
271
277
  const logArgs = ['log', `--max-count=${maxCount}`, `--pretty=format:${pretty}`];
272
278
  const raw = await git.raw([...logArgs, ...refs]).catch((err) => {
273
279
  if (!upstream)
@@ -278,12 +284,16 @@ export async function gitLog(workspaceId, maxCount = 50) {
278
284
  .map(record => record.trim())
279
285
  .filter(Boolean)
280
286
  .map(record => {
281
- const [hash = '', message = '', author = '', date = ''] = record.split('\x1f');
287
+ const [hash = '', parentHashes = '', message = '', author = '', date = '', refsRaw = ''] = record.split('\x1f');
288
+ const parents = parentHashes ? parentHashes.split(' ').map(p => p.substring(0, 7)) : [];
289
+ const refs = refsRaw ? refsRaw.split(', ').map(r => r.trim()).filter(Boolean) : [];
282
290
  return {
283
291
  hash: hash.substring(0, 7),
292
+ parents,
284
293
  message,
285
294
  author,
286
295
  date,
296
+ refs,
287
297
  };
288
298
  });
289
299
  }
@@ -376,7 +386,7 @@ export async function gitPush(workspaceId) {
376
386
  const remotes = await git.getRemotes(true);
377
387
  if (!remotes.length)
378
388
  throw new Error('No remote repository configured. Please add a remote first.');
379
- await git.push('origin', branch);
389
+ await git.push('origin', branch, ['--set-upstream']);
380
390
  }
381
391
  export async function gitFetch(workspaceId) {
382
392
  const ws = getWorkspace(workspaceId);
@@ -392,6 +402,11 @@ export async function gitPull(workspaceId) {
392
402
  const git = getGit(ws);
393
403
  const status = await git.status();
394
404
  const branch = status.current || 'HEAD';
405
+ const upstream = await getUpstreamRef(git, branch);
406
+ if (upstream?.startsWith('origin/')) {
407
+ await git.pull('origin', upstream.slice('origin/'.length));
408
+ return;
409
+ }
395
410
  await git.pull('origin', branch);
396
411
  }
397
412
  export async function gitGetRemotes(workspaceId) {
@@ -486,6 +501,13 @@ export async function gitMergeBase(workspaceId) {
486
501
  const result = await git.raw(['merge-base', 'HEAD', 'origin/HEAD']).catch(() => '');
487
502
  return result.trim();
488
503
  }
504
+ export async function gitReset(workspaceId, commitHash, mode = 'mixed') {
505
+ const ws = getWorkspace(workspaceId);
506
+ if (!ws)
507
+ throw new Error('Workspace not found');
508
+ const git = getGit(ws);
509
+ await git.reset([`--${mode}`, commitHash]);
510
+ }
489
511
  export async function gitGetConfig(scope, workspaceId) {
490
512
  const scopeFlag = scope === 'global' ? '--global' : '--local';
491
513
  const git = workspaceId ? getGit(getWorkspace(workspaceId)) : simpleGit();