import type { InternalAuthOptions } from '../types/auth.js'; import type { ProcessTransportOptions } from '../core/process-transport.js'; import type { QueryTransportProvider } from '../core/transport.js'; import type { DaemonGetModelsParams, DaemonValidateByokModelParams } from './protocol.js'; import type { BYOKProviderInfo, ByokConfigCheckResult, ByokConfigInfo, ByokConfigReference, CheckByokConfigInput, CreateByokConfigInput, DeleteByokConfigInput, UpdateByokConfigInput } from '../protocol/control.js'; import type { AccountInfo, ModelInfo, UsageInfo } from '../protocol/common.js'; import type { PluginDetails } from '../types/plugins.js'; export type DaemonState = 'ready' | 'stopping' | 'stopped' | 'failed'; export type SessionRuntimeState = 'pending' | 'ready' | 'inactive' | 'failed'; export interface DaemonSessionInfo { localSessionId: string; title: string; cwd?: string; state: SessionRuntimeState; createdAt: string; updatedAt: string; } export interface StartDaemonOptions { auth: InternalAuthOptions; /** Idle Worker timeout in milliseconds. Set to 0 to disable reclamation. */ workerIdleTimeoutMs?: number; /** * Budget for the `daemon.initialize` round trip; defaults to 30s. * * The CLI lands the in-band credentials while handling initialize — token * exchange, user info, a possible host callback for the first token, and the * account tier prefill — so the wall time follows the host's network and the * CLI's own startup cost. Raise this when either is slow; initialize only * resolves once that work is complete. */ initializeTimeoutMs?: number; pathToQoderCLIExecutable?: string; proxy?: string; env?: Record; /** * daemon 子进程 stderr 的实时回调。 * * `query()` 的 `Options.stderr` 一直有这个通道,daemon 侧此前没有——于是 daemon * 写在 stderr 上的一切宿主都收不到,只能等进程死后从错误对象里捡一个截断的尾巴。 * 联调时最需要的恰恰是实时看到 daemon 说了什么,所以补上。 * 与 `QoderCliProcessError.stderr` 互补:这个是流式的、完整的;那个是事后截断的。 * 回调抛错不影响 daemon,也不会中断 stderr 采集。 */ stderr?: (data: string) => void; /** * 打开 SDK 侧诊断日志,语义与 `query()` 的 `Options.debug` 一致; * 环境变量 `QODER_AGENT_SDK_DEBUG` 也能打开。此前 daemon 链路完全没有诊断输出, * 而它是唯一承载多会话的进程,出问题时最需要这条通道。 */ debug?: boolean; /** 诊断日志落盘路径。给了它就隐含打开诊断,且不再走 stderr 回调。 */ debugFile?: string; } export interface Daemon { readonly state: DaemonState; /** * 列出会话。`cwd` 给定时只列该工作目录名下的会话;缺省时返回所有目录的全部会话 * (daemon 无 cwd 概念,「不传目录」即「不过滤」,由 CLI 侧全量扫盘)。 */ listSessions(cwd?: string): Promise; /** * 重命名会话。`cwd` 用于在磁盘上定位会话目录;daemon-bound 会话可省略——SDK 会自动 * 带上该会话 open 时的 cwd。仅当重命名一个并非经本 daemon 打开的历史会话时才需显式传。 */ renameSession(localSessionId: string, title: string, cwd?: string): Promise; /** 删除会话。`cwd` 语义同 renameSession。 */ deleteSession(localSessionId: string, cwd?: string): Promise; /** * Account-level queries, answered from the credentials the daemon was * started with — never from a Session's. They require a daemon that accepted * `StartDaemonOptions.auth` and reported `daemon_queries_v1`; otherwise they * reject. * * Unlike the per-`Query` equivalents these do not swallow failures into * `null`: capability is already negotiated here, so a rejection is a real * error (`DaemonRpcError` carries the daemon's code and retryable flag). */ getModels(options?: DaemonGetModelsParams): Promise; getByokConfig(): Promise; validateByokModel(input: DaemonValidateByokModelParams): Promise; listByokConfigs(): Promise; createByokConfig(input: CreateByokConfigInput): Promise; updateByokConfig(input: UpdateByokConfigInput): Promise; deleteByokConfig(target: DeleteByokConfigInput): Promise; checkByokConfig(input: CheckByokConfigInput): Promise; listPlugins(): Promise; getUsageInfo(): Promise; accountInfo(): Promise; stop(): Promise; } interface InternalDaemonRuntime { /** Local CLI launch context for feedback that bypasses the daemon. */ readonly hostActionLaunch: { proxy?: string; cliPath?: string; env?: Record; }; readonly auth: InternalAuthOptions; readonly transportProvider: QueryTransportProvider; } export declare function getDaemonRuntime(daemon: Daemon): InternalDaemonRuntime | undefined; export declare function startDaemon(options: StartDaemonOptions): Promise; /** * 宿主什么都没配时的默认诊断落盘位置。 * * 联调场景里客户只是正常使用,不会去设 `QODER_AGENT_SDK_DEBUG`,也不会在代码里传 * `debug`/`debugFile`——而 SdkDiagnostics 三者全无时是彻底静默的,于是 SDK 侧那半条 * 链路(spawn、握手、请求往返、会话开关)对客户完全不可见。默认落到文件补上这一段。 * * 三个刻意的选择: * - **写文件而不是 stderr**:daemon 侧默认往 process.stderr 写会污染宿主输出, * 而宿主可能正把 stderr 当协议通道或展示给用户。文件是安全的默认。 * - **放在 CLI 日志同一个 logs/ 目录下**:`getConfigDir()` 与 CLI 的日志根同源 * (同样认 QODER_CONFIG_DIR 与品牌目录),排障时两侧日志在一处,不用猜路径。 * - **文件名带 pid 与时间戳**:一个宿主进程可能反复起停 daemon,共用一个追加文件 * 会无限增长且多实例互相插话;按次分文件后单个文件的生命周期等于一个 daemon。 * * 显式传了 `debug: true`(意图是走 stderr 回调)时不覆盖宿主的选择不返回默认路径。 */ export declare function defaultDaemonDiagnosticsFile(options: { debug?: boolean; }): string | undefined; export {};