@amaster.ai/copilot-client 1.1.0-beta.72 → 1.1.0-beta.74

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/index.d.cts CHANGED
@@ -63,6 +63,8 @@ interface Conversation {
63
63
  status: "submitted" | "working" | "completed" | "error";
64
64
  messages: MessagesItem[];
65
65
  lastUpdated: string;
66
+ requestState?: ConversationRequestState;
67
+ runtimeError?: ConversationRuntimeError | null;
66
68
  role?: Role;
67
69
  historyId?: string;
68
70
  system?: {
@@ -74,6 +76,14 @@ interface HistoryState {
74
76
  next: string | null;
75
77
  hasMore: boolean;
76
78
  }
79
+ type ConversationRequestState = "idle" | "submitting" | "streaming" | "recovering" | "error";
80
+ interface ConversationRuntimeError {
81
+ code: "network" | "unknown";
82
+ message: string;
83
+ retryable: boolean;
84
+ source: "send" | "stream" | "recovery";
85
+ timestamp: string;
86
+ }
77
87
  interface UpdateMessageInput {
78
88
  taskId: string;
79
89
  messageId: string;
@@ -99,8 +109,6 @@ interface ConversationControllerOptions {
99
109
  strings: ConversationStrings;
100
110
  mode?: ContextIdMode;
101
111
  getContextId?: () => string;
102
- loadHistoryOnInit?: boolean;
103
- resumeOnInit?: boolean;
104
112
  }
105
113
  interface ConversationController {
106
114
  getSnapshot(): ConversationControllerSnapshot;
@@ -123,6 +131,88 @@ interface ConversationController {
123
131
  type CopilotClient = {
124
132
  createConversationController(options: ConversationControllerOptions): ConversationController;
125
133
  };
126
- declare function createCopilotClient(http?: HttpClient, baseUrl?: string, getAccessToken?: () => string | null, getUserUid?: () => string | null): CopilotClient;
134
+ declare function createCopilotClient(http: HttpClient, baseUrl?: string, getAccessToken?: () => string | null, getUserUid?: () => string | null): CopilotClient;
135
+
136
+ interface AutoVoiceReplyMessage {
137
+ messageId?: string;
138
+ role?: string;
139
+ kind: string;
140
+ content?: string;
141
+ }
142
+ interface AutoVoiceReplyConversation {
143
+ taskId: string;
144
+ status: string;
145
+ requestState?: string;
146
+ messages: AutoVoiceReplyMessage[];
147
+ }
148
+ interface AutoVoiceReplySourceSnapshot {
149
+ conversations: AutoVoiceReplyConversation[];
150
+ isLoading: boolean;
151
+ }
152
+ interface AutoVoiceReplySource {
153
+ subscribe(listener: () => void): () => void;
154
+ getSnapshot(): AutoVoiceReplySourceSnapshot;
155
+ }
156
+ interface AutoVoiceReplySpeechSnapshot {
157
+ status: "idle" | "connecting" | "speaking" | "error";
158
+ error?: string | null;
159
+ voice?: string | null;
160
+ }
161
+ interface AutoVoiceReplySpeechDriver {
162
+ subscribe(listener: () => void): () => void;
163
+ getSnapshot(): AutoVoiceReplySpeechSnapshot;
164
+ startStream(input: {
165
+ id: string;
166
+ voice?: string | null;
167
+ audioFormat?: "pcm" | "mp3" | "wav" | "opus";
168
+ sampleRate?: number;
169
+ }): Promise<void>;
170
+ appendText(input: {
171
+ id: string;
172
+ text: string;
173
+ }): Promise<void>;
174
+ commit(): void;
175
+ finish(): void;
176
+ stop(): void;
177
+ setVoice?(voice: string | null): void;
178
+ getVoice?(): string | null;
179
+ }
180
+ interface AutoVoiceReplyStorage {
181
+ getItem(key: string): string | null | undefined;
182
+ setItem(key: string, value: string): void;
183
+ }
184
+ interface AutoVoiceReplySnapshot {
185
+ enabled: boolean;
186
+ status: "idle" | "connecting" | "speaking" | "error";
187
+ connecting: boolean;
188
+ speaking: boolean;
189
+ voice: string | null;
190
+ activeTaskId: string | null;
191
+ suppressedTaskId: string | null;
192
+ error: string | null;
193
+ }
194
+ interface AutoVoiceReplyController {
195
+ subscribe(listener: () => void): () => void;
196
+ getSnapshot(): AutoVoiceReplySnapshot;
197
+ setEnabled(enabled: boolean): void;
198
+ toggleEnabled(): void;
199
+ toggleEnabledOrStop(): void;
200
+ stop(): void;
201
+ setVoice(voice: string | null): void;
202
+ getVoice(): string | null;
203
+ destroy(): void;
204
+ }
205
+ interface CreateAutoVoiceReplyControllerOptions {
206
+ source: AutoVoiceReplySource;
207
+ speech: AutoVoiceReplySpeechDriver;
208
+ storage?: AutoVoiceReplyStorage;
209
+ enabledStorageKey?: string;
210
+ defaultVoice?: string | null;
211
+ id?: string;
212
+ audioFormat?: "pcm" | "mp3" | "wav" | "opus";
213
+ sampleRate?: number;
214
+ preprocessText?: (text: string) => string;
215
+ }
216
+ declare function createAutoVoiceReplyController(options: CreateAutoVoiceReplyControllerOptions): AutoVoiceReplyController;
127
217
 
128
- export { type Conversation, type ConversationController, type ConversationControllerOptions, type ConversationControllerSnapshot, type ConversationStrings, type CopilotClient, type ErrorMessage, type FileContent, type HistoryState, type ImageContent, type MessageContent, type MessagesItem, type Role, type TextContent, type TextMessage, type ThoughtMessage, type ToolMessage, type UIRenderMessage, type UpdateMessageInput, createCopilotClient };
218
+ export { type AutoVoiceReplyController, type AutoVoiceReplyConversation, type AutoVoiceReplyMessage, type AutoVoiceReplySnapshot, type AutoVoiceReplySource, type AutoVoiceReplySourceSnapshot, type AutoVoiceReplySpeechDriver, type AutoVoiceReplySpeechSnapshot, type AutoVoiceReplyStorage, type Conversation, type ConversationController, type ConversationControllerOptions, type ConversationControllerSnapshot, type ConversationRequestState, type ConversationRuntimeError, type ConversationStrings, type CopilotClient, type CreateAutoVoiceReplyControllerOptions, type ErrorMessage, type FileContent, type HistoryState, type ImageContent, type MessageContent, type MessagesItem, type Role, type TextContent, type TextMessage, type ThoughtMessage, type ToolMessage, type UIRenderMessage, type UpdateMessageInput, createAutoVoiceReplyController, createCopilotClient };
package/dist/index.d.ts CHANGED
@@ -63,6 +63,8 @@ interface Conversation {
63
63
  status: "submitted" | "working" | "completed" | "error";
64
64
  messages: MessagesItem[];
65
65
  lastUpdated: string;
66
+ requestState?: ConversationRequestState;
67
+ runtimeError?: ConversationRuntimeError | null;
66
68
  role?: Role;
67
69
  historyId?: string;
68
70
  system?: {
@@ -74,6 +76,14 @@ interface HistoryState {
74
76
  next: string | null;
75
77
  hasMore: boolean;
76
78
  }
79
+ type ConversationRequestState = "idle" | "submitting" | "streaming" | "recovering" | "error";
80
+ interface ConversationRuntimeError {
81
+ code: "network" | "unknown";
82
+ message: string;
83
+ retryable: boolean;
84
+ source: "send" | "stream" | "recovery";
85
+ timestamp: string;
86
+ }
77
87
  interface UpdateMessageInput {
78
88
  taskId: string;
79
89
  messageId: string;
@@ -99,8 +109,6 @@ interface ConversationControllerOptions {
99
109
  strings: ConversationStrings;
100
110
  mode?: ContextIdMode;
101
111
  getContextId?: () => string;
102
- loadHistoryOnInit?: boolean;
103
- resumeOnInit?: boolean;
104
112
  }
105
113
  interface ConversationController {
106
114
  getSnapshot(): ConversationControllerSnapshot;
@@ -123,6 +131,88 @@ interface ConversationController {
123
131
  type CopilotClient = {
124
132
  createConversationController(options: ConversationControllerOptions): ConversationController;
125
133
  };
126
- declare function createCopilotClient(http?: HttpClient, baseUrl?: string, getAccessToken?: () => string | null, getUserUid?: () => string | null): CopilotClient;
134
+ declare function createCopilotClient(http: HttpClient, baseUrl?: string, getAccessToken?: () => string | null, getUserUid?: () => string | null): CopilotClient;
135
+
136
+ interface AutoVoiceReplyMessage {
137
+ messageId?: string;
138
+ role?: string;
139
+ kind: string;
140
+ content?: string;
141
+ }
142
+ interface AutoVoiceReplyConversation {
143
+ taskId: string;
144
+ status: string;
145
+ requestState?: string;
146
+ messages: AutoVoiceReplyMessage[];
147
+ }
148
+ interface AutoVoiceReplySourceSnapshot {
149
+ conversations: AutoVoiceReplyConversation[];
150
+ isLoading: boolean;
151
+ }
152
+ interface AutoVoiceReplySource {
153
+ subscribe(listener: () => void): () => void;
154
+ getSnapshot(): AutoVoiceReplySourceSnapshot;
155
+ }
156
+ interface AutoVoiceReplySpeechSnapshot {
157
+ status: "idle" | "connecting" | "speaking" | "error";
158
+ error?: string | null;
159
+ voice?: string | null;
160
+ }
161
+ interface AutoVoiceReplySpeechDriver {
162
+ subscribe(listener: () => void): () => void;
163
+ getSnapshot(): AutoVoiceReplySpeechSnapshot;
164
+ startStream(input: {
165
+ id: string;
166
+ voice?: string | null;
167
+ audioFormat?: "pcm" | "mp3" | "wav" | "opus";
168
+ sampleRate?: number;
169
+ }): Promise<void>;
170
+ appendText(input: {
171
+ id: string;
172
+ text: string;
173
+ }): Promise<void>;
174
+ commit(): void;
175
+ finish(): void;
176
+ stop(): void;
177
+ setVoice?(voice: string | null): void;
178
+ getVoice?(): string | null;
179
+ }
180
+ interface AutoVoiceReplyStorage {
181
+ getItem(key: string): string | null | undefined;
182
+ setItem(key: string, value: string): void;
183
+ }
184
+ interface AutoVoiceReplySnapshot {
185
+ enabled: boolean;
186
+ status: "idle" | "connecting" | "speaking" | "error";
187
+ connecting: boolean;
188
+ speaking: boolean;
189
+ voice: string | null;
190
+ activeTaskId: string | null;
191
+ suppressedTaskId: string | null;
192
+ error: string | null;
193
+ }
194
+ interface AutoVoiceReplyController {
195
+ subscribe(listener: () => void): () => void;
196
+ getSnapshot(): AutoVoiceReplySnapshot;
197
+ setEnabled(enabled: boolean): void;
198
+ toggleEnabled(): void;
199
+ toggleEnabledOrStop(): void;
200
+ stop(): void;
201
+ setVoice(voice: string | null): void;
202
+ getVoice(): string | null;
203
+ destroy(): void;
204
+ }
205
+ interface CreateAutoVoiceReplyControllerOptions {
206
+ source: AutoVoiceReplySource;
207
+ speech: AutoVoiceReplySpeechDriver;
208
+ storage?: AutoVoiceReplyStorage;
209
+ enabledStorageKey?: string;
210
+ defaultVoice?: string | null;
211
+ id?: string;
212
+ audioFormat?: "pcm" | "mp3" | "wav" | "opus";
213
+ sampleRate?: number;
214
+ preprocessText?: (text: string) => string;
215
+ }
216
+ declare function createAutoVoiceReplyController(options: CreateAutoVoiceReplyControllerOptions): AutoVoiceReplyController;
127
217
 
128
- export { type Conversation, type ConversationController, type ConversationControllerOptions, type ConversationControllerSnapshot, type ConversationStrings, type CopilotClient, type ErrorMessage, type FileContent, type HistoryState, type ImageContent, type MessageContent, type MessagesItem, type Role, type TextContent, type TextMessage, type ThoughtMessage, type ToolMessage, type UIRenderMessage, type UpdateMessageInput, createCopilotClient };
218
+ export { type AutoVoiceReplyController, type AutoVoiceReplyConversation, type AutoVoiceReplyMessage, type AutoVoiceReplySnapshot, type AutoVoiceReplySource, type AutoVoiceReplySourceSnapshot, type AutoVoiceReplySpeechDriver, type AutoVoiceReplySpeechSnapshot, type AutoVoiceReplyStorage, type Conversation, type ConversationController, type ConversationControllerOptions, type ConversationControllerSnapshot, type ConversationRequestState, type ConversationRuntimeError, type ConversationStrings, type CopilotClient, type CreateAutoVoiceReplyControllerOptions, type ErrorMessage, type FileContent, type HistoryState, type ImageContent, type MessageContent, type MessagesItem, type Role, type TextContent, type TextMessage, type ThoughtMessage, type ToolMessage, type UIRenderMessage, type UpdateMessageInput, createAutoVoiceReplyController, createCopilotClient };
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- import {createHttpClient}from'@amaster.ai/http-client';import {createParser}from'eventsource-parser';import Pe from'miniprogram-text-decoder';var ne=class{constructor(){this.aborted=false;this.listeners=[];this.signal={aborted:false,addEventListener:(e,o)=>{this.listeners.push(o);}};}abort(){this.aborted||(this.aborted=true,this.signal.aborted=true,this.listeners.forEach(e=>e()));}};function le(){return typeof AbortController<"u"?new AbortController:new ne}function g(){return new Date().toISOString()}function j(){return `msg-${Date.now()}-${Math.random().toString(36).slice(2,10)}`}function ke(t){return {...t}}function se(t){return {...t,system:t.system?{...t.system}:void 0,messages:t.messages.map(e=>ke(e))}}function oe(t){return {starting:t.starting,isLoading:t.isLoading,isLoadingHistory:t.isLoadingHistory,historyState:{...t.historyState},conversations:t.order.map(e=>t.byId[e]).filter(e=>!!e).map(e=>se(e))}}var W={"text-content":(t,e,o,s,d)=>{if(!o)return t;let i=t.messages.find(r=>r.messageId===o),m=e.text||"";return i&&"content"in i?{...t,messages:t.messages.map(r=>r.messageId===o?{...r,content:r.content+m}:r),lastUpdated:g()}:{...t,messages:[...t.messages,{messageId:o,role:s,kind:"text-content",content:m,timestamp:d?.timestamp||g()}],lastUpdated:g()}},thought:(t,e,o,s,d)=>{if(!o)return t;let i=e?.data?.description||"",m=t.messages.find(r=>r.messageId===o);return m&&"thought"in m?{...t,messages:t.messages.map(r=>r.messageId===o?{...r,thought:r.thought+i}:r),lastUpdated:g()}:{...t,messages:[...t.messages,{messageId:o,role:s,kind:"thought",thought:i,timestamp:d?.timestamp||g()}],lastUpdated:g()}},tool:(t,e,o,s,d)=>{let i=e?.data||{},m=i?.tool,r=m?.displayName||m?.name||"",a=i?.request,u=a?.callId;if(!u||!r)return t;let I=i?.status,y=t.messages.find(x=>x.messageId===u);return y&&"toolStatus"in y?{...t,messages:t.messages.map(x=>x.messageId===u?{...x,toolStatus:I||x.toolStatus}:x),lastUpdated:g()}:{...t,messages:[...t.messages,{messageId:u,role:s,kind:"tool",toolName:r,toolDescription:a?.args?.query||"",toolStatus:I||"pending",timestamp:d?.timestamp||g()}],lastUpdated:g()}},error:(t,e,o,s)=>{let d=e?.text||e?.data?.error||"\u53D1\u751F\u9519\u8BEF";return {...t,messages:[...t.messages,{messageId:o||`error-${Date.now()}`,role:s,kind:"error",content:d,timestamp:g()}],status:"error",lastUpdated:g()}},"ui-render":(t,e,o,s,d)=>{if(!o)return t;let i=t.messages.find(a=>a.messageId===o),r=(e?.data||{}).spec||{root:"",elements:{}};return i&&i.kind==="ui-render"?{...t,messages:t.messages.map(a=>a.messageId===o?{...a,spec:r}:a),lastUpdated:g()}:{...t,messages:[...t.messages,{messageId:o,role:s,kind:"ui-render",spec:r,timestamp:d?.timestamp||g()}],lastUpdated:g()}}};function ae(t,e){return t?.data?.tool?"tool":t?.data?.type==="ui"?"ui-render":t?.kind==="text"?"text-content":t?.data?.type==="though"||e?.coderAgent?.kind==="thought"?"thought":e?.error?"error":"unknown"}function de(t,e){let s=(e.mode||"conversation")==="single-turn",d=s?false:e.loadHistoryOnInit,i=s?false:e.resumeOnInit,m=()=>e.getContextId?.()??t.createContextId(s?"single-turn":"conversation"),r={byId:{},order:[],starting:true,isLoading:false,isLoadingHistory:false,historyState:{next:null,hasMore:false}},a=new Set,u=null,y=null,x="unknown",v="",c=null,R=false,A=m(),q=t.createScopedRuntime(A),k=()=>{if(R)return;let n=oe(r);a.forEach(l=>l(n));},J=n=>{r.order=r.order.filter(l=>l!==n);},M=(n,l=true)=>{J(n),r.order=l?[...r.order,n]:[n,...r.order];},P=()=>{x="unknown",v="";},L=()=>{r.byId={},r.order=[],r.historyState={next:null,hasMore:false};},F=()=>(A=m(),q=t.createScopedRuntime(A),A),_=()=>{u?.abort(),u=null,r.isLoading=false,k();},D=()=>{P(),y=null,u=null,r.isLoading=false,k();},$=n=>{r.byId[n.taskId]=n,M(n.taskId,true),k();},z=n=>{r.byId[n]&&(delete r.byId[n],J(n),k());},Z=()=>{$({taskId:"loading-placeholder",status:"working",messages:[{messageId:"loading-placeholder",role:"assistant",kind:"text-content",content:e.strings.thinking,timestamp:g()}],lastUpdated:g()});},ee=()=>{z("loading-placeholder");},te=({kind:n,taskId:l,part:f,status:p,handler:w,isHistory:b,historyId:T,messageId:C})=>{let h=C||v,E=p?.message?.role==="agent"?"assistant":"user";!C&&(n==="ui-render"||n!=="unknown"&&n!==x)&&(x=n,h=j(),v=h);let U=r.byId[l]??{taskId:l,status:b?"completed":"submitted",messages:[],role:E,historyId:T,lastUpdated:g()},S=w(U,f,h,E,p);r.byId[l]={...S,status:p?.state||U.status,lastUpdated:g()},b||M(l,true),k();},V=()=>{$({taskId:j(),status:"error",messages:[{messageId:`error-${Date.now()}`,role:"assistant",kind:"error",content:e.strings.errorMessage,timestamp:g()}],lastUpdated:g()}),r.isLoading=false,k();},be=n=>{if(!n?.result)return;let l=n.result,{taskId:f,status:p,metadata:w,final:b}=l;if(b){D();return}if(!f)return;y=f;let T=p?.message?.parts?.[0],C=ae(T,w),h=W[C];h&&(ee(),te({kind:C,taskId:f,part:T,status:p,handler:h}));},ve=(n,l)=>{let{messageId:f,historyId:p}=n||{};if(!f)return;let w=n.parts?.[0],b=ae(w);if(b==="text-content"){let C=w.text||"";if(C=C.trim(),C.startsWith("<ui>")){let h=C.slice(4).trim();try{let E=JSON.parse(h);E.root&&E.elements&&te({kind:"ui-render",taskId:l,part:{kind:"data",data:{type:"ui",spec:E}},handler:W["ui-render"],isHistory:!0,historyId:p,messageId:f,status:{message:n}});}catch{}return}}let T=W[b];T&&te({kind:b,taskId:l,part:w,handler:T,isHistory:true,historyId:p,messageId:f,status:{message:n}});},K=async(n,l,f=false,p=0)=>{_(),P();let w=le();u=w,f&&(Z(),r.isLoading=true,k());let b=false,T=false,C=false,h=false,E=l?.taskId||null,U=q.sendMessage(n,{taskId:l?.taskId,signal:w.signal,onMessage:S=>{let H=S?.result?.taskId,re=!!S?.result?.final;H&&(E=H),re&&(h=true),b=true,be(S);},onClose:()=>{}});try{await U;}catch(S){S?.name==="AbortError"||w.signal.aborted?C=true:(T=true,console.error("[ConversationController] Stream error:",S));}finally{if(u===w&&(u=null),!C&&!h&&p<2)try{let H=await q.getChatStatus(E||void 0);if(H.working&&H.taskId){y=H.taskId,await K([],{taskId:H.taskId},!1,p+1);return}if(!b&&!E&&!H.taskId&&p<1){await K(n,l,!1,p+1);return}}catch(H){console.error("[ConversationController] recovery failed:",H);}T||!b&&f&&!C?V():C?(r.isLoading=false,ee(),k()):h&&r.isLoading?D():!h&&r.isLoading&&V();}};return {getSnapshot(){return oe(r)},subscribe(n){return a.add(n),()=>{a.delete(n);}},async init(){if(!R)return c||(r.starting=true,k(),c=(async()=>{try{if(d&&await this.loadHistory(),i){let n=await q.getChatStatus();n.taskId&&n.working&&(y=n.taskId,await K([],{taskId:n.taskId},!1));}}catch(n){console.error("[ConversationController] init failed:",n);}finally{r.starting=false,k(),c=null;}})(),c)},destroy(){R=true,_(),a.clear();},async sendMessage(n){if(!(r.isLoading||!n.trim())){s&&(this.abort(),L(),P(),y=null,F()),$({taskId:j(),status:"submitted",messages:[{messageId:j(),role:"user",kind:"text-content",content:n,timestamp:g()}],lastUpdated:g()});try{await K([{role:"user",content:n}],void 0,!0);}catch(l){if(l.name==="AbortError")return;V();}}},abort(){let n=u?.signal.aborted;_(),P(),y=null,ee(),n||Promise.resolve();},async cancelChat(n){let l=n||y;if(this.abort(),$({taskId:j(),status:"error",messages:[{messageId:`cancel-${Date.now()}`,role:"assistant",kind:"text-content",content:e.strings.cancelled,timestamp:g()}],lastUpdated:g()}),!!l)try{await q.cancelChat(l),y=null;}catch(f){console.error("[ConversationController] cancel failed:",f);}},resetConversation(n){if(this.abort(),L(),y=null,P(),s&&F(),n){let l=`conv-${Date.now()}`;r.byId[l]={taskId:l,status:"submitted",messages:[{messageId:`greeting-${Date.now()}`,role:"assistant",kind:"text-content",content:n,timestamp:g()}],lastUpdated:g()},r.order=[l];}k();},async startNewConversation(){$({taskId:j(),status:"submitted",messages:[],lastUpdated:g(),system:{level:"newConversation"}});try{await q.newConversation();}catch(n){console.error("[ConversationController] newConversation failed:",n);}},async loadHistory(n=20,l){r.isLoadingHistory=true,k();try{let f=await q.getHistory(n,l),p=f?.messages||[],w="",b="",T=[];p.forEach(C=>{let h=C.role==="agent"?"assistant":"user";h!==b&&(w=`history-conv-${j()}`,T.push(w),b=h),ve(C,w);}),r.order=[...T,...r.order.filter(C=>!T.includes(C))],r.historyState={next:f?.next||null,hasMore:f?.hasMore||!1};}catch(f){console.error("[ConversationController] loadHistory failed:",f);}finally{r.isLoadingHistory=false,k();}},async loadMoreHistory(){!r.historyState.hasMore||r.isLoadingHistory||!r.historyState.next||await this.loadHistory(20,r.historyState.next);},getConversation(n){let l=r.byId[n];return l?se(l):void 0},clearConversation(n){z(n);},removeMessage(n,l){let f=r.byId[n];f&&(r.byId[n]={...f,messages:f.messages.filter(p=>p.messageId!==l),lastUpdated:g()},M(n,true),k());},updateMessage(n){let{taskId:l,messageId:f,content:p,partial:w=false,status:b,response:T,metadata:C={}}=n,h=r.byId[l];if(!h)return;let E=h.messages.findIndex(re=>re.messageId===f);if(E===-1)return;let U=h.messages[E];if(!U)return;let S={...U,...C};p!==void 0&&("content"in S?S.content=w?`${S.content||""}${p}`:p:"thought"in S?S.thought=w?`${S.thought||""}${p}`:p:U.kind==="text-content"&&(S.content=w?`${U.content||""}${p}`:p)),("toolStatus"in S||b)&&(S.toolStatus=b||S.toolStatus),T!==void 0&&(S.response=T);let H=[...h.messages];H[E]=S,r.byId[l]={...h,messages:H,lastUpdated:g()},M(l,true),k();}}}function N(){let t=typeof globalThis<"u"?globalThis:typeof global<"u"?global:typeof window<"u"?window:{};return {Taro:t?.Taro,wx:typeof wx<"u"?wx:t?.wx,tt:typeof tt<"u"?tt:t?.tt,my:typeof my<"u"?my:t?.my,swan:typeof swan<"u"?swan:t?.swan,qq:typeof qq<"u"?qq:t?.qq,jd:typeof jd<"u"?jd:t?.jd}}function B(t){let e=N();return typeof t=="function"?t:typeof e?.Taro?.request=="function"?e.Taro.request.bind(e.Taro):typeof e?.wx?.request=="function"?e.wx.request.bind(e.wx):typeof e?.tt?.request=="function"?e.tt.request.bind(e.tt):typeof e?.my?.request=="function"?e.my.request.bind(e.my):typeof e?.swan?.request=="function"?e.swan.request.bind(e.swan):typeof e?.qq?.request=="function"?e.qq.request.bind(e.qq):typeof e?.jd?.request=="function"?e.jd.request.bind(e.jd):null}function ue(t){return createHttpClient({adapter:B(t)?"taro":"axios",miniProgramRequest:t})}function ce(){let t=N();return typeof t?.wx?.request=="function"||typeof t?.qq?.request=="function"}function me(){return typeof N()?.tt?.createEventSource=="function"}function O(){let t=typeof globalThis<"u"?globalThis.crypto:void 0;return t&&typeof t.randomUUID=="function"?t.randomUUID():t&&typeof t.getRandomValues=="function"?"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let s=(t.getRandomValues(new Uint8Array(1))[0]??0)%16;return (e==="x"?s:s&3|8).toString(16)}):"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let o=Math.random()*16|0;return (e==="x"?o:o&3|8).toString(16)})}function fe(t){let e=/^www\.([\da-z-]+)(?:-[^.]+)?\.[\w-]+\.(?:local|ai|cn)$/.exec(t);if(e?.[1])return e[1];let o=/^([\da-z-]+)(?:-[^.]+)?\.[\w-]+\.(?:local|ai|cn)$/.exec(t);return o?.[1]?o[1]:null}function Re(){if(typeof window>"u")return null;try{let t=window.location.href,e=/\/app\/([\da-z-]+)(?:\/|$)/.exec(t);return e?.[1]?e[1]:fe(window.location.hostname)}catch{return null}}var ie=null,Ae=null;function ge(t){let e=t?fe(t):Re();return e||(ie||(ie=O()),ie)}function pe(t,e,o){return (s="conversation")=>{let d=N(),i=ge();if(e&&typeof d?.wx?.request=="function"){let a=t?t.replace(/^https?:\/\//,"").split("/")[0]:"";i=ge(a);}let m=o?.()??Ae??(Ae=`anonymous-${O()}`),r=`${i}:${m}`;return s==="single-turn"?`${r}:${O()}`:r}}function ye(t){return typeof t=="string"?[{kind:"text",text:t}]:t.map(e=>{switch(e.type){case "text":return {kind:"text",text:e.text};case "image":return e.data?{kind:"file",file:{bytes:e.data,mimeType:e.mimeType||"image/png"}}:e.url?{kind:"file",file:{uri:e.url,mimeType:e.mimeType||"image/png"}}:null;case "file":return e.data?{kind:"file",file:{bytes:e.data,...e.mimeType&&{mimeType:e.mimeType},...e.name&&{name:e.name}}}:e.url?{kind:"file",file:{uri:e.url,...e.mimeType&&{mimeType:e.mimeType},...e.name&&{name:e.name}}}:null;default:return null}}).filter(e=>e!==null)}function xe(t){return typeof t=="string"?t:t.filter(e=>e.type==="text").map(e=>e.text).join(`
2
- `)}function Ce(t){return {createContextId(e){return t.createContextId(e)},createScopedRuntime(e){return t.createRuntime(e)}}}function he({createContextId:t,postRpc:e,sendMessageStream:o}){return Ce({createContextId:t,createRuntime(s){return {async sendMessage(d,i){let{taskId:m,signal:r,onOpen:a,onMessage:u,onClose:I}=i,y=d.find(q=>q.role==="system"),x=d.filter(q=>q.role!=="system"),v=x[x.length-1],c=v?ye(v.content):[{kind:"text",text:""}],R=y?xe(y.content):void 0,A={jsonrpc:"2.0",id:O(),method:"message/stream",params:{message:{contextId:s,kind:"message",messageId:O(),role:"user",parts:c,...m?{taskId:m}:{},...R?{metadata:{systemPrompt:R}}:{}}}};await o(A,{onOpen:a,onMessage:u,onClose:I},r);},cancelChat(d){let i={jsonrpc:"2.0",id:O(),method:"tasks/cancel",params:{id:d}};return e(i)},async getHistory(d=50,i){try{let r=(await e({jsonrpc:"2.0",method:"messages/list",id:O(),params:{filter:{contextId:s},limit:d,...i?{next:i}:{}}}))?.data?.result||{},a=r?.messages||[],u=r?.next||"";return {messages:a,next:u,hasMore:!!u}}catch{return}},async newConversation(){try{await e({jsonrpc:"2.0",method:"messages/clear",id:O(),params:{contextId:s}});}catch{}},async getChatStatus(d){try{let i={jsonrpc:"2.0",id:O(),method:"tasks/get",params:d?{id:d}:{contextId:s}},r=(await e(i))?.data?.result;return {working:r?.status?.state==="working",taskId:r?.id,error:r?.error?.message||""}}catch(i){return {working:false,error:i?.message||""}}}}}})}function Q(t){if(t instanceof Error)return t;if(t&&typeof t=="object"){let e=t,o=typeof e.errMsg=="string"&&e.errMsg||typeof e.message=="string"&&e.message||JSON.stringify(e),s=new Error(o);return (typeof e.errorCode=="number"||typeof e.errorCode=="string")&&(s.errorCode=e.errorCode),(typeof e.errNo=="number"||typeof e.errNo=="string")&&(s.errNo=e.errNo),s.raw=t,s}return new Error(String(t))}function G(){if(typeof DOMException<"u")return new DOMException("Aborted","AbortError");let t=new Error("Aborted");return t.name="AbortError",t}function X(t){return createParser({onEvent:e=>{try{t.onMessage(JSON.parse(e.data));}catch(o){console.error("[copilot stream] failed to parse SSE event:",o,e.data);}}})}function Y(t,e){if(t){if(t.aborted){e();return}t.addEventListener("abort",e);}}async function Se(t,e,o,s,d){let i={"Content-Type":"application/json",...o},m=await fetch(t,{method:"POST",headers:i,credentials:"include",body:JSON.stringify(e),signal:d});if(!m.ok)throw new Error(`Stream request failed: ${m.statusText||m.status}`);if(s.onOpen?.(),!m.body){s.onClose?.();return}let r=m.body.getReader(),a=new TextDecoder,u=X(s);try{for(;;){if(d?.aborted)throw G();let{done:I,value:y}=await r.read();if(I)break;u.feed(a.decode(y,{stream:!0}));}}finally{s.onClose?.();}}async function Me(t,e,o={},s,d){return new Promise((i,m)=>{let r=N(),a=false,u,I=false,y=c=>{let R=String(c?.errMsg||c?.message||""),A=c?.errNo,q=c?.errorCode;return I&&/stream closed/i.test(R)&&(A===21104||q===30)},x=c=>{if(!a){if(a=true,c){m(Q(c));return}s.onClose?.(),i();}};try{u=r.tt.createEventSource({url:t,method:"POST",header:{...o},data:e});}catch(c){x(c);return}let v=c=>{if(c&&y(c)){u.close?.(),x();return}u.close?.(),x(c);};u.onOpen?.(()=>{s.onOpen?.();}),u.onMessage?.(c=>{I=true;try{s.onMessage(typeof c?.data=="string"?JSON.parse(c.data):c?.data);}catch(R){console.error("[douyin eventsource] failed to parse message:",R,c);}}),u.onError?.(c=>{v(c);}),u.onClose?.(()=>{x();}),Y(d,()=>{v(G());});})}function Ee(t,e){if(!t)return "";let o=t instanceof Uint8Array?t:new Uint8Array(t);return o.length===0?"":e.decode(o,{stream:false})}async function Ie(t,e,o={},s,d,i){return new Promise((m,r)=>{let a=new Uint8Array(0),u=new Pe("utf-8",{fatal:false}),I=false,y=false,x=false,v=X(s),c=M=>{if(!y){if(y=true,M){r(Q(M));return}s.onClose?.(),m();}},R=()=>{x||(x=true,s.onOpen?.());},A=M=>{M&&(R(),v.feed(M));},q=M=>{if(!(y||!M.data))try{I=!0;let P=new Uint8Array(M.data),L=new Uint8Array(a.length+P.length);L.set(a),L.set(P,a.length),a=L;let F=0;for(;F<a.length;){let _=a.subarray(F),D=u.decode(_,{stream:!1});if(D.length===0)break;if(D.includes("\uFFFD")){let $=D.lastIndexOf("\uFFFD")===0?0:D.indexOf("\uFFFD");if($<=0)break;let z=D.slice(0,$);z&&A(z);let Z=new TextEncoder().encode(z);F+=Z.length;break}A(D),F+=_.length;}a=a.subarray(F);}catch(P){console.error("[mini stream] chunk process error:",P);}},k=M=>{R(),M.header?.["content-type"]?.includes("text/event-stream")===false&&console.warn("Warning: server did not return event-stream");},J=B(i);if(!J){r(new Error("Mini-program request API not found"));return}try{let M=J({url:t,method:"POST",header:{"Content-Type":"application/json",Accept:"text/event-stream",...o},data:typeof e=="string"?e:JSON.stringify(e),responseType:"arraybuffer",enableChunked:ce(),timeout:3e5,success:P=>{if(!I&&P?.data){let L=Ee(P.data,u);A(L);}if(a.length>0){let L=u.decode(a,{stream:!0});A(L);}c();},fail:P=>{c(P);}});Y(d,()=>{M.abort?.(),c(G());}),M.onChunkReceived?.(q),M.onHeadersReceived?.(k);}catch(M){c(M);}})}async function we(t,e,o,s,d,i){let m=o?.(),r=m?{Authorization:`Bearer ${m}`}:{},a=me(),u=B(i);if(a){await Me(t,e,r,s,d);return}if(u){await Ie(t,e,r,s,d,i);return}await Se(t,e,r,s,d);}function He(t,e,o,s){let d=B(t?.miniProgramRequest),i=d||void 0,m=t??ue(i),r="";try{r=process.env.TARO_APP_API_BASE_URL||process.env.VITE_API_BASE_URL||process.env.API_BASE_URL||"";}catch{}r=String(r||"").trim();let a=`${e||r}/api/proxy/builtin/platform/copilot`,u=v=>m.request({url:a,method:"POST",data:v}),I=pe(a,d,s);async function y(v,c,R){try{await we(a,v,o,c,R,i);}catch(A){if(R?.aborted)return;throw A}}let x=he({createContextId:I,postRpc:u,sendMessageStream:y});return {createConversationController(v){return de(x,v)}}}export{He as createCopilotClient};//# sourceMappingURL=index.js.map
1
+ import {getMiniProgramRequest,resolveMiniProgramGlobals}from'@amaster.ai/http-client';import {createParser}from'eventsource-parser';import je from'miniprogram-text-decoder';var me=class{constructor(){this.aborted=false;this.listeners=[];this.signal={aborted:false,addEventListener:(t,r)=>{this.listeners.push(r);}};}abort(){this.aborted||(this.aborted=true,this.signal.aborted=true,this.listeners.forEach(t=>t()));}};function ve(){return typeof AbortController<"u"?new AbortController:new me}function f(){return new Date().toISOString()}function Q(){return `msg-${Date.now()}-${Math.random().toString(36).slice(2,10)}`}function De(e){return {...e}}function pe(e){return {...e,system:e.system?{...e.system}:void 0,runtimeError:e.runtimeError?{...e.runtimeError}:void 0,messages:e.messages.map(t=>De(t))}}function fe(e){return {starting:e.starting,isLoading:e.isLoading,isLoadingHistory:e.isLoadingHistory,historyState:{...e.historyState},conversations:e.order.map(t=>e.byId[t]).filter(t=>!!t).map(t=>pe(t))}}var oe={"text-content":(e,t,r,a,i)=>{if(!r)return e;let c=e.messages.find(n=>n.messageId===r),d=t.text||"";return c&&"content"in c?{...e,messages:e.messages.map(n=>n.messageId===r?{...n,content:n.content+d}:n),lastUpdated:f()}:{...e,messages:[...e.messages,{messageId:r,role:a,kind:"text-content",content:d,timestamp:i?.timestamp||f()}],lastUpdated:f()}},thought:(e,t,r,a,i)=>{if(!r)return e;let c=t?.data?.description||"",d=e.messages.find(n=>n.messageId===r);return d&&"thought"in d?{...e,messages:e.messages.map(n=>n.messageId===r?{...n,thought:n.thought+c}:n),lastUpdated:f()}:{...e,messages:[...e.messages,{messageId:r,role:a,kind:"thought",thought:c,timestamp:i?.timestamp||f()}],lastUpdated:f()}},tool:(e,t,r,a,i)=>{let c=t?.data||{},d=c?.tool,n=d?.displayName||d?.name||"",m=c?.request,y=m?.callId;if(!y||!n)return e;let x=c?.status,S=e.messages.find(b=>b.messageId===y);return S&&"toolStatus"in S?{...e,messages:e.messages.map(b=>b.messageId===y?{...b,toolStatus:x||b.toolStatus}:b),lastUpdated:f()}:{...e,messages:[...e.messages,{messageId:y,role:a,kind:"tool",toolName:n,toolDescription:m?.args?.query||"",toolStatus:x||"pending",timestamp:i?.timestamp||f()}],lastUpdated:f()}},error:(e,t,r,a)=>{let i=t?.text||t?.data?.error||"\u53D1\u751F\u9519\u8BEF";return {...e,messages:[...e.messages,{messageId:r||`error-${Date.now()}`,role:a,kind:"error",content:i,timestamp:f()}],status:"error",lastUpdated:f()}},"ui-render":(e,t,r,a,i)=>{if(!r)return e;let c=e.messages.find(m=>m.messageId===r),n=(t?.data||{}).spec||{root:"",elements:{}};return c&&c.kind==="ui-render"?{...e,messages:e.messages.map(m=>m.messageId===r?{...m,spec:n}:m),lastUpdated:f()}:{...e,messages:[...e.messages,{messageId:r,role:a,kind:"ui-render",spec:n,timestamp:i?.timestamp||f()}],lastUpdated:f()}}};function ye(e,t){return e?.data?.tool?"tool":e?.data?.type==="ui"?"ui-render":e?.kind==="text"?"text-content":e?.data?.type==="though"||t?.coderAgent?.kind==="thought"?"thought":t?.error?"error":"unknown"}function Fe(e,t){if(typeof e=="string"){let r=e.trim().toUpperCase();if(r==="TT"||r==="DOUYIN"||r==="WEAPP"||r==="WECHAT")return true}return t?typeof t.TT<"u"&&e===t.TT||typeof t.WEAPP<"u"&&e===t.WEAPP:false}function ae(){let e=resolveMiniProgramGlobals();return Fe(e?.Taro?.getEnv?.(),e?.Taro?.ENV_TYPE)?true:typeof e?.wx?.request=="function"||typeof e?.tt?.request=="function"||typeof e?.my?.request=="function"||typeof e?.swan?.request=="function"||typeof e?.qq?.request=="function"||typeof e?.jd?.request=="function"}function be(){let e=resolveMiniProgramGlobals();return !(typeof e?.tt?.request=="function"||typeof e?.tt?.createEventSource=="function")}function Me(){return typeof resolveMiniProgramGlobals()?.tt?.createEventSource=="function"}function Re(e,t){let a=(t.mode||"conversation")==="single-turn",i=!a,c=!a,d=()=>t.getContextId?.()??e.createContextId(a?"single-turn":"conversation"),n={byId:{},order:[],starting:true,isLoading:false,isLoadingHistory:false,historyState:{next:null,hasMore:false}},m=new Set,y=null,S=null,b="unknown",M="",P=null,R=false,D=d(),q=e.createScopedRuntime(D),h=null,g=()=>{if(R)return;let s=fe(n);m.forEach(o=>o(s));},H=s=>{n.order=n.order.filter(o=>o!==s);},k=(s,o=true)=>{H(s),n.order=o?[...n.order,s]:[s,...n.order];},I=()=>{b="unknown",M="";},z=s=>{let o=s&&typeof s=="object"?s:{},u=String(o.message||o.errMsg||"").toLowerCase(),p=String(o.errorCode||""),A=String(o.errNo||"");return o.name==="TypeError"||/failed to fetch|fetch failed|timed out|disconnected|offline|断网/.test(u)||["600009","21101","21102","21103"].includes(p)||["600009","21101","21102","21103"].includes(A)},_=(s,o="stream")=>{let u=s&&typeof s=="object"?s:{},p=String(u.message||u.errMsg||"").toLowerCase();return {code:z(s)?"network":"unknown",message:p,retryable:true,source:o,timestamp:f()}},L=(s,o)=>{if(!s)return;let u=n.byId[s];u&&(n.byId[s]={...u,requestState:o.requestState??u.requestState,runtimeError:o.runtimeError===void 0?u.runtimeError:o.runtimeError,status:o.status??u.status,lastUpdated:f()});},j=s=>{L(s,{requestState:"idle",runtimeError:null});},X=()=>{n.byId={},n.order=[],n.historyState={next:null,hasMore:false};},K=s=>{n.isLoading=s,!s&&ne();},G=()=>(D=d(),q=e.createScopedRuntime(D),D),Z=()=>{y?.abort(),y=null,j(h),K(false),g();},se=()=>{I(),j(h),h&&L(h,{status:"completed"}),h=null,S=null,y=null,K(false),g();},J=s=>{n.byId[s.taskId]=s,k(s.taskId,true),g();},re=s=>{n.byId[s]&&(delete n.byId[s],H(s),g());},ue=()=>{J({taskId:"loading-placeholder",status:"working",messages:[{messageId:"loading-placeholder",role:"assistant",kind:"text-content",content:t.strings.thinking,timestamp:f()}],lastUpdated:f()});},ne=()=>{re("loading-placeholder");},Y=({kind:s,taskId:o,part:u,status:p,handler:A,isHistory:C,historyId:E,messageId:T})=>{let w=T||M,O=p?.message?.role==="agent"?"assistant":"user";!T&&(s==="ui-render"||s!=="unknown"&&s!==b)&&(b=s,w=Q(),M=w);let $=n.byId[o]??{taskId:o,status:C?"completed":"submitted",messages:[],role:O,historyId:E,lastUpdated:f()},U=A($,u,w,O,p);n.byId[o]={...U,status:p?.state||$.status,lastUpdated:f()},C||k(o,true),g();},l=(s,o="stream",u=h)=>{L(u,{requestState:"error",runtimeError:_(s,o),status:"error"}),u&&h===u&&(h=null),K(false),g();},v=s=>{if(!s?.result)return;let o=s.result,{taskId:u,status:p,metadata:A,final:C}=o;if(C){se();return}if(!u)return;S=u;let E=p?.message?.parts?.[0],T=ye(E,A),w=oe[T];w&&(ne(),Y({kind:T,taskId:u,part:E,status:p,handler:w}));},F=(s,o)=>{let{messageId:u,historyId:p}=s||{};if(!u)return;let A=s.parts?.[0],C=ye(A);if(C==="text-content"){let T=A.text||"";if(T=T.trim(),T.startsWith("<ui>")){let w=T.slice(4).trim();try{let O=JSON.parse(w);O.root&&O.elements&&Y({kind:"ui-render",taskId:o,part:{kind:"data",data:{type:"ui",spec:O}},handler:oe["ui-render"],isHistory:!0,historyId:p,messageId:u,status:{message:s}});}catch{}return}}let E=oe[C];E&&Y({kind:C,taskId:o,part:A,handler:E,isHistory:true,historyId:p,messageId:u,status:{message:s}});},V=async(s,o,u=false,p=0,A=false,C=h)=>{h=C,Z(),I(),L(C,{requestState:"submitting",runtimeError:null,status:"submitted"});let E=ve();y=E,u&&(ue(),K(true),g());let T=false,w=false,O=false,$=false,U=o?.taskId||null,ee=q.sendMessage(s,{taskId:o?.taskId,signal:E.signal,preferMiniProgramRequest:A,onMessage:W=>{let ge=W?.result?.taskId,N=!!W?.result?.final;ge&&(U=ge),N&&($=true),T=true,L(C,{requestState:N?"idle":"streaming",runtimeError:null,status:N?"completed":"working"}),v(W);},onClose:()=>{}});let ce=async()=>{if(Me()&&!!getMiniProgramRequest()&&!O&&!$&&p<2){console.log("[recovering]"),L(C,{requestState:"recovering",runtimeError:null,status:"working"}),g();try{let N=await q.getChatStatus(U||void 0);if(N.working&&N.taskId)return S=N.taskId,await V([],{taskId:N.taskId},!0,p+1,!0,C),!0;if(!T&&!U&&!N.taskId&&p<1)return await V(s,o,!0,p+1,!0,C),!0}catch(N){return console.error("[ConversationController] recovery failed:",N),l(N,"recovery",C),true}}return false},de,Ce=false;try{await ee;}catch(W){W?.name==="AbortError"||E.signal.aborted?O=true:(w=true,de=W,console.error("[ConversationController] Stream error:",W));}finally{y===E&&(y=null),Ce=await ce();}Ce||(w?l(de,"stream",C):!T&&u&&!O?l(de,"send",C):O?(j(C),C&&h===C&&(h=null),K(false),g()):$&&n.isLoading?se():!$&&n.isLoading&&l(void 0,"stream",C));};return {getSnapshot(){return fe(n)},subscribe(s){return m.add(s),()=>{m.delete(s);}},async init(){if(!R)return P||(n.starting=true,g(),P=(async()=>{try{if(i&&await this.loadHistory(),c){let s=await q.getChatStatus();s.taskId&&s.working&&(S=s.taskId,await V([],{taskId:s.taskId},!1));}}catch(s){console.error("[ConversationController] init failed:",s);}finally{n.starting=false,g(),P=null;}})(),P)},destroy(){R=true,Z(),m.clear();},async sendMessage(s){if(n.isLoading||!s.trim())return;a&&(this.abort(),X(),I(),S=null,G());let o=Q();h=o,J({taskId:o,status:"submitted",requestState:"submitting",runtimeError:null,messages:[{messageId:Q(),role:"user",kind:"text-content",content:s,timestamp:f()}],lastUpdated:f()});try{await V([{role:"user",content:s}],void 0,!0,0,!1,o);}catch(u){if(u.name==="AbortError")return;l(u,"send",o);}},abort(){let s=y?.signal.aborted;Z(),I(),j(h),h=null,S=null,ne(),s||Promise.resolve();},async cancelChat(s){let o=s||S;if(this.abort(),J({taskId:Q(),status:"error",messages:[{messageId:`cancel-${Date.now()}`,role:"assistant",kind:"text-content",content:t.strings.cancelled,timestamp:f()}],lastUpdated:f()}),!!o)try{await q.cancelChat(o),S=null;}catch(u){console.error("[ConversationController] cancel failed:",u);}},resetConversation(s){if(this.abort(),X(),h=null,S=null,I(),a&&G(),s){let o=`conv-${Date.now()}`;n.byId[o]={taskId:o,status:"submitted",messages:[{messageId:`greeting-${Date.now()}`,role:"assistant",kind:"text-content",content:s,timestamp:f()}],lastUpdated:f()},n.order=[o];}g();},async startNewConversation(){J({taskId:Q(),status:"submitted",messages:[],lastUpdated:f(),system:{level:"newConversation"}});try{await q.newConversation();}catch(s){console.error("[ConversationController] newConversation failed:",s);}},async loadHistory(s=20,o){n.isLoadingHistory=true,g();try{let u=await q.getHistory(s,o),p=u?.messages||[],A="",C="",E=[];p.forEach(T=>{let w=T.role==="agent"?"assistant":"user";w!==C&&(A=`history-conv-${Q()}`,E.push(A),C=w),F(T,A);}),n.order=[...E,...n.order.filter(T=>!E.includes(T))],n.historyState={next:u?.next||null,hasMore:u?.hasMore||!1};}catch(u){console.error("[ConversationController] loadHistory failed:",u);}finally{n.isLoadingHistory=false,g();}},async loadMoreHistory(){!n.historyState.hasMore||n.isLoadingHistory||!n.historyState.next||await this.loadHistory(20,n.historyState.next);},getConversation(s){let o=n.byId[s];return o?pe(o):void 0},clearConversation(s){re(s);},removeMessage(s,o){let u=n.byId[s];u&&(n.byId[s]={...u,messages:u.messages.filter(p=>p.messageId!==o),lastUpdated:f()},k(s,true),g());},updateMessage(s){let{taskId:o,messageId:u,content:p,partial:A=false,status:C,response:E,metadata:T={}}=s,w=n.byId[o];if(!w)return;let O=w.messages.findIndex(ce=>ce.messageId===u);if(O===-1)return;let $=w.messages[O];if(!$)return;let U={...$,...T};p!==void 0&&("content"in U?U.content=A?`${U.content||""}${p}`:p:"thought"in U?U.thought=A?`${U.thought||""}${p}`:p:$.kind==="text-content"&&(U.content=A?`${$.content||""}${p}`:p)),("toolStatus"in U||C)&&(U.toolStatus=C||U.toolStatus),E!==void 0&&(U.response=E);let ee=[...w.messages];ee[O]=U,n.byId[o]={...w,messages:ee,lastUpdated:f()},k(o,true),g();}}}function B(){let e=typeof globalThis<"u"?globalThis.crypto:void 0;return e&&typeof e.randomUUID=="function"?e.randomUUID():e&&typeof e.getRandomValues=="function"?"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,t=>{let a=(e.getRandomValues(new Uint8Array(1))[0]??0)%16;return (t==="x"?a:a&3|8).toString(16)}):"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,t=>{let r=Math.random()*16|0;return (t==="x"?r:r&3|8).toString(16)})}function ke(e){let t=/^www\.([\da-z-]+)(?:-[^.]+)?\.[\w-]+\.(?:local|ai|cn)$/.exec(e);if(t?.[1])return t[1];let r=/^([\da-z-]+)(?:-[^.]+)?\.[\w-]+\.(?:local|ai|cn)$/.exec(e);return r?.[1]?r[1]:null}function $e(){if(typeof window>"u")return null;try{let e=window.location.href,t=/\/app\/([\da-z-]+)(?:\/|$)/.exec(e);return t?.[1]?t[1]:ke(window.location.hostname)}catch{return null}}var Se=null,Ne=null;function Ie(e){let t=e?ke(e):$e();return t||(Se||(Se=B()),Se)}function Te(e,t){return (r="conversation")=>{let a=ae(),i=Ie();if(a){let n=e?e.replace(/^https?:\/\//,"").split("/")[0]:"";i=Ie(n);}let c=t?.()??Ne??(Ne=`anonymous-${B()}`),d=`${i}:${c}`;return r==="single-turn"?`${d}:${B()}`:d}}function we(e){return typeof e=="string"?[{kind:"text",text:e}]:e.map(t=>{switch(t.type){case "text":return {kind:"text",text:t.text};case "image":return t.data?{kind:"file",file:{bytes:t.data,mimeType:t.mimeType||"image/png"}}:t.url?{kind:"file",file:{uri:t.url,mimeType:t.mimeType||"image/png"}}:null;case "file":return t.data?{kind:"file",file:{bytes:t.data,...t.mimeType&&{mimeType:t.mimeType},...t.name&&{name:t.name}}}:t.url?{kind:"file",file:{uri:t.url,...t.mimeType&&{mimeType:t.mimeType},...t.name&&{name:t.name}}}:null;default:return null}}).filter(t=>t!==null)}function Ae(e){return typeof e=="string"?e:e.filter(t=>t.type==="text").map(t=>t.text).join(`
2
+ `)}function Ee(e){return {createContextId(t){return e.createContextId(t)},createScopedRuntime(t){return e.createRuntime(t)}}}function Pe({createContextId:e,postRpc:t,sendMessageStream:r}){return Ee({createContextId:e,createRuntime(a){return {async sendMessage(i,c){let{taskId:d,signal:n,onOpen:m,onMessage:y,onClose:x,preferMiniProgramRequest:S}=c,b=i.find(h=>h.role==="system"),M=i.filter(h=>h.role!=="system"),P=M[M.length-1],R=P?we(P.content):[{kind:"text",text:""}],D=b?Ae(b.content):void 0,q={jsonrpc:"2.0",id:B(),method:"message/stream",params:{message:{contextId:a,kind:"message",messageId:B(),role:"user",parts:R,...d?{taskId:d}:{},...D?{metadata:{systemPrompt:D}}:{}}}};await r(q,{onOpen:m,onMessage:y,onClose:x},n,S);},cancelChat(i){let c={jsonrpc:"2.0",id:B(),method:"tasks/cancel",params:{id:i}};return t(c)},async getHistory(i=50,c){try{let n=(await t({jsonrpc:"2.0",method:"messages/list",id:B(),params:{filter:{contextId:a},limit:i,...c?{next:c}:{}}}))?.data?.result||{},m=n?.messages||[],y=n?.next||"";return {messages:m,next:y,hasMore:!!y}}catch{return}},async newConversation(){try{await t({jsonrpc:"2.0",method:"messages/clear",id:B(),params:{contextId:a}});}catch{}},async getChatStatus(i){try{let c={jsonrpc:"2.0",id:B(),method:"tasks/get",params:i?{id:i}:{contextId:a}},n=(await t(c))?.data?.result;return {working:n?.status?.state==="working",taskId:n?.id,error:n?.error?.message||""}}catch(c){return {working:false,error:c?.message||""}}}}}})}function Ve(e){if(e instanceof Error)return e;if(e&&typeof e=="object"){let t=e,r=typeof t.errMsg=="string"&&t.errMsg||typeof t.message=="string"&&t.message||JSON.stringify(t),a=new Error(r);return (typeof t.errorCode=="number"||typeof t.errorCode=="string")&&(a.errorCode=t.errorCode),(typeof t.errNo=="number"||typeof t.errNo=="string")&&(a.errNo=t.errNo),a.raw=e,a}return new Error(String(e))}function ie(){if(typeof DOMException<"u")return new DOMException("Aborted","AbortError");let e=new Error("Aborted");return e.name="AbortError",e}function le(e){return createParser({onEvent:t=>{try{e.onMessage(JSON.parse(t.data));}catch(r){console.error("[copilot stream] failed to parse SSE event:",r,t.data);}}})}function Ue(e,t){if(e){if(e.aborted){t();return}e.addEventListener("abort",t);}}async function Le(e,t,r,a,i){let c={"Content-Type":"application/json",...r},d=await fetch(e,{method:"POST",headers:c,credentials:"include",body:JSON.stringify(t),signal:i});if(!d.ok)throw new Error(`Stream request failed: ${d.statusText||d.status}`);if(a.onOpen?.(),!d.body){a.onClose?.();return}let n=d.body.getReader(),m=new TextDecoder,y=le(a);try{for(;;){if(i?.aborted)throw ie();let{done:x,value:S}=await n.read();if(x)break;y.feed(m.decode(S,{stream:!0}));}}finally{a.onClose?.();}}function Be(e,t){if(!e)return "";let r=e instanceof Uint8Array?e:new Uint8Array(e);return r.length===0?"":t.decode(r,{stream:false})}async function he(e,t,r={},a,i){return new Promise((c,d)=>{let n=new Uint8Array(0),m=new je("utf-8",{fatal:false}),y=false,x=false,S=false,b=le(a),M=g=>{if(!x){if(x=true,g){d(Ve(g));return}a.onClose?.(),c();}},P=()=>{S||(S=true,a.onOpen?.());},R=g=>{g&&(P(),b.feed(g));},D=g=>{if(!(x||!g.data))try{y=!0;let H=new Uint8Array(g.data),k=new Uint8Array(n.length+H.length);k.set(n),k.set(H,n.length),n=k;let I=0;for(;I<n.length;){let z=n.subarray(I),_=m.decode(z,{stream:!1});if(_.length===0)break;if(_.includes("\uFFFD")){let L=_.lastIndexOf("\uFFFD")===0?0:_.indexOf("\uFFFD");if(L<=0)break;let j=_.slice(0,L);j&&R(j);let X=new TextEncoder().encode(j);I+=X.length;break}R(_),I+=z.length;}n=n.subarray(I);}catch(H){console.error("[mini stream] chunk process error:",H);}},q=g=>{P(),g.header?.["content-type"]?.includes("text/event-stream")===false&&console.warn("Warning: server did not return event-stream");},h=getMiniProgramRequest();if(!h){d(new Error("Mini-program request API not found"));return}try{let g=h({url:e,method:"POST",header:{"Content-Type":"application/json",Accept:"text/event-stream",...r},data:typeof t=="string"?t:JSON.stringify(t),responseType:"arraybuffer",...be()?{enableChunked:!0}:{},success:H=>{if(!y&&H?.data){let k=Be(H.data,m);R(k);}if(n.length>0){let k=m.decode(n,{stream:!0});R(k);}M();},fail:H=>{M(H);}});Ue(i,()=>{g.abort?.(),M(ie());}),g.onChunkReceived?.(D),g.onHeadersReceived?.(q);}catch(g){M(g);}})}async function He(e,t,r,a,i,c=false){let d=r?.(),n=d?{Authorization:`Bearer ${d}`}:{},m=getMiniProgramRequest(),y=ae()&&!!m;if(c&&y){await he(e,t,n,a,i);return}if(y){await he(e,t,n,a,i);return}await Le(e,t,n,a,i);}function ze(e,t,r,a){let i="";try{i=process.env.TARO_APP_API_BASE_URL||process.env.VITE_API_BASE_URL||process.env.API_BASE_URL||"";}catch{}i=String(i||"").trim();let c=`${t||i}/api/proxy/builtin/platform/copilot`,d=x=>e.request({url:c,method:"POST",data:x}),n=Te(c,a);async function m(x,S,b,M){try{await He(c,x,r,S,b,M);}catch(P){if(b?.aborted)return;throw P}}let y=Pe({createContextId:n,postRpc:d,sendMessageStream:m});return {createConversationController(x){return Re(y,x)}}}var Ke=/[\n。!?.!?;;]/,We=/[,、,::]\s*$/;var qe=e=>{if(!e)return null;for(let t=e.messages.length-1;t>=0;t-=1){let r=e.messages[t];if(r&&r.role==="assistant"&&(r.kind==="text-content"||r.kind==="message")&&r.content?.trim())return r}return null},Ge=e=>{if(!e)return null;for(let t=e.messages.length-1;t>=0;t-=1){let r=e.messages[t];if(r&&r.role==="user"&&r.messageId)return r.messageId}return null},Oe=(e,t)=>{if(!e)return null;if(!t)return qe(e);let r=e.messages.findIndex(a=>a.messageId===t);if(r<0)return qe(e);for(let a=e.messages.length-1;a>r;a-=1){let i=e.messages[a];if(i&&i.role==="assistant"&&(i.kind==="text-content"||i.kind==="message")&&i.content?.trim())return i}return null},Je=e=>{for(let t=e.length-1;t>=0;t-=1){let r=e[t];if(r&&(r.requestState==="submitting"||r.requestState==="streaming"||r.requestState==="recovering"||r.status==="submitted"||r.status==="working"))return r}return null},Ye=(e,t)=>t&&e.find(r=>r.taskId===t)||null,Qe=(e,t)=>{let r=e.trimStart();if(!r)return {segments:[],remainder:""};if(t)return {segments:[r].filter(Boolean),remainder:""};let a=[],i=0;for(let d=0;d<r.length;d+=1){let n=r[d];if(!n||!Ke.test(n))continue;let m=r.slice(i,d+1).trim();m&&a.push(m),i=d+1;}let c=r.slice(i).trimStart();return c.length>=24&&We.test(c)&&(a.push(c.trim()),c=""),{segments:a,remainder:c}};function Xe(e){let{source:t,speech:r,storage:a,enabledStorageKey:i,defaultVoice:c=null,id:d="auto-voice-reply",audioFormat:n="pcm",sampleRate:m=24e3,preprocessText:y}=e,x=false,S=i?a?.getItem(i)==="true":false,b=t.getSnapshot().isLoading,M=null,P=null,R=null,D=false,q=null,h="",g="",H=Promise.resolve(),k=r.getVoice?.()??c,I={enabled:S,status:r.getSnapshot().status,connecting:r.getSnapshot().status==="connecting",speaking:r.getSnapshot().status==="speaking",voice:k,activeTaskId:M,suppressedTaskId:R,error:r.getSnapshot().error||null},z=new Set,_=()=>{let l=r.getSnapshot(),v={enabled:S,status:l.status,connecting:l.status==="connecting",speaking:l.status==="speaking",voice:k,activeTaskId:M,suppressedTaskId:R,error:l.error||null},F=I.enabled!==v.enabled||I.status!==v.status||I.connecting!==v.connecting||I.speaking!==v.speaking||I.voice!==v.voice||I.activeTaskId!==v.activeTaskId||I.suppressedTaskId!==v.suppressedTaskId||I.error!==v.error;return F&&(I=v),F},L=()=>{x||(_(),z.forEach(l=>l()));},j=()=>{i&&a?.setItem(i,S?"true":"false");},X=(l=null)=>{q=l,h="",g="",D=false;},K=()=>{M=null,P=null;},G=l=>{let v=l?.preserveRoundContext??false;h="",g="",q=null,D=false,v||K(),r.stop();},Z=l=>(H=H.then(()=>l(),()=>l()),H),se=async l=>{if(!(!l.length||x)){D||(await r.startStream({id:d,voice:k,audioFormat:n,sampleRate:m}),D=true);for(let v of l){if(x)return;let F=y?y(v):v;F.trim()&&(await r.appendText({id:d,text:F}),r.commit());}}},J=async(l,v)=>{let F=l.messageId||null,V=l.content||"";if(!V.trim())return;q!==F&&X(F);let s=h;if(s&&!V.startsWith(s)){h=V;return}let o=V.slice(s.length);if(h=V,!o&&!v)return;g+=o;let{segments:u,remainder:p}=Qe(g,v);g=p,u.length&&await se(u),v&&r.finish();},re=()=>{if(x)return;let l=t.getSnapshot();if(!S){b=l.isLoading;return}let v=Je(l.conversations),F=b;if(l.isLoading&&v){if(v.taskId!==M&&(M=v.taskId,P=Ge(v),R=null),R===v.taskId){b=l.isLoading,L();return}let V=Oe(v,P);V&&Z(()=>J(V,false));}else if(F&&!l.isLoading){let V=Ye(l.conversations,M);if(V&&R!==V.taskId){let s=Oe(V,P);s&&Z(()=>J(s,true));}V?.taskId===R&&(R=null),K();}b=l.isLoading,L();},ue=t.subscribe(re),ne=r.subscribe(()=>{if(x)return;let l=r.getVoice?.()??k??c;l!==k&&(k=l),L();}),Y={subscribe(l){return z.add(l),()=>{z.delete(l);}},getSnapshot(){return _(),I},setEnabled(l){S!==l&&(S=l,j(),S?(b=t.getSnapshot().isLoading,re()):(G(),R=null),L());},toggleEnabled(){Y.setEnabled(!S);},toggleEnabledOrStop(){let l=r.getSnapshot().status;if(l==="connecting"||l==="speaking"){R=M,G({preserveRoundContext:true}),L();return}Y.toggleEnabled();},stop(){R=M,G({preserveRoundContext:true}),L();},setVoice(l){k=l,r.setVoice?.(l),L();},getVoice(){return k},destroy(){x||(x=true,G(),R=null,ue(),ne(),z.clear());}};return Y}export{Xe as createAutoVoiceReplyController,ze as createCopilotClient};//# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map