workspace-update-host.mjs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. /** Private, token-authenticated test controls for tasks in the real Desktop Host process. */
  2. import { createServer } from 'node:http'
  3. import { randomUUID } from 'node:crypto'
  4. import { writeFile } from 'node:fs/promises'
  5. import { join } from 'node:path'
  6. import { createRequire } from 'node:module'
  7. import { pathToFileURL } from 'node:url'
  8. export const inject = ['agents', 'agentPresets']
  9. export async function apply(ctx) {
  10. const root = process.env.DSH_WORKSPACE_UPDATE_ROOT
  11. const token = process.env.DSH_WORKSPACE_UPDATE_TOKEN
  12. if (!root || !token) throw new Error('Private workspace qualification configuration is missing')
  13. const require = createRequire(join(process.cwd(), 'package.json'))
  14. const { createUserMessage } = await import(pathToFileURL(require.resolve('@deepseek-ai/dsh-llm')).href)
  15. let owned
  16. let holdShutdown = false
  17. const requests = new Set()
  18. const requestHistory = []
  19. ctx.on('connection/request', async (request, _response, next) => {
  20. const entry = { method: request.method, url: request.url, startedAt: Date.now() }
  21. requests.add(entry)
  22. requestHistory.push(entry)
  23. try { await next() } finally { entry.finishedAt = Date.now(); requests.delete(entry) }
  24. })
  25. const server = createServer((request, response) => {
  26. if (request.method !== 'POST' || request.headers['x-qualification-token'] !== token) { response.writeHead(403).end(); return }
  27. void (async () => {
  28. if (request.url === '/queue') {
  29. owned ??= await ctx.agents.create({ sessionId: `update-confirmation-race-${randomUUID()}`, meta: { cwd: root },
  30. setup: async agentCtx => { await ctx.agentPresets.mount(agentCtx, 'standard') } })
  31. owned.agent.send(createUserMessage({ content: [{ type: 'text', text: 'Keep this queued task until explicitly approved' }], source: { kind: 'user' } }), 'next-turn', false)
  32. } else if (request.url === '/clear') owned?.agent.inbox.clear()
  33. else if (request.url === '/hold-shutdown') holdShutdown = true
  34. else if (request.url !== '/status') throw new Error('Unknown qualification operation')
  35. response.setHeader('Content-Type', 'application/json')
  36. response.end(JSON.stringify({ queued: owned?.agent.inbox.nextTurn.length ?? 0, holdShutdown,
  37. requests: [...requests], requestHistory, agents: ctx.agents.list().map(agent => ({ status: agent.status,
  38. nextTurn: agent.inbox.nextTurn.length, nextStep: agent.inbox.nextStep.length })),
  39. }))
  40. })().catch(error => { response.writeHead(500).end(String(error)) })
  41. })
  42. ctx.effect(() => async () => {
  43. server.closeAllConnections()
  44. await new Promise((resolve, reject) => server.close(error => error ? reject(error) : resolve()))
  45. if (holdShutdown) await new Promise(() => {})
  46. await owned?.dispose()
  47. })
  48. await new Promise((resolve, reject) => { server.once('error', reject); server.listen(0, '127.0.0.1', resolve) })
  49. await writeFile(join(root, 'host-control.json'), JSON.stringify({ url: `http://127.0.0.1:${server.address().port}` }))
  50. }