@multiplayer-app/ai-agent-react 0.1.0-beta.41 → 0.1.0-beta.42
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/dist/ai-agent-react.cjs.js +1 -1
- package/dist/ai-agent-react.cjs.js.map +1 -1
- package/dist/ai-agent-react.es.js +3 -3
- package/dist/ai-agent-react.es.js.map +1 -1
- package/dist/runtime/transports/ProxyTransport.d.ts +0 -1
- package/dist/runtime/transports/ProxyTransport.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -29,7 +29,7 @@ React keys must be passed directly to JSX without using spread:
|
|
|
29
29
|
let props = %s;
|
|
30
30
|
<%s key={someKey} {...props} />`,Zo,vr,z7,vr),Dh[vr+Zo]=!0}}return U===r?R7(bt):C7(bt),bt}}function I7(U,oe,be){return zh(U,oe,be,!0)}function O7(U,oe,be){return zh(U,oe,be,!1)}var L7=O7,D7=I7;da.Fragment=r,da.jsx=L7,da.jsxs=D7}()),da}process.env.NODE_ENV==="production"?sd.exports=q7():sd.exports=B7();var T=sd.exports;exports.SortOrder=void 0;(function(e){e.Asc="asc",e.Desc="desc"})(exports.SortOrder||(exports.SortOrder={}));exports.MessageRole=void 0;(function(e){e.System="system",e.User="user",e.Assistant="assistant",e.Tool="tool",e.Reasoning="reasoning",e.Error="error"})(exports.MessageRole||(exports.MessageRole={}));exports.AgentAttachmentType=void 0;(function(e){e.File="file",e.Link="link",e.Artifact="artifact",e.Context="context"})(exports.AgentAttachmentType||(exports.AgentAttachmentType={}));exports.AgentToolCallStatus=void 0;(function(e){e.Pending="pending",e.Running="running",e.Succeeded="succeeded",e.Failed="failed"})(exports.AgentToolCallStatus||(exports.AgentToolCallStatus={}));exports.AgentProcessStatus=void 0;(function(e){e.Queued="queued",e.ApprovalRequired="approvalRequired",e.Running="running",e.Paused="paused",e.Error="error",e.Complete="complete"})(exports.AgentProcessStatus||(exports.AgentProcessStatus={}));exports.StreamChunkType=void 0;(function(e){e.Message="message",e.Reasoning="reasoning",e.Tool="tool",e.Artifact="artifact",e.Error="error",e.Chat="chat"})(exports.StreamChunkType||(exports.StreamChunkType={}));exports.ChatType=void 0;(function(e){e.Chat="chat",e.Agent="agent"})(exports.ChatType||(exports.ChatType={}));exports.AgentStatus=void 0;(function(e){e.Processing="processing",e.Streaming="streaming",e.Finished="finished",e.Aborted="aborted",e.WaitingForUserAction="waitingForUserAction",e.Error="error"})(exports.AgentStatus||(exports.AgentStatus={}));exports.AgentToolType=void 0;(function(e){e.API_TOOL="api_tool",e.WEB_SEARCH="web_search",e.LOCAL_FUNCTION="local_function"})(exports.AgentToolType||(exports.AgentToolType={}));exports.ActivityOperationName=void 0;(function(e){e.MESSAGE_PROCESSING="messageProcessing",e.AGENT_SELECTION="agentSelection",e.STEP_FINISHED="stepFinished",e.TITLE_GENERATION="titleGeneration"})(exports.ActivityOperationName||(exports.ActivityOperationName={}));var Ri={ChatNew:"chat:new",MessageNew:"message:new",ChatUpdate:"chat:update"},ji={Path:"/socket.io",UserRoomPrefix:"user:",DefaultUserId:"guest"},s5=["webSnippet","formSnapshot","formField"],U7=j.z.string().datetime({offset:!0}).or(j.z.string().datetime()),H7=j.z.object({app:j.z.string().min(1).optional(),url:j.z.string().url().optional(),route:j.z.string().min(1).optional(),domPath:j.z.string().min(1).optional()}).strict(),j7=j.z.object({containsPII:j.z.boolean().optional(),redactionsApplied:j.z.array(j.z.string().min(1)).max(50).optional()}).strict(),V7=j.z.union([j.z.object({type:j.z.literal("text"),exact:j.z.string().min(1).max(4e3),prefix:j.z.string().min(1).max(500).optional(),suffix:j.z.string().min(1).max(500).optional(),domPath:j.z.string().min(1).max(2e3).optional(),startOffset:j.z.number().int().min(0).optional(),endOffset:j.z.number().int().min(0).optional()}).strict(),j.z.object({type:j.z.literal("dom"),domPath:j.z.string().min(1).max(2e3)}).strict(),j.z.object({type:j.z.literal("form"),formId:j.z.string().min(1).max(200).optional(),fieldName:j.z.string().min(1).max(200).optional(),domPath:j.z.string().min(1).max(2e3).optional()}).strict()]),po=j.z.object({schemaVersion:j.z.literal(1),kind:j.z.string().min(1).max(100),capturedAt:U7,source:H7.optional(),security:j7.optional(),target:V7.optional()}),G7=po.extend({kind:j.z.literal("webSnippet"),title:j.z.string().min(1).max(200).optional(),selectedText:j.z.string().min(1).max(4e3)}).strict(),W7=po.extend({kind:j.z.literal("formSnapshot"),formId:j.z.string().min(1).max(200).optional(),formName:j.z.string().min(1).max(200).optional(),fields:j.z.array(j.z.object({name:j.z.string().min(1).max(200),label:j.z.string().min(1).max(200).optional(),value:j.z.string().min(0).max(1e3),inputType:j.z.enum(["text","textarea","number","select","radio","checkbox","date","email","tel"]).optional(),options:j.z.array(j.z.object({value:j.z.string().min(0).max(500),label:j.z.string().min(0).max(500)}).strict()).max(200).optional(),domPath:j.z.string().min(1).max(2e3).optional()}).strict()).min(1).max(50)}).strict(),K7=po.extend({kind:j.z.literal("formField"),formId:j.z.string().min(1).max(200).optional(),fieldName:j.z.string().min(1).max(200),fieldLabel:j.z.string().min(1).max(200).optional(),value:j.z.string().min(0).max(1e3),inputType:j.z.enum(["text","textarea","number","select","radio","checkbox","date","email","tel"]).optional(),options:j.z.array(j.z.object({value:j.z.string().min(0).max(500),label:j.z.string().min(0).max(500)}).strict()).max(200).optional(),domPath:j.z.string().min(1).max(2e3).optional()}).strict(),Y7=po.extend({kind:j.z.string().min(1).max(100).refine(function(e){return!s5.includes(e)},"kind must not collide with built-in kinds"),title:j.z.string().min(1).max(200).optional(),summary:j.z.string().min(1).max(4e3).optional(),data:j.z.record(j.z.string().min(1).max(200),j.z.unknown()).optional()}).strict().superRefine(function(e,t){if(e.data){var n=JSON.stringify(e.data);n.length>12e3&&t.addIssue({code:"custom",message:"data is too large (max ~12k JSON chars)",path:["data"]})}}),l5=j.z.union([G7,W7,K7,Y7]),ri=j.z.object({id:j.z.string().min(1),type:j.z.nativeEnum(exports.AgentAttachmentType),name:j.z.string().min(1).max(500),url:j.z.string().url().optional(),mimeType:j.z.string().min(1).max(200).optional(),metadata:j.z.record(j.z.string(),j.z.unknown()).optional()}).strict(),c5=j.z.union([ri.extend({type:j.z.literal(exports.AgentAttachmentType.Context),metadata:l5}).strict(),ri.extend({type:j.z.literal(exports.AgentAttachmentType.File),size:j.z.number().int().min(0).optional(),metadata:j.z.object({uploadedAt:j.z.string().optional(),s3Key:j.z.string().optional(),processingStatus:j.z.enum(["pending","processed","failed"]).optional(),size:j.z.number().int().min(0).optional(),lastModified:j.z.number().optional()}).optional()}).strict(),ri.extend({type:j.z.literal(exports.AgentAttachmentType.Link)}).strict(),ri.extend({type:j.z.literal(exports.AgentAttachmentType.Artifact)}).strict()]),Z7=j.z.object({chatId:j.z.string().optional(),content:j.z.string().min(1),contextKey:j.z.string().min(1),attachments:j.z.array(c5).optional(),metadata:j.z.record(j.z.string(),j.z.unknown()).optional(),model:j.z.string().optional(),temperature:j.z.number().optional(),userId:j.z.string().optional()}).strict();new TextEncoder;const X7=new TextDecoder,Q7=3;class Kr{constructor(t){this.config=t}streamControllers=new Map;socketId;updateConfig(t){if(t.mode!=="proxy")throw new Error("ProxyTransport.updateConfig requires proxy mode configuration");this.config=t}setSocketId(t){this.socketId=t}withHeaders(t,n){const r={...this.config.headers,...t};this.config.apiKey&&(r.Authorization=`Bearer ${this.config.apiKey}`);const a=n?.body!==void 0&&n?.body!==null,i=Object.keys(r).some(o=>o.toLowerCase()==="content-type");return a&&!i&&(r["Content-Type"]="application/json"),r}async formatHttpError(t,n){const r=n.status,a=n.statusText,i=n.headers.get("content-type")??"";let o;try{if(i.includes("application/json")){const l=await n.json();o=typeof l?.message=="string"&&l.message||typeof l?.error=="string"&&l.error||typeof l?.detail=="string"&&l.detail||typeof l?.title=="string"&&l.title||typeof l=="string"&&l||(l?JSON.stringify(l):void 0)}else{const l=(await n.text()).trim();!/<\s*html[\s>]|<\s*body[\s>]/i.test(l)&&l&&(o=l.length>500?l.slice(0,500)+"…":l)}}catch{}const s=`Message sending failed (${r}${a?` ${a}`:""}).`;return o?`${s} ${o}`:`${s} Please try again.`}async request(t,n){const r=await fetch(`${this.config.baseUrl}${t}`,{...n,headers:this.withHeaders(n?.headers,n),signal:n?.signal});if(!r.ok)throw new Error(await this.formatHttpError(t,r));if(r.status===204)return;if(r.headers.get("content-type")?.includes("application/json")){const i=await r.text();return i?JSON.parse(i):void 0}const a=await r.text();if(a)return JSON.parse(a)}async sendMessage(t){const n={};return this.socketId&&(n["x-socket-id"]=this.socketId),this.request("/chats/send",{method:"POST",headers:n,body:JSON.stringify(t)})}async streamMessage(t,n,r){const a=r?.streamKey??t.chatId??`stream-${Date.now()}-${Math.random().toString(16).slice(2)}`,i=new AbortController,o=setTimeout(()=>i.abort(),this.config.timeoutMs??5*60*1e3);try{const s={Accept:"text/event-stream"};if(this.socketId&&(s["x-socket-id"]=this.socketId),i.signal.aborted)throw new Error("Stream was aborted before fetch started");this.streamControllers.set(a,i);const l=await fetch(`${this.config.baseUrl}/chats/stream`,{method:"POST",signal:i.signal,body:JSON.stringify(t),headers:this.withHeaders(s,{method:"POST",body:JSON.stringify(t)})});if(!l.ok)throw new Error(await this.formatHttpError("/chats/stream",l));if(!l.body)throw new Error("Streaming response body missing");const u=l.body.getReader();let d="",p;for(;;){const{value:h,done:m}=await u.read();if(m)break;d+=X7.decode(h,{stream:!0});const g=d.split(`
|
|
31
31
|
|
|
32
|
-
`);d=g.pop()??"";for(const y of g){const w=y.trim();if(!w.startsWith("data:"))continue;const _=w.replace(/^data:\s*/,"");if(!_||_==="[DONE]"){n({type:exports.StreamChunkType.Message,done:!0});continue}let k;try{k=JSON.parse(_)}catch(v){console.error("Failed to parse SSE chunk",v);continue}k.message?.chat&&(p=k.message.chat,this.streamControllers.set(p,i)),n(k)}}if(p)try{const h=await this.getMessages(p,{limit:Q7});return{id:p,messages:h.messages}}catch(h){console.error("Failed to fetch messages after streaming",h)}}finally{clearTimeout(o);const s=[];for(const[l,u]of this.streamControllers.entries())u===i&&s.push(l);s.forEach(l=>this.streamControllers.delete(l))}}cancelStream(t){this.cancelHttpStream(t),t&&this.request(`/chats/${t}/abort`,{method:"POST",body:JSON.stringify({})}).catch(n=>{console.error("Failed to call abort API:",n)})}cancelHttpStream(t){if(t){const r=this.streamControllers.get(t);if(r){r.abort();const a=[];for(const[i,o]of this.streamControllers.entries())o===r&&a.push(i);a.forEach(i=>this.streamControllers.delete(i))}return}const n=new Set(this.streamControllers.values());for(const r of n)r.abort();this.streamControllers.clear()}async listChats(t){const n=new URLSearchParams;t?.contextKey&&n.set("contextKey",t.contextKey),t?.skip!=null&&n.set("skip",String(t.skip)),t?.limit&&n.set("limit",String(t.limit)),t?.
|
|
32
|
+
`);d=g.pop()??"";for(const y of g){const w=y.trim();if(!w.startsWith("data:"))continue;const _=w.replace(/^data:\s*/,"");if(!_||_==="[DONE]"){n({type:exports.StreamChunkType.Message,done:!0});continue}let k;try{k=JSON.parse(_)}catch(v){console.error("Failed to parse SSE chunk",v);continue}k.message?.chat&&(p=k.message.chat,this.streamControllers.set(p,i)),n(k)}}if(p)try{const h=await this.getMessages(p,{limit:Q7});return{id:p,messages:h.messages}}catch(h){console.error("Failed to fetch messages after streaming",h)}}finally{clearTimeout(o);const s=[];for(const[l,u]of this.streamControllers.entries())u===i&&s.push(l);s.forEach(l=>this.streamControllers.delete(l))}}cancelStream(t){this.cancelHttpStream(t),t&&this.request(`/chats/${t}/abort`,{method:"POST",body:JSON.stringify({})}).catch(n=>{console.error("Failed to call abort API:",n)})}cancelHttpStream(t){if(t){const r=this.streamControllers.get(t);if(r){r.abort();const a=[];for(const[i,o]of this.streamControllers.entries())o===r&&a.push(i);a.forEach(i=>this.streamControllers.delete(i))}return}const n=new Set(this.streamControllers.values());for(const r of n)r.abort();this.streamControllers.clear()}async listChats(t){const n=new URLSearchParams;t?.contextKey&&n.set("contextKey",t.contextKey),t?.skip!=null&&n.set("skip",String(t.skip)),t?.limit&&n.set("limit",String(t.limit)),t?.sortField&&n.set("sortField",t.sortField),t?.sortOrder&&n.set("sortOrder",t.sortOrder);const r=await this.request(`/chats?${n.toString()}`);return{cursor:r.cursor,data:r.data}}async getChat(t){return await this.request(`/chats/${t}`)}async getMessages(t,n){const r=new URLSearchParams({});return n?.limit!=null&&r.set("limit",String(n.limit)),n?.before&&r.set("before",n.before),this.request(`/chats/${t}/messages?${r.toString()}`)}deleteChat(t){return this.request(`/chats/${t}`,{method:"DELETE"})}listAgents(){return this.request("/agents")}controlAgent(t){return this.request(`/agents/${t.id}/control`,{method:"POST",body:JSON.stringify({action:t.action})})}listArtifacts(t){return this.request(`/chats/${t}/artifacts`)}listActivities(t){const n=new URLSearchParams;return t?.groupId&&n.set("groupId",t.groupId),t?.parentId&&n.set("parentId",t.parentId),t?.skip!=null&&n.set("skip",String(t.skip)),t?.limit!=null&&n.set("limit",String(t.limit)),t?.sort!=null&&(n.set("sortField",t.sort.field),n.set("sortOrder",t.sort.order)),this.request(`/activities?${n.toString()}`)}async getActivity(t){return this.request(`/activities/${t}`)}async recordToolCallAction(t,n,r){const a={};return r?.excludeSocketId!==!1&&this.socketId&&(a["x-socket-id"]=this.socketId),this.request(`/chats/${t}/actions`,{method:"POST",headers:a,body:JSON.stringify({kind:"toolCall",toolCallId:n.toolCallId,action:n.action,...n.data?{data:n.data}:{},...n.systemMessage?{systemMessage:n.systemMessage}:{}})})}async generateTitle(t){return`${t.contextKey} request ${new Date().toISOString()}`}async listModels(){return(await this.request("/models")).models}}const J7="mp-agents-chats",e_=3,Xt="chats",Ht="messages";class t_{db=null;initPromise=null;async init(){if(!this.db)return this.initPromise?this.initPromise:(this.initPromise=new Promise((t,n)=>{const r=indexedDB.open(J7,e_);r.onerror=()=>n(new Error("Failed to open IndexedDB")),r.onsuccess=()=>{this.db=r.result,t()},r.onupgradeneeded=a=>{const i=a.target.result;a.oldVersion;let o;i.objectStoreNames.contains(Xt)?o=r.transaction.objectStore(Xt):o=i.createObjectStore(Xt,{keyPath:"id"}),o.indexNames.contains("contextKey")||o.createIndex("contextKey","contextKey",{unique:!1}),o.indexNames.contains("updatedAt")||o.createIndex("updatedAt","updatedAt",{unique:!1}),o.indexNames.contains("userId")||o.createIndex("userId","userId",{unique:!1}),i.objectStoreNames.contains(Ht)||i.createObjectStore(Ht,{keyPath:"chatId"}).createIndex("chatId","chatId",{unique:!0})}}),this.initPromise)}async saveChat(t){if(await this.init(),!this.db)throw new Error("IndexedDB not initialized");const{messages:n,...r}=t;return new Promise((a,i)=>{const l=this.db.transaction([Xt],"readwrite").objectStore(Xt).put(r);l.onsuccess=()=>a(),l.onerror=()=>i(new Error("Failed to save chat"))})}async getChat(t){if(await this.init(),!this.db)throw new Error("IndexedDB not initialized");return new Promise((n,r)=>{const a=this.db.transaction([Xt,Ht],"readwrite"),i=a.objectStore(Xt),o=i.get(t);o.onsuccess=async()=>{const s=o.result;if(!s){n(null);return}if(s.messages&&Array.isArray(s.messages)){const d=s.messages,{messages:p,...h}=s;a.objectStore(Ht).put({chatId:t,messages:d}),i.put(h)}const{messages:l,...u}=s;n(u)},o.onerror=()=>r(new Error("Failed to get chat"))})}async listChats(t){if(await this.init(),!this.db)throw new Error("IndexedDB not initialized");return new Promise((n,r)=>{const a=this.db.transaction([Xt,Ht],"readwrite"),i=a.objectStore(Xt),o=i.getAll();o.onsuccess=()=>{let s=o.result??[];const l=a.objectStore(Ht);if(s=s.map(u=>{if(u.messages&&Array.isArray(u.messages)){l.put({chatId:u.id,messages:u.messages});const{messages:h,...m}=u;return i.put(m),m}const{messages:d,...p}=u;return p}),t?.contextKey&&(s=s.filter(u=>u.contextKey===t.contextKey)),t?.userId){const u=t.userId??"guest";s=s.filter(d=>(d.userId??"guest")===u)}s.sort((u,d)=>u.updatedAt<d.updatedAt?1:-1),n(s)},o.onerror=()=>r(new Error("Failed to list chats"))})}async deleteChat(t){if(await this.init(),!this.db)throw new Error("IndexedDB not initialized");return new Promise((n,r)=>{const a=this.db.transaction([Xt,Ht],"readwrite");a.objectStore(Xt).delete(t),a.objectStore(Ht).delete(t),a.oncomplete=()=>n(),a.onerror=()=>r(new Error("Failed to delete chat"))})}async clearAll(){if(await this.init(),!this.db)throw new Error("IndexedDB not initialized");return new Promise((t,n)=>{const r=this.db.transaction([Xt,Ht],"readwrite");r.objectStore(Xt).clear(),r.objectStore(Ht).clear(),r.oncomplete=()=>t(),r.onerror=()=>n(new Error("Failed to clear"))})}async getMessages(t){return await this.init(),this.db?new Promise((n,r)=>{const o=this.db.transaction([Ht],"readonly").objectStore(Ht).get(t);o.onsuccess=()=>{const s=o.result;n(s?.messages??[])},o.onerror=()=>r(new Error("Failed to get messages"))}):[]}async saveMessages(t,n){if(await this.init(),!this.db)throw new Error("IndexedDB not initialized");return new Promise((r,a)=>{const s=this.db.transaction([Ht],"readwrite").objectStore(Ht).put({chatId:t,messages:n});s.onsuccess=()=>r(),s.onerror=()=>a(new Error("Failed to save messages"))})}async appendMessages(t,n){const r=await this.getMessages(t);r.push(...n),await this.saveMessages(t,r)}}const At=new t_,n_=new TextDecoder,r_=3;class Xo{constructor(t){if(this.config=t,t.mode!=="direct")throw new Error("DirectTransport requires direct mode configuration");if(!t.model)throw new Error("DirectTransport requires a model to be specified");if(!t.apiKey)throw new Error("DirectTransport requires an API key. Set VITE_LLM_API_KEY in your .env file");this.initializeStorage().catch(n=>{console.error("Failed to initialize chat storage:",n)})}chats=new Map;chatState=new Map;toolRegistry;streamControllers=new Map;contextKeys;initialized=!1;models;untitledChatText="Untitled chat";updateConfig(t){if(t.mode!=="direct")throw new Error("DirectTransport.updateConfig requires direct mode configuration");if(!t.model)throw new Error("DirectTransport requires a model to be specified");if(!t.apiKey)throw new Error("DirectTransport requires an API key");this.config=t}setContextKeys(t){this.contextKeys=t}async initializeStorage(){if(!this.initialized)try{(await At.listChats()).forEach(n=>{this.chats.set(n.id,n)}),this.initialized=!0}catch(t){console.error("Failed to load chats from IndexedDB:",t),this.initialized=!0}}generateLocalTitle(t){const r=(t.split(`
|
|
33
33
|
`).map(s=>s.trim()).find(s=>s.length>0)??"").replace(/^(\#{1,6}\s+|\d+\.\s+|[-*+]\s+)/,"").replace(/\s+/g," ").trim();if(!r)return this.untitledChatText;const a=80;if(r.length<=a)return r;const i=r.slice(0,a),o=i.lastIndexOf(" ");return o>a*.6?`${i.slice(0,o)}…`:`${i}…`}setToolRegistry(t){this.toolRegistry=t}setModels(t){this.models=t}setUntitledChatText(t){this.untitledChatText=t}toolsToFunctions(t){if(!this.toolRegistry)return;const n=this.toolRegistry.list();return n.length===0?void 0:(t?n.filter(a=>!0):n).map(a=>this.toolToFunction(a))}toolToFunction(t){return{type:"function",function:{name:t.name,description:t.description||t.label,parameters:this.normalizeSchema(t.schema)}}}normalizeSchema(t){if(!t||typeof t!="object")return{type:"object",properties:{},required:[]};const n=t,r={};if(n.properties&&typeof n.properties=="object")for(const[i,o]of Object.entries(n.properties))r[i]=this.normalizePropertySchema(o);const a=Array.isArray(n.required)&&n.required.every(i=>typeof i=="string")?n.required:[];return{type:"object",properties:r,required:a}}normalizePropertySchema(t){if(!t||typeof t!="object"||Array.isArray(t))return{};const n=t,r=typeof n.type=="string"?n.type:void 0;if(r==="enum"){const a=Array.isArray(n.options)?n.options.filter(s=>typeof s=="string"):[],i={type:"string"};a.length>0&&(i.enum=a);const o=this.extractDescription(n);return o&&(i.description=o),typeof n.default=="string"&&(i.default=n.default),i}if(r==="string"&&("label"in n||"placeholder"in n)){const a={type:"string"},i=this.extractDescription(n);return i&&(a.description=i),typeof n.default=="string"&&(a.default=n.default),a}return n}extractDescription(t){if(typeof t.description=="string")return t.description;if(typeof t.label=="string")return t.label}endpoint(){if(this.config.provider==="openrouter")return this.config.endpoint??"https://openrouter.ai/api/v1/chat/completions";if(this.config.provider==="openai")return this.config.endpoint??"https://api.openai.com/v1/chat/completions";if(!this.config.endpoint)throw new Error("Custom direct transport requires endpoint");return this.config.endpoint}buildHeaders(){const t={"Content-Type":"application/json",...this.config.headers};return this.config.apiKey&&(t.Authorization=`Bearer ${this.config.apiKey}`),t}async clearErrorMessages(t){const n=await At.getMessages(t);if(!n.length)return;const r=n.filter(a=>a.role!==exports.MessageRole.Error);r.length!==n.length&&await At.saveMessages(t,r)}async appendErrorMessage(t,n){const r={id:Rt.nanoid(),chat:t,content:n,role:exports.MessageRole.Error,createdAt:new Date().toISOString(),reasoning:"",toolCalls:[],attachments:[]};await At.appendMessages(t,[r])}attachChatToError(t,n,r){const a=t instanceof Error?t:new Error(r);return a.chat||Object.defineProperty(a,"chat",{value:n,configurable:!0,enumerable:!1,writable:!0}),a}async ensureChat(t){if(await this.initializeStorage(),t.chatId&&this.chats.has(t.chatId))return this.chats.get(t.chatId);if(t.chatId)try{const o=await At.getChat(t.chatId);if(o)return this.chats.set(o.id,o),o}catch(o){console.error("Failed to load chat from IndexedDB:",o)}const n=t.metadata?.title,r=typeof n=="string"&&n.trim().length>0?n:this.generateLocalTitle(t.content),a=t.userId??"guest",i={id:t.chatId??Rt.nanoid(),title:r,type:exports.ChatType.Chat,status:exports.AgentStatus.Processing,contextKey:t.contextKey,userId:a,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()};return this.chats.set(i.id,i),await this.persistChat(i),i}async persistChat(t){t.updatedAt=new Date().toISOString(),this.chats.set(t.id,t),At.saveChat(t).catch(n=>{console.error("Failed to persist chat to IndexedDB:",n)})}toOpenAIMessage(t){return{role:t.role===exports.MessageRole.Reasoning?exports.MessageRole.Assistant:t.role,content:t.content}}async callModel(t,n,r){const a=n??this.config.model;if(!a)throw new Error("Model is required. Either specify in payload or config.");const i={model:a,messages:t.map(d=>this.toOpenAIMessage(d))},o=await fetch(this.endpoint(),{method:"POST",headers:this.buildHeaders(),body:JSON.stringify(i)});if(!o.ok)throw new Error(`The AI provider returned an error (status ${o.status}).`);return(await o.json()).choices?.[0]?.message?.content??""}async generateLlmTitle(t){const n=this.config.model;if(!n)return this.generateLocalTitle(t.content);const r=["You generate very short, human-friendly chat titles.","Rules:","- At most 8 words.","- No quotes, no markdown, no emojis.","- Summarize the main intent of the user message.","","User message:",t.content].join(`
|
|
34
34
|
`),a={model:n,messages:[{role:"system",content:"You are a title generator."},{role:"user",content:r}]};try{const i=await fetch(this.endpoint(),{method:"POST",headers:this.buildHeaders(),body:JSON.stringify(a)});if(!i.ok)return this.generateLocalTitle(t.content);const l=(await i.json()).choices?.[0]?.message?.content?.trim();return l?this.generateLocalTitle(l):this.generateLocalTitle(t.content)}catch{return this.generateLocalTitle(t.content)}}async generateTitle(t){return(t.strategy==="llm"?"llm":"local")==="llm"?this.generateLlmTitle({content:t.content,contextKey:t.contextKey}):this.generateLocalTitle(t.content)}async sendMessage(t){const n=await this.ensureChat(t);await this.clearErrorMessages(n.id);const r=await At.getMessages(n.id),a={id:Rt.nanoid(),chat:n.id,role:exports.MessageRole.User,content:t.content,createdAt:new Date().toISOString(),attachments:t.attachments??[],reasoning:"",toolCalls:[]},i=[...r,a];try{const o=await this.callModel(i,t.model,t.contextKey),s={id:Rt.nanoid(),chat:n.id,role:exports.MessageRole.Assistant,content:o,createdAt:new Date().toISOString(),reasoning:"",toolCalls:[],attachments:[]};return await At.saveMessages(n.id,[...i,s]),await this.persistChat(n),n}catch(o){const s=o instanceof Error?o.message:"Failed to send message";throw await this.appendErrorMessage(n.id,s),await this.persistChat(n),this.attachChatToError(o,n,s)}}async streamMessage(t,n,r){const a=t.model??this.config.model;if(!a)throw new Error("Model is required. Either specify in payload or config.");const i=await this.ensureChat(t),o=r?.streamKey??i.id;await this.clearErrorMessages(i.id),t.chatId||n({type:exports.StreamChunkType.Chat,chatId:i.id,chat:{...i}});const s={id:Rt.nanoid(),chat:i.id,role:exports.MessageRole.User,content:t.content,createdAt:new Date().toISOString(),attachments:t.attachments};await At.appendMessages(i.id,[s]);const l=await At.getMessages(i.id),u=new AbortController;this.streamControllers.set(o,u),o!==i.id&&this.streamControllers.set(i.id,u);let d=!1;const p=async(k,v)=>{const M=k instanceof Error?k.message:v;return d||(await this.appendErrorMessage(i.id,M),await this.persistChat(i),d=!0),this.attachChatToError(k??new Error(M),i,M)};let h;try{h=await fetch(this.endpoint(),{method:"POST",headers:{...this.buildHeaders(),Accept:"text/event-stream"},body:JSON.stringify({model:a,stream:!0,messages:l.map(k=>this.toOpenAIMessage(k))}),signal:u.signal})}catch(k){throw k?.name==="AbortError"?(await this.persistChat(i),this.streamControllers.get(o)===u&&this.streamControllers.delete(o),k):(this.streamControllers.get(o)===u&&this.streamControllers.delete(o),await p(k,"Streaming request failed"))}if(!h.ok){this.streamControllers.get(o)===u&&this.streamControllers.delete(o);const v=`The AI provider returned an error (status ${h.status}).`;throw await p(new Error(v),v)}if(!h.body)throw this.streamControllers.get(o)===u&&this.streamControllers.delete(o),await p(new Error("Streaming response body missing"),"Streaming response body missing");const m=h.body.getReader();let g="",y="";const w={id:Rt.nanoid(),chat:i.id,role:exports.MessageRole.Assistant,content:"",createdAt:new Date().toISOString()};await At.appendMessages(i.id,[w]);try{for(;;){const{value:k,done:v}=await m.read();if(v)break;g+=n_.decode(k,{stream:!0});const M=g.split(`
|
|
35
35
|
|