// 1. 定义印客学院支持的AI提供商和消息角色
type InkeProvider = 'openai' | 'anthropic' | 'moonshot' | 'inke-internal';
type InkeMessageRole = 'student' | 'tutor' | 'system' | 'tool'; // 印客学院特有角色
// 2. 使用泛型定义核心消息结构,Content和ToolCall可被具体化
interface InkeMessage<Content = string, ToolCall = any> {
id: `msg_${string}`; // 使用模板字面量类型约束ID格式
sessionId: string; // 隶属于印客学院的某个课程会话
courseId?: string; // 印客学院课程ID
// 3. 使用条件类型,为不同提供商定义特定的响应结构
type InkeAPIResponse<P extends InkeProvider, T = any> = P extends 'openai'
object: 'chat.completion';
usage: { prompt_tokens: number; completion_tokens: number; total_tokens: number };
_inke: { cost: number; model: string };
content: Array<{ type: 'text'; text: string }>;
stop_reason: string | null;
_inke: { provider: 'anthropic'; coursewareCompat: boolean };
: P extends 'inke-internal'
? T & { _inke: { internalId: string; processedBy: string } } // 内部模型格式
// 4. 使用示例:安全地处理不同提供商的响应
async function handleInkeResponse<P extends InkeProvider>(response: InkeAPIResponse<P>) {
// TypeScript能根据传入的response类型推断出P,从而知道response的具体结构
if ('object' in response && response.object === 'chat.completion') {
// 此处,TypeScript知道response是OpenAI格式
console.log(`OpenAI Tokens used: ${response.usage.total_tokens}`);
console.log(`印客学院计费成本: ${response._inke.cost}`);