setup.ts 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. import { mkdtemp, mkdir, rm } from 'node:fs/promises'
  2. import { homedir } from 'node:os'
  3. import { join } from 'node:path'
  4. import type { Context } from '@deepseek-ai/cordis'
  5. import type { Agent } from '@deepseek-ai/dsh-agent'
  6. import SessionStore from '@deepseek-ai/dsh-session'
  7. import SessionProjections from '@deepseek-ai/dsh-session-projection'
  8. import FileSystem from '@deepseek-ai/dsh-fs-local'
  9. import Subprocess from '@deepseek-ai/dsh-subprocess-local'
  10. import Sandbox from '@deepseek-ai/dsh-sandbox-local'
  11. import SandboxPolicy from '@deepseek-ai/dsh-sandbox-policy'
  12. import type { SandboxMode } from '@deepseek-ai/dsh-sandbox'
  13. import NodePtcRuntime from '@deepseek-ai/dsh-ptc-runtime-node'
  14. import type { Config as NodeRuntimeConfig } from '@deepseek-ai/dsh-ptc-runtime-node'
  15. import { onTestFinished } from 'vitest'
  16. /** Mount real Node execution services with a private working directory and awaited cleanup. */
  17. export async function mountPtcRuntime(ctx: Context, mode: SandboxMode = 'danger-full-access') {
  18. const root = await mkdtemp(join(homedir(), '.dsh-workflow-test-'))
  19. onTestFinished(async () => {
  20. await ctx.fiber.dispose()
  21. await rm(root, { recursive: true, force: true })
  22. })
  23. const cwd = join(root, 'workspace')
  24. await mkdir(cwd)
  25. await mountWorkflowRuntime(ctx, { cwd, mode, runtimeConfig: { graceMs: 50 } })
  26. return { root, cwd }
  27. }
  28. /** Mount the real execution services in a caller-owned context and directory. */
  29. export async function mountWorkflowRuntime(
  30. ctx: Context,
  31. options: { cwd?: string; mode?: SandboxMode; runtimeConfig?: NodeRuntimeConfig } = {},
  32. ): Promise<NodePtcRuntime> {
  33. if (!ctx.get('sessions')) await ctx.plugin(SessionStore)
  34. if (!ctx.get('sessionProjections')) await ctx.plugin(SessionProjections)
  35. if (!ctx.get('fs')) await ctx.plugin(FileSystem)
  36. if (!ctx.get('subprocess')) await ctx.plugin(Subprocess)
  37. if (!ctx.get('sandbox')) await ctx.plugin(Sandbox)
  38. if (!ctx.get('sandboxPolicy')) await ctx.plugin(SandboxPolicy, {
  39. mode: options.mode ?? 'danger-full-access',
  40. ...options.cwd === undefined ? {} : { workspaceRoot: options.cwd },
  41. })
  42. if (!ctx.get('ptcRuntime')) await ctx.plugin(NodePtcRuntime, options.runtimeConfig ?? {})
  43. return ctx.ptcRuntime as NodePtcRuntime
  44. }
  45. /** Give a stub subagent provider a parent with a real Session and immutable cwd. */
  46. export function fakeParent(ctx: Context): Agent {
  47. const session = ctx.sessions.create(undefined, { meta: { cwd: ctx.sandboxPolicy.workspaceRoot } })
  48. return { id: session.id, session, options: {} } as unknown as Agent
  49. }