feat: prepare Zhinian desktop client for pilot release

This commit is contained in:
inman
2026-04-29 10:23:20 +08:00
parent f9361e686a
commit 47b83b79fc
149 changed files with 15341 additions and 3590 deletions

View File

@@ -0,0 +1,9 @@
{
"name": "@yinian/kernel-core",
"version": "0.1.0",
"private": true,
"type": "module",
"main": "./src/index.ts",
"types": "./src/index.ts"
}

View File

@@ -0,0 +1,160 @@
export type Brand<T, Name extends string> = T & { readonly __brand: Name };
export type UserId = Brand<string, 'UserId'>;
export type HotelId = Brand<string, 'HotelId'>;
export type ConversationId = Brand<string, 'ConversationId'>;
export type MessageId = Brand<string, 'MessageId'>;
export type SkillId = Brand<string, 'SkillId'>;
export type TaskId = Brand<string, 'TaskId'>;
export type ExecutionId = Brand<string, 'ExecutionId'>;
export interface User {
id: UserId;
name: string;
avatar?: string;
email?: string;
phone?: string;
hotels: HotelMembership[];
}
export interface HotelMembership {
hotelId: HotelId;
role: 'owner' | 'manager' | 'staff' | 'viewer';
}
export interface Hotel {
id: HotelId;
name: string;
brand?: string;
city: string;
ota: HotelOTABinding[];
}
export interface HotelOTABinding {
ota: 'ctrip' | 'meituan' | 'booking' | 'agoda' | 'qunar' | string;
externalId: string;
enabled: boolean;
}
export type MessageRole = 'user' | 'assistant' | 'system' | 'tool';
export interface Message {
id: MessageId;
conversationId: ConversationId;
role: MessageRole;
blocks: ContentBlock[];
createdAt: number;
}
export type ContentBlock =
| TextBlock
| ToolCallBlock
| ToolResultBlock
| ArtifactBlock
| ReasoningBlock;
export interface TextBlock {
type: 'text';
text: string;
}
export interface ReasoningBlock {
type: 'reasoning';
text: string;
}
export interface ToolCallBlock {
type: 'tool_call';
toolCallId: string;
name: string;
input: Record<string, unknown>;
}
export interface ToolResultBlock {
type: 'tool_result';
toolCallId: string;
status: 'success' | 'failed';
output: unknown;
error?: KernelError;
}
export interface ArtifactBlock {
type: 'artifact';
artifact: Artifact;
}
export type Artifact =
| { kind: 'markdown'; id: string; title?: string; content: string }
| { kind: 'table'; id: string; title?: string; columns: string[]; rows: unknown[][] }
| { kind: 'chart'; id: string; title?: string; spec: unknown }
| { kind: 'image'; id: string; title?: string; url: string }
| { kind: 'file'; id: string; title?: string; url: string; mime: string };
export interface KernelError {
code: KernelErrorCode;
message: string;
retryable: boolean;
cause?: unknown;
}
export type KernelErrorCode =
| 'kernel_unavailable'
| 'kernel_timeout'
| 'kernel_aborted'
| 'auth_required'
| 'permission_denied'
| 'skill_not_found'
| 'skill_execution_failed'
| 'invalid_input'
| 'rate_limited'
| 'unknown';
export interface Conversation {
id: ConversationId;
title: string;
hotelId: HotelId;
createdAt: number;
updatedAt: number;
messageCount: number;
}
export interface CreateConversationInput {
hotelId: HotelId;
title?: string;
}
export interface SendMessageInput {
conversationId: ConversationId;
content: TextBlock | { type: 'invoke_skill'; skillId: SkillId; input: Record<string, unknown> };
}
export type ConversationStreamEvent =
| { type: 'message_start'; message: Pick<Message, 'id' | 'role' | 'createdAt'> }
| { type: 'text_delta'; messageId: MessageId; delta: string }
| { type: 'reasoning_delta'; messageId: MessageId; delta: string }
| { type: 'tool_call'; messageId: MessageId; block: ToolCallBlock }
| { type: 'tool_result'; messageId: MessageId; block: ToolResultBlock }
| { type: 'artifact'; messageId: MessageId; artifact: Artifact }
| { type: 'message_complete'; messageId: MessageId; message: Message }
| { type: 'error'; error: KernelError };
export interface ConversationPort {
list(query?: { hotelId?: HotelId; limit?: number }): Promise<Conversation[]>;
get(id: ConversationId): Promise<Conversation>;
create(input: CreateConversationInput): Promise<Conversation>;
delete(id: ConversationId): Promise<void>;
send(input: SendMessageInput): AsyncIterable<ConversationStreamEvent>;
abort(conversationId: ConversationId): Promise<void>;
history(conversationId: ConversationId, opts?: { before?: MessageId; limit?: number }): Promise<Message[]>;
}
export interface Adapter {
readonly info: { name: string; kernelVersion: string };
connect(): Promise<void>;
disconnect(): Promise<void>;
health(): Promise<{ ready: boolean; details?: Record<string, unknown> }>;
readonly conversation: ConversationPort;
}
export type AdapterFactory<Config> = (config: Config) => Adapter;