index.ts 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. /**
  2. * @deepseek-ai/dsh-host-apiproxy — the API gateway every client shape shares:
  3. * the ApiProxy contract (api/: types + zod schemas, browser-safe), the fetch
  4. * carrier pair (fetch/: toFetchHandler on the host side, AbstractApiClient +
  5. * platform subclasses on the client side), and the host-side implementation
  6. * (api-proxy.ts: createApiProxy + the ApiProxyService gateway plugin providing
  7. * `ctx.apiProxy`). Transport-agnostic by design: this package registers no
  8. * routes — carriers (HTTP today, IPC later) wrap `ctx.apiProxy` themselves.
  9. */
  10. import { Context, Service } from 'cordis'
  11. import z from 'schemastery'
  12. import type { ApiProxy } from './api/index.ts'
  13. import { createApiProxy } from './api-proxy.ts'
  14. export type * from './api/index.ts'
  15. export { RpcId } from './api/rpc.ts'
  16. export { toFetchHandler } from './fetch/handler.ts'
  17. export { AbstractApiClient, InProcessApiClient } from './fetch/client.ts'
  18. export type { IApiClient } from './fetch/client.ts'
  19. export { createApiProxy } from './api-proxy.ts'
  20. export type { ApiProxyDefaults } from './api-proxy.ts'
  21. declare module 'cordis' {
  22. interface Context {
  23. /** The host-side ApiProxy implementation (the transport-agnostic gateway face). */
  24. apiProxy: ApiProxy
  25. }
  26. }
  27. /** Gateway plugin config: the host-level default agent routing. */
  28. export interface Config {
  29. /** Default provider route for created/resumed agents. */
  30. provider: string
  31. /** Default model id. */
  32. model: string
  33. }
  34. /**
  35. * The API gateway service: implements the ApiProxy contract over the composed
  36. * host context and provides it as `ctx.apiProxy`. The default project
  37. * directory for new sessions is the host process working directory (not a
  38. * config field this round).
  39. */
  40. export class ApiProxyService extends Service implements ApiProxy {
  41. static inject = ['agents', 'sessions', 'tools', 'userInteraction']
  42. static Config: z<Config> = z.object({
  43. provider: z.string().required(),
  44. model: z.string().required(),
  45. })
  46. readonly sessions: ApiProxy['sessions']
  47. readonly host: ApiProxy['host']
  48. readonly events: ApiProxy['events']
  49. readonly respond: ApiProxy['respond']
  50. constructor(ctx: Context, config: Config) {
  51. super(ctx, 'apiProxy')
  52. const api = createApiProxy(ctx, { provider: config.provider, model: config.model, cwd: process.cwd() })
  53. this.sessions = api.sessions
  54. this.host = api.host
  55. this.events = api.events
  56. // createApiProxy returns closures (no `this` capture); bind only satisfies
  57. // the unbound-method lint without changing behavior.
  58. this.respond = api.respond.bind(api)
  59. }
  60. }
  61. export default ApiProxyService