@h-ai/ai 0.1.0-alpha.53 → 0.1.0-alpha.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -168,8 +168,16 @@ const batch = await registry.executeAll(toolCalls)
168
168
  const chat = await ai.llm.chat({ messages, tools: registry.getDefinitions() })
169
169
  ```
170
170
 
171
+ ### A2A 协议边界
172
+
173
+ `ai.a2a.getAgentCard()` 返回完整 A2A 0.3 Agent Card,含 `protocolVersion`、MIME 和 streaming 能力;Kit 默认发现路径为 `/.well-known/agent-card.json`。`handleRequest()` 始终返回 JSON-RPC/SSE 处理结果,未初始化返回 JSON-RPC 错误。可信 HTTP 认证上下文的 `agentId` 映射为 executor 的 `context.user.userName`。当前支持 JSON-RPC/SSE,不声明 push notifications、gRPC 或 REST 支持;业务资源授权仍由应用负责。
174
+
175
+ A2A 的任务表和消息表在 `ai.init()` 阶段初始化。任务按可信 `agentId` 隔离读取(含获取、取消和继续消息);匿名请求共享匿名作用域,需隔离的部署必须开启认证。`listMessages` 是服务端管理接口,支持 `callerId`、`contextId`、`since` 过滤,不能直接向未授权客户端暴露。旧版任务记录没有可靠主体信息,升级后不会自动推断归属或删除数据,需由应用审核后迁移 `object_id` 为 `user:<agentId>`(匿名为 `anonymous`)。旧消息缺少主体/上下文字段时不会匹配相应过滤条件。
176
+
171
177
  ### MCP Server
172
178
 
179
+ `ai.mcp` 是进程内注册表,独立 `createMcpServer` 使用 SDK transport,两者不会自动互相注册。`ai.mcp` 在注册时编译工具 JSON Schema,调用时校验输入;资源输出必须恰好含 `text` / `blob` 之一;提示词参数与 SDK 消息输出均校验,支持图片和音频内容。HTTP 示例只展示 transport 连接,应用仍须挂载请求处理与认证,并在退出时关闭 server。
180
+
173
181
  ```ts
174
182
  import { createMcpServer, StreamableHTTPServerTransport } from '@h-ai/ai'
175
183
  import { z } from 'zod'
@@ -1,9 +1,10 @@
1
1
  import * as _h_ai_core from '@h-ai/core';
2
2
  import { HaiResult } from '@h-ai/core';
3
- import { a_ as ChatMessage, az as InteractionScope, Y as MemoryType, bL as RagOptions, bP as ReasoningOptions, cm as ToolRegistryOperations, bx as MemoryEntry, c2 as SessionInfo, bq as LLMOperations, bD as MemoryOperations, bK as RagOperations, bO as ReasoningOperations, c as AIConfig, d as AIConfigInput, aP as AIStoreProvider, co as ToolsOperations, c6 as StreamOperations, bV as RetrievalOperations, bk as KnowledgeOperations, aJ as A2AOperations, s as AudioOperations, k as AudioContent, a3 as PlayableAudio, l as AudioFormat } from './ai-reasoning-types-CuITylkA.js';
3
+ import { a_ as ChatMessage, az as InteractionScope, Y as MemoryType, bL as RagOptions, bP as ReasoningOptions, cm as ToolRegistryOperations, bx as MemoryEntry, c2 as SessionInfo, bq as LLMOperations, bD as MemoryOperations, bK as RagOperations, bO as ReasoningOperations, d as AIConfigInput, aP as AIStoreProvider, c as AIConfig, co as ToolsOperations, c6 as StreamOperations, bV as RetrievalOperations, bk as KnowledgeOperations, aJ as A2AOperations, s as AudioOperations, k as AudioContent, a3 as PlayableAudio, l as AudioFormat } from './ai-reasoning-types-D9UyA9Yc.js';
4
4
  import * as zod from 'zod';
5
5
  import { z } from 'zod';
6
6
  import { Buffer } from 'node:buffer';
7
+ import { PromptMessage } from '@modelcontextprotocol/sdk/types.js';
7
8
  import * as zod_v4_core from 'zod/v4/core';
8
9
 
9
10
  /**
@@ -1045,27 +1046,10 @@ interface MCPPromptArgument {
1045
1046
  /** 是否必填(默认 `false`) */
1046
1047
  required?: boolean;
1047
1048
  }
1048
- /** MCP 提示词消息(getPrompt 的返回值元素) */
1049
- interface MCPPromptMessage {
1050
- /** 消息角色 */
1051
- role: 'user' | 'assistant';
1052
- /** 消息内容 */
1053
- content: MCPPromptContent;
1054
- }
1055
- /** MCP 提示词内容(支持纯文本或资源引用) */
1056
- interface MCPPromptContent {
1057
- /** 内容类型:`'text'` 纯文本 | `'resource'` 资源引用 */
1058
- type: 'text' | 'resource';
1059
- /** 文本内容(type 为 `'text'` 时) */
1060
- text?: string;
1061
- /** 资源引用(type 为 `'resource'` 时) */
1062
- resource?: {
1063
- uri: string;
1064
- text?: string;
1065
- blob?: string;
1066
- mimeType?: string;
1067
- };
1068
- }
1049
+ /** MCP 提示词消息,直接复用 SDK 的完整判别联合(含图片、音频与嵌入资源) */
1050
+ type MCPPromptMessage = PromptMessage;
1051
+ /** MCP 提示词内容;按 type 缩窄后访问对应字段 */
1052
+ type MCPPromptContent = PromptMessage['content'];
1069
1053
  /** MCP 服务器创建选项 */
