index.ts 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /**
  2. * The code-execution seam (`ctx.codeRuntime`): an abstract service defining
  3. * WHAT a code runtime does — run one model-written program against a set of
  4. * host-provided async bindings and report `{ value, logs, error? }` — without
  5. * saying HOW. Implementations subclass {@link CodeRuntime} and register
  6. * themselves as the `codeRuntime` service; backends may differ by execution
  7. * substrate (worker thread, separate process, container) and by source
  8. * language, both declared as readonly descriptors. The design and its
  9. * consumer (the tool registry's Code Mode) are specified in the Code Mode RFC
  10. * (docs/rfc/implemented/feature/2026-06-15-code-mode.md).
  11. *
  12. * The split mirrors the bash seam (`BashExecutor`): the runtime knows nothing
  13. * about tools or sessions — it is handed named async functions and a program,
  14. * and everything tool-shaped stays with the consumer.
  15. *
  16. * @module @deepseek-ai/dsh-code-runtime
  17. */
  18. import { Context, Service } from 'cordis'
  19. import type { CodeRunRequest, CodeRunResult } from './types.ts'
  20. export type {
  21. CodeBindingFunction,
  22. CodeBindingNamespace,
  23. CodeLogEntry,
  24. CodeRunFailure,
  25. CodeRunRequest,
  26. CodeRunResult,
  27. } from './types.ts'
  28. declare module 'cordis' {
  29. interface Context {
  30. codeRuntime: CodeRuntime
  31. }
  32. }
  33. /**
  34. * Abstract code-execution service. Subclass, implement {@link run} and the
  35. * two descriptors, and load the subclass as a plugin — it registers as
  36. * `ctx.codeRuntime` (one implementation per context; loading a second throws,
  37. * cordis' standard duplicate-service behavior).
  38. *
  39. * Semantics every implementation must honor:
  40. * - {@link run} resolves with an error FIELD for every program outcome —
  41. * parse/transform failures, thrown exceptions, budget expiry, abort,
  42. * substrate death ({@link CodeRunFailure}'s taxonomy). It REJECTS only for
  43. * caller misuse of the seam itself (e.g. a run submitted after disposal).
  44. * - Binding calls bridge to the caller's {@link CodeBindingFunction}s
  45. * verbatim; arguments and resolutions must be structured-cloneable, and the
  46. * runtime treats the program as a hostile peer (arbitrary binding names are
  47. * own properties, malformed traffic is rejected or ignored, never crashes
  48. * the host).
  49. * - Runs are isolated from each other: no state survives from one run to the
  50. * next through the runtime.
  51. * - Disposal reaches quiescence: in-flight runs are terminated AND awaited
  52. * before the service's own teardown completes (no orphan substrate survives
  53. * `fiber.dispose()`).
  54. */
  55. export abstract class CodeRuntime extends Service {
  56. /**
  57. * The source language {@link run} expects `program` to be written in, as a
  58. * lowercase identifier. Informational, not gating — a consumer that
  59. * generates language-specific presentation (typed SDK stubs, usage
  60. * instructions) switches on it and fails loud on a language it cannot
  61. * present. Well-known value: `'typescript'`.
  62. */
  63. abstract readonly language: string
  64. /**
  65. * The execution substrate, as a lowercase identifier. Informational, not
  66. * gating — a descriptor so deployments and diagnostics can tell backends
  67. * apart, not a security claim. Well-known values: `'worker-thread'`,
  68. * `'process'`, `'container'`.
  69. */
  70. abstract readonly isolation: string
  71. constructor(ctx: Context) {
  72. super(ctx, 'codeRuntime')
  73. }
  74. /**
  75. * Execute one program against the request's bindings and capture what it
  76. * emitted. See the class doc for the resolution contract (error is a result
  77. * field; rejection means seam misuse only).
  78. * @param request - the program, its bindings, and the abort signal; the
  79. * request carries everything the runtime acts on, with no hidden defaults.
  80. * @returns the run's outcome: completion value (when transferable), the
  81. * ordered log capture, and the failure (if any).
  82. */
  83. abstract run(request: CodeRunRequest): Promise<CodeRunResult>
  84. }
  85. export default CodeRuntime