mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-08-29 04:26:38 +00:00
92 lines
3.5 KiB
TypeScript
92 lines
3.5 KiB
TypeScript
/**
|
|
* @deepseek-ai/dsh-host-apiproxy — the API gateway every client shape shares:
|
|
* the ApiProxy contract (api/: types + zod schemas, browser-safe), the fetch
|
|
* carrier pair (fetch/: toFetchHandler on the host side, AbstractApiClient +
|
|
* platform subclasses on the client side), and the host-side implementation
|
|
* (api-proxy.ts: createApiProxy + the ApiProxyService gateway plugin providing
|
|
* `ctx.apiProxy`). Transport-agnostic by design: this package registers no
|
|
* routes — physical carriers wrap `ctx.apiProxy` themselves.
|
|
*
|
|
* The gateway consumes `ctx.agentDefaultModel` only for the deployment metadata
|
|
* returned by `host.describe`; Session Controller owns Session model selection.
|
|
*/
|
|
|
|
import { Context, Service } from '@deepseek-ai/cordis'
|
|
import z from '@deepseek-ai/schemastery'
|
|
import type {} from '@deepseek-ai/dsh-agent-default-model'
|
|
import type { ApiProxy } from './api/index.ts'
|
|
import { createApiProxy } from './api-proxy.ts'
|
|
import {
|
|
DEFAULT_SESSION_LOG_COMPRESSION_LEVEL,
|
|
type SessionLogCompressionLevel,
|
|
} from './session-export.ts'
|
|
|
|
export type * from './api/index.ts'
|
|
export { RpcId } from './api/rpc.ts'
|
|
export { toFetchHandler } from './fetch/handler.ts'
|
|
export { AbstractApiClient, InProcessApiClient } from './fetch/client.ts'
|
|
export type { IApiClient } from './fetch/client.ts'
|
|
export { createApiProxy } from './api-proxy.ts'
|
|
export type { ApiProxyDefaults } from './api-proxy.ts'
|
|
|
|
declare module '@deepseek-ai/cordis' {
|
|
interface Context {
|
|
/** The host-side ApiProxy implementation (the transport-agnostic gateway face). */
|
|
apiProxy: ApiProxy
|
|
}
|
|
}
|
|
|
|
/** Gateway plugin configuration. */
|
|
export interface Config {
|
|
/**
|
|
* Whether this deployment can hand paths to a native desktop opener —
|
|
* the `hasDocument` capability the agent-preset roster reports. Absent,
|
|
* the platform is asked (macOS/Windows/WSL yes; Linux only with a display
|
|
* server); set it explicitly where detection misleads, e.g. `false` in a
|
|
* container whose DISPLAY points nowhere a user can see.
|
|
*/
|
|
nativeOpen?: boolean
|
|
/**
|
|
* DEFLATE level for every session-log ZIP entry: `0` stores without
|
|
* compression, `1` favors CPU/latency, and `9` favors archive size.
|
|
* @default 6
|
|
*/
|
|
sessionExportCompressionLevel?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
|
|
}
|
|
|
|
/**
|
|
* The API gateway service: implements the ApiProxy contract over the composed
|
|
* host context and provides it as `ctx.apiProxy`. Its cwd metadata must match
|
|
* the default project directory supplied to Session Controller.
|
|
*/
|
|
export class ApiProxyService extends Service implements ApiProxy {
|
|
static inject = [
|
|
'agentDefaultModel', 'agents', 'attachments', 'sessions', 'sessionQuery',
|
|
]
|
|
|
|
static Config: z<Config> = z.object({
|
|
nativeOpen: z.boolean(),
|
|
sessionExportCompressionLevel: z.number().step(1).min(0).max(9)
|
|
.default(DEFAULT_SESSION_LOG_COMPRESSION_LEVEL) as z<SessionLogCompressionLevel>,
|
|
})
|
|
|
|
readonly host: ApiProxy['host']
|
|
readonly downloads: ApiProxy['downloads']
|
|
|
|
constructor(ctx: Context, config: Config) {
|
|
super(ctx, 'apiProxy')
|
|
const api = createApiProxy(ctx, {
|
|
defaultModelSelection: () => ctx.agentDefaultModel.currentSelection(),
|
|
cwd: process.cwd(),
|
|
...config.nativeOpen === undefined ? {} : { canOpenPath: () => config.nativeOpen as boolean },
|
|
...(config.sessionExportCompressionLevel === undefined
|
|
? {}
|
|
: { sessionExportCompressionLevel: config.sessionExportCompressionLevel }),
|
|
})
|
|
this.host = api.host
|
|
this.downloads = api.downloads
|
|
}
|
|
}
|
|
|
|
export default ApiProxyService
|