/** * 对象关系分析 · AI 研判接口 * * 会话 CRUD 走 aiHttp(裸响应,/insight/** 与 /chat/** 同为无 Result 包装); * 流式走 ai/api/sse 的通用 SSE 解析器(与 AI 数据分析页共用同一份实现, * 事件协议同构,只多一帧 insight)。 */ import { aiHttp } from '@/ai/api/http'; import { streamSse } from '@/ai/api/sse'; import { resolveApiUrl } from '@/ai/utils/constants'; import type { SseHandlers } from '@/ai/api/types'; import type { InsightClueVO, InsightCreateParams, InsightMessagePage, InsightMessageTraceVO, InsightSessionVO, InsightStreamParams, } from './types'; /** 控制器前缀(aiHttp 会自动补 /js + /a) */ const BASE = '/insight'; /** 流式地址(fetch 不走 defHttp,需自己拼全路径) */ const STREAM_URL = resolveApiUrl(`${BASE}/stream`); /** 创建研判会话:拼装动态系统提示词 + 固化上下文快照 */ export function createInsightSession(params: InsightCreateParams): Promise { return aiHttp.postRaw(`${BASE}/sessions`, params as unknown as Record); } /** 历史分析记录(抽屉「历史」下拉) */ export function listInsightSessions(caseId: string | number, scope = 'BATCH'): Promise { return aiHttp.getRaw(`${BASE}/sessions`, { caseId, scope }); } /** 会话详情(含上下文摘要) */ export function getInsightSession(id: string | number, caseId: string | number): Promise { return aiHttp.getRaw(`${BASE}/sessions/${id}`, { caseId }); } /** 消息分页:page 从 1 开始(第 1 页 = 最新的 N 条),排序由服务端写死为 seq DESC */ export function listInsightMessages( id: string | number, caseId: string | number, page = 1, limit = 20, ): Promise { return aiHttp.getRaw(`${BASE}/sessions/${id}/messages`, { caseId, page, limit }); } /** 单条消息的工具调用明细 + 思考过程(大字段,按需拉) */ export function getInsightMessageTrace( messageId: string | number, caseId: string | number, ): Promise { return aiHttp.getRaw(`${BASE}/messages/${messageId}/trace`, { caseId }); } /** 删除会话(消息随外键级联) */ export function deleteInsightSession(id: string | number, caseId: string | number): Promise { return aiHttp.getRaw(`${BASE}/sessions/${id}/delete`, { caseId }); } /** 线索聚合(为「线索推送」页预留,本期不接页面) */ export function listInsightClues(caseId: string | number, level?: string, limit?: number): Promise { return aiHttp.getRaw(`${BASE}/clues`, { caseId, level, limit }); } /** * 流式分析。 * * @param params 入参(首轮 message 留空) * @param handlers 事件回调(onInsight 为研判专属帧) * @param signal 中止信号 */ export function streamInsight(params: InsightStreamParams, handlers: SseHandlers, signal?: AbortSignal): Promise { return streamSse(STREAM_URL, params, handlers, signal); }