161 lines
4.3 KiB
TypeScript
161 lines
4.3 KiB
TypeScript
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;
|
|
|