import type { BackgroundTask, BackgroundTaskStopResult } from "../schemas/background"; import type { TurnProjection } from "../schemas/projection"; import type { McpAppArchive } from "../schemas/mcp-app"; import type { PublishedSolutionRef, ReplayPreview, ReplaySpeed, SessionDetail, SessionInfo, TemplateId } from "../schemas/session"; import type { McpAppContextState, McpAppContextUpdate } from "../schemas/mcp-app"; import type { Task } from "../schemas/task"; import type { BladeClient, UploadProgress } from "../blade-client"; import type { AgentSession } from "../session/agent-session"; import { type SessionDefinition } from "../session/definition"; import type { SessionProfile } from "../types/sdk-profile"; export interface SessionPlugin { /** Technical ID: always used for paths, authorization, caching and calls. */ name: string; /** Business name declared by the package; null falls back to `name`. */ display_name?: string | null; /** * Opaque content token for the package-local icon, or null when the plugin * ships none. Pass it to `fetchSessionPluginIcon`; never used as a path. */ icon?: string | null; /** Whether BH lists this plugin for the current user; null means BH was unavailable. */ installed: boolean | null; /** * Configuration standing as the list could determine it without reading the * user's Home: `unchecked` means nobody has looked yet, never "configured". */ config?: SessionPluginConfigSummary; /** Persisted session choice, independent of preparation success. */ active: boolean; /** Previously prepared skills may remain after deselection. */ projected: boolean; projection_source?: string | null; status: string; reason?: string | null; } /** Selection/preparation result; installed facts are obtained from the BH-backed list. */ export type SessionPluginActivation = Pick; /** * How a plugin's user configuration stands. * * `not_required` — the package ships no config schema, the plugin keeps its old * behaviour. `required` — a schema exists but the stored configuration is * missing or does not validate. `configured` — stored configuration validates. * `error` — the declaration itself is unusable. */ export type SessionPluginConfigStateName = "not_required" | "required" | "configured" | "error"; /** List-level view: `unchecked` means nobody has read this user's file yet. */ export type SessionPluginConfigSummary = SessionPluginConfigStateName | "unchecked"; export interface SessionPluginConfigError { /** JSON Pointer of the offending field. */ path: string; /** Value-free message; the platform never echoes submitted secrets. */ message: string; } export interface SessionPluginConfigState { state: SessionPluginConfigStateName; reason: string | null; /** The package-declared JSON Schema (Draft 2020-12), or null. */ schema: Record | null; /** Stored values with `writeOnly` properties removed. */ values: Record; /** JSON Pointers of `writeOnly` properties that currently hold a value. */ write_only: string[]; /** Opaque revision for optimistic concurrency; null when nothing is stored. */ revision: string | null; errors: SessionPluginConfigError[]; } export interface SessionPluginConfigSet { /** JSON Pointer; arrays are replaced as a whole. */ path: string; value: unknown; } export interface SessionPluginConfigUpdate { /** Omit (or pass null) to publish unconditionally. */ expected_revision?: string | null; set?: SessionPluginConfigSet[]; remove?: string[]; } export interface CreateSessionRequest { intent?: string; template_id?: TemplateId; /** 正式 Solution 来源。Hub 使用 { source: "hub", org, name }。 */ solution_ref?: PublishedSolutionRef; /** @deprecated 请使用结构化的 solution_ref;继续支持以保证现有 SDK 调用无感升级。 */ solution_id?: string; /** 从已有会话复制其不可变 Solution 与 Skill 运行快照。 */ solution_snapshot_session_id?: string; biz_role_id?: string | null; primary_skill_id?: string | null; model?: string | null; enable_thinking?: boolean | null; memory_enabled?: boolean | null; env?: Record; disable_tools?: string[] | null; session_solution_asset_id?: string | null; compaction_ratio?: number | null; runtime_type?: "sandbox" | "daemon" | "native" | null; daemon_id?: string | null; /** runtime_type 为 "native" 时必填:daemon 上要用哪个原生智能体(如 rt_codex)。 */ agent_runtime_id?: string | null; chat_group_id?: string | null; } export interface CheckpointNode { id: string; parent_id: string | null; content_preview: string; content: string; timestamp: string; } export type ContentPart = { type: "text"; text: string; } | { type: "image_url"; image_url: { url: string; detail?: string; }; }; export interface HistoryNode { id: string; parent_id: string | null; kind: string; role: string; timestamp: string; preview: string; content: string | ContentPart[]; tool_calls: Array<{ id?: string; type?: string; function?: { name?: string; arguments?: string; }; }> | null; usage: { prompt_tokens?: number; completion_tokens?: number; total_tokens?: number; } | null; total_tokens: number; token_diff: number; is_deprecated: boolean; loop_name: string; } export interface SessionHistory { nodes: HistoryNode[]; active_branch: string | null; branches: string[]; system_prompt_tokens?: number | null; tools_tokens?: number | null; tokenizer_model?: string | null; } export interface TokenizeResult { model: string; prompt_tokens: number; prompt: string; } export interface PaginatedSessionsResult { items: SessionInfo[]; total: number; limit: number; offset: number; content_match_truncated?: boolean; } export interface GlobalSearchConversationResult { type: "conversation"; session: SessionInfo; snippet: string; matched: "title" | "content"; } export interface GlobalSearchFileResult { type: "file"; session: SessionInfo; path: string; name: string; snippet: string; matched: "name" | "path"; } export type GlobalSearchResultItem = GlobalSearchConversationResult | GlobalSearchFileResult; export interface GlobalSearchResult { items: GlobalSearchResultItem[]; truncated: boolean; indexing: boolean; } export interface SkillDevSession { session: SessionInfo; skill_id: string; display_name: string; skill_description: string; } export interface ShareLinkResult { token: string; url: string; expires_at: string | null; } export interface SessionContextStats { tokens_used: number; context_window: number; compaction_ratio: number; } export interface SessionTurnsPage { turns: TurnProjection[]; nextBefore: string | null; currentMode: "planning" | "executing"; } /** `getSessionTurnsPage` 的取数参数:向后翻页(before)或从某条发言定位(fromEntryId)。 */ export interface SessionTurnsQuery { limit?: number; before?: string; /** * 从这条用户发言开始、一直到最新。服务端按当前分支校验它,命中不了不会回空页 * (`entry_not_found` / `entry_not_in_branch`),窗口首条就是这条发言,它的 * `nextBefore` 可以继续当 `before` 往上翻。 */ fromEntryId?: string; } /** * 服务端明确说这条发言不在当前分支上(`entry_not_found` / `entry_not_in_branch`), * 和"这次没取到"(网络 / 5xx / 鉴权)分开:前者说明这个定位目标已经没了,后者只说明这次失败。 */ export declare function isEntryGoneError(error: unknown): boolean; /** 侧栏「消息历史」的一条:只有 id、标题和时间,没有消息体。 */ export interface SessionTurnIndexItem { entryId: string; preview: string; createdAt: string | null; } export interface SessionTurnIndex { sessionId: string; items: SessionTurnIndexItem[]; } export interface HistoricalCommand { deliveryId: string; toolCallId?: string; action: string; payload?: unknown; } export type ResultFeedbackReason = "not_solved" | "inaccurate" | "incomplete" | "needs_major_changes" | "too_slow" | "other"; export interface ResultFeedback { session_id: string; assistant_entry_id: string; surface: "chat" | "software_factory" | "unknown"; project_id: string | null; helpful: boolean; reason: ResultFeedbackReason | null; created_at: string; updated_at: string; } export interface FileEntry { name: string; path: string; is_dir: boolean; created_at: number; tags?: string[]; } export type UploadFileEntry = File | { file: File; name: string; }; export interface UploadFilesOptions { onProgress?: (progress: UploadProgress) => void; } export interface AppCliDefinition { /** 智能体在 Bash 中直接执行的业务命令名,例如 `library`。 */ command: string; /** Python 脚本由沙盒系统 Python 执行;executable 必须是 Linux 可执行文件。 */ runtime: "python" | "executable"; /** CLI 文件本身,或浏览器可以读取的 URL。 */ source: Blob | string | URL; /** source 是普通 Blob 时使用的上传文件名。 */ filename?: string; } export interface AppCliAttachment { command: string; runtime: "python" | "executable"; digest: string; } export interface ImportPreviewSkill { name: string; description: string; path: string; } export interface ImportPreviewScenario { scenario?: { name?: string; }; skills?: string[]; preview_urls?: string[]; init_script?: string; generated_at?: string; } export interface ImportPreview { user_messages: string[]; turn_count: number; skills: ImportPreviewSkill[]; scenario: ImportPreviewScenario | null; } export interface ImportSessionOptions { /** 导入后改用这个正式 Solution 的最新版。 */ solution_ref?: PublishedSolutionRef; /** 导入后改用已有会话的完整运行快照。 */ solution_snapshot_session_id?: string; } export declare class SessionsResource { private client; private readonly pendingImages; /** Fetch an immutable message image using this client's authenticated identity. */ fetchImage(sessionId: string, assetId: string, preview?: boolean): Promise; /** Fetch a public-share image; the server validates the share token on every request. */ fetchSharedImage(token: string, assetId: string, preview?: boolean): Promise; private fetchImagePath; constructor(client: BladeClient); getMcpApp(sessionId: string, sourceId: string, init?: RequestInit): Promise; onMcpAppChanged(sessionId: string, sourceId: string, listener: () => void): () => void; callMcpApp(sessionId: string, sourceId: string, request: { request_id: string; name: string; arguments: Record; }, init?: RequestInit): Promise<{ response: Record; replayed: boolean; }>; /** * 连接一个已存在的会话,返回实时会话对象 AgentSession * (自动完成历史加载、Socket.IO 订阅、断线重连补数)。 */ connect(sessionId: string): Promise; listSessionPlugins(sessionId: string, init?: RequestInit): Promise<{ plugins: SessionPlugin[]; sync_version: number; sync_pending: boolean; }>; setSessionPluginActivation(sessionId: string, name: string, active: boolean, init?: RequestInit): Promise<{ plugin: SessionPluginActivation; sync_version: number; }>; /** * Fetch a plugin's package-local icon as bytes. * * The request carries the client's own bearer credentials, so callers turn * the blob into an object URL instead of pointing `` at an API path and * hoping the request is authenticated. */ fetchSessionPluginIcon(sessionId: string, name: string): Promise; /** Authenticated URL for the icon; useful where a blob URL cannot be used. */ sessionPluginIconUrl(sessionId: string, name: string): string; /** * 准备一个插件的配置:把包准备好并读出用户的配置契约,**不启用**它。 * * 开启插件前必须先走这一步:缺配置时用户只会看到配置表单,服务端不会先把 * active 持久化成 true 再靠补偿关掉。它不修改会话的插件选择、不连接 MCP。 */ prepareSessionPluginConfig(sessionId: string, name: string, init?: RequestInit): Promise<{ plugin: string; config: SessionPluginConfigState; }>; /** * Read a plugin's configuration contract and the user's stored values. * * Secrets are never returned: `write_only` lists the pointers that hold one. */ getSessionPluginConfig(sessionId: string, name: string, init?: RequestInit): Promise<{ plugin: string; config: SessionPluginConfigState; }>; /** * Publish explicit set/remove operations to the user's keychain file. * * Fields absent from both lists keep their stored value, so a form never has * to round-trip a secret. Rejections leave the previous file untouched; the * call never restarts MCP servers. */ updateSessionPluginConfig(sessionId: string, name: string, update: SessionPluginConfigUpdate, init?: RequestInit): Promise<{ plugin: string; config: SessionPluginConfigState; }>; /** 创建新会话并直接连接,返回可收发消息的 AgentSession。 */ create(request?: CreateSessionRequest | SessionDefinition): Promise; private createDeclared; private prepareSolution; private cleanupSolutionAsset; private fetchSessionsPage; listSessions(template_id_prefix?: string, solution_id?: string): Promise; listSessionsPaginated(params: { limit: number; offset: number; template_id_prefix?: string; solution_id?: string; solution_registry_id?: string; q?: string; chat_group_id?: string; }): Promise; listSessionsWithSkillData(): Promise; searchOwnedContent(params: { q: string; limit?: number; }): Promise; createSession(intent?: string, template_id?: TemplateId, primary_skill_id?: string | null): Promise<{ session_id: string; }>; createSessionWithRequest(request: CreateSessionRequest): Promise<{ session_id: string; }>; createWithProfile(params: { intent: string; profile: SessionProfile; }): Promise<{ session_id: string; }>; getSession(sessionId: string, init?: RequestInit): Promise; updateSession(sessionId: string, payload: { intent?: string; chat_group_id?: string | null; }): Promise; setSessionEnv(sessionId: string, env: Record): Promise; pinSession(sessionId: string, pinned: boolean): Promise; startReplaySession(sourceSessionId: string, speed?: ReplaySpeed): Promise<{ session_id: string; }>; updateReplaySession(sessionId: string, payload: { speed?: ReplaySpeed; status?: "autonomous"; }): Promise<{ replay_state: SessionInfo["replay_state"]; }>; /** 查询会话能否作为回放来源;不支持时 reason 可直接展示,用来提前禁用入口。 */ getReplayPreview(sessionId: string): Promise; updateSharing(sessionId: string, shared: boolean): Promise<{ shared: boolean; }>; updateSessionMemory(sessionId: string, memoryEnabled: boolean): Promise<{ memory_enabled: boolean; }>; createShare(sessionId: string): Promise; revokeShare(sessionId: string, token: string): Promise<{ revoked: boolean; }>; getSharedSession(token: string): Promise; getSessionTasks(sessionId: string): Promise; getSessionTurns(sessionId: string): Promise; getSessionTurnsPage(sessionId: string, options?: SessionTurnsQuery, init?: RequestInit): Promise; /** * 当前分支上可导航的用户发言目录(消息导航侧栏)。 * * 只回 id、标题和时间:侧栏要列的是**整条会话**的发言,而窗口外的发言 id 只能 * 从服务端拿;消息体仍然走 `/turns`。 */ getSessionTurnIndex(sessionId: string): Promise; getMcpAppContext(sessionId: string, sourceId: string, init?: RequestInit): Promise; updateMcpAppContext(sessionId: string, sourceId: string, body: McpAppContextUpdate, init?: RequestInit): Promise<{ status: "accepted"; revision: string; }>; getSessionTurnCommands(sessionId: string): Promise; listResultFeedback(sessionId: string): Promise; putResultFeedback(sessionId: string, assistantEntryId: string, feedback: { helpful: boolean; reason?: ResultFeedbackReason | null; }): Promise; getSessionContextStats(sessionId: string, init?: RequestInit): Promise; getSessionHistory(sessionId: string, init?: RequestInit): Promise; tokenizePrompt(prompt: string, model?: string): Promise; tokenizeMessages(messages: Array>, options?: { model?: string; add_generation_prompt?: boolean; enable_thinking?: boolean | null; tools?: Array>; }): Promise; getSessionCheckpoints(sessionId: string, init?: RequestInit): Promise<{ nodes: CheckpointNode[]; leaf_id: string | null; }>; checkoutSession(sessionId: string, checkpointId: string, position: "before" | "turn_end", mode?: "both" | "conversation" | "code", linear?: boolean): Promise<{ id: string; content: string; position: string; mode?: string; files_restored?: boolean; linear?: boolean; }>; rewindSession(sessionId: string, checkpointId: string): Promise<{ id: string; content: string; }>; switchBranch(sessionId: string, checkpointId: string): Promise<{ id: string; leaf_id: string; }>; deleteSession(sessionId: string, options?: { deleteWorkspace?: boolean; }): Promise<{ deleted: boolean; workspace_deleted?: boolean; }>; listBackgroundTasks(sessionId: string, init?: RequestInit): Promise; getBackgroundTask(sessionId: string, taskId: string, tail?: number, init?: RequestInit): Promise; stopBackgroundTask(sessionId: string, taskId: string): Promise; probeSessionUrl(sessionId: string, url: string): Promise<{ reachable: boolean; requires_proxy: boolean; }>; listDir(sessionId: string, dirPath: string, showHidden?: boolean): Promise; countFiles(sessionId: string, dirPath?: string): Promise; /** 在浏览器中下载一个会话文件。 */ downloadFile(sessionId: string, filePath: string, downloadName?: string): Promise; uploadFiles(sessionId: string, dirPath: string, files: FileList | File[] | UploadFileEntry[], options?: UploadFilesOptions): Promise<{ uploaded: string[]; failed: string[]; results: Array<{ index: number; path?: string; error?: string; }>; }>; /** 把应用自己的业务 CLI 安装到会话沙盒,并保留开发者声明的命令名。 */ attachAppCli(sessionId: string, definition: AppCliDefinition): Promise; deleteFile(sessionId: string, filePath: string): Promise; writeFile(sessionId: string, filePath: string, content: string): Promise<{ success: boolean; }>; renameFile(sessionId: string, filePath: string, newName: string): Promise<{ path: string; }>; copyFile(sessionId: string, filePath: string): Promise<{ path: string; }>; shareFile(sessionId: string, sourcePath: string, linkName?: string, shareFolder?: string): Promise<{ path: string; target: string; }>; getDownloadDirUrl(sessionId: string, dirPath: string): string; exportSession(sessionId: string): Promise; previewImport(file: File): Promise; importSession(file: File, name?: string, solutionOverride?: string | null | ImportSessionOptions): Promise<{ session_id: string; }>; }