1070
1054
  interface McpServerOptions {
1071
1055
  /** 服务器名称 */
@@ -1073,37 +1057,25 @@ interface McpServerOptions {
1073
1057
  /** 服务器版本(默认 `'1.0.0'`) */
1074
1058
  version?: string;
1075
1059
  }
1076
- /**
1077
- * MCP Provider 接口
1078
- *
1079
- * 定义 MCP 工具/资源/提示词的注册与调用能力。
1080
- */
1081
- interface MCPProvider {
1082
- registerTool: <TInput, TOutput>(definition: MCPToolDefinition, handler: MCPToolHandler<TInput, TOutput>) => HaiResult<void>;
1083
- registerResource: (resource: MCPResource, handler: () => Promise<MCPResourceContent>) => HaiResult<void>;
1084
- registerPrompt: (prompt: MCPPrompt, handler: (args: Record<string, string>) => Promise<MCPPromptMessage[]>) => HaiResult<void>;
1085
- callTool: (name: string, args: unknown, context?: MCPContext) => Promise<HaiResult<unknown>>;
1086
- readResource: (uri: string) => Promise<HaiResult<MCPResourceContent>>;
1087
- getPrompt: (name: string, args: Record<string, string>) => Promise<HaiResult<MCPPromptMessage[]>>;
1088
- }
1089
1060
  /**
1090
1061
  * MCP 操作接口(通过 `ai.mcp` 访问)
1091
1062
  *
1092
1063
  * 需要先调用 `ai.init()` 初始化,否则所有方法返回 `NOT_INITIALIZED` 错误。
1093
1064
  */
1094
1065
  interface MCPOperations {
1066
+ /** 注册工具并编译 JSON Schema;非法 Schema 返回 MCP_TOOL_ERROR,同名注册覆盖 */
1095
1067
  registerTool: <TInput, TOutput>(definition: MCPToolDefinition, handler: MCPToolHandler<TInput, TOutput>) => HaiResult<void>;
1068
+ /** 注册资源加载器;读取时校验 text/blob 输出 */
1096
1069
  registerResource: (resource: MCPResource, handler: () => Promise<MCPResourceContent>) => HaiResult<void>;
1070
+ /** 注册提示词;调用时校验必填参数和 SDK 消息格式 */
1097
1071
  registerPrompt: (prompt: MCPPrompt, handler: (args: Record<string, string>) => Promise<MCPPromptMessage[]>) => HaiResult<void>;
1072
+ /** 校验输入后执行工具;自动补齐缺失的 requestId */
1098
1073
  callTool: (name: string, args: unknown, context?: MCPContext) => Promise<HaiResult<unknown>>;
1074
+ /** 读取资源,输出必须恰好含一个有效 text 或 blob */
1099
1075
  readResource: (uri: string) => Promise<HaiResult<MCPResourceContent>>;
1076
+ /** 渲染提示词;必填参数必须是自身属性,且提供的已声明参数必须是字符串 */
1100
1077
  getPrompt: (name: string, args: Record<string, string>) => Promise<HaiResult<MCPPromptMessage[]>>;
1101
1078
  }
1102
- /** MCP 子功能工厂依赖(内部使用) */
1103
- interface AIMCPFunctionsDeps {
1104
- /** 校验后的 AI 配置 */
1105
- config: AIConfig;
1106
- }
1107
1079
 
1108
1080
  /**
1109
1081
  * @h-ai/ai — Persona 子功能类型
@@ -1764,4 +1736,4 @@ interface AudioWsEndMessage {
1764
1736
  /** 服务端 JSON 消息(合成音频以二进制帧返回,不走 JSON) */
1765
1737
  type AudioWsServerMessage = AudioWsSpeechMessage | AudioWsTranscriptMessage | AudioWsSegmentStartedMessage | AudioWsSegmentDoneMessage | AudioWsErrorMessage | AudioWsEndMessage;
1766
1738
 
1767
- export { type FileParseMethod as $, type AIFunctions as A, type CompressOptions as B, type CompressionStrategy as C, type CompressResult as D, type ConsolidateOptions as E, type ConsolidateResult as F, type GenerateImageRequest as G, HaiAIError as H, type ImageOperations as I, type ContextChatOptions as J, type ContextChatResult as K, type ContextDeps as L, type McpServerOptions as M, type ContextManager as N, type ContextManagerOptions as O, type ContextOperations as P, type ContextResetOptions as Q, type ReferenceImage as R, type ContextStreamEvent as S, type ConversationTurn as T, type ConversationTurnStatus as U, type EmbeddingItem as V, type EmbeddingOperations as W, type EmbeddingProvider as X, type EmbeddingRequest as Y, type EmbeddingResponse as Z, type FileOperations as _, type AIInitOptions as a, type FileParseOptions as a0, type FileParseRequest as a1, type FileParseResult as a2, type MCPContext as a3, type MCPOperations as a4, type MCPPrompt as a5, type MCPPromptArgument as a6, type MCPPromptContent as a7, type MCPPromptMessage as a8, type MCPProvider as a9, type MCPResource as aa, type MCPResourceContent as ab, type MCPToolDefinition as ac, type MCPToolHandler as ad, type OutputFormat as ae, type PersonaOperations as af, type PersonaProfile as ag, type PersonaProfileInput as ah, type PersonaProfileUpdate as ai, type PersonaScopeOptions as aj, type RerankDocument as ak, type RerankItem as al, type RerankOperations as am, type RerankRequest as an, type RerankResponse as ao, type SummaryOperations as ap, type SummaryOptions as aq, type SummaryResult as ar, type TokenOperations as as, AUDIO_WS_PATH as b, AudioFormatSchema as c, type AudioWsClientMessage as d, AudioWsClientMessageSchema as e, type AudioWsDoneMessage as f, AudioWsDoneMessageSchema as g, type AudioWsEndMessage as h, type AudioWsErrorMessage as i, type AudioWsSegmentDoneMessage as j, type AudioWsSegmentStartedMessage as k, type AudioWsServerMessage as l, type AudioWsSpeechMessage as m, type AudioWsStartMessage as n, AudioWsStartMessageSchema as o, type AudioWsTextMessage as p, AudioWsTextMessageSchema as q, type AudioWsTranscriptMessage as r, CompressionStrategySchema as s, type GenerateImageResult as t, type GeneratedImage as u, type ImageSize as v, serializePlayableAudio as w, type AIMCPFunctionsDeps as x, type CommitTurnInput as y, type CompressOperations as z };
1739
+ export { type FileParseOptions as $, type AIFunctions as A, type CompressResult as B, type CompressionStrategy as C, type ConsolidateOptions as D, type ConsolidateResult as E, type ContextChatOptions as F, type GenerateImageRequest as G, HaiAIError as H, type ImageOperations as I, type ContextChatResult as J, type ContextDeps as K, type ContextManager as L, type McpServerOptions as M, type ContextManagerOptions as N, type ContextOperations as O, type ContextResetOptions as P, type ContextStreamEvent as Q, type ReferenceImage as R, type ConversationTurn as S, type ConversationTurnStatus as T, type EmbeddingItem as U, type EmbeddingOperations as V, type EmbeddingProvider as W, type EmbeddingRequest as X, type EmbeddingResponse as Y, type FileOperations as Z, type FileParseMethod as _, type AIInitOptions as a, type FileParseRequest as a0, type FileParseResult as a1, type MCPContext as a2, type MCPOperations as a3, type MCPPrompt as a4, type MCPPromptArgument as a5, type MCPPromptContent as a6, type MCPPromptMessage as a7, type MCPResource as a8, type MCPResourceContent as a9, type MCPToolDefinition as aa, type MCPToolHandler as ab, type OutputFormat as ac, type PersonaOperations as ad, type PersonaProfile as ae, type PersonaProfileInput as af, type PersonaProfileUpdate as ag, type PersonaScopeOptions as ah, type RerankDocument as ai, type RerankItem as aj, type RerankOperations as ak, type RerankRequest as al, type RerankResponse as am, type SummaryOperations as an, type SummaryOptions as ao, type SummaryResult as ap, type TokenOperations as aq, AUDIO_WS_PATH as b, AudioFormatSchema as c, type AudioWsClientMessage as d, AudioWsClientMessageSchema as e, type AudioWsDoneMessage as f, AudioWsDoneMessageSchema as g, type AudioWsEndMessage as h, type AudioWsErrorMessage as i, type AudioWsSegmentDoneMessage as j, type AudioWsSegmentStartedMessage as k, type AudioWsServerMessage as l, type AudioWsSpeechMessage as m, type AudioWsStartMessage as n, AudioWsStartMessageSchema as o, type AudioWsTextMessage as p, AudioWsTextMessageSchema as q, type AudioWsTranscriptMessage as r, CompressionStrategySchema as s, type GenerateImageResult as t, type GeneratedImage as u, type ImageSize as v, serializePlayableAudio as w, type CommitTurnInput as x, type CompressOperations as y, type CompressOptions as z };
@@ -1,3 +1,4 @@
1
+ import { AgentCard } from '@a2a-js/sdk';
1
2
  import { AgentExecutor } from '@a2a-js/sdk/server';
2
3
  import { HaiResult, HaiError } from '@h-ai/core';
3
4
  import { CleanOptionsInput, ChunkOptionsInput } from '@h-ai/datapipe';
@@ -487,6 +488,8 @@ interface A2AMessageRecord {
487
488
  id: string;
488
489
  /** 关联的 A2A Task ID */
489
490
  taskId: string;
491
+ /** 所属会话上下文 ID(历史记录可能缺失) */
492
+ contextId?: string;
490
493
  /** 消息角色:user(入站请求)/ agent(出站响应) */
491
494
  role: 'user' | 'agent';
492
495
  /** 消息内容(JSON 序列化的 Part[] 数组) */
@@ -526,7 +529,7 @@ interface A2AAuthenticator {
526
529
  }
527
530
  /** A2A 任务查询过滤器 */
528
531
  interface A2ATaskFilter {
529
- /** 按任务状态过滤 */
532
+ /** 按消息角色过滤(user / agent),不是任务生命周期状态 */
530
533
  status?: string | string[];
531
534
  /** 按上下文 ID 过滤 */
532
535
  contextId?: string;
@@ -560,21 +563,21 @@ interface A2AOperations {
560
563
  *
561
564
  * 配置了 a2a 后即可使用,无需注册 executor。
562
565
  *
563
- * @returns Agent Card 配置
566
+ * @returns 符合 A2A 0.3 的完整 Agent Card(含能力与安全方案)
564
567
  */
565
- getAgentCard: () => HaiResult<A2AAgentCardConfig>;
568
+ getAgentCard: () => HaiResult<AgentCard>;
566
569
  /**
567
570
  * 处理入站 JSON-RPC 请求
568
571
  *
569
572
  * 将 HTTP 请求体路由到 SDK 的 JsonRpcTransportHandler。
570
573
  *
571
574
  * @param requestBody - JSON-RPC 请求体
572
- * @param context - 可选的调用上下文(含认证信息)
573
- * @returns JSON-RPC 响应(单条或流式)
575
+ * @param context - 可信 HTTP 层认证上下文;agentId 映射为 SDK user.userName
576
+ * @returns JSON-RPC 响应(单条或流式);未初始化也返回 JSON-RPC 错误,不混入 HaiResult
574
577
  */
575
578
  handleRequest: (requestBody: unknown, context?: Record<string, unknown>) => Promise<A2AHandleResult>;
576
579
  /**
577
- * 查询 A2A 任务列表
580
+ * 查询 A2A 消息列表(服务端管理接口,不自动推断调用方权限)
578
581
  *
579
582
  * @param filter - 查询过滤器
580
583
  * @returns 分页的消息记录列表
package/dist/browser.d.ts CHANGED
@@ -1,10 +1,12 @@
1
- export { A as A2AConfig, a as A2AConfigSchema, b as A2ASkillConfigSchema, c as AIConfig, d as AIConfigInput, e as AIConfigSchema, f as ApiType, g as ApiTypeSchema, h as AudioCapabilitiesRequest, i as AudioConfig, j as AudioConfigSchema, k as AudioContent, l as AudioFormat, m as AudioInputStream, n as AudioModelCapabilities, o as AudioModelEntry, p as AudioModelEntrySchema, q as AudioOperation, r as AudioOperationSchema, s as AudioOperations, t as AudioOperationsSchema, u as AudioProviderName, v as AudioProviderSchema, w as AudioReference, C as CompressConfig, x as CompressConfigSchema, E as EmbeddingConfig, y as EmbeddingConfigSchema, z as EntityType, B as EntityTypeSchema, F as FileConfig, D as FileConfigSchema, I as ImageConfig, G as ImageConfigSchema, H as ImageModelEntry, J as ImageModelEntrySchema, K as ImageProviderName, L as ImageProviderSchema, M as KnowledgeConfig, N as KnowledgeConfigSchema, O as LLMConfig, P as LLMConfigSchema, Q as MCPConfig, R as MCPConfigSchema, S as MCPServerCapabilities, T as MCPServerCapabilitiesSchema, U as MCPServerConfig, V as MCPServerConfigSchema, W as MemoryConfig, X as MemoryConfigSchema, Y as MemoryType, Z as MemoryTypeSchema, _ as ModelEntry, $ as ModelEntrySchema, a0 as ModelScenario, a1 as ModelScenarioSchema, a2 as OptionalSecretSchema, a3 as PlayableAudio, a4 as ResolveRequiredModelEntryOptions, a5 as ResolvedAudioModel, a6 as ResolvedImageModel, a7 as ResolvedModelConfig, a8 as RetrievalConfig, a9 as RetrievalConfigSchema, aa as RetrievalSourceConfig, ab as RetrievalSourceSchema, ac as SummaryConfig, ad as SummaryConfigSchema, ae as SynthesisEvent, af as SynthesisOptions, ag as SynthesisRequest, ah as SynthesisResult, ai as SynthesisStreamRequest, aj as SynthesisTextSegment, ak as TokenConfig, al as TokenConfigSchema, am as TranscriptionEvent, an as TranscriptionOptions, ao as TranscriptionRequest, ap as TranscriptionResult, aq as TranscriptionSegment, ar as TranscriptionStreamRequest, as as TranscriptionTimestampGranularity, at as TranscriptionWord, au as ensureAudioCredential, av as resolveAudioModel, aw as resolveImageModel, ax as resolveModelApi, ay as resolveModelEntry } from './ai-reasoning-types-CuITylkA.js';
2
- export { A as AIFunctions, a as AIInitOptions, b as AUDIO_WS_PATH, c as AudioFormatSchema, d as AudioWsClientMessage, e as AudioWsClientMessageSchema, f as AudioWsDoneMessage, g as AudioWsDoneMessageSchema, h as AudioWsEndMessage, i as AudioWsErrorMessage, j as AudioWsSegmentDoneMessage, k as AudioWsSegmentStartedMessage, l as AudioWsServerMessage, m as AudioWsSpeechMessage, n as AudioWsStartMessage, o as AudioWsStartMessageSchema, p as AudioWsTextMessage, q as AudioWsTextMessageSchema, r as AudioWsTranscriptMessage, C as CompressionStrategy, s as CompressionStrategySchema, G as GenerateImageRequest, t as GenerateImageResult, u as GeneratedImage, H as HaiAIError, I as ImageOperations, v as ImageSize, R as ReferenceImage, w as serializePlayableAudio } from './ai-audio-ws-protocol-COIRfUFF.js';
1
+ export { A as A2AConfig, a as A2AConfigSchema, b as A2ASkillConfigSchema, c as AIConfig, d as AIConfigInput, e as AIConfigSchema, f as ApiType, g as ApiTypeSchema, h as AudioCapabilitiesRequest, i as AudioConfig, j as AudioConfigSchema, k as AudioContent, l as AudioFormat, m as AudioInputStream, n as AudioModelCapabilities, o as AudioModelEntry, p as AudioModelEntrySchema, q as AudioOperation, r as AudioOperationSchema, s as AudioOperations, t as AudioOperationsSchema, u as AudioProviderName, v as AudioProviderSchema, w as AudioReference, C as CompressConfig, x as CompressConfigSchema, E as EmbeddingConfig, y as EmbeddingConfigSchema, z as EntityType, B as EntityTypeSchema, F as FileConfig, D as FileConfigSchema, I as ImageConfig, G as ImageConfigSchema, H as ImageModelEntry, J as ImageModelEntrySchema, K as ImageProviderName, L as ImageProviderSchema, M as KnowledgeConfig, N as KnowledgeConfigSchema, O as LLMConfig, P as LLMConfigSchema, Q as MCPConfig, R as MCPConfigSchema, S as MCPServerCapabilities, T as MCPServerCapabilitiesSchema, U as MCPServerConfig, V as MCPServerConfigSchema, W as MemoryConfig, X as MemoryConfigSchema, Y as MemoryType, Z as MemoryTypeSchema, _ as ModelEntry, $ as ModelEntrySchema, a0 as ModelScenario, a1 as ModelScenarioSchema, a2 as OptionalSecretSchema, a3 as PlayableAudio, a4 as ResolveRequiredModelEntryOptions, a5 as ResolvedAudioModel, a6 as ResolvedImageModel, a7 as ResolvedModelConfig, a8 as RetrievalConfig, a9 as RetrievalConfigSchema, aa as RetrievalSourceConfig, ab as RetrievalSourceSchema, ac as SummaryConfig, ad as SummaryConfigSchema, ae as SynthesisEvent, af as SynthesisOptions, ag as SynthesisRequest, ah as SynthesisResult, ai as SynthesisStreamRequest, aj as SynthesisTextSegment, ak as TokenConfig, al as TokenConfigSchema, am as TranscriptionEvent, an as TranscriptionOptions, ao as TranscriptionRequest, ap as TranscriptionResult, aq as TranscriptionSegment, ar as TranscriptionStreamRequest, as as TranscriptionTimestampGranularity, at as TranscriptionWord, au as ensureAudioCredential, av as resolveAudioModel, aw as resolveImageModel, ax as resolveModelApi, ay as resolveModelEntry } from './ai-reasoning-types-D9UyA9Yc.js';
2
+ export { A as AIFunctions, a as AIInitOptions, b as AUDIO_WS_PATH, c as AudioFormatSchema, d as AudioWsClientMessage, e as AudioWsClientMessageSchema, f as AudioWsDoneMessage, g as AudioWsDoneMessageSchema, h as AudioWsEndMessage, i as AudioWsErrorMessage, j as AudioWsSegmentDoneMessage, k as AudioWsSegmentStartedMessage, l as AudioWsServerMessage, m as AudioWsSpeechMessage, n as AudioWsStartMessage, o as AudioWsStartMessageSchema, p as AudioWsTextMessage, q as AudioWsTextMessageSchema, r as AudioWsTranscriptMessage, C as CompressionStrategy, s as CompressionStrategySchema, G as GenerateImageRequest, t as GenerateImageResult, u as GeneratedImage, H as HaiAIError, I as ImageOperations, v as ImageSize, R as ReferenceImage, w as serializePlayableAudio } from './ai-audio-ws-protocol-BcF5gqtG.js';
3
3
  export { A2AClientOperations, AIApiAdapter, AIClient, AIClientConfig, AudioClientConfig, AudioClientOperations, AudioTicketRequest, StreamOptions, StreamProgress, collectStreamContent, createA2AClient, createAIClient, createAudioClient, createUnconfiguredAudioClient, parseSSE } from './client/index.js';
4
+ import '@a2a-js/sdk';
4
5
  import '@a2a-js/sdk/server';
5
6
  import '@h-ai/core';
6
7
  import '@h-ai/datapipe';
7
8
  import 'zod';
8
9
  import 'openai';
9
10
  import 'node:buffer';
11
+ import '@modelcontextprotocol/sdk/types.js';
10
12
  import 'zod/v4/core';
package/dist/browser.js CHANGED
@@ -1,5 +1,5 @@
1
- export { A2AConfigSchema, A2ASkillConfigSchema, AIConfigSchema, AUDIO_WS_PATH, ApiTypeSchema, AudioConfigSchema, AudioFormatSchema, AudioModelEntrySchema, AudioOperationSchema, AudioOperationsSchema, AudioProviderSchema, AudioWsClientMessageSchema, AudioWsDoneMessageSchema, AudioWsStartMessageSchema, AudioWsTextMessageSchema, CompressConfigSchema, CompressionStrategySchema, EmbeddingConfigSchema, EntityTypeSchema, FileConfigSchema, ImageConfigSchema, ImageModelEntrySchema, ImageProviderSchema, KnowledgeConfigSchema, LLMConfigSchema, MCPConfigSchema, MCPServerCapabilitiesSchema, MCPServerConfigSchema, MemoryConfigSchema, MemoryTypeSchema, ModelEntrySchema, ModelScenarioSchema, OptionalSecretSchema, RetrievalConfigSchema, RetrievalSourceSchema, SummaryConfigSchema, TokenConfigSchema, ensureAudioCredential, resolveAudioModel, resolveImageModel, resolveModelApi, resolveModelEntry, serializePlayableAudio } from './chunk-PLNY4UUT.js';
2
- export { collectStreamContent, createA2AClient, createAIClient, createAudioClient, createUnconfiguredAudioClient, parseSSE } from './chunk-6RWS5OWJ.js';
1
+ export { A2AConfigSchema, A2ASkillConfigSchema, AIConfigSchema, AUDIO_WS_PATH, ApiTypeSchema, AudioConfigSchema, AudioFormatSchema, AudioModelEntrySchema, AudioOperationSchema, AudioOperationsSchema, AudioProviderSchema, AudioWsClientMessageSchema, AudioWsDoneMessageSchema, AudioWsStartMessageSchema, AudioWsTextMessageSchema, CompressConfigSchema, CompressionStrategySchema, EmbeddingConfigSchema, EntityTypeSchema, FileConfigSchema, ImageConfigSchema, ImageModelEntrySchema, ImageProviderSchema, KnowledgeConfigSchema, LLMConfigSchema, MCPConfigSchema, MCPServerCapabilitiesSchema, MCPServerConfigSchema, MemoryConfigSchema, MemoryTypeSchema, ModelEntrySchema, ModelScenarioSchema, OptionalSecretSchema, RetrievalConfigSchema, RetrievalSourceSchema, SummaryConfigSchema, TokenConfigSchema, ensureAudioCredential, resolveAudioModel, resolveImageModel, resolveModelApi, resolveModelEntry, serializePlayableAudio } from './chunk-GD7RNBUX.js';
2
+ export { collectStreamContent, createA2AClient, createAIClient, createAudioClient, createUnconfiguredAudioClient, parseSSE } from './chunk-7SMQSE4S.js';
3
3
  export { HaiAIError } from './chunk-JC7QBT3C.js';
4
4
  //# sourceMappingURL=browser.js.map
5
5
  //# sourceMappingURL=browser.js.map
@@ -574,5 +574,5 @@ async function collectStreamContent(stream) {
574
574
  }
575
575
 
576
576
  export { collectStreamContent, createA2AClient, createAIClient, createAudioClient, createUnconfiguredAudioClient, parseSSE };
577
- //# sourceMappingURL=chunk-6RWS5OWJ.js.map
578
- //# sourceMappingURL=chunk-6RWS5OWJ.js.map
577
+ //# sourceMappingURL=chunk-7SMQSE4S.js.map
578
+ //# sourceMappingURL=chunk-7SMQSE4S.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/client/ai-a2a-client.ts","../src/client/ai-audio-client.ts","../src/client/ai-client.ts"],"names":[],"mappings":"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","file":"chunk-7SMQSE4S.js","sourcesContent":["/**\n * @h-ai/ai — 前端 A2A 客户端\n *\n * 浏览器端 A2A 操作客户端,通过 API 服务调用后端 A2A 能力。\n * @module ai-a2a-client\n */\n\nimport type {\n A2ACallResult,\n A2AMessageRecord,\n AgentCard,\n} from '../a2a/ai-a2a-types.js'\nimport type { StorePage } from '../store/ai-store-types.js'\nimport type { AIApiAdapter } from './ai-client.js'\n\n// ─── A2A 客户端接口 ───\n\n/**\n * A2A 客户端接口\n *\n * 提供浏览器端调用后端 A2A API 的能力。\n */\nexport interface A2AClientOperations {\n /** 获取完整 A2A Agent Card;传输失败时抛出异常 */\n getAgentCard: () => Promise<AgentCard>\n /** 查询 A2A 消息记录 */\n listMessages: (filter?: { contextId?: string, status?: string, limit?: number, offset?: number }) => Promise<StorePage<A2AMessageRecord>>\n /** 作为客户端调用远端 Agent */\n callRemoteAgent: (remoteUrl: string, message: string, options?: { timeout?: number }) => Promise<A2ACallResult>\n}\n\n// ─── A2A API 路径 ───\n\nconst A2A_PATH = {\n agentCard: '/a2a/agent-card',\n messages: '/a2a/messages',\n callRemote: '/a2a/call',\n} as const\n\n// ─── 工厂函数 ───\n\n/**\n * 创建 A2A 客户端\n *\n * @param api - API 适配器(来自 @h-ai/api-client)\n * @returns A2A 客户端操作实例\n */\nexport function createA2AClient(api: AIApiAdapter): A2AClientOperations {\n return {\n async getAgentCard(): Promise<AgentCard> {\n const result = await api.post<AgentCard>(A2A_PATH.agentCard)\n if (!result.success) {\n throw new Error(`A2A get agent card failed: ${result.error.message}`)\n }\n return result.data\n },\n\n async listMessages(filter?: { contextId?: string, status?: string, limit?: number, offset?: number }): Promise<StorePage<A2AMessageRecord>> {\n const result = await api.post<StorePage<A2AMessageRecord>>(A2A_PATH.messages, filter ?? {})\n if (!result.success) {\n throw new Error(`A2A list messages failed: ${result.error.message}`)\n }\n return result.data\n },\n\n async callRemoteAgent(remoteUrl: string, message: string, options?: { timeout?: number }): Promise<A2ACallResult> {\n const result = await api.post<A2ACallResult>(A2A_PATH.callRemote, {\n remoteUrl,\n message,\n ...options,\n })\n if (!result.success) {\n throw new Error(`A2A remote call failed: ${result.error.message}`)\n }\n return result.data\n },\n }\n}\n","/**\n * @h-ai/ai/client — 浏览器语音客户端\n *\n * 通过统一 WebSocket 连接 `@h-ai/serv` 的语音入口,向浏览器暴露与 Node 端一致的\n * `ai.audio.*` 业务 API。WebSocket 建立、消息编解码等传输细节在此内部完成,\n * 调用方不接触任何厂商原生事件。\n * @module client/ai-audio-client\n */\n\nimport type {\n SynthesisEvent,\n SynthesisRequest,\n SynthesisResult,\n SynthesisStreamRequest,\n SynthesisTextSegment,\n TranscriptionEvent,\n TranscriptionRequest,\n TranscriptionResult,\n TranscriptionStreamRequest,\n} from '../audio/ai-audio-types.js'\nimport type { AudioWsServerMessage, AudioWsStartMessage } from '../audio/ai-audio-ws-protocol.js'\nimport { HaiAIError } from '../ai-types.js'\n\n/**\n * 构造带领域错误码的浏览器客户端错误\n *\n * 浏览器 Client 约定出错抛异常;此处在 `Error.code` 上保留领域错误码\n * (取消 / 连接失败 / 服务端领域错误),供调用方区分正常结束、取消与异常断连。\n */\nfunction audioClientError(code: string | number, message: string): Error {\n const error = new Error(message)\n ;(error as { code?: string | number }).code = code\n return error\n}\n\n// ─── 客户端配置 ───\n\n/**\n * getTicket 收到的当前 Audio 请求摘要\n *\n * 供应用签发与本次操作严格绑定的能力票据(如 `iam.ticket.issue({ grant })`),\n * 使票据只能用于本次操作 / 模型 / 会话,降低票据被重放的风险。\n */\nexport interface AudioTicketRequest {\n /** 本次操作类型 */\n operation: 'transcribe' | 'synthesize'\n /** 本次使用的模型 ID(如有指定) */\n model?: string\n}\n\n/** 浏览器语音客户端配置 */\nexport interface AudioClientConfig {\n /** 语音 WebSocket 完整 URL(如 `wss://host/api/v1/ai/audio`) */\n url: string\n /**\n * 获取短期、一次性的 Audio WebSocket ticket\n *\n * ticket 应由已登录 HTTP 请求签发,并在服务端首次校验时原子消费。\n * 收到当前请求摘要(operation / model),可签发与本次操作严格绑定的票据。\n */\n getTicket: (request: AudioTicketRequest) => string | Promise<string>\n}\n\n/**\n * 浏览器语音操作接口\n *\n * 与 Node 端 `AudioOperations` 业务形态一致;出错时抛出异常(浏览器 Client 约定)。\n */\nexport interface AudioClientOperations {\n /** 将完整音频识别为完整文本 */\n transcribe: (request: TranscriptionRequest) => Promise<TranscriptionResult>\n /** 持续输入音频或增量返回识别文本(含语音起止事件) */\n transcribeStream: (request: TranscriptionStreamRequest) => AsyncIterable<TranscriptionEvent>\n /** 将完整文本合成为完整音频 */\n synthesize: (request: SynthesisRequest) => Promise<SynthesisResult>\n /** 持续输入文本段并按段输出结构化音频事件 */\n synthesizeStream: (request: SynthesisStreamRequest) => AsyncIterable<SynthesisEvent>\n}\n\n// ─── 浏览器 WebSocket 辅助 ───\n\n/** WebSocket 收到的消息 */\ninterface BrowserWsMessage {\n text?: string\n binary?: Uint8Array\n isBinary: boolean\n}\n\n/** 浏览器 WebSocket 连接封装 */\ninterface BrowserWsConnection {\n send: (data: string | Uint8Array) => void\n messages: () => AsyncIterableIterator<BrowserWsMessage>\n close: () => void\n}\n\n/** 建立浏览器 WebSocket 连接(内部消息队列 → 异步迭代) */\nfunction openBrowserWs(url: string, signal?: AbortSignal): Promise<BrowserWsConnection> {\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(url)\n ws.binaryType = 'arraybuffer'\n\n const queue: BrowserWsMessage[] = []\n let waiting: ((result: IteratorResult<BrowserWsMessage>) => void) | null = null\n let closed = false\n let opened = false\n let aborted = false\n let failure: Error | null = null\n\n function settleClosed(): void {\n if (closed)\n return\n closed = true\n signal?.removeEventListener('abort', onAbort)\n if (waiting) {\n const w = waiting\n waiting = null\n w({ value: undefined, done: true })\n }\n }\n\n function onAbort(): void {\n aborted = true\n if (!opened) {\n // 连接建立前取消:直接以取消错误拒绝建连\n settleClosed()\n reject(audioClientError(HaiAIError.AUDIO_CANCELLED.code, 'Audio operation cancelled'))\n }\n // 连接建立后取消:关闭连接,由消息迭代器在终止时抛出 AUDIO_CANCELLED\n ws.close()\n }\n\n /**\n * socket 关闭且未按协议正常收到 `end` 时的终止错误。\n *\n * 消费方在收到服务端 `end` 时会主动 break,因而正常结束不会走到此分支;\n * 走到此分支即意味着连接在完成前关闭,须区分取消 / 网络异常抛出对应领域错误。\n */\n function terminalError(): Error {\n if (aborted)\n return audioClientError(HaiAIError.AUDIO_CANCELLED.code, 'Audio operation cancelled')\n if (failure)\n return failure\n return audioClientError(HaiAIError.AUDIO_CONNECTION_FAILED.code, 'Audio WebSocket closed before completion')\n }\n\n function push(message: BrowserWsMessage): void {\n if (waiting) {\n const w = waiting\n waiting = null\n w({ value: message, done: false })\n }\n else {\n queue.push(message)\n }\n }\n\n ws.onmessage = (event: MessageEvent): void => {\n if (typeof event.data === 'string')\n push({ isBinary: false, text: event.data })\n else\n push({ isBinary: true, binary: new Uint8Array(event.data as ArrayBuffer) })\n }\n // 连接建立前后的错误都记录:建立前直接拒绝,建立后由迭代器在关闭时抛出 AUDIO_CONNECTION_FAILED\n ws.onerror = (): void => {\n failure = audioClientError(HaiAIError.AUDIO_CONNECTION_FAILED.code, 'Audio WebSocket connection failed')\n if (!opened) {\n settleClosed()\n reject(failure)\n }\n }\n ws.onclose = (): void => settleClosed()\n\n if (signal) {\n if (signal.aborted)\n onAbort()\n else\n signal.addEventListener('abort', onAbort, { once: true })\n }\n\n ws.onopen = (): void => {\n opened = true\n resolve({\n // DOM WebSocket.send 的 BufferSource 泛型限定为 ArrayBuffer,Uint8Array 需显式收窄\n send: data => ws.send(data as string | Uint8Array<ArrayBuffer>),\n async* messages() {\n while (true) {\n if (queue.length > 0) {\n yield queue.shift() as BrowserWsMessage\n continue\n }\n if (closed)\n throw terminalError()\n const next = await new Promise<IteratorResult<BrowserWsMessage>>((res) => {\n waiting = res\n })\n if (next.done)\n throw terminalError()\n yield next.value\n }\n },\n close: () => ws.close(),\n })\n }\n })\n}\n\n// ─── 客户端实现 ───\n\n/**\n * 创建浏览器语音客户端\n *\n * @param config - 语音客户端配置\n * @returns 浏览器语音操作接口\n */\nexport function createAudioClient(config: AudioClientConfig): AudioClientOperations {\n async function buildUrl(request: AudioTicketRequest): Promise<string> {\n const ticket = await config.getTicket(request)\n if (!ticket)\n throw new Error('Audio WebSocket ticket is required')\n const separator = config.url.includes('?') ? '&' : '?'\n return `${config.url}${separator}ticket=${encodeURIComponent(ticket)}`\n }\n\n function startMessage(operation: 'transcribe' | 'synthesize', extra: Partial<AudioWsStartMessage>): string {\n return JSON.stringify({ type: 'start', operation, ...extra } satisfies AudioWsStartMessage)\n }\n\n async function* transcribeStream(request: TranscriptionStreamRequest): AsyncIterable<TranscriptionEvent> {\n const conn = await openBrowserWs(await buildUrl({ operation: 'transcribe', model: request.model }), request.signal)\n try {\n const format = request.audio.format\n const sampleRate = request.audio.sampleRate\n conn.send(startMessage('transcribe', { stream: true, model: request.model, language: request.language, contextHints: request.contextHints, format, sampleRate, channels: request.audio.channels }))\n\n const sendAudio = (async () => {\n if ('chunks' in request.audio) {\n for await (const part of request.audio.chunks)\n conn.send(part)\n }\n else {\n conn.send(request.audio.data)\n }\n conn.send(JSON.stringify({ type: 'done' }))\n })()\n let sendError: unknown\n sendAudio.catch((e: unknown) => {\n sendError = e\n })\n\n for await (const message of conn.messages()) {\n if (message.isBinary || !message.text)\n continue\n const event = JSON.parse(message.text) as AudioWsServerMessage\n if (event.type === 'transcript')\n yield { type: 'transcript', text: event.text, final: event.final }\n else if (event.type === 'speech_started')\n yield { type: 'speech_started' }\n else if (event.type === 'speech_stopped')\n yield { type: 'speech_stopped' }\n else if (event.type === 'error')\n throw audioClientError(event.code, event.message)\n else if (event.type === 'end')\n break\n }\n if (sendError)\n throw sendError\n }\n finally {\n conn.close()\n }\n }\n\n async function transcribe(request: TranscriptionRequest): Promise<TranscriptionResult> {\n // 完整识别:服务端缓冲全部音频后返回单条最终结果\n const conn = await openBrowserWs(await buildUrl({ operation: 'transcribe', model: request.model }), request.signal)\n try {\n conn.send(startMessage('transcribe', { stream: false, model: request.model, language: request.language, contextHints: request.contextHints, format: request.audio.format, sampleRate: request.audio.sampleRate, channels: request.audio.channels }))\n conn.send(request.audio.data)\n conn.send(JSON.stringify({ type: 'done' }))\n\n let text = ''\n for await (const message of conn.messages()) {\n if (message.isBinary || !message.text)\n continue\n const event = JSON.parse(message.text) as AudioWsServerMessage\n if (event.type === 'transcript')\n text = event.text\n else if (event.type === 'error')\n throw audioClientError(event.code, event.message)\n else if (event.type === 'end')\n break\n }\n return { text }\n }\n finally {\n conn.close()\n }\n }\n\n async function* synthesizeStream(request: SynthesisStreamRequest): AsyncIterable<SynthesisEvent> {\n const conn = await openBrowserWs(await buildUrl({ operation: 'synthesize', model: request.model }), request.signal)\n try {\n conn.send(startMessage('synthesize', { model: request.model, voice: request.voice, instruction: request.instruction, format: request.format, sampleRate: request.sampleRate }))\n\n const sendText = (async () => {\n const segments = isSynthesisTextSegment(request.text) ? singleSegment(request.text) : request.text\n for await (const segment of segments)\n conn.send(JSON.stringify({ type: 'text', segmentId: segment.id, text: segment.text }))\n conn.send(JSON.stringify({ type: 'done' }))\n })()\n let sendError: unknown\n sendText.catch((e: unknown) => {\n sendError = e\n })\n\n let activeSegmentId: string | undefined\n for await (const message of conn.messages()) {\n if (message.isBinary && message.binary) {\n if (!activeSegmentId)\n throw new Error('Audio frame received outside a synthesis segment')\n yield { type: 'audio', segmentId: activeSegmentId, data: message.binary }\n continue\n }\n if (!message.text)\n continue\n const event = JSON.parse(message.text) as AudioWsServerMessage\n if (event.type === 'segment_started') {\n if (activeSegmentId)\n throw new Error('Synthesis segment started before the previous segment completed')\n activeSegmentId = event.segmentId\n yield event\n }\n else if (event.type === 'segment_done') {\n if (activeSegmentId !== event.segmentId)\n throw new Error('Synthesis segment completion does not match the active segment')\n yield event\n activeSegmentId = undefined\n }\n else if (event.type === 'error') {\n throw audioClientError(event.code, event.message)\n }\n else if (event.type === 'end') {\n // 收到 end 但仍有未完成的合成段:视为本次合成失败,不得把部分音频当作成功结果\n if (activeSegmentId)\n throw audioClientError(HaiAIError.AUDIO_PROTOCOL_ERROR.code, 'Synthesis ended before the active segment completed')\n break\n }\n }\n if (sendError)\n throw sendError\n }\n finally {\n conn.close()\n }\n }\n\n async function synthesize(request: SynthesisRequest): Promise<SynthesisResult> {\n const chunks: Uint8Array[] = []\n let meta: { format: SynthesisResult['format'], sampleRate?: number, channels?: 1 | 2 } | undefined\n for await (const event of synthesizeStream({ ...request, text: { id: 'synthesis', text: request.text } })) {\n if (event.type === 'segment_started')\n meta = { format: event.format, sampleRate: event.sampleRate, channels: event.channels }\n else if (event.type === 'audio')\n chunks.push(event.data)\n }\n // 音频格式来自服务端解析后的 Provider 真实输出(随 segment_started 下发),不由请求参数猜测\n if (!meta)\n throw audioClientError(HaiAIError.AUDIO_PROTOCOL_ERROR.code, 'Synthesis completed without segment metadata')\n const total = chunks.reduce((sum, c) => sum + c.length, 0)\n const data = new Uint8Array(total)\n let offset = 0\n for (const chunk of chunks) {\n data.set(chunk, offset)\n offset += chunk.length\n }\n return { data, format: meta.format, sampleRate: meta.sampleRate, channels: meta.channels ?? 1 }\n }\n\n return { transcribe, transcribeStream, synthesize, synthesizeStream }\n}\n\nfunction isSynthesisTextSegment(value: SynthesisStreamRequest['text']): value is SynthesisTextSegment {\n return typeof value === 'object' && value !== null && 'id' in value && 'text' in value\n}\n\nasync function* singleSegment(segment: SynthesisTextSegment): AsyncIterable<SynthesisTextSegment> {\n yield segment\n}\n\n/** 未配置语音入口时的占位实现(调用即抛出,提示需配置 audio) */\nexport function createUnconfiguredAudioClient(): AudioClientOperations {\n const message = 'Audio client not configured. Provide `audio` in createAIClient() config.'\n return {\n transcribe: () => Promise.reject(new Error(message)),\n async* transcribeStream() { throw new Error(message) },\n synthesize: () => Promise.reject(new Error(message)),\n async* synthesizeStream() { throw new Error(message) },\n }\n}\n","/**\n * @h-ai/ai — 前端 AI 客户端\n *\n * 基于 @h-ai/api-client 的 AI 领域客户端。\n * 通过 `createAIClient()` 工厂函数创建,消除自建 HTTP 层,\n * 复用 api-client 提供的 Token 管理、超时、拦截器等基础能力。\n * @module ai-client\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { KnowledgeAskResult, KnowledgeDocumentInfo, KnowledgeIngestResult, KnowledgeRetrieveResult } from '../knowledge/ai-knowledge-types.js'\nimport type {\n ChatCompletionChunk,\n ChatCompletionRequest,\n ChatCompletionResponse,\n ChatMessage,\n ChatRecord,\n} from '../llm/ai-llm-types.js'\nimport type { MemoryEntry, MemoryEntryInput, MemoryUpdateInput } from '../memory/ai-memory-types.js'\nimport type { RagResult } from '../rag/ai-rag-types.js'\nimport type { ReasoningResult } from '../reasoning/ai-reasoning-types.js'\nimport type { SessionInfo, StorePage } from '../store/ai-store-types.js'\nimport type { AudioClientConfig, AudioClientOperations } from './ai-audio-client.js'\n\nimport { createAudioClient, createUnconfiguredAudioClient } from './ai-audio-client.js'\n\n// ─── API 适配器接口 ───\n\n/**\n * AI 客户端所需的 API 调用能力\n *\n * 结构兼容 `@h-ai/api-client` 的 `apiClient` 默认单例(鸭子类型)。\n * 传入 `apiClient` 默认单例即可,无需额外适配。\n */\nexport interface AIApiAdapter {\n /** POST 请求(返回 HaiResult) */\n post: <T>(path: string, body?: unknown) => Promise<HaiResult<T>>\n /** 流式请求(返回 SSE data 行的 AsyncIterable) */\n stream: (path: string, body?: unknown) => AsyncIterable<string>\n}\n\n// ─── 客户端配置 ───\n\n/**\n * AI 客户端配置\n *\n * @example\n * ```ts\n * import { apiClient } from '@h-ai/api-client'\n * import { createAIClient } from '@h-ai/ai/client'\n *\n * await apiClient.init({ baseUrl: '/api', auth: { ... } })\n * const aiClient = createAIClient({ api: apiClient })\n * ```\n */\nexport interface AIClientConfig {\n /**\n * API 调用适配器\n *\n * 传入 `apiClient` 默认单例(初始化后)。\n * baseUrl、Token 管理、超时等通过 api-client 配置。\n */\n api: AIApiAdapter\n /**\n * 语音 WebSocket 配置(可选)\n *\n * 提供后 `client.audio.*` 通过统一 WebSocket 连接 `@h-ai/serv` 语音入口;\n * 未提供时调用 `client.audio.*` 抛出「未配置」错误。\n */\n audio?: AudioClientConfig\n}\n\n/** 流式响应进度(`onProgress` 回调参数) */\nexport interface StreamProgress {\n /** 当前累积的文本内容 */\n content: string\n /** 是否已完成 */\n done: boolean\n /** 完成原因(仅 `done=true` 时有值,如 `'stop'`) */\n finishReason?: string\n}\n\n/** 流式响应选项 */\nexport interface StreamOptions {\n /** 进度回调(每次收到 chunk 时触发) */\n onProgress?: (progress: StreamProgress) => void\n}\n\n// ─── 客户端接口 ───\n\n/**\n * AI 客户端接口\n *\n * 提供浏览器端调用 AI API 的能力,HTTP 基础设施委托给 @h-ai/api-client。\n */\nexport interface AIClient {\n // ─── LLM ───\n /** 发送对话请求(非流式) */\n chat: (request: ChatCompletionRequest) => Promise<ChatCompletionResponse>\n /** 发送流式对话请求,返回异步迭代器 */\n chatStream: (request: ChatCompletionRequest, options?: StreamOptions) => AsyncIterable<ChatCompletionChunk>\n /** 便捷方法:发送纯文本消息并返回回复文本 */\n sendMessage: (message: string, systemPrompt?: string) => Promise<string>\n /** 便捷方法:流式发送纯文本消息并返回完整回复 */\n sendMessageStream: (message: string, options?: StreamOptions, systemPrompt?: string) => Promise<string>\n /** 简单问答(单轮,自动构造 messages) */\n ask: (question: string, options?: { systemPrompt?: string, model?: string }) => Promise<string>\n /** 流式简单问答,返回异步文本流 */\n askStream: (question: string, options?: { systemPrompt?: string, model?: string }) => AsyncIterable<string>\n\n // ─── Knowledge ───\n /** 知识检索(向量 + 实体增强) */\n knowledgeRetrieve: (query: string, options?: { topK?: number, collection?: string }) => Promise<KnowledgeRetrieveResult>\n /** 知识问答(RAG + 信源) */\n knowledgeAsk: (query: string, options?: { model?: string, collection?: string }) => Promise<KnowledgeAskResult>\n /** 导入文档 */\n knowledgeIngest: (input: { documentId: string, content: string, title?: string, collection?: string, metadata?: Record<string, unknown> }) => Promise<KnowledgeIngestResult>\n /** 列出已导入文档 */\n knowledgeListDocuments: (options?: { collection?: string, offset?: number, limit?: number }) => Promise<KnowledgeDocumentInfo[]>\n /** 删除已导入文档 */\n knowledgeRemoveDocument: (documentId: string, options?: { collection?: string }) => Promise<void>\n\n // ─── Memory ───\n /** 检索相关记忆 */\n recallMemories: (query: string, options?: { topK?: number, types?: string[], minImportance?: number, objectId?: string }) => Promise<MemoryEntry[]>\n /** 列出记忆(分页) */\n listMemories: (options?: { types?: string[], objectId?: string, offset?: number, limit?: number }) => Promise<StorePage<MemoryEntry>>\n /** 添加记忆 */\n addMemory: (entry: MemoryEntryInput) => Promise<MemoryEntry>\n /** 更新记忆 */\n updateMemory: (memoryId: string, updates: MemoryUpdateInput) => Promise<MemoryEntry>\n /** 删除记忆 */\n removeMemory: (memoryId: string) => Promise<void>\n\n // ─── Session ───\n /** 列出会话 */\n listSessions: (objectId: string) => Promise<SessionInfo[]>\n /** 重命名会话 */\n renameSession: (sessionId: string, title: string) => Promise<void>\n /** 删除会话 */\n removeSession: (sessionId: string) => Promise<void>\n /** 获取对话历史 */\n chatHistory: (objectId: string, sessionId: string, options?: { limit?: number, order?: 'asc' | 'desc' }) => Promise<ChatRecord[]>\n\n // ─── RAG ───\n /** RAG 查询(检索 + 生成) */\n ragQuery: (query: string, options?: { collection?: string, topK?: number, model?: string }) => Promise<RagResult>\n /** RAG 流式查询,返回 SSE 数据行 */\n ragQueryStream: (query: string, options?: { collection?: string, topK?: number, model?: string }) => AsyncIterable<string>\n\n // ─── Reasoning ───\n /** 推理(多步思考) */\n reasoningRun: (query: string, options?: { model?: string, maxSteps?: number }) => Promise<ReasoningResult>\n /** 推理流式,返回 SSE 数据行 */\n reasoningRunStream: (query: string, options?: { model?: string, maxSteps?: number }) => AsyncIterable<string>\n\n // ─── Token ───\n /** 估算文本的 Token 数 */\n estimateTokens: (text: string) => Promise<{ tokens: number }>\n\n // ─── Audio ───\n /** 语音操作(识别 / 合成),需在 createAIClient 配置 `audio` */\n audio: AudioClientOperations\n}\n\n// ─── AI API 路径(与 ai-api-contract 保持一致) ───\n\nconst AI_PATH = {\n // LLM\n chat: '/ai/chat',\n chatStream: '/ai/chat/stream',\n chatHistory: '/ai/chat/history',\n ask: '/ai/ask',\n askStream: '/ai/ask/stream',\n // Knowledge\n knowledgeRetrieve: '/ai/knowledge/retrieve',\n knowledgeAsk: '/ai/knowledge/ask',\n knowledgeIngest: '/ai/knowledge/ingest',\n knowledgeDocuments: '/ai/knowledge/documents',\n knowledgeRemoveDocument: '/ai/knowledge/documents/remove',\n // Memory\n memoryRecall: '/ai/memory/recall',\n memoryList: '/ai/memory/list',\n memoryAdd: '/ai/memory/add',\n memoryUpdate: '/ai/memory/update',\n memoryRemove: '/ai/memory/remove',\n // Session\n sessions: '/ai/sessions',\n sessionRename: '/ai/sessions/rename',\n sessionRemove: '/ai/sessions/remove',\n // RAG\n ragQuery: '/ai/rag/query',\n ragQueryStream: '/ai/rag/query/stream',\n // Reasoning\n reasoningRun: '/ai/reasoning/run',\n reasoningRunStream: '/ai/reasoning/run/stream',\n // Token\n tokenEstimate: '/ai/token/estimate',\n} as const\n\n// ─── 工厂函数 ───\n\n/**\n * 创建 AI 客户端\n *\n * 通过 @h-ai/api-client 的 ApiClient 实例调用后端 AI API。\n * HTTP 层(Token、超时、拦截器)全部复用 api-client,本模块仅负责:\n * - 非流式 / 流式 ChatCompletion 协议适配\n * - SSE 解析与 ChatCompletionChunk 类型化\n * - onProgress 进度回调\n *\n * @param config - 客户端配置\n * @returns AI 客户端实例\n *\n * @example\n * ```ts\n * import { apiClient } from '@h-ai/api-client'\n * import { createAIClient } from '@h-ai/ai/client'\n *\n * await apiClient.init({ baseUrl: '/api' })\n * const client = createAIClient({ api: apiClient })\n * const reply = await client.sendMessage('你好')\n * ```\n */\nexport function createAIClient(config: AIClientConfig): AIClient {\n const { api } = config\n const audio = config.audio ? createAudioClient(config.audio) : createUnconfiguredAudioClient()\n\n return {\n async chat(req: ChatCompletionRequest): Promise<ChatCompletionResponse> {\n const result = await api.post<ChatCompletionResponse>(AI_PATH.chat, { ...req, stream: false })\n if (!result.success) {\n throw new Error(`AI chat request failed: ${result.error.message}`)\n }\n return result.data\n },\n\n async* chatStream(\n req: ChatCompletionRequest,\n options?: StreamOptions,\n ): AsyncIterable<ChatCompletionChunk> {\n let content = ''\n\n for await (const data of api.stream(AI_PATH.chatStream, { ...req, stream: true })) {\n try {\n const chunk: ChatCompletionChunk = JSON.parse(data)\n const delta = chunk.choices[0]?.delta?.content\n if (delta) {\n content += delta\n }\n const finishReason = chunk.choices[0]?.finish_reason\n if (finishReason) {\n options?.onProgress?.({ content, done: true, finishReason })\n }\n else {\n options?.onProgress?.({ content, done: false })\n }\n yield chunk\n }\n catch {\n // 忽略解析错误的行\n }\n }\n },\n\n async sendMessage(message: string, systemPrompt?: string): Promise<string> {\n const messages: ChatMessage[] = []\n if (systemPrompt) {\n messages.push({ role: 'system', content: systemPrompt })\n }\n messages.push({ role: 'user', content: message })\n const response = await this.chat({ messages })\n return response.choices[0]?.message?.content ?? ''\n },\n\n async sendMessageStream(\n message: string,\n options?: StreamOptions,\n systemPrompt?: string,\n ): Promise<string> {\n const messages: ChatMessage[] = []\n if (systemPrompt) {\n messages.push({ role: 'system', content: systemPrompt })\n }\n messages.push({ role: 'user', content: message })\n\n let content = ''\n for await (const chunk of this.chatStream({ messages }, options)) {\n const delta = chunk.choices[0]?.delta?.content\n if (delta) {\n content += delta\n }\n }\n return content\n },\n\n async recallMemories(query: string, options?: { topK?: number, types?: string[], minImportance?: number, objectId?: string }): Promise<MemoryEntry[]> {\n const result = await api.post<{ items: MemoryEntry[] }>(AI_PATH.memoryRecall, { query, ...options })\n if (!result.success) {\n throw new Error(`Memory recall failed: ${result.error.message}`)\n }\n return result.data.items\n },\n\n async listMemories(options?: { types?: string[], objectId?: string, offset?: number, limit?: number }): Promise<StorePage<MemoryEntry>> {\n const result = await api.post<StorePage<MemoryEntry>>(AI_PATH.memoryList, options ?? {})\n if (!result.success) {\n throw new Error(`Memory list failed: ${result.error.message}`)\n }\n return result.data\n },\n\n async listSessions(objectId: string): Promise<SessionInfo[]> {\n const result = await api.post<{ items: SessionInfo[] }>(AI_PATH.sessions, { objectId })\n if (!result.success) {\n throw new Error(`Session list failed: ${result.error.message}`)\n }\n return result.data.items\n },\n\n async chatHistory(objectId: string, sessionId: string, options?: { limit?: number, order?: 'asc' | 'desc' }): Promise<ChatRecord[]> {\n const result = await api.post<{ items: ChatRecord[] }>(AI_PATH.chatHistory, { objectId, sessionId, ...options })\n if (!result.success) {\n throw new Error(`Chat history failed: ${result.error.message}`)\n }\n return result.data.items\n },\n\n // ─── LLM ask/askStream ───\n\n async ask(question: string, options?: { systemPrompt?: string, model?: string }): Promise<string> {\n const result = await api.post<{ text: string }>(AI_PATH.ask, { question, ...options })\n if (!result.success) {\n throw new Error(`AI ask failed: ${result.error.message}`)\n }\n return result.data.text\n },\n\n async* askStream(question: string, options?: { systemPrompt?: string, model?: string }): AsyncIterable<string> {\n for await (const data of api.stream(AI_PATH.askStream, { question, ...options })) {\n yield data\n }\n },\n\n // ─── Knowledge ───\n\n async knowledgeRetrieve(query: string, options?: { topK?: number, collection?: string }): Promise<KnowledgeRetrieveResult> {\n const result = await api.post<KnowledgeRetrieveResult>(AI_PATH.knowledgeRetrieve, { query, ...options })\n if (!result.success) {\n throw new Error(`Knowledge retrieve failed: ${result.error.message}`)\n }\n return result.data\n },\n\n async knowledgeAsk(query: string, options?: { model?: string, collection?: string }): Promise<KnowledgeAskResult> {\n const result = await api.post<KnowledgeAskResult>(AI_PATH.knowledgeAsk, { query, ...options })\n if (!result.success) {\n throw new Error(`Knowledge ask failed: ${result.error.message}`)\n }\n return result.data\n },\n\n async knowledgeIngest(input: { documentId: string, content: string, title?: string, collection?: string, metadata?: Record<string, unknown> }): Promise<KnowledgeIngestResult> {\n const result = await api.post<KnowledgeIngestResult>(AI_PATH.knowledgeIngest, input)\n if (!result.success) {\n throw new Error(`Knowledge ingest failed: ${result.error.message}`)\n }\n return result.data\n },\n\n async knowledgeListDocuments(options?: { collection?: string, offset?: number, limit?: number }): Promise<KnowledgeDocumentInfo[]> {\n const result = await api.post<{ items: KnowledgeDocumentInfo[] }>(AI_PATH.knowledgeDocuments, options ?? {})\n if (!result.success) {\n throw new Error(`Knowledge list documents failed: ${result.error.message}`)\n }\n return result.data.items\n },\n\n async knowledgeRemoveDocument(documentId: string, options?: { collection?: string }): Promise<void> {\n const result = await api.post<void>(AI_PATH.knowledgeRemoveDocument, { documentId, ...options })\n if (!result.success) {\n throw new Error(`Knowledge remove document failed: ${result.error.message}`)\n }\n },\n\n // ─── Memory (extended) ───\n\n async addMemory(entry: MemoryEntryInput): Promise<MemoryEntry> {\n const result = await api.post<MemoryEntry>(AI_PATH.memoryAdd, entry)\n if (!result.success) {\n throw new Error(`Memory add failed: ${result.error.message}`)\n }\n return result.data\n },\n\n async updateMemory(memoryId: string, updates: MemoryUpdateInput): Promise<MemoryEntry> {\n const result = await api.post<MemoryEntry>(AI_PATH.memoryUpdate, { memoryId, ...updates })\n if (!result.success) {\n throw new Error(`Memory update failed: ${result.error.message}`)\n }\n return result.data\n },\n\n async removeMemory(memoryId: string): Promise<void> {\n const result = await api.post<void>(AI_PATH.memoryRemove, { memoryId })\n if (!result.success) {\n throw new Error(`Memory remove failed: ${result.error.message}`)\n }\n },\n\n // ─── Session (extended) ───\n\n async renameSession(sessionId: string, title: string): Promise<void> {\n const result = await api.post<void>(AI_PATH.sessionRename, { sessionId, title })\n if (!result.success) {\n throw new Error(`Session rename failed: ${result.error.message}`)\n }\n },\n\n async removeSession(sessionId: string): Promise<void> {\n const result = await api.post<void>(AI_PATH.sessionRemove, { sessionId })\n if (!result.success) {\n throw new Error(`Session remove failed: ${result.error.message}`)\n }\n },\n\n // ─── RAG ───\n\n async ragQuery(query: string, options?: { collection?: string, topK?: number, model?: string }): Promise<RagResult> {\n const result = await api.post<RagResult>(AI_PATH.ragQuery, { query, ...options })\n if (!result.success) {\n throw new Error(`RAG query failed: ${result.error.message}`)\n }\n return result.data\n },\n\n async* ragQueryStream(query: string, options?: { collection?: string, topK?: number, model?: string }): AsyncIterable<string> {\n for await (const data of api.stream(AI_PATH.ragQueryStream, { query, ...options })) {\n yield data\n }\n },\n\n // ─── Reasoning ───\n\n async reasoningRun(query: string, options?: { model?: string, maxSteps?: number }): Promise<ReasoningResult> {\n const result = await api.post<ReasoningResult>(AI_PATH.reasoningRun, { query, ...options })\n if (!result.success) {\n throw new Error(`Reasoning run failed: ${result.error.message}`)\n }\n return result.data\n },\n\n async* reasoningRunStream(query: string, options?: { model?: string, maxSteps?: number }): AsyncIterable<string> {\n for await (const data of api.stream(AI_PATH.reasoningRunStream, { query, ...options })) {\n yield data\n }\n },\n\n // ─── Token ───\n\n async estimateTokens(text: string): Promise<{ tokens: number }> {\n const result = await api.post<{ tokens: number }>(AI_PATH.tokenEstimate, { text })\n if (!result.success) {\n throw new Error(`Token estimate failed: ${result.error.message}`)\n }\n return result.data\n },\n\n // ─── Audio ───\n\n audio,\n }\n}\n\n// ─── SSE 解析工具 ───\n\n/**\n * 从 fetch Response 中解析 SSE data 字段\n *\n * 自动处理分片缓冲和 `[DONE]` 结束标记。\n *\n * @param response - fetch 响应对象\n * @yields SSE data 字符串(不含 `[DONE]`)\n *\n * @example\n * ```ts\n * const resp = await fetch('/api/chat', { method: 'POST', body })\n * for await (const data of parseSSE(resp)) {\n * const chunk = JSON.parse(data) // ChatCompletionChunk\n * }\n * ```\n */\nexport async function* parseSSE(response: Response): AsyncIterable<string> {\n const reader = response.body?.getReader()\n if (!reader) {\n throw new Error('Response body is not readable')\n }\n\n const decoder = new TextDecoder()\n let buffer = ''\n\n try {\n while (true) {\n const { done, value } = await reader.read()\n if (done)\n break\n\n buffer += decoder.decode(value, { stream: true })\n const lines = buffer.split('\\n')\n buffer = lines.pop() ?? ''\n\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n const data = line.slice(6)\n if (data !== '[DONE]') {\n yield data\n }\n }\n }\n }\n }\n finally {\n reader.releaseLock()\n }\n}\n\n/**\n * 收集流式响应的完整文本内容\n *\n * 完整消费流并拼接所有 `delta.content` 片段。\n *\n * @param stream - 聊天响应块流\n * @returns 完整文本\n *\n * @example\n * ```ts\n * const client = createAIClient({ api })\n * const stream = client.chatStream({ messages })\n * const fullText = await collectStreamContent(stream)\n * ```\n */\nexport async function collectStreamContent(\n stream: AsyncIterable<ChatCompletionChunk>,\n): Promise<string> {\n let content = ''\n for await (const chunk of stream) {\n const delta = chunk.choices[0]?.delta?.content\n if (delta) {\n content += delta\n }\n }\n return content\n}\n"]}
@@ -11,6 +11,10 @@ var MemoryTypeSchema = z.enum(["fact", "preference", "event", "entity", "instruc
11
11
 
12
12
  // messages/en-US.json
13
13
  var en_US_default = {
14
+ ai_mcpInvalidToolSchema: "Invalid input schema for MCP tool: {name}",
15
+ ai_mcpInvalidToolInput: "Invalid input for MCP tool: {name}",
16
+ ai_mcpInvalidResource: "MCP resource must contain either valid text or blob: {uri}",
17
+ ai_mcpInvalidPrompt: "Invalid MCP prompt arguments or messages: {name}",
14
18
  $schema: "https://inlang.com/schema/inlang-message-format",
15
19
  ai_notInitialized: "AI service not initialized. Call ai.init() first.",
16
20
  ai_initFailed: "Failed to initialize AI service: {error}",
@@ -112,6 +116,10 @@ var en_US_default = {
112
116
 
113
117
  // messages/zh-CN.json
114
118
  var zh_CN_default = {
119
+ ai_mcpInvalidToolSchema: "MCP \u5DE5\u5177\u8F93\u5165 Schema \u65E0\u6548\uFF1A{name}",
120
+ ai_mcpInvalidToolInput: "MCP \u5DE5\u5177\u8F93\u5165\u65E0\u6548\uFF1A{name}",
121
+ ai_mcpInvalidResource: "MCP \u8D44\u6E90\u5FC5\u987B\u4E14\u53EA\u80FD\u5305\u542B\u6709\u6548 text \u6216 blob\uFF1A{uri}",
122
+ ai_mcpInvalidPrompt: "MCP \u63D0\u793A\u8BCD\u53C2\u6570\u6216\u6D88\u606F\u65E0\u6548\uFF1A{name}",
115
123
  $schema: "https://inlang.com/schema/inlang-message-format",
116
124
  ai_notInitialized: "AI \u670D\u52A1\u672A\u521D\u59CB\u5316\uFF0C\u8BF7\u5148\u8C03\u7528 ai.init()",
117
125
  ai_initFailed: "AI \u670D\u52A1\u521D\u59CB\u5316\u5931\u8D25\uFF1A{error}",
@@ -732,5 +740,5 @@ var AudioWsDoneMessageSchema = AudioWsDoneMessageSchema$1;
732
740
  var AudioWsClientMessageSchema = AudioWsClientMessageSchema$1;
733
741
 
734
742
  export { A2AConfigSchema, A2ASkillConfigSchema, AIConfigSchema, AUDIO_WS_PATH, ApiTypeSchema, AudioConfigSchema, AudioFormatSchema, AudioModelEntrySchema, AudioOperationSchema, AudioOperationsSchema, AudioProviderSchema, AudioWsClientMessageSchema, AudioWsDoneMessageSchema, AudioWsStartMessageSchema, AudioWsTextMessageSchema, CompressConfigSchema, CompressionStrategySchema, EmbeddingConfigSchema, EntityTypeSchema, FileConfigSchema, ImageConfigSchema, ImageModelEntrySchema, ImageProviderSchema, KnowledgeConfigSchema, LLMConfigSchema, MCPConfigSchema, MCPServerCapabilitiesSchema, MCPServerConfigSchema, MemoryConfigSchema, MemoryTypeSchema, ModelEntrySchema, ModelScenarioSchema, OptionalSecretSchema, RetrievalConfigSchema, RetrievalSourceSchema, SummaryConfigSchema, TokenConfigSchema, aiM, ensureAudioCredential, resolveAudioModel, resolveImageModel, resolveModelApi, resolveModelEntry, serializePlayableAudio };
735
- //# sourceMappingURL=chunk-PLNY4UUT.js.map
736
- //# sourceMappingURL=chunk-PLNY4UUT.js.map
743
+ //# sourceMappingURL=chunk-GD7RNBUX.js.map
744
+ //# sourceMappingURL=chunk-GD7RNBUX.js.map