@frost1994/agentic-core 1.0.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":["../src/http.ts","../src/state/index.ts","../src/orchestrator/index.ts","../src/knowledge/index.ts"],"sourcesContent":["/**\r\n * AI Assistant REST HTTP Client\r\n *\r\n * Zero-dependency HTTP client for communicating with the Frost AI backend.\r\n * Automatically unwraps `Result<T>` responses (`{ code, message, data, traceId }`).\r\n * Designed for the core package with no framework dependency.\r\n */\r\n\r\nimport type {\r\n AssistantMessage,\r\n Conversation,\r\n ModelOption,\r\n} from './protocol/types'\r\n\r\ninterface ApiResult<T> {\r\n code: number\r\n message: string\r\n data: T\r\n traceId?: string\r\n}\r\n\r\nexport interface PluginConfig {\r\n systemCode: string\r\n defaultMode: string\r\n themeStrategy: string\r\n themePreset: string\r\n primaryColor: string\r\n defaultModelCode: string\r\n enableFullscreen: boolean\r\n enableDrawer: boolean\r\n enableKnowledge: boolean\r\n enableText2Sql: boolean\r\n rateLimitPerHour: number\r\n}\r\n\r\nexport interface DataSourceItem {\r\n code: string\r\n name: string\r\n type: string\r\n description?: string\r\n}\r\n\r\nexport interface TableInfo {\r\n tableName: string\r\n tableComment?: string\r\n columns?: Array<{\r\n columnName: string\r\n columnType: string\r\n columnComment?: string\r\n sensitive?: boolean\r\n }>\r\n}\r\n\r\nexport class AiHttpError extends Error {\r\n readonly code: number\r\n readonly traceId?: string\r\n\r\n constructor(code: number, message: string, traceId?: string) {\r\n super(message)\r\n this.name = 'AiHttpError'\r\n this.code = code\r\n this.traceId = traceId\r\n }\r\n}\r\n\r\nexport class AiHttpClient {\r\n private readonly baseUrl: string\r\n private readonly headersProvider: () => Record<string, string>\r\n\r\n constructor(baseUrl: string, headersProvider: () => Record<string, string>) {\r\n this.baseUrl = baseUrl.replace(/\\/+$/, '')\r\n this.headersProvider = headersProvider\r\n }\r\n\r\n async getPluginConfig(systemCode: string): Promise<PluginConfig | null> {\r\n const raw = await this.request<Record<string, unknown>>(\r\n 'GET',\r\n `/plugin/config?systemCode=${encodeURIComponent(systemCode)}`,\r\n ).catch(() => null)\r\n\r\n if (!raw) {\r\n return null\r\n }\r\n\r\n return {\r\n systemCode: (raw.systemCode as string) ?? systemCode,\r\n defaultMode: (raw.defaultMode as string) ?? 'floating',\r\n themeStrategy: (raw.themeStrategy as string) ?? 'system',\r\n themePreset: (raw.themePreset as string) ?? 'light',\r\n primaryColor: (raw.primaryColor as string) ?? '#409EFF',\r\n defaultModelCode: (raw.defaultModelCode as string) ?? 'default',\r\n enableFullscreen: Boolean(raw.enableFullscreen ?? true),\r\n enableDrawer: Boolean(raw.enableDrawer ?? true),\r\n enableKnowledge: Boolean(raw.enableKnowledge ?? false),\r\n enableText2Sql: Boolean(raw.enableText2Sql ?? true),\r\n rateLimitPerHour: Number(raw.rateLimitPerHour ?? 100),\r\n }\r\n }\r\n\r\n async listModels(): Promise<ModelOption[]> {\r\n const raw = await this.request<Array<Record<string, unknown>>>('GET', '/models')\r\n\r\n return raw.map((item) => ({\r\n code: (item.code as string) ?? (item.modelCode as string) ?? '',\r\n name: (item.name as string) ?? (item.modelName as string) ?? '',\r\n supportStream: Boolean(item.supportStream ?? true),\r\n supportToolCall: Boolean(item.supportToolCall ?? false),\r\n bestFor: ((item.bestFor as ModelOption['bestFor']) ?? []).filter(Boolean),\r\n maxTokens: typeof item.maxTokens === 'number' ? item.maxTokens : undefined,\r\n })).filter((item) => item.code && item.name)\r\n }\r\n\r\n async createConversation(\r\n systemCode: string,\r\n title?: string,\r\n modelCode?: string,\r\n ): Promise<Conversation> {\r\n return this.request<Conversation>('POST', '/conversations', {\r\n systemCode,\r\n title: title ?? 'New conversation',\r\n modelCode: modelCode ?? 'default',\r\n })\r\n }\r\n\r\n async listConversations(\r\n systemCode: string,\r\n page = 1,\r\n size = 20,\r\n ): Promise<Conversation[]> {\r\n return this.request<Conversation[]>(\r\n 'GET',\r\n `/conversations?systemCode=${encodeURIComponent(systemCode)}&page=${page}&size=${size}`,\r\n )\r\n }\r\n\r\n async getMessages(conversationId: string): Promise<AssistantMessage[]> {\r\n return this.request<AssistantMessage[]>(\r\n 'GET',\r\n `/conversations/${encodeURIComponent(conversationId)}/messages`,\r\n )\r\n }\r\n\r\n async deleteConversation(conversationId: string): Promise<void> {\r\n await this.request<void>(\r\n 'DELETE',\r\n `/conversations/${encodeURIComponent(conversationId)}`,\r\n )\r\n }\r\n\r\n async getSuggestions(systemCode: string, sceneCode?: string): Promise<string[]> {\r\n let path = `/suggestions?systemCode=${encodeURIComponent(systemCode)}`\r\n if (sceneCode) {\r\n path += `&sceneCode=${encodeURIComponent(sceneCode)}`\r\n }\r\n return this.request<string[]>('GET', path)\r\n }\r\n\r\n async confirmAction(actionId: string, confirm: boolean): Promise<void> {\r\n await this.request<void>('POST', '/actions/confirm', {\r\n actionId,\r\n confirm,\r\n })\r\n }\r\n\r\n async listDataSources(): Promise<DataSourceItem[]> {\r\n const raw = await this.request<Array<Record<string, unknown>>>('GET', '/data-sources')\r\n\r\n return raw.map((item) => ({\r\n code: (item.code as string) ?? (item.sourceCode as string) ?? '',\r\n name: (item.name as string) ?? (item.sourceName as string) ?? '',\r\n type: (item.type as string) ?? (item.dbType as string) ?? '',\r\n description: item.description as string | undefined,\r\n })).filter((item) => item.code && item.name)\r\n }\r\n\r\n async listTables(dataSourceCode: string): Promise<TableInfo[]> {\r\n const raw = await this.request<Array<Record<string, unknown>>>(\r\n 'GET',\r\n `/data-sources/${encodeURIComponent(dataSourceCode)}/tables`,\r\n )\r\n\r\n return raw.map((item) => ({\r\n tableName: (item.tableName as string) ?? '',\r\n tableComment:\r\n (item.tableComment as string)\r\n ?? (item.tableAlias as string)\r\n ?? (item.description as string)\r\n ?? undefined,\r\n columns: Array.isArray(item.columns) ? item.columns as TableInfo['columns'] : undefined,\r\n })).filter((item) => item.tableName)\r\n }\r\n\r\n async submitFeedback(\r\n messageId: string,\r\n rating: number,\r\n comment?: string,\r\n ): Promise<void> {\r\n await this.request<void>('POST', '/feedback', {\r\n messageId,\r\n rating,\r\n comment,\r\n })\r\n }\r\n\r\n async health(): Promise<{ status: string; service: string }> {\r\n const healthUrl = this.baseUrl.endsWith('/api/ai')\r\n ? `${this.baseUrl.slice(0, -'/api/ai'.length)}/actuator/health`\r\n : `${this.baseUrl}/health`\r\n\r\n const res = await fetch(healthUrl, {\r\n method: 'GET',\r\n headers: this.headersProvider(),\r\n })\r\n\r\n if (!res.ok) {\r\n throw new AiHttpError(res.status, `HTTP ${res.status}: ${res.statusText}`)\r\n }\r\n\r\n const json = await res.json() as ApiResult<{ status: string; service: string }> | { status: string }\r\n if ('code' in json) {\r\n if (json.code !== 200) {\r\n throw new AiHttpError(json.code, json.message ?? 'Unknown API error', json.traceId)\r\n }\r\n return json.data\r\n }\r\n\r\n return {\r\n status: json.status,\r\n service: 'ai-gateway',\r\n }\r\n }\r\n\r\n private async request<T>(\r\n method: string,\r\n path: string,\r\n body?: unknown,\r\n ): Promise<T> {\r\n const url = `${this.baseUrl}${path}`\r\n const headers = {\r\n 'Content-Type': 'application/json',\r\n ...this.headersProvider(),\r\n }\r\n\r\n const init: RequestInit = {\r\n method,\r\n headers,\r\n }\r\n\r\n if (body !== undefined && (method === 'POST' || method === 'PUT' || method === 'PATCH')) {\r\n init.body = JSON.stringify(body)\r\n }\r\n\r\n const res = await fetch(url, init)\r\n if (!res.ok) {\r\n throw new AiHttpError(res.status, `HTTP ${res.status}: ${res.statusText}`)\r\n }\r\n\r\n if (res.status === 204 || method === 'DELETE') {\r\n return undefined as T\r\n }\r\n\r\n const json = await res.json() as ApiResult<T>\r\n if (json.code !== undefined && json.code !== 200) {\r\n throw new AiHttpError(\r\n json.code,\r\n json.message ?? 'Unknown API error',\r\n json.traceId,\r\n )\r\n }\r\n\r\n return json.data as T\r\n }\r\n}\r\n","/**\r\n * Pure TypeScript state management for AI Assistant Core\r\n *\r\n * No Vue / React / Pinia dependency.\r\n * Can be wrapped by any framework's reactive system.\r\n */\r\n\r\nimport type {\r\n AiOpenMode,\r\n AiThemeMode,\r\n AssistantMessage,\r\n Conversation,\r\n MessageStatus,\r\n ToolStep,\r\n} from '../protocol'\r\n\r\n// ---------------------------------------------------------------------------\r\n// State shape\r\n// ---------------------------------------------------------------------------\r\n\r\nexport interface AssistantState {\r\n /** UI visibility */\r\n visible: boolean\r\n /** Current display mode */\r\n mode: AiOpenMode\r\n /** Previous mode before switch (for back-navigation) */\r\n previousMode: AiOpenMode | null\r\n /** Floating window position (px) */\r\n position: { x: number; y: number }\r\n /** Floating window size (px) */\r\n size: { width: number; height: number }\r\n /** Business system code */\r\n systemCode: string\r\n /** Selected model code */\r\n modelCode: string\r\n /** Current conversation id */\r\n currentConversationId: string | null\r\n /** All loaded conversations */\r\n conversations: Conversation[]\r\n /** Messages keyed by conversation id */\r\n messagesByConversation: Record<string, AssistantMessage[]>\r\n /** Tool steps keyed by message id */\r\n toolStepsByMessage: Record<string, ToolStep[]>\r\n /** Stream connection status */\r\n streamStatus: 'idle' | 'connecting' | 'streaming' | 'reconnecting' | 'closed' | 'error'\r\n /** Last received sequence number (for ack / resume) */\r\n lastSeq: number\r\n /** Last heartbeat timestamp */\r\n lastHeartbeatAt: number\r\n /** Reconnect attempt counter */\r\n reconnectAttempt: number\r\n /** Theme mode */\r\n themeMode: AiThemeMode\r\n /** Primary color */\r\n primaryColor: string\r\n /** Whether an error toast is currently shown */\r\n hasError: boolean\r\n /** Last error message (transient) */\r\n lastError: string | null\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Action types (discriminated union for reducer)\r\n// ---------------------------------------------------------------------------\r\n\r\nexport type StateAction =\r\n | { type: 'OPEN'; mode?: AiOpenMode }\r\n | { type: 'CLOSE' }\r\n | { type: 'TOGGLE' }\r\n | { type: 'SWITCH_MODE'; mode: AiOpenMode }\r\n | { type: 'SET_POSITION'; x: number; y: number }\r\n | { type: 'SET_SIZE'; width: number; height: number }\r\n | { type: 'SET_SYSTEM_CODE'; systemCode: string }\r\n | { type: 'SET_MODEL_CODE'; modelCode: string }\r\n | { type: 'SET_CONVERSATION'; id: string | null }\r\n | { type: 'ADD_CONVERSATION'; conversation: Conversation }\r\n | { type: 'SET_CONVERSATIONS'; conversations: Conversation[] }\r\n | { type: 'APPEND_MESSAGE'; conversationId: string; message: AssistantMessage }\r\n | { type: 'APPEND_DELTA'; conversationId: string; messageId: string; delta: string }\r\n | { type: 'UPDATE_MESSAGE_STATUS'; conversationId: string; messageId: string; status: MessageStatus }\r\n | { type: 'SET_MESSAGES'; conversationId: string; messages: AssistantMessage[] }\r\n | { type: 'APPEND_TOOL_STEP'; messageId: string; step: ToolStep }\r\n | { type: 'UPDATE_TOOL_STEP'; messageId: string; stepId: string; patch: Partial<ToolStep> }\r\n | { type: 'SET_STREAM_STATUS'; status: AssistantState['streamStatus'] }\r\n | { type: 'SET_LAST_SEQ'; seq: number }\r\n | { type: 'SET_HEARTBEAT'; ts: number }\r\n | { type: 'INCREMENT_RECONNECT' }\r\n | { type: 'RESET_RECONNECT' }\r\n | { type: 'SET_THEME'; mode: AiThemeMode }\r\n | { type: 'SET_PRIMARY_COLOR'; color: string }\r\n | { type: 'SET_ERROR'; error: string | null }\r\n | { type: 'HYDRATE'; state: Partial<AssistantState> }\r\n\r\n// ---------------------------------------------------------------------------\r\n// Factory\r\n// ---------------------------------------------------------------------------\r\n\r\nexport function createInitialState(overrides?: Partial<AssistantState>): AssistantState {\r\n return {\r\n visible: false,\r\n mode: 'floating',\r\n previousMode: null,\r\n position: { x: 0, y: 0 },\r\n size: { width: 420, height: 600 },\r\n systemCode: '',\r\n modelCode: '',\r\n currentConversationId: null,\r\n conversations: [],\r\n messagesByConversation: {},\r\n toolStepsByMessage: {},\r\n streamStatus: 'idle',\r\n lastSeq: 0,\r\n lastHeartbeatAt: 0,\r\n reconnectAttempt: 0,\r\n themeMode: 'system',\r\n primaryColor: '#1677ff',\r\n hasError: false,\r\n lastError: null,\r\n ...overrides,\r\n }\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Reducer (pure function)\r\n// ---------------------------------------------------------------------------\r\n\r\nexport function reducer(state: AssistantState, action: StateAction): AssistantState {\r\n switch (action.type) {\r\n case 'OPEN':\r\n return {\r\n ...state,\r\n visible: true,\r\n mode: action.mode ?? state.mode,\r\n }\r\n\r\n case 'CLOSE':\r\n return { ...state, visible: false }\r\n\r\n case 'TOGGLE':\r\n return { ...state, visible: !state.visible }\r\n\r\n case 'SWITCH_MODE': {\r\n return {\r\n ...state,\r\n previousMode: state.mode,\r\n mode: action.mode,\r\n }\r\n }\r\n\r\n case 'SET_POSITION':\r\n return {\r\n ...state,\r\n position: { x: action.x, y: action.y },\r\n }\r\n\r\n case 'SET_SIZE':\r\n return {\r\n ...state,\r\n size: { width: action.width, height: action.height },\r\n }\r\n\r\n case 'SET_SYSTEM_CODE':\r\n return { ...state, systemCode: action.systemCode }\r\n\r\n case 'SET_MODEL_CODE':\r\n return { ...state, modelCode: action.modelCode }\r\n\r\n case 'SET_CONVERSATION':\r\n return { ...state, currentConversationId: action.id }\r\n\r\n case 'ADD_CONVERSATION': {\r\n const next = [action.conversation, ...state.conversations]\r\n return { ...state, conversations: next }\r\n }\r\n\r\n case 'SET_CONVERSATIONS':\r\n return { ...state, conversations: action.conversations }\r\n\r\n case 'APPEND_MESSAGE': {\r\n const list = state.messagesByConversation[action.conversationId] ?? []\r\n return {\r\n ...state,\r\n messagesByConversation: {\r\n ...state.messagesByConversation,\r\n [action.conversationId]: [...list, action.message],\r\n },\r\n }\r\n }\r\n\r\n case 'APPEND_DELTA': {\r\n const list = state.messagesByConversation[action.conversationId]\r\n if (!list) return state\r\n const idx = list.findIndex(m => m.id === action.messageId)\r\n if (idx === -1) return state\r\n const next = list.slice()\r\n next[idx] = { ...next[idx], content: next[idx].content + action.delta }\r\n return {\r\n ...state,\r\n messagesByConversation: {\r\n ...state.messagesByConversation,\r\n [action.conversationId]: next,\r\n },\r\n }\r\n }\r\n\r\n case 'UPDATE_MESSAGE_STATUS': {\r\n const list = state.messagesByConversation[action.conversationId]\r\n if (!list) return state\r\n const idx = list.findIndex(m => m.id === action.messageId)\r\n if (idx === -1) return state\r\n const next = list.slice()\r\n const msg = next[idx]\r\n next[idx] = {\r\n ...msg,\r\n status: action.status,\r\n finishedAt:\r\n action.status === 'success' || action.status === 'failed'\r\n ? new Date().toISOString()\r\n : msg.finishedAt,\r\n }\r\n return {\r\n ...state,\r\n messagesByConversation: {\r\n ...state.messagesByConversation,\r\n [action.conversationId]: next,\r\n },\r\n }\r\n }\r\n\r\n case 'SET_MESSAGES':\r\n return {\r\n ...state,\r\n messagesByConversation: {\r\n ...state.messagesByConversation,\r\n [action.conversationId]: action.messages,\r\n },\r\n }\r\n\r\n case 'APPEND_TOOL_STEP': {\r\n const steps = state.toolStepsByMessage[action.messageId] ?? []\r\n return {\r\n ...state,\r\n toolStepsByMessage: {\r\n ...state.toolStepsByMessage,\r\n [action.messageId]: [...steps, action.step],\r\n },\r\n }\r\n }\r\n\r\n case 'UPDATE_TOOL_STEP': {\r\n const steps = state.toolStepsByMessage[action.messageId]\r\n if (!steps) return state\r\n const idx = steps.findIndex(s => s.stepId === action.stepId)\r\n if (idx === -1) return state\r\n const next = steps.slice()\r\n next[idx] = { ...next[idx], ...action.patch }\r\n return {\r\n ...state,\r\n toolStepsByMessage: {\r\n ...state.toolStepsByMessage,\r\n [action.messageId]: next,\r\n },\r\n }\r\n }\r\n\r\n case 'SET_STREAM_STATUS':\r\n return { ...state, streamStatus: action.status }\r\n\r\n case 'SET_LAST_SEQ':\r\n return { ...state, lastSeq: action.seq }\r\n\r\n case 'SET_HEARTBEAT':\r\n return { ...state, lastHeartbeatAt: action.ts }\r\n\r\n case 'INCREMENT_RECONNECT':\r\n return { ...state, reconnectAttempt: state.reconnectAttempt + 1 }\r\n\r\n case 'RESET_RECONNECT':\r\n return { ...state, reconnectAttempt: 0 }\r\n\r\n case 'SET_THEME':\r\n return { ...state, themeMode: action.mode }\r\n\r\n case 'SET_PRIMARY_COLOR':\r\n return { ...state, primaryColor: action.color }\r\n\r\n case 'SET_ERROR':\r\n return {\r\n ...state,\r\n hasError: action.error !== null,\r\n lastError: action.error,\r\n }\r\n\r\n case 'HYDRATE':\r\n return { ...state, ...action.state }\r\n\r\n default:\r\n return state\r\n }\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Serialization / Deserialization\r\n// ---------------------------------------------------------------------------\r\n\r\nexport interface SerializedState {\r\n version: number\r\n state: Omit<AssistantState, 'streamStatus' | 'lastSeq' | 'lastHeartbeatAt' | 'reconnectAttempt' | 'hasError' | 'lastError'>\r\n}\r\n\r\nconst SERIAL_VERSION = 1\r\n\r\n/** Serialize state to JSON-safe object (excludes transient stream fields). */\r\nexport function serialize(state: AssistantState): SerializedState {\r\n const {\r\n streamStatus,\r\n lastSeq,\r\n lastHeartbeatAt,\r\n reconnectAttempt,\r\n hasError,\r\n lastError,\r\n ...persistable\r\n } = state\r\n void streamStatus\r\n void lastSeq\r\n void lastHeartbeatAt\r\n void reconnectAttempt\r\n void hasError\r\n void lastError\r\n return { version: SERIAL_VERSION, state: persistable as SerializedState['state'] }\r\n}\r\n\r\n/** Deserialize and merge with fresh initial state defaults. */\r\nexport function deserialize(data: unknown): AssistantState | null {\r\n if (!data || typeof data !== 'object') return null\r\n const parsed = data as SerializedState\r\n if (parsed.version !== SERIAL_VERSION) return null\r\n return createInitialState(parsed.state)\r\n}\r\n\r\n/** Convenience: serialize to JSON string. */\r\nexport function serializeToString(state: AssistantState): string {\r\n return JSON.stringify(serialize(state))\r\n}\r\n\r\n/** Convenience: deserialize from JSON string. */\r\nexport function deserializeFromString(json: string): AssistantState | null {\r\n try {\r\n return deserialize(JSON.parse(json))\r\n } catch {\r\n return null\r\n }\r\n}\r\n","/**\r\n * Tool-call orchestrator for AI Assistant Core\r\n *\r\n * ToolRegistry — register / lookup tools\r\n * ToolOrchestrator — execute steps in parallel or serial order\r\n */\r\n\r\nimport type { ToolDefinition, ToolExecutor, ToolStep } from '../protocol'\r\nimport { generateId } from '../utils'\r\n\r\n// ---------------------------------------------------------------------------\r\n// ToolRegistry\r\n// ---------------------------------------------------------------------------\r\n\r\nexport interface RegisteredTool {\r\n definition: ToolDefinition\r\n executor: ToolExecutor\r\n}\r\n\r\nexport class ToolRegistry {\r\n private readonly tools = new Map<string, RegisteredTool>()\r\n\r\n /** Register a tool with its definition and executor. */\r\n register(definition: ToolDefinition, executor: ToolExecutor): void {\r\n this.tools.set(definition.name, { definition, executor })\r\n }\r\n\r\n /** Unregister a tool by name. */\r\n unregister(name: string): boolean {\r\n return this.tools.delete(name)\r\n }\r\n\r\n /** Look up a registered tool. */\r\n get(name: string): RegisteredTool | undefined {\r\n return this.tools.get(name)\r\n }\r\n\r\n /** Check whether a tool is registered. */\r\n has(name: string): boolean {\r\n return this.tools.has(name)\r\n }\r\n\r\n /** List all registered tool names. */\r\n list(): string[] {\r\n return Array.from(this.tools.keys())\r\n }\r\n\r\n /** Get all definitions (for sending to LLM). */\r\n getDefinitions(): ToolDefinition[] {\r\n return Array.from(this.tools.values()).map(t => t.definition)\r\n }\r\n\r\n /** Clear all registrations. */\r\n clear(): void {\r\n this.tools.clear()\r\n }\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// ToolOrchestrator\r\n// ---------------------------------------------------------------------------\r\n\r\nexport interface OrchestratorOptions {\r\n registry: ToolRegistry\r\n onStepStart?: (step: ToolStep) => void\r\n onStepProgress?: (stepId: string, percent: number, message?: string) => void\r\n onStepComplete?: (step: ToolStep) => void\r\n onStepError?: (step: ToolStep, error: Error) => void\r\n}\r\n\r\nexport type ExecutionMode = 'parallel' | 'serial'\r\n\r\nexport interface ExecutionPlan {\r\n mode: ExecutionMode\r\n steps: Array<{\r\n toolName: string\r\n args: Record<string, unknown>\r\n title?: string\r\n }>\r\n}\r\n\r\nexport class ToolOrchestrator {\r\n private readonly registry: ToolRegistry\r\n private readonly onStepStart?: (step: ToolStep) => void\r\n private readonly onStepComplete?: (step: ToolStep) => void\r\n private readonly onStepError?: (step: ToolStep, error: Error) => void\r\n\r\n constructor(options: OrchestratorOptions) {\r\n this.registry = options.registry\r\n this.onStepStart = options.onStepStart\r\n this.onStepComplete = options.onStepComplete\r\n this.onStepError = options.onStepError\r\n }\r\n\r\n /**\r\n * Execute a plan of tool steps.\r\n *\r\n * - `serial`: steps run one after another; if one fails, abort the rest.\r\n * - `parallel`: steps run concurrently; all results collected regardless of individual failures.\r\n */\r\n async execute(plan: ExecutionPlan): Promise<ToolStep[]> {\r\n if (plan.mode === 'serial') {\r\n return this.executeSerial(plan.steps)\r\n }\r\n return this.executeParallel(plan.steps)\r\n }\r\n\r\n /** Execute a single tool step. */\r\n async executeSingle(\r\n toolName: string,\r\n args: Record<string, unknown>,\r\n title?: string\r\n ): Promise<ToolStep> {\r\n const registered = this.registry.get(toolName)\r\n if (!registered) {\r\n const step: ToolStep = {\r\n stepId: generateId('step_'),\r\n toolName,\r\n title: title ?? toolName,\r\n status: 'error',\r\n args,\r\n message: `Tool \"${toolName}\" is not registered`,\r\n }\r\n this.onStepError?.(step, new Error(step.message))\r\n return step\r\n }\r\n\r\n const step: ToolStep = {\r\n stepId: generateId('step_'),\r\n toolName,\r\n title: title ?? registered.definition.description ?? toolName,\r\n status: 'running',\r\n args,\r\n }\r\n\r\n this.onStepStart?.(step)\r\n\r\n const startTime = Date.now()\r\n try {\r\n const result = await registered.executor(args)\r\n step.status = 'success'\r\n step.result = result\r\n step.durationMs = Date.now() - startTime\r\n this.onStepComplete?.(step)\r\n return step\r\n } catch (err) {\r\n step.status = 'error'\r\n step.result = err instanceof Error ? err.message : String(err)\r\n step.durationMs = Date.now() - startTime\r\n this.onStepError?.(step, err instanceof Error ? err : new Error(String(err)))\r\n return step\r\n }\r\n }\r\n\r\n private async executeSerial(\r\n steps: ExecutionPlan['steps']\r\n ): Promise<ToolStep[]> {\r\n const results: ToolStep[] = []\r\n for (const s of steps) {\r\n const result = await this.executeSingle(s.toolName, s.args, s.title)\r\n results.push(result)\r\n if (result.status === 'error') {\r\n // Abort remaining serial steps\r\n break\r\n }\r\n }\r\n return results\r\n }\r\n\r\n private async executeParallel(\r\n steps: ExecutionPlan['steps']\r\n ): Promise<ToolStep[]> {\r\n return Promise.all(\r\n steps.map(s => this.executeSingle(s.toolName, s.args, s.title))\r\n )\r\n }\r\n}\r\n","/**\r\n * Knowledge-base citation parser for AI Assistant Core\r\n *\r\n * Parses [1] [2] citation markers in assistant text and\r\n * matches them against content chunks returned by the backend.\r\n */\r\n\r\n// ---------------------------------------------------------------------------\r\n// CitationParser\r\n// ---------------------------------------------------------------------------\r\n\r\nexport interface Citation {\r\n /** Raw marker text, e.g. \"[1]\" */\r\n marker: string\r\n /** Numeric index, e.g. 1 */\r\n index: number\r\n /** Start position in the source text */\r\n start: number\r\n /** End position in the source text */\r\n end: number\r\n}\r\n\r\nexport class CitationParser {\r\n /** Regex for citation markers: [1], [12], etc. */\r\n private static readonly MARKER_RE = /\\[(\\d+)\\]/g\r\n\r\n /**\r\n * Extract all citation markers from a text block.\r\n *\r\n * @param text — source text containing [1], [2], … markers\r\n * @returns ordered list of citations with positions\r\n */\r\n parse(text: string): Citation[] {\r\n const citations: Citation[] = []\r\n let match: RegExpExecArray | null\r\n CitationParser.MARKER_RE.lastIndex = 0\r\n while ((match = CitationParser.MARKER_RE.exec(text)) !== null) {\r\n citations.push({\r\n marker: match[0],\r\n index: parseInt(match[1], 10),\r\n start: match.index,\r\n end: match.index + match[0].length,\r\n })\r\n }\r\n return citations\r\n }\r\n\r\n /**\r\n * Strip citation markers from text, returning clean text and a mapping.\r\n *\r\n * @returns `{ text: string, citations: Citation[] }`\r\n */\r\n strip(text: string): { text: string; citations: Citation[] } {\r\n const citations = this.parse(text)\r\n if (citations.length === 0) {\r\n return { text, citations: [] }\r\n }\r\n\r\n let cleaned = ''\r\n let lastEnd = 0\r\n for (const c of citations) {\r\n cleaned += text.slice(lastEnd, c.start)\r\n lastEnd = c.end\r\n }\r\n cleaned += text.slice(lastEnd)\r\n\r\n return { text: cleaned.trim(), citations }\r\n }\r\n\r\n /**\r\n * Replace citation markers with custom formatter output.\r\n *\r\n * @param text — source text\r\n * @param format — callback receiving citation index, returns replacement string\r\n */\r\n replace(text: string, format: (index: number) => string): string {\r\n return text.replace(CitationParser.MARKER_RE, (_match, num) => format(parseInt(num, 10)))\r\n }\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// ChunkMatcher\r\n// ---------------------------------------------------------------------------\r\n\r\nexport interface KnowledgeChunk {\r\n /** Chunk index (1-based, matching citation numbers) */\r\n index: number\r\n /** Source title or document name */\r\n title: string\r\n /** Chunk text content */\r\n content: string\r\n /** Optional source URL or identifier */\r\n source?: string\r\n /** Relevance score (0–1) */\r\n score?: number\r\n}\r\n\r\nexport interface MatchedChunk extends KnowledgeChunk {\r\n /** Citation markers that reference this chunk */\r\n citedBy: number[]\r\n}\r\n\r\nexport class ChunkMatcher {\r\n /**\r\n * Match parsed citations to a list of knowledge chunks.\r\n *\r\n * @param citations — output from `CitationParser.parse()`\r\n * @param chunks — chunks returned by backend (should be 1-based indexed)\r\n * @returns chunks that were cited, with `citedBy` populated\r\n */\r\n match(citations: Citation[], chunks: KnowledgeChunk[]): MatchedChunk[] {\r\n const citedIndices = new Set(citations.map(c => c.index))\r\n const indexToCitations = new Map<number, number[]>()\r\n\r\n for (const c of citations) {\r\n const arr = indexToCitations.get(c.index) ?? []\r\n arr.push(c.index)\r\n indexToCitations.set(c.index, arr)\r\n }\r\n\r\n const matched: MatchedChunk[] = []\r\n for (const chunk of chunks) {\r\n if (citedIndices.has(chunk.index)) {\r\n matched.push({\r\n ...chunk,\r\n citedBy: indexToCitations.get(chunk.index) ?? [chunk.index],\r\n })\r\n }\r\n }\r\n\r\n // Preserve chunk order\r\n matched.sort((a, b) => a.index - b.index)\r\n return matched\r\n }\r\n\r\n /**\r\n * Build a flat map: citation index → chunk.\r\n *\r\n * @returns Map where key is citation number and value is the matching chunk\r\n */\r\n buildIndexMap(chunks: KnowledgeChunk[]): Map<number, KnowledgeChunk> {\r\n const map = new Map<number, KnowledgeChunk>()\r\n for (const chunk of chunks) {\r\n map.set(chunk.index, chunk)\r\n }\r\n return map\r\n }\r\n\r\n /**\r\n * Find chunks that are NOT cited in the text (orphans).\r\n */\r\n findOrphans(citations: Citation[], chunks: KnowledgeChunk[]): KnowledgeChunk[] {\r\n const cited = new Set(citations.map(c => c.index))\r\n return chunks.filter(c => !cited.has(c.index))\r\n }\r\n}\r\n"],"names":["step","generateId"],"mappings":"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"}