Download packages/klient/src/core/facade/session.ts from SaylorTwift/kimi-code: direct link, hf CLI and curl.
- Browser
- Download file 7.81 kB
-
https://huggingface.co/SaylorTwift/kimi-code/resolve/main/packages/klient/src/core/facade/session.ts
- Command line
-
hf download hf://SaylorTwift/kimi-code/packages/klient/src/core/facade/session.ts
-
curl -L -o session.ts https://huggingface.co/SaylorTwift/kimi-code/resolve/main/packages/klient/src/core/facade/session.ts
7.81 kB
| /** | |
| * The session facade — one `klient.session(id)` handle aggregating the | |
| * session-scope services (metadata, activity, approvals, questions, | |
| * interactions) plus the app-scope lifecycle service for close/archive/ | |
| * restore/delete/fork/createChild. `agents()` reads the metadata registry (agent | |
| * handles are not serializable, so no agent-lifecycle channel exists on the | |
| * wire). | |
| */ | |
| import type { | |
| ApprovalRequest, | |
| ApprovalResponse, | |
| } from '@moonshot-ai/agent-core-v2/agent/interaction/approval'; | |
| import type { | |
| Interaction, | |
| InteractionKind, | |
| } from '@moonshot-ai/agent-core-v2/human/interaction/interaction'; | |
| import type { | |
| QuestionRequest, | |
| QuestionResult, | |
| } from '@moonshot-ai/agent-core-v2/agent/interaction/question'; | |
| import type { | |
| AgentMeta, | |
| SessionMeta, | |
| SessionMetaPatch, | |
| } from '@moonshot-ai/agent-core-v2/session/sessionMetadata/sessionMetadata'; | |
| import type { SkillSummary } from '@moonshot-ai/agent-core-v2/features/skill/catalog/types'; | |
| import type { ScopeRef } from '../channel.js'; | |
| import type { McpServerConfig } from '../../contract/mcp.js'; | |
| import type { ScopedCaller } from './global.js'; | |
| export type { ScopedCaller } from './global.js'; | |
| /** What `sessionLifecycleService.create` and `sessionManager.restore` leave on the wire. */ | |
| interface HandleWire { | |
| readonly id: string; | |
| } | |
| /** | |
| * Options for `SessionFacade.restore` — mirrors the engine's | |
| * `ResumeSessionOptions`. `mcpServers` injects ephemeral per-session MCP | |
| * servers when restore re-materializes a cold session (ignored when the | |
| * session is already live). | |
| */ | |
| export interface SessionRestoreOptions { | |
| readonly additionalDirs?: readonly string[]; | |
| readonly mcpServers?: Readonly<Record<string, McpServerConfig>>; | |
| } | |
| export interface SessionApprovalsFacade { | |
| list(): Promise<readonly ApprovalRequest[]>; | |
| decide(id: string, response: ApprovalResponse): Promise<void>; | |
| } | |
| export interface SessionQuestionsFacade { | |
| list(): Promise<readonly QuestionRequest[]>; | |
| answer(id: string, result: QuestionResult): Promise<void>; | |
| dismiss(id: string): Promise<void>; | |
| } | |
| export interface SessionInteractionsFacade { | |
| list(kind?: InteractionKind): Promise<readonly Interaction[]>; | |
| respond(id: string, response: unknown): Promise<void>; | |
| } | |
| export interface SessionSkillsFacade { | |
| /** | |
| * Every skill in the session-merged catalog as a plain summary (the | |
| * catalog's readiness is resolved engine-side). Subscribe to | |
| * `session.events` `'skills.changed'` for updates. | |
| */ | |
| list(): Promise<readonly SkillSummary[]>; | |
| } | |
| /** | |
| * Derived session lifecycle phase. The facade reads the engine's session | |
| * activity view (busy + pending interaction) and maps it onto the v1 | |
| * precedence: pending approvals and questions first, then busy, then idle. | |
| */ | |
| export type SessionStatus = 'running' | 'idle' | 'awaiting_approval' | 'awaiting_question'; | |
| export interface SessionFacade { | |
| get(): Promise<SessionMeta>; | |
| setTitle(title: string): Promise<void>; | |
| /** | |
| * Generate and apply a title from the main agent's first prompts via the | |
| * managed `chat_title` tool. `undefined` when generation is unavailable | |
| * (no managed OAuth login, no prompt yet, or a custom title is set). | |
| * `force` regenerates anyway, overwriting a generated or custom title. | |
| * `source` picks the conversation excerpt: `user_prompts` (default), | |
| * `first_turn` (opening prompt + first reply; strict), or `digest` | |
| * (head+tail of a multi-turn conversation). | |
| */ | |
| generateTitle(opts?: { | |
| force?: boolean; | |
| source?: 'user_prompts' | 'first_turn' | 'digest'; | |
| }): Promise<string | undefined>; | |
| update(patch: SessionMetaPatch): Promise<void>; | |
| setArchived(archived: boolean): Promise<void>; | |
| status(): Promise<SessionStatus>; | |
| close(): Promise<void>; | |
| archive(): Promise<void>; | |
| /** Re-materialize a closed session; `false` when it no longer exists. */ | |
| restore(opts?: SessionRestoreOptions): Promise<boolean>; | |
| /** Permanently delete the session and its persisted data; throws when missing. */ | |
| delete(): Promise<void>; | |
| fork(input?: { title?: string; metadata?: Record<string, unknown> }): Promise<SessionMeta>; | |
| createChild(input?: { title?: string; metadata?: Record<string, unknown> }): Promise<SessionMeta>; | |
| readonly approvals: SessionApprovalsFacade; | |
| readonly questions: SessionQuestionsFacade; | |
| readonly interactions: SessionInteractionsFacade; | |
| readonly skills: SessionSkillsFacade; | |
| /** Agent id → metadata for every agent registered in this session. */ | |
| agents(): Promise<Readonly<Record<string, AgentMeta>>>; | |
| } | |
| export function createSessionFacade(call: ScopedCaller, sessionId: string): SessionFacade { | |
| const scope: ScopeRef = { sessionId }; | |
| const read = (): Promise<SessionMeta> => | |
| call(scope, 'sessionMetadata', 'read', []) as Promise<SessionMeta>; | |
| const spawn = async ( | |
| method: 'fork' | 'createChild', | |
| input: { title?: string; metadata?: Record<string, unknown> } = {}, | |
| ): Promise<SessionMeta> => { | |
| return call({}, 'sessionManager', method, [ | |
| { sourceSessionId: sessionId, title: input.title, metadata: input.metadata }, | |
| ]) as Promise<SessionMeta>; | |
| }; | |
| return { | |
| get: read, | |
| setTitle: (title) => call(scope, 'sessionMetadata', 'setTitle', [title]) as Promise<void>, | |
| generateTitle: (opts) => | |
| call(scope, 'sessionTitleService', 'generateTitle', [opts]) as Promise< | |
| string | undefined | |
| >, | |
| update: (patch) => call(scope, 'sessionMetadata', 'update', [patch]) as Promise<void>, | |
| setArchived: (archived) => | |
| call(scope, 'sessionMetadata', 'setArchived', [archived]) as Promise<void>, | |
| status: async () => { | |
| const activity = (await call(scope, 'sessionActivityView', 'state', [])) as { | |
| readonly busy: boolean; | |
| readonly pendingInteraction: 'none' | 'approval' | 'question'; | |
| }; | |
| if (activity.pendingInteraction === 'approval') return 'awaiting_approval'; | |
| if (activity.pendingInteraction === 'question') return 'awaiting_question'; | |
| return activity.busy ? 'running' : 'idle'; | |
| }, | |
| close: () => call({}, 'sessionManager', 'close', [sessionId]) as Promise<void>, | |
| archive: () => call({}, 'sessionManager', 'archive', [sessionId]) as Promise<void>, | |
| restore: async (opts) => { | |
| const handle = (await call({}, 'sessionManager', 'restore', [sessionId, opts])) as HandleWire | null; | |
| return handle !== null && handle !== undefined; | |
| }, | |
| delete: () => call({}, 'sessionManager', 'delete', [sessionId]) as Promise<void>, | |
| fork: (input) => spawn('fork', input), | |
| createChild: (input) => spawn('createChild', input), | |
| approvals: { | |
| list: () => | |
| call(scope, 'sessionApprovalService', 'listPending', []) as Promise< | |
| readonly ApprovalRequest[] | |
| >, | |
| decide: (id, response) => | |
| call(scope, 'sessionApprovalService', 'decide', [id, response]) as Promise<void>, | |
| }, | |
| questions: { | |
| list: () => | |
| call(scope, 'sessionQuestionService', 'listPending', []) as Promise< | |
| readonly QuestionRequest[] | |
| >, | |
| answer: (id, result) => | |
| call(scope, 'sessionQuestionService', 'answer', [id, result]) as Promise<void>, | |
| dismiss: (id) => call(scope, 'sessionQuestionService', 'dismiss', [id]) as Promise<void>, | |
| }, | |
| interactions: { | |
| list: (kind) => | |
| call(scope, 'sessionInteractionService', 'listPending', [kind]) as Promise< | |
| readonly Interaction[] | |
| >, | |
| respond: (id, response) => | |
| call(scope, 'sessionInteractionService', 'respond', [id, response]) as Promise<void>, | |
| }, | |
| skills: { | |
| list: () => | |
| call(scope, 'sessionSkillCatalog', 'list', []) as Promise<readonly SkillSummary[]>, | |
| }, | |
| agents: async () => { | |
| const meta = await read(); | |
| return meta.agents ?? {}; | |
| }, | |
| }; | |
| } | |