loader-composition.e2e.ts 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import { readFileSync } from 'node:fs'
  2. import { join } from 'node:path'
  3. import { fileURLToPath } from 'node:url'
  4. import { describe, expect, it } from 'vitest'
  5. import { runLoaderSmoke } from '@deepseek-ai/dsh-loader-smoke'
  6. const PRODUCTION_PROFILE_PROCESS_TIMEOUT_MS = 60_000
  7. const PRODUCTION_PROFILE_TEST_TIMEOUT_MS = PRODUCTION_PROFILE_PROCESS_TIMEOUT_MS + 15_000
  8. const fixtureDir = fileURLToPath(new URL(
  9. './fixtures/loader/',
  10. import.meta.url,
  11. ))
  12. const driver = join(fixtureDir, 'driver.ts')
  13. const configPath = join(fixtureDir, 'claude-code.patch.yml')
  14. const packageDir = fileURLToPath(new URL('..', import.meta.url))
  15. const manifest = JSON.parse(readFileSync(join(packageDir, 'package.json'), 'utf8')) as {
  16. dsh?: { bundle?: { patch?: string } }
  17. }
  18. const bundlePatch = manifest.dsh?.bundle?.patch
  19. if (bundlePatch === undefined) throw new Error('Claude Code package must declare a Bundle patch')
  20. const bundlePatchPath = join(packageDir, bundlePatch)
  21. const repoTsconfig = fileURLToPath(new URL('../../../../tsconfig.json', import.meta.url))
  22. describe('product-provider public Loader composition', () => {
  23. it('loads the Bundle default, two named Claude instances, their tools, and Codex without starting either product', async () => {
  24. const { stdout, stderr } = await runLoaderSmoke({
  25. label: 'product-provider Loader composition',
  26. tempDirPrefix: 'dsh-product-provider-loader-',
  27. binScript: driver,
  28. libBinScript: driver,
  29. configPath,
  30. binArgs: [configPath, bundlePatchPath],
  31. tsconfigPath: repoTsconfig,
  32. processTimeoutMs: PRODUCTION_PROFILE_PROCESS_TIMEOUT_MS,
  33. env: {
  34. // Loading the optional package must not probe or start a Claude binary.
  35. PATH: '',
  36. },
  37. })
  38. expect(stderr).toBe('')
  39. expect(JSON.parse(stdout)).toEqual({
  40. registeredProviders: ['claude-code', 'claude-primary', 'claude-secondary', 'codex'],
  41. providers: [
  42. {
  43. name: 'codex',
  44. capabilities: {
  45. agentOptions: false,
  46. outputSchema: false,
  47. depthLimit: false,
  48. toolFilter: false,
  49. persona: false,
  50. },
  51. inheritsParentContext: false,
  52. },
  53. {
  54. name: 'claude-code',
  55. capabilities: {
  56. agentOptions: false,
  57. outputSchema: false,
  58. depthLimit: false,
  59. toolFilter: false,
  60. persona: false,
  61. },
  62. inheritsParentContext: false,
  63. },
  64. {
  65. name: 'claude-primary',
  66. capabilities: {
  67. agentOptions: false,
  68. outputSchema: false,
  69. depthLimit: false,
  70. toolFilter: false,
  71. persona: false,
  72. },
  73. inheritsParentContext: false,
  74. },
  75. {
  76. name: 'claude-secondary',
  77. capabilities: {
  78. agentOptions: false,
  79. outputSchema: false,
  80. depthLimit: false,
  81. toolFilter: false,
  82. persona: false,
  83. },
  84. inheritsParentContext: false,
  85. },
  86. ],
  87. tools: [
  88. {
  89. name: 'subagent_codex',
  90. parameterNames: ['description', 'prompt', 'run_in_background'],
  91. required: ['description', 'prompt'],
  92. },
  93. {
  94. name: 'subagent_claude_code',
  95. parameterNames: ['description', 'prompt', 'run_in_background'],
  96. required: ['description', 'prompt'],
  97. },
  98. {
  99. name: 'subagent_claude_primary',
  100. parameterNames: ['description', 'prompt', 'run_in_background'],
  101. required: ['description', 'prompt'],
  102. },
  103. {
  104. name: 'subagent_claude_secondary',
  105. parameterNames: ['description', 'prompt', 'run_in_background'],
  106. required: ['description', 'prompt'],
  107. },
  108. ],
  109. jobTools: ['job_kill', 'job_list', 'job_output'],
  110. starts: 0,
  111. })
  112. }, PRODUCTION_PROFILE_TEST_TIMEOUT_MS)
  113. })