feat: prepare Zhinian desktop client for pilot release
This commit is contained in:
9
packages/kernel-core/package.json
Normal file
9
packages/kernel-core/package.json
Normal 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"
|
||||
}
|
||||
|
||||
160
packages/kernel-core/src/index.ts
Normal file
160
packages/kernel-core/src/index.ts
Normal 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;
|
||||
|
||||
Reference in New Issue
Block a user