@useago/sdk 1.0.7 → 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -3
- package/dist/{AgoClient--y10UXUV.cjs → AgoClient-B3-WGVne.cjs} +3 -3
- package/dist/{AgoClient-DYdIe_R4.js → AgoClient-QcTtrN7u.js} +3 -0
- package/dist/angular.cjs +1 -1
- package/dist/angular.d.cts +46 -8
- package/dist/angular.d.ts +46 -8
- package/dist/angular.js +1 -1
- package/dist/{createConversationSession-BuMXp0Ia.cjs → createConversationSession-C0diFTUk.cjs} +1 -1
- package/dist/{createConversationSession-CCT1hCf8.js → createConversationSession-CR-71aLR.js} +1 -1
- package/dist/createFormCollector-BI3DXaew.cjs +1 -0
- package/dist/createFormCollector-CFt1_QSL.js +299 -0
- package/dist/devtools.d.cts +46 -8
- package/dist/devtools.d.ts +46 -8
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +64 -9
- package/dist/index.d.ts +64 -9
- package/dist/index.js +53 -45
- package/dist/react.cjs +1 -1
- package/dist/react.d.cts +47 -9
- package/dist/react.d.ts +47 -9
- package/dist/react.js +2 -2
- package/dist/testing.d.cts +46 -8
- package/dist/testing.d.ts +46 -8
- package/dist/vue.cjs +1 -1
- package/dist/vue.d.cts +46 -8
- package/dist/vue.d.ts +46 -8
- package/dist/vue.js +1 -1
- package/dist/widget.cjs +4 -4
- package/dist/widget.d.cts +77 -8
- package/dist/widget.d.ts +77 -8
- package/dist/widget.js +371 -366
- package/package.json +1 -1
- package/dist/createFormCollector-BwM7qTrp.js +0 -276
- package/dist/createFormCollector-DWzGKDwO.cjs +0 -1
package/README.md
CHANGED
|
@@ -3,9 +3,20 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/@useago/sdk)
|
|
4
4
|
[](https://www.npmjs.com/package/@useago/sdk)
|
|
5
5
|
|
|
6
|
-
**The agent
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
**The customer-facing agent platform for your product.**
|
|
7
|
+
|
|
8
|
+
AGO embeds AI agents directly into your frontend stack: React, Vue, Angular or
|
|
9
|
+
plain TypeScript. Send messages, stream responses, expose frontend actions, and
|
|
10
|
+
let agents guide users, trigger workflows, or operate **your** UI.
|
|
11
|
+
|
|
12
|
+
Internal agent platforms help employees work faster. Customer-facing agents are
|
|
13
|
+
a different problem. They have to be reliable, safe, measurable, brand-aligned,
|
|
14
|
+
and integrated into the product experience.
|
|
15
|
+
|
|
16
|
+
AGO provides the operating layer behind the SDK: business and user context, tool
|
|
17
|
+
orchestration, evaluations, quality monitoring, security controls, human
|
|
18
|
+
fallback, and continuous improvement. Your team ships product-native agents that
|
|
19
|
+
resolve customer needs, without rebuilding the full customer-facing agent platform.
|
|
9
20
|
|
|
10
21
|
In two minutes you'll have a working chat on your page and an agent that can
|
|
11
22
|
navigate your app. The quickstart below uses **React**; every other stack gets
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
var h=class extends Error{constructor(e,t,s){super(e),this.code=t,this.statusCode=s,this.name="AgoError"}},u=class b extends h{constructor(t,s,n,r,i,a){super(t,s,n),this.type=r,this.param=i,this.docUrl=a,this.name="AgoApiError"}static fromResponse(t,s){const n=t.error;return new b(n.doc_url?`${n.message} See ${n.doc_url}`:n.message,n.code,s,n.type,n.param,n.doc_url)}},d=class extends h{constructor(e,t){super(e,"network_error"),this.originalError=t,this.name="AgoNetworkError"}},
|
|
1
|
+
var h=class extends Error{constructor(e,t,s){super(e),this.code=t,this.statusCode=s,this.name="AgoError"}},u=class b extends h{constructor(t,s,n,r,i,a){super(t,s,n),this.type=r,this.param=i,this.docUrl=a,this.name="AgoApiError"}static fromResponse(t,s){const n=t.error;return new b(n.doc_url?`${n.message} See ${n.doc_url}`:n.message,n.code,s,n.type,n.param,n.doc_url)}},d=class extends h{constructor(e,t){super(e,"network_error"),this.originalError=t,this.name="AgoNetworkError"}},m=class extends h{constructor(e,t="stream_error"){super(e,t),this.name="AgoStreamError"}},g=class extends h{constructor(e,t,s){super(e,"function_error"),this.functionName=t,this.originalError=s,this.name="AgoFunctionError"}},$=class{constructor(e=!1){this.enabled=e}enable(){this.enabled=!0}disable(){this.enabled=!1}log(...e){this.enabled&&console.log("[AGO SDK]",...e)}warn(...e){this.enabled&&console.warn("[AGO SDK]",...e)}error(...e){console.error("[AGO SDK]",...e)}debug(...e){this.enabled&&console.debug("[AGO SDK]",...e)}},o=new $,y="ago_widget_id";function x(){if(typeof localStorage<"u"){const t=localStorage.getItem(y);if(t)return t}const e=typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`ago-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,12)}`;if(typeof localStorage<"u")try{localStorage.setItem(y,e)}catch{}return e}var R=class{constructor(e){this.baseUrl=e.baseUrl.replace(/\/$/,""),this.headers={"X-User-Anon-Id":e.widgetId||x()},e.userEmail&&(this.headers["X-User-Email"]=e.userEmail),e.userJwt&&(this.headers.Authorization=`Bearer ${e.userJwt}`),e.permission&&(this.headers["X-Widget-Permission"]=e.permission)}updateConfig(e){e.baseUrl&&(this.baseUrl=e.baseUrl.replace(/\/$/,"")),e.widgetId&&(this.headers["X-User-Anon-Id"]=e.widgetId),e.userEmail&&(this.headers["X-User-Email"]=e.userEmail),e.userJwt&&(this.headers.Authorization=`Bearer ${e.userJwt}`),e.permission!==void 0&&(e.permission?this.headers["X-Widget-Permission"]=e.permission:delete this.headers["X-Widget-Permission"])}async get(e){return this.request("GET",e)}async post(e,t){return this.request("POST",e,t)}async postStream(e,t){const s=`${this.baseUrl}${e}`;o.debug("POST (stream)",s,t);try{const n=await fetch(s,{method:"POST",headers:{...this.headers,"Content-Type":"application/json"},body:t?JSON.stringify(t):void 0});return n.ok||await this.handleErrorResponse(n),n}catch(n){throw n instanceof u?n:new d(`Network error: ${n instanceof Error?n.message:"Unknown error"}. Check that \`baseUrl\` is reachable and includes the protocol (https://).`,n instanceof Error?n:void 0)}}async postFormData(e,t){const s=`${this.baseUrl}${e}`;o.debug("POST (formData)",s);const n={...this.headers};try{const r=await fetch(s,{method:"POST",headers:n,body:t});return r.ok||await this.handleErrorResponse(r),r}catch(r){throw r instanceof u?r:new d(`Network error: ${r instanceof Error?r.message:"Unknown error"}. Check that \`baseUrl\` is reachable and includes the protocol (https://).`,r instanceof Error?r:void 0)}}async request(e,t,s){const n=`${this.baseUrl}${t}`;o.debug(e,n,s);try{const r=await fetch(n,{method:e,headers:{...this.headers,"Content-Type":"application/json"},body:s?JSON.stringify(s):void 0});return r.ok||await this.handleErrorResponse(r),r.status===204?void 0:r.json()}catch(r){throw r instanceof u?r:new d(`Network error: ${r instanceof Error?r.message:"Unknown error"}. Check that \`baseUrl\` is reachable and includes the protocol (https://).`,r instanceof Error?r:void 0)}}async handleErrorResponse(e){let t;try{t=await e.json()}catch{}if(t?.error)throw u.fromResponse(t,e.status);let s="";throw e.status===401||e.status===403?s=" Check `userJwt` (and that it has not expired).":e.status===404&&(s=" Check that `baseUrl` points at your AGO API root."),new u(`HTTP ${e.status}: ${e.statusText}.${s}`,"http_error",e.status,"api_error")}},C=class{constructor(){this.functions=new Map}register(e,t,s){if(typeof e=="object"){const{name:r,handler:i,description:a,parameters:l}=e;return this.register(r,i,{description:a,parameters:l})}const n=e;if(!t||!s)throw new h(`registerFunction("${n}"): both a handler and a schema are required. Pass them as arguments or use the single-object form: registerFunction({ name, parameters, handler }).`,"function_invalid_registration");this.functions.has(n)&&o.warn(`Function "${n}" is being overwritten`),this.functions.set(n,{schema:{...s,name:n},handler:t}),o.log(`Registered function: ${n}`)}unregister(e){const t=this.functions.delete(e);return t&&o.log(`Unregistered function: ${e}`),t}get(e){return this.functions.get(e)}has(e){return this.functions.has(e)}getSchemas(){return Array.from(this.functions.values()).map(e=>e.schema)}async execute(e,t){const s=this.functions.get(e);if(!s)throw new g(`Function "${e}" is not registered`,e);o.log(`Executing function: ${e}`,t);try{const n=await s.handler(t);return o.log(`Function ${e} completed:`,n),n}catch(n){throw o.error(`Function ${e} failed:`,n),new g(`Function "${e}" execution failed: ${n instanceof Error?n.message:"Unknown error"}`,e,n instanceof Error?n:void 0)}}clear(){this.functions.clear(),o.log("Cleared all registered functions")}get size(){return this.functions.size}},E=class{constructor(){this.entries=new Map,this.dynamicProviders=new Map}set(e,t){this.entries.set(e,t),o.log(`ClientContext set: ${e}`)}remove(e){const t=this.entries.delete(e);return t&&o.log(`ClientContext removed: ${e}`),t}addDynamicProvider(e,t){this.dynamicProviders.set(e,t),o.log(`DynamicContext provider added: ${e}`)}removeDynamicProvider(e){const t=this.dynamicProviders.delete(e);return t&&o.log(`DynamicContext provider removed: ${e}`),t}getSnapshot(){if(this.entries.size===0&&this.dynamicProviders.size===0)return null;const e={};for(const[t,s]of this.entries)e[t]=s;for(const[t,s]of this.dynamicProviders)try{const n=s();n&&(e[t]=n)}catch(n){o.error(`DynamicContext provider "${t}" threw:`,n)}return Object.keys(e).length===0?null:{entries:e}}clear(){this.entries.clear(),this.dynamicProviders.clear(),o.log("ClientContext cleared")}};function f(e){return e===null||typeof e!="object"?JSON.stringify(e)??"null":Array.isArray(e)?`[${e.map(f).join(",")}]`:`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${f(e[t])}`).join(",")}}`}var _=class{constructor(e){this.callbacks=e,this.buffer="",this.message={},this.toolCalls=[],this.sources=[],this.followUpReplies=[],this.isFirstChunk=!0,this.answerCompleteEmitted=!1,this.firedClientFunctions=new Set}async processStream(e){if(!e.body)throw new m("Response has no body. The endpoint did not return a stream: check that `baseUrl` points at an AGO API and nothing (proxy, mock) strips the SSE body.","stream_no_body");const t=e.body.getReader(),s=new TextDecoder;try{for(;;){const{done:n,value:r}=await t.read();if(n)break;const i=s.decode(r,{stream:!0});this.buffer+=i,this.processBuffer()}return this.buffer.trim()&&this.processBuffer(),this.buildFinalMessage()}catch(n){const r=n instanceof Error?n:new m("Stream processing failed mid-flight. The connection may have dropped; retry the message.");throw this.callbacks.onError?.(r),r}finally{t.releaseLock()}}processBuffer(){const e=this.buffer.split(`
|
|
2
2
|
|
|
3
3
|
`);this.buffer=e.pop()||"";for(const t of e){if(!t.trim())continue;const s=t.split(`
|
|
4
|
-
`);for(const n of s)if(!n.startsWith(": ")&&n.startsWith("data: ")){const r=n.slice(6);try{const i=JSON.parse(r);this.handleChunk(i)}catch(i){o.warn("Failed to parse SSE data:",r,i)}}}}handleChunk(e){if(this.callbacks.onRawChunk?.(e),e.message_id&&!this.message.id&&(this.message.id=e.message_id),e.thread?.id&&(this.message.conversationId=e.thread.id,this.isFirstChunk&&this.message.id&&(this.isFirstChunk=!1,this.callbacks.onStart?.({conversationId:this.message.conversationId,messageId:this.message.id}))),e.content!==void 0&&(this.message.content=(this.message.content||"")+e.content,this.message.conversationId&&this.message.id&&this.callbacks.onChunk?.({content:e.content,conversationId:this.message.conversationId,messageId:this.message.id})),e.full_content!==void 0&&(this.message.content=e.full_content),e.status&&(this.message.status=e.status),e.agent&&(this.message.agent={id:e.agent.id,name:e.agent.name,displayName:e.agent.display_name}),e.knowledge_sources&&(this.sources=e.knowledge_sources.map(t=>{const s=t.knowledge_document;return{id:s.id,title:s.title,url:s.use_external_link?s.external_link_url:s.internal_link_url}})),e.type==="client_function"&&e.function_name){const t=`${e.function_name}::${f(e.arguments??{})}`;this.firedClientFunctions.has(t)||(this.firedClientFunctions.add(t),this.callbacks.onClientFunction?.({invocationId:e.id||"",functionName:e.function_name,arguments:e.arguments||{},conversationId:this.message.conversationId||""}))}if(e.tool_call_data&&e.type&&e.type!=="client_function"){const t=this.parseToolCall(e);this.callbacks.onToolCall?.(t);const s=this.toolCalls.findIndex(n=>n.id===t.id);s>=0?this.toolCalls[s]=t:this.toolCalls.push(t)}e.follow_up_replies&&(this.followUpReplies=e.follow_up_replies),this.message.status==="DONE"&&!this.answerCompleteEmitted&&this.message.id&&(this.answerCompleteEmitted=!0,this.callbacks.onAnswerComplete?.(this.buildMessage()))}parseToolCall(e){return{id:e.id||"",type:e.type||"status_message",status:e.status||"unknown",toolName:e.tool_name||"",toolDisplayName:e.tool_display_name,message:e.message,formSchema:e.form_schema,data:e.data,functionName:e.function_name,arguments:e.arguments}}buildMessage(){return{id:this.message.id||"",conversationId:this.message.conversationId||"",content:this.message.content||"",role:"assistant",status:this.message.status||"DONE",agent:this.message.agent,sources:this.sources.length>0?this.sources:void 0,toolCalls:this.toolCalls.length>0?this.toolCalls:void 0,followUpReplies:this.followUpReplies.length>0?this.followUpReplies:void 0,createdAt:new Date}}buildFinalMessage(){const e=this.buildMessage();return this.callbacks.onComplete?.(e),e}};function I(e){const t=e.message.toLowerCase();return t.includes("load failed")||t.includes("failed to fetch")||t.includes("network")||t.includes("abort")}var S=class{constructor(){this.handlers=new Map}on(e,t){this.handlers.has(e)||this.handlers.set(e,new Set),this.handlers.get(e).add(t)}off(e,t){const s=this.handlers.get(e);s&&s.delete(t)}emit(e,t){const s=this.handlers.get(e);s&&s.forEach(n=>{try{n(t)}catch(r){console.error(`Error in event handler for ${String(e)}:`,r)}})}once(e,t){const s=(n=>{this.off(e,s),t(n)});this.on(e,s)}waitFor(e,t){return new Promise((s,n)=>{let r;const i=(a=>{r&&clearTimeout(r),s(a)});this.once(e,i),t?.timeout&&(r=setTimeout(()=>{this.off(e,i),n(new Error(`waitFor("${String(e)}") timed out after ${t.timeout}ms`))},t.timeout))})}removeAllListeners(e){e?this.handlers.delete(e):this.handlers.clear()}},w='`baseUrl` is required, e.g. new AgoClient({ baseUrl: "https://YOUR-DOMAIN.api.useago.com" }). Try the live demo endpoint https://playground.api.useago.com. See docs/general/configuration.md#error-codes (config_missing_base_url).',
|
|
4
|
+
`);for(const n of s)if(!n.startsWith(": ")&&n.startsWith("data: ")){const r=n.slice(6);try{const i=JSON.parse(r);this.handleChunk(i)}catch(i){o.warn("Failed to parse SSE data:",r,i)}}}}handleChunk(e){if(this.callbacks.onRawChunk?.(e),e.message_id&&!this.message.id&&(this.message.id=e.message_id),e.thread?.id&&(this.message.conversationId=e.thread.id,this.isFirstChunk&&this.message.id&&(this.isFirstChunk=!1,this.callbacks.onStart?.({conversationId:this.message.conversationId,messageId:this.message.id}))),e.content!==void 0&&(this.message.content=(this.message.content||"")+e.content,this.message.conversationId&&this.message.id&&this.callbacks.onChunk?.({content:e.content,conversationId:this.message.conversationId,messageId:this.message.id})),e.full_content!==void 0&&(this.message.content=e.full_content),e.status&&(this.message.status=e.status),e.agent&&(this.message.agent={id:e.agent.id,name:e.agent.name,displayName:e.agent.display_name}),e.knowledge_sources&&(this.sources=e.knowledge_sources.map(t=>{const s=t.knowledge_document;return{id:s.id,title:s.title,url:s.use_external_link?s.external_link_url:s.internal_link_url}})),e.type==="client_function"&&e.function_name){const t=`${e.function_name}::${f(e.arguments??{})}`;this.firedClientFunctions.has(t)||(this.firedClientFunctions.add(t),this.callbacks.onClientFunction?.({invocationId:e.id||"",functionName:e.function_name,arguments:e.arguments||{},conversationId:this.message.conversationId||""}))}if(e.tool_call_data&&e.type&&e.type!=="client_function"){const t=this.parseToolCall(e);this.callbacks.onToolCall?.(t);const s=this.toolCalls.findIndex(n=>n.id===t.id);s>=0?this.toolCalls[s]=t:this.toolCalls.push(t)}e.follow_up_replies&&(this.followUpReplies=e.follow_up_replies),this.message.status==="DONE"&&!this.answerCompleteEmitted&&this.message.id&&(this.answerCompleteEmitted=!0,this.callbacks.onAnswerComplete?.(this.buildMessage()))}parseToolCall(e){return{id:e.id||"",type:e.type||"status_message",status:e.status||"unknown",toolName:e.tool_name||"",toolDisplayName:e.tool_display_name,message:e.message,formSchema:e.form_schema,data:e.data,functionName:e.function_name,arguments:e.arguments}}buildMessage(){return{id:this.message.id||"",conversationId:this.message.conversationId||"",content:this.message.content||"",role:"assistant",status:this.message.status||"DONE",agent:this.message.agent,sources:this.sources.length>0?this.sources:void 0,toolCalls:this.toolCalls.length>0?this.toolCalls:void 0,followUpReplies:this.followUpReplies.length>0?this.followUpReplies:void 0,createdAt:new Date}}buildFinalMessage(){const e=this.buildMessage();return this.callbacks.onComplete?.(e),e}};function I(e){const t=e.message.toLowerCase();return t.includes("load failed")||t.includes("failed to fetch")||t.includes("network")||t.includes("abort")}var S=class{constructor(){this.handlers=new Map}on(e,t){this.handlers.has(e)||this.handlers.set(e,new Set),this.handlers.get(e).add(t)}off(e,t){const s=this.handlers.get(e);s&&s.delete(t)}emit(e,t){const s=this.handlers.get(e);s&&s.forEach(n=>{try{n(t)}catch(r){console.error(`Error in event handler for ${String(e)}:`,r)}})}once(e,t){const s=(n=>{this.off(e,s),t(n)});this.on(e,s)}waitFor(e,t){return new Promise((s,n)=>{let r;const i=(a=>{r&&clearTimeout(r),s(a)});this.once(e,i),t?.timeout&&(r=setTimeout(()=>{this.off(e,i),n(new Error(`waitFor("${String(e)}") timed out after ${t.timeout}ms`))},t.timeout))})}removeAllListeners(e){e?this.handlers.delete(e):this.handlers.clear()}},w='`baseUrl` is required, e.g. new AgoClient({ baseUrl: "https://YOUR-DOMAIN.api.useago.com" }). Try the live demo endpoint https://playground.api.useago.com. See docs/general/configuration.md#error-codes (config_missing_base_url).',F=/^[a-z][a-z0-9+.-]*:\/\//i,v=!1;function p(e,t="AgoClient"){if(typeof e!="object"||e===null)throw new h(`${t}: ${w}`,"config_missing_base_url");const s=e.baseUrl;if(typeof s!="string"||s.trim()==="")throw new h(`${t}: ${w}`,"config_missing_base_url");!s.startsWith("/")&&!F.test(s)&&(v||(v=!0,console.warn(`[AGO] ${t}: \`baseUrl\` has no protocol and is not a relative path (config_suspect_base_url). Requests will fail: Node throws a URL parse error, browsers fetch it as a relative path. Use "https://..." (or a "/path" for a same-origin proxy).`)))}var U=class k{constructor(t){this.warnedEmptyConversations=new Set,p(t,"AgoClient"),this.config=t,this.httpClient=new R(t),this.functionRegistry=new C,this.contextRegistry=new E,this.eventEmitter=new S,t.debug&&o.enable(),o.log("AgoClient initialized")}async sendMessage(t,s){const n=this.functionRegistry.getSchemas(),r=this.contextRegistry.getSnapshot(),i=this.config.agent||this.config.defaultAgentId,a={content:t,conversation_id:s?.conversationId,agent_id:s?.agentId||i};n.length>0&&(a.client_functions=n),r&&(a.client_context=r);let l;if(s?.files&&s.files.length>0){const c=new FormData;c.append("content",t),s.conversationId&&c.append("conversation_id",s.conversationId),(s.agentId||i)&&c.append("agent_id",s.agentId||i||""),n.length>0&&c.append("client_functions",JSON.stringify(n)),r&&c.append("client_context",JSON.stringify(r));for(const A of s.files)c.append("files",A);l=await this.httpClient.postFormData("/api/sdk/v1/messages",c)}else l=await this.httpClient.postStream("/api/sdk/v1/messages",a);return this.processSSEResponse(l)}async processSSEResponse(t){let s=!1;const n=await new _({onRawChunk:r=>{this.eventEmitter.emit("stream:message",r)},onStart:r=>{this.eventEmitter.emit("message:start",r)},onChunk:r=>{this.eventEmitter.emit("message:chunk",r)},onToolCall:r=>{this.eventEmitter.emit("toolCall:received",r),r.type==="form"&&this.eventEmitter.emit("toolCall:form",r)},onClientFunction:async r=>{s=!0,this.eventEmitter.emit("function:invoke",r),await this.handleClientFunctionInvocation(r)},onAnswerComplete:r=>{this.eventEmitter.emit("message:answer-complete",r)},onComplete:r=>{this.eventEmitter.emit("message:complete",r)},onError:r=>{this.eventEmitter.emit("message:error",{error:r.message,code:r instanceof h?r.code:void 0})}}).processStream(t);return this.maybeFlagEmptyReply(n,s),n}maybeFlagEmptyReply(t,s){t.status==="DONE"&&(t.content??"").trim()===""&&!s&&!(t.toolCalls&&t.toolCalls.length>0)&&!(t.followUpReplies&&t.followUpReplies.length>0)&&setTimeout(()=>{if(this.eventEmitter.emit("message:empty",{conversationId:t.conversationId??"",messageId:t.id??""}),this.config.warnOnEmptyReply===!1)return;const n=t.conversationId||"(no conversation)";if(this.warnedEmptyConversations.has(n))return;this.warnedEmptyConversations.add(n);const r=this.config.agent||this.config.defaultAgentId;t.id?console.warn("[AGO] Reply completed with empty content. Possible causes: "+(r?`the agent "${r}" may not exist for this tenant, `:"an unknown `agent` slug, ")+"or the agent replied with no text. Listen for the `message:empty` event to handle this in your app; silence this warning with `warnOnEmptyReply: false`."):console.warn("[AGO] The stream completed without any message data. Possible causes: "+(r?`the agent "${r}" may not exist for this tenant, or `:"")+"`baseUrl` does not point at an AGO endpoint that returns server-sent events. Listen for the `message:empty` event to handle this in your app; silence this warning with `warnOnEmptyReply: false`.")},0)}async handleClientFunctionInvocation(t){let s,n;try{s=await this.functionRegistry.execute(t.functionName,t.arguments)}catch(r){n=r instanceof Error?r.message:"Unknown error",o.error("Client function execution failed:",r)}if(t.invocationId)try{await this.submitToolCallForm(t.invocationId,{result:s,error:n,_type:"client_function_result"})}catch(r){o.error("Failed to submit function result:",r)}this.eventEmitter.emit("function:result",{invocationId:t.invocationId,result:s,error:n})}async getConversations(){return(await this.httpClient.get("/api/sdk/v1/conversations")).items.map(t=>({id:t.id,title:t.title,lastMessageDate:new Date(t.last_message_date)}))}async getConversation(t){const s=await this.httpClient.get(`/api/sdk/v1/conversations/${t}`),n={id:s.id,title:s.title,lastMessageDate:new Date(s.last_message_date),messages:s.messages.map(r=>({id:r.id,conversationId:s.id,content:r.content,role:r.role,status:r.status,createdAt:new Date(r.created_at),toolCalls:k.mapPersistedToolCalls(r.tool_call_data)}))};return this.eventEmitter.emit("conversation:loaded",n),n}static mapPersistedToolCalls(t){if(!(!t||t.length===0))return t.map(s=>({id:String(s.id??""),type:s.type??"status_message",status:String(s.status??"unknown"),toolName:s.tool_name??"",toolDisplayName:s.tool_display_name,message:s.message,formSchema:s.form_schema,data:s.data,functionName:s.function_name,arguments:s.arguments}))}async getMessages(t){return(await this.getConversation(t)).messages||[]}async submitToolCallForm(t,s){await this.httpClient.post(`/api/sdk/v1/tool-calls/${t}/submit`,{formData:s})}async confirmToolCall(t){await this.httpClient.post(`/api/tool-calls/${t}/confirm/`)}async rejectToolCall(t){await this.httpClient.post(`/api/tool-calls/${t}/reject/`)}async getFormCollector(t){const s=await this.httpClient.get(`/api/sdk/v1/forms/${encodeURIComponent(t)}`);return{name:s.name,description:s.description,schema:s.schema,submit:s.submit??void 0}}async submitFormCollector(t,s){return this.httpClient.post("/api/sdk/v1/forms/submit",{name:t,values:s})}async submitFeedback(t,s){await this.httpClient.post(`/api/sdk/v1/messages/${t}/feedback`,{rating:s})}registerFunction(t,s,n){typeof t=="object"?this.functionRegistry.register(t):this.functionRegistry.register(t,s,n)}register(t){if(Array.isArray(t))for(const s of t)this.functionRegistry.register(s);else this.functionRegistry.register(t)}unregisterFunction(t){return this.functionRegistry.unregister(t)}getRegisteredFunctions(){return this.functionRegistry.getSchemas()}registerNavigationFunction(t,s){const n=s.map(i=>i.name),r=s.map(i=>`- "${i.name}": ${i.description}`).join(`
|
|
5
5
|
`);this.registerFunction("navigateToPage",async i=>{const a=i.page,l=s.find(c=>c.name===a);return l?(t(l.path),{success:!0,navigatedTo:l.path}):{success:!1,error:`Unknown page: ${a}`}},{description:`Navigate the user to a page in the application. Available pages:
|
|
6
|
-
${r}`,parameters:{type:"object",properties:{page:{type:"string",description:"The page to navigate to",enum:n}},required:["page"]}})}setContext(t,s){this.contextRegistry.set(t,s),this.notifyContextChanged()}removeContext(t){const s=this.contextRegistry.remove(t);return s&&this.notifyContextChanged(),s}addDynamicContext(t,s){this.contextRegistry.addDynamicProvider(t,s),this.notifyContextChanged()}removeDynamicContext(t){const s=this.contextRegistry.removeDynamicProvider(t);return s&&this.notifyContextChanged(),s}notifyContextChanged(){this.eventEmitter.emit("context:changed",this.contextRegistry.getSnapshot())}enableAutoPageContext(){this.addDynamicContext("browser-page",()=>{const t=typeof window<"u"?window.location.href:void 0,s=typeof document<"u"?document.title:void 0;return!t&&!s?null:{name:"Browser page",description:"Current page the user is viewing",data:{url:t,title:s}}})}getContextSnapshot(){return this.contextRegistry.getSnapshot()}on(t,s){this.eventEmitter.on(t,s)}off(t,s){this.eventEmitter.off(t,s)}once(t,s){this.eventEmitter.once(t,s)}waitFor(t,s){return this.eventEmitter.waitFor(t,s)}updateConfig(t){const s={};for(const[r,i]of Object.entries(t))i!==void 0&&(s[r]=i);const n={...this.config,...s};p(n,"AgoClient.updateConfig"),this.config=n,this.httpClient.updateConfig(s),s.debug!==void 0&&(s.debug?o.enable():o.disable())}destroy(){this.eventEmitter.removeAllListeners(),this.functionRegistry.clear(),this.contextRegistry.clear(),o.log("AgoClient destroyed")}};Object.defineProperty(exports,"AgoApiError",{enumerable:!0,get:function(){return u}});Object.defineProperty(exports,"AgoClient",{enumerable:!0,get:function(){return
|
|
6
|
+
${r}`,parameters:{type:"object",properties:{page:{type:"string",description:"The page to navigate to",enum:n}},required:["page"]}})}setContext(t,s){this.contextRegistry.set(t,s),this.notifyContextChanged()}removeContext(t){const s=this.contextRegistry.remove(t);return s&&this.notifyContextChanged(),s}addDynamicContext(t,s){this.contextRegistry.addDynamicProvider(t,s),this.notifyContextChanged()}removeDynamicContext(t){const s=this.contextRegistry.removeDynamicProvider(t);return s&&this.notifyContextChanged(),s}notifyContextChanged(){this.eventEmitter.emit("context:changed",this.contextRegistry.getSnapshot())}emitFormEvent(t,s){this.eventEmitter.emit(t,s)}enableAutoPageContext(){this.addDynamicContext("browser-page",()=>{const t=typeof window<"u"?window.location.href:void 0,s=typeof document<"u"?document.title:void 0;return!t&&!s?null:{name:"Browser page",description:"Current page the user is viewing",data:{url:t,title:s}}})}getContextSnapshot(){return this.contextRegistry.getSnapshot()}on(t,s){this.eventEmitter.on(t,s)}off(t,s){this.eventEmitter.off(t,s)}once(t,s){this.eventEmitter.once(t,s)}waitFor(t,s){return this.eventEmitter.waitFor(t,s)}updateConfig(t){const s={};for(const[r,i]of Object.entries(t))i!==void 0&&(s[r]=i);const n={...this.config,...s};p(n,"AgoClient.updateConfig"),this.config=n,this.httpClient.updateConfig(s),s.debug!==void 0&&(s.debug?o.enable():o.disable())}destroy(){this.eventEmitter.removeAllListeners(),this.functionRegistry.clear(),this.contextRegistry.clear(),o.log("AgoClient destroyed")}};Object.defineProperty(exports,"AgoApiError",{enumerable:!0,get:function(){return u}});Object.defineProperty(exports,"AgoClient",{enumerable:!0,get:function(){return U}});Object.defineProperty(exports,"AgoError",{enumerable:!0,get:function(){return h}});Object.defineProperty(exports,"AgoFunctionError",{enumerable:!0,get:function(){return g}});Object.defineProperty(exports,"AgoNetworkError",{enumerable:!0,get:function(){return d}});Object.defineProperty(exports,"AgoStreamError",{enumerable:!0,get:function(){return m}});Object.defineProperty(exports,"ClientContextRegistry",{enumerable:!0,get:function(){return E}});Object.defineProperty(exports,"EventEmitter",{enumerable:!0,get:function(){return S}});Object.defineProperty(exports,"FunctionRegistry",{enumerable:!0,get:function(){return C}});Object.defineProperty(exports,"SSEHandler",{enumerable:!0,get:function(){return _}});Object.defineProperty(exports,"isStreamNetworkError",{enumerable:!0,get:function(){return I}});Object.defineProperty(exports,"logger",{enumerable:!0,get:function(){return o}});Object.defineProperty(exports,"validateConfig",{enumerable:!0,get:function(){return p}});
|
|
@@ -595,6 +595,9 @@ ${i}`,
|
|
|
595
595
|
notifyContextChanged() {
|
|
596
596
|
this.eventEmitter.emit("context:changed", this.contextRegistry.getSnapshot());
|
|
597
597
|
}
|
|
598
|
+
emitFormEvent(t, s) {
|
|
599
|
+
this.eventEmitter.emit(t, s);
|
|
600
|
+
}
|
|
598
601
|
enableAutoPageContext() {
|
|
599
602
|
this.addDynamicContext("browser-page", () => {
|
|
600
603
|
const t = typeof window < "u" ? window.location.href : void 0, s = typeof document < "u" ? document.title : void 0;
|
package/dist/angular.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("./AgoClient
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("./AgoClient-B3-WGVne.cjs");var n=class{constructor(e){this.client=new o.AgoClient(e),this.messages$=this.fromEvent("message:complete"),this.chunks$=this.fromEvent("message:chunk"),this.errors$=this.fromEvent("message:error"),this.messageStart$=this.fromEvent("message:start")}fromEvent(e){const t=this.client;return{subscribe(i){const s=r=>{i.next?.(r)};return t.on(e,s),{unsubscribe:()=>t.off(e,s)}}}}sendMessage(e,t){return this.client.sendMessage(e,t)}getConversations(){return this.client.getConversations()}getConversation(e){return this.client.getConversation(e)}getMessages(e){return this.client.getMessages(e)}submitToolCallForm(e,t){return this.client.submitToolCallForm(e,t)}confirmToolCall(e){return this.client.confirmToolCall(e)}rejectToolCall(e){return this.client.rejectToolCall(e)}submitFeedback(e,t){return this.client.submitFeedback(e,t)}registerFunction(e,t,i){typeof e=="object"?this.client.registerFunction(e):this.client.registerFunction(e,t,i)}unregisterFunction(e){return this.client.unregisterFunction(e)}registerNavigationFunction(e,t){this.client.registerNavigationFunction(e,t)}on(e,t){this.client.on(e,t)}off(e,t){this.client.off(e,t)}updateConfig(e){this.client.updateConfig(e)}getClient(){return this.client}destroy(){this.client.destroy()}};function c(e){return{provide:n,useValue:new n(e)}}exports.AgoService=n;exports.provideAgo=c;
|
package/dist/angular.d.cts
CHANGED
|
@@ -176,6 +176,7 @@ declare class AgoClient {
|
|
|
176
176
|
* call it when their store updates so observers like the dev panel stay live.
|
|
177
177
|
*/
|
|
178
178
|
notifyContextChanged(): void;
|
|
179
|
+
/* Excluded from this release type: emitFormEvent */
|
|
179
180
|
/**
|
|
180
181
|
* Enable automatic capture of the current browser page (URL + title).
|
|
181
182
|
* Injected as a dynamic context entry named `browser-page`.
|
|
@@ -290,6 +291,27 @@ export declare interface AgoClientEvents {
|
|
|
290
291
|
result: unknown;
|
|
291
292
|
error?: string;
|
|
292
293
|
};
|
|
294
|
+
/**
|
|
295
|
+
* A form collector submitted successfully. `result` is the raw submit response
|
|
296
|
+
* (POST body / handler return value / backend relay result) — the third-party
|
|
297
|
+
* API's answer. `values` is the submitted field set, `name` the collector name.
|
|
298
|
+
*/
|
|
299
|
+
"form:submitted": {
|
|
300
|
+
name: string;
|
|
301
|
+
values: Record<string, unknown>;
|
|
302
|
+
result: unknown;
|
|
303
|
+
};
|
|
304
|
+
/**
|
|
305
|
+
* A form collector submit was attempted and failed at the network/server level
|
|
306
|
+
* (HTTP non-2xx, or a thrown handler/fetch). `error` is the message. Validation
|
|
307
|
+
* pre-checks (missing required fields, no submit target) are NOT errors and do
|
|
308
|
+
* not fire this — they are returned to the caller as `{ ok: false }`.
|
|
309
|
+
*/
|
|
310
|
+
"form:error": {
|
|
311
|
+
name: string;
|
|
312
|
+
values: Record<string, unknown>;
|
|
313
|
+
error: string;
|
|
314
|
+
};
|
|
293
315
|
"connection:status": {
|
|
294
316
|
connected: boolean;
|
|
295
317
|
};
|
|
@@ -550,7 +572,7 @@ declare interface FormCollectorDefinition<V = Record<string, unknown>> {
|
|
|
550
572
|
|
|
551
573
|
/**
|
|
552
574
|
* Shape of a form's fields. Mirrors a client function's `parameters` (so the same
|
|
553
|
-
* object feeds the store, the update function, and the dynamic context). Additionally allows the SDK-only per-field `requiredWhen`, which {@link toWireParameters} removes
|
|
575
|
+
* object feeds the store, the update function, and the dynamic context). Additionally allows the SDK-only per-field `requiredWhen`, which {@link toWireParameters} removes from the LLM tool's `parameters` (the full schema still reaches the agent via dynamic context).
|
|
554
576
|
*/
|
|
555
577
|
declare interface FormCollectorSchema {
|
|
556
578
|
type: "object";
|
|
@@ -567,17 +589,32 @@ declare interface FormField {
|
|
|
567
589
|
}
|
|
568
590
|
|
|
569
591
|
/**
|
|
570
|
-
* A field's conditional-requiredness rule
|
|
571
|
-
*
|
|
572
|
-
*
|
|
592
|
+
* A field's conditional-requiredness rule: either a single {@link FormFieldLeafCondition}
|
|
593
|
+
* or a boolean combination of rules. `anyOf` is OR (true when any nested rule
|
|
594
|
+
* holds); `allOf` is AND (true when every nested rule holds). Both nest
|
|
595
|
+
* arbitrarily, so you can mix them, e.g.
|
|
596
|
+
* `{ anyOf: [{ property: "a", op: ">=", value: 1 }, { property: "b", value: "1" }] }`.
|
|
597
|
+
* An empty `anyOf` is never required; an empty `allOf` is always required.
|
|
598
|
+
*
|
|
599
|
+
* Stripped from the LLM tool's `parameters` (see {@link toWireParameters}), but the
|
|
600
|
+
* full schema, `requiredWhen` included, still reaches the agent via the dynamic
|
|
601
|
+
* context so it knows when each field becomes required.
|
|
602
|
+
*/
|
|
603
|
+
declare type FormFieldCondition = FormFieldLeafCondition | {
|
|
604
|
+
anyOf: FormFieldCondition[];
|
|
605
|
+
} | {
|
|
606
|
+
allOf: FormFieldCondition[];
|
|
607
|
+
};
|
|
608
|
+
|
|
609
|
+
/**
|
|
610
|
+
* A single leaf comparison. The field it guards becomes required exactly when the
|
|
611
|
+
* controlling `property` matches `value` against the answers collected so far:
|
|
573
612
|
* - a single `value`, no `op` — equality (compared as strings);
|
|
574
613
|
* - a single `value` with `op` — numeric comparison (both sides coerced to numbers);
|
|
575
614
|
* - an array `value`, no `op` — "one of": matches when the property equals any
|
|
576
615
|
* listed value.
|
|
577
|
-
*
|
|
578
|
-
* SDK-only — it is stripped from the schema before it reaches the LLM tool
|
|
579
616
|
*/
|
|
580
|
-
declare interface
|
|
617
|
+
declare interface FormFieldLeafCondition {
|
|
581
618
|
/** The controlling field whose value the rule tests. */
|
|
582
619
|
property: string;
|
|
583
620
|
/** Comparison operator; omitted means equality. Ignored when `value` is an array. */
|
|
@@ -598,7 +635,8 @@ declare interface FormFieldSchema {
|
|
|
598
635
|
default?: unknown;
|
|
599
636
|
/**
|
|
600
637
|
* Makes the field required only while this condition holds. Drives the dynamic
|
|
601
|
-
* `missing` list; stripped
|
|
638
|
+
* `missing` list; stripped from the LLM tool's `parameters` (still sent to the
|
|
639
|
+
* agent via dynamic context). See {@link toWireParameters}.
|
|
602
640
|
*/
|
|
603
641
|
requiredWhen?: FormFieldCondition;
|
|
604
642
|
}
|
package/dist/angular.d.ts
CHANGED
|
@@ -176,6 +176,7 @@ declare class AgoClient {
|
|
|
176
176
|
* call it when their store updates so observers like the dev panel stay live.
|
|
177
177
|
*/
|
|
178
178
|
notifyContextChanged(): void;
|
|
179
|
+
/* Excluded from this release type: emitFormEvent */
|
|
179
180
|
/**
|
|
180
181
|
* Enable automatic capture of the current browser page (URL + title).
|
|
181
182
|
* Injected as a dynamic context entry named `browser-page`.
|
|
@@ -290,6 +291,27 @@ export declare interface AgoClientEvents {
|
|
|
290
291
|
result: unknown;
|
|
291
292
|
error?: string;
|
|
292
293
|
};
|
|
294
|
+
/**
|
|
295
|
+
* A form collector submitted successfully. `result` is the raw submit response
|
|
296
|
+
* (POST body / handler return value / backend relay result) — the third-party
|
|
297
|
+
* API's answer. `values` is the submitted field set, `name` the collector name.
|
|
298
|
+
*/
|
|
299
|
+
"form:submitted": {
|
|
300
|
+
name: string;
|
|
301
|
+
values: Record<string, unknown>;
|
|
302
|
+
result: unknown;
|
|
303
|
+
};
|
|
304
|
+
/**
|
|
305
|
+
* A form collector submit was attempted and failed at the network/server level
|
|
306
|
+
* (HTTP non-2xx, or a thrown handler/fetch). `error` is the message. Validation
|
|
307
|
+
* pre-checks (missing required fields, no submit target) are NOT errors and do
|
|
308
|
+
* not fire this — they are returned to the caller as `{ ok: false }`.
|
|
309
|
+
*/
|
|
310
|
+
"form:error": {
|
|
311
|
+
name: string;
|
|
312
|
+
values: Record<string, unknown>;
|
|
313
|
+
error: string;
|
|
314
|
+
};
|
|
293
315
|
"connection:status": {
|
|
294
316
|
connected: boolean;
|
|
295
317
|
};
|
|
@@ -550,7 +572,7 @@ declare interface FormCollectorDefinition<V = Record<string, unknown>> {
|
|
|
550
572
|
|
|
551
573
|
/**
|
|
552
574
|
* Shape of a form's fields. Mirrors a client function's `parameters` (so the same
|
|
553
|
-
* object feeds the store, the update function, and the dynamic context). Additionally allows the SDK-only per-field `requiredWhen`, which {@link toWireParameters} removes
|
|
575
|
+
* object feeds the store, the update function, and the dynamic context). Additionally allows the SDK-only per-field `requiredWhen`, which {@link toWireParameters} removes from the LLM tool's `parameters` (the full schema still reaches the agent via dynamic context).
|
|
554
576
|
*/
|
|
555
577
|
declare interface FormCollectorSchema {
|
|
556
578
|
type: "object";
|
|
@@ -567,17 +589,32 @@ declare interface FormField {
|
|
|
567
589
|
}
|
|
568
590
|
|
|
569
591
|
/**
|
|
570
|
-
* A field's conditional-requiredness rule
|
|
571
|
-
*
|
|
572
|
-
*
|
|
592
|
+
* A field's conditional-requiredness rule: either a single {@link FormFieldLeafCondition}
|
|
593
|
+
* or a boolean combination of rules. `anyOf` is OR (true when any nested rule
|
|
594
|
+
* holds); `allOf` is AND (true when every nested rule holds). Both nest
|
|
595
|
+
* arbitrarily, so you can mix them, e.g.
|
|
596
|
+
* `{ anyOf: [{ property: "a", op: ">=", value: 1 }, { property: "b", value: "1" }] }`.
|
|
597
|
+
* An empty `anyOf` is never required; an empty `allOf` is always required.
|
|
598
|
+
*
|
|
599
|
+
* Stripped from the LLM tool's `parameters` (see {@link toWireParameters}), but the
|
|
600
|
+
* full schema, `requiredWhen` included, still reaches the agent via the dynamic
|
|
601
|
+
* context so it knows when each field becomes required.
|
|
602
|
+
*/
|
|
603
|
+
declare type FormFieldCondition = FormFieldLeafCondition | {
|
|
604
|
+
anyOf: FormFieldCondition[];
|
|
605
|
+
} | {
|
|
606
|
+
allOf: FormFieldCondition[];
|
|
607
|
+
};
|
|
608
|
+
|
|
609
|
+
/**
|
|
610
|
+
* A single leaf comparison. The field it guards becomes required exactly when the
|
|
611
|
+
* controlling `property` matches `value` against the answers collected so far:
|
|
573
612
|
* - a single `value`, no `op` — equality (compared as strings);
|
|
574
613
|
* - a single `value` with `op` — numeric comparison (both sides coerced to numbers);
|
|
575
614
|
* - an array `value`, no `op` — "one of": matches when the property equals any
|
|
576
615
|
* listed value.
|
|
577
|
-
*
|
|
578
|
-
* SDK-only — it is stripped from the schema before it reaches the LLM tool
|
|
579
616
|
*/
|
|
580
|
-
declare interface
|
|
617
|
+
declare interface FormFieldLeafCondition {
|
|
581
618
|
/** The controlling field whose value the rule tests. */
|
|
582
619
|
property: string;
|
|
583
620
|
/** Comparison operator; omitted means equality. Ignored when `value` is an array. */
|
|
@@ -598,7 +635,8 @@ declare interface FormFieldSchema {
|
|
|
598
635
|
default?: unknown;
|
|
599
636
|
/**
|
|
600
637
|
* Makes the field required only while this condition holds. Drives the dynamic
|
|
601
|
-
* `missing` list; stripped
|
|
638
|
+
* `missing` list; stripped from the LLM tool's `parameters` (still sent to the
|
|
639
|
+
* agent via dynamic context). See {@link toWireParameters}.
|
|
602
640
|
*/
|
|
603
641
|
requiredWhen?: FormFieldCondition;
|
|
604
642
|
}
|
package/dist/angular.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as o } from "./AgoClient-
|
|
1
|
+
import { t as o } from "./AgoClient-QcTtrN7u.js";
|
|
2
2
|
var n = class {
|
|
3
3
|
constructor(t) {
|
|
4
4
|
this.client = new o(t), this.messages$ = this.fromEvent("message:complete"), this.chunks$ = this.fromEvent("message:chunk"), this.errors$ = this.fromEvent("message:error"), this.messageStart$ = this.fromEvent("message:start");
|
package/dist/{createConversationSession-BuMXp0Ia.cjs → createConversationSession-C0diFTUk.cjs}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
const d=require("./createFormCollector-
|
|
1
|
+
const d=require("./createFormCollector-BI3DXaew.cjs");var f="ago_widget_id",g="ago_last_thread",y=7200*1e3;function v(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const r=Math.floor(Math.random()*16);return(e==="x"?r:r&3|8).toString(16)})}function _(e={}){const r=e.key??f,i=e.threadKey??g,u=e.ttlMs??y,l=e.storage??(typeof localStorage<"u"?localStorage:void 0);let n=e.widgetId??"";if(!n&&l)try{n=l.getItem(r)??""}catch{}if(n||(n=v()),l)try{l.setItem(r,n)}catch{}const o=d.createStore({value:null,lastMessageAt:null},{key:i,storage:l}),c=o.get();c.value!==null&&s(c.lastMessageAt)&&o.set({value:null,lastMessageAt:null});function s(t){return t===null?!0:Number.isFinite(u)?Date.now()-t>u:!1}return{widgetId:n,key:r,getLastActiveThread(){const{value:t,lastMessageAt:a}=o.get();return t===null||s(a)?null:t},setActiveThread(t,a){const x=a==null?null:a instanceof Date?a.getTime():a;o.set({value:t,lastMessageAt:x})},clear(){o.set({value:null,lastMessageAt:null})}}}Object.defineProperty(exports,"createConversationSession",{enumerable:!0,get:function(){return _}});
|
package/dist/{createConversationSession-CCT1hCf8.js → createConversationSession-CR-71aLR.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as d } from "./createFormCollector-
|
|
1
|
+
import { i as d } from "./createFormCollector-CFt1_QSL.js";
|
|
2
2
|
var f = "ago_widget_id", g = "ago_last_thread", y = 7200 * 1e3;
|
|
3
3
|
function v() {
|
|
4
4
|
return typeof crypto < "u" && typeof crypto.randomUUID == "function" ? crypto.randomUUID() : "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (e) => {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const C=require("./AgoClient-B3-WGVne.cjs");function W(n,e){const a=e?e.storage??(typeof localStorage<"u"?localStorage:void 0):void 0;let s=n;if(e&&a)try{const m=a.getItem(e.key);m!=null&&(s=JSON.parse(m))}catch{}const i=new Set,c=()=>i.forEach(m=>m(s));function b(){if(e&&a)try{a.setItem(e.key,JSON.stringify(s))}catch{}}return{get:()=>s,set:m=>{s=m,b(),c()},subscribe:m=>(i.add(m),()=>{i.delete(m)})}}var T=/^[a-zA-Z0-9_-]{1,40}$/,x=n=>n==null||n==="";function v(n,e){if("anyOf"in n)return n.anyOf.some(c=>v(c,e));if("allOf"in n)return n.allOf.every(c=>v(c,e));const a=e[n.property];if(x(a))return!1;if(Array.isArray(n.value))return n.value.some(c=>String(a)===String(c));if(!n.op)return String(a)===String(n.value);const s=Number(a),i=Number(n.value);if(Number.isNaN(s)||Number.isNaN(i))return!1;switch(n.op){case">=":return s>=i;case"<=":return s<=i;case">":return s>i;case"<":return s<i;default:return C.logger.warn(`Unknown requiredWhen op "${n.op}"; treating as not required.`),!1}}function h(n,e){const a=n.properties??{},s=new Set;for(const c of n.required??[]){const b=a[c]?.requiredWhen;(!b||v(b,e))&&s.add(c)}for(const[c,b]of Object.entries(a))b.requiredWhen&&v(b.requiredWhen,e)&&s.add(c);const i=[...s].filter(c=>x(e[c]));return{missing:i,complete:i.length===0}}function R(n){const e={};for(const[a,s]of Object.entries(n.properties??{}))e[a]={type:s.type,...s.description!=null&&{description:s.description},...s.enum&&{enum:s.enum},...s.default!==void 0&&{default:s.default}};return{type:"object",properties:e,required:[]}}function A(n){const{name:e,description:a,schema:s}=n;if(!T.test(e))throw new Error(`Invalid form collector name "${e}": must match ${T} (it becomes the update_/submit_ function names).`);const i=typeof n.submit=="string"?n.submit?{via:"client",url:n.submit}:!1:n.submit??!1;n.autoSubmit===!0&&!i&&C.logger.warn(`FormCollector "${e}": autoSubmit is ignored because no submit target is configured.`);const c=(n.autoSubmit??!0)&&!!i,b=s.properties??{},m=t=>{const r={};for(const[u,o]of Object.entries(t)){const l=b[u];if(l)if(o==null)r[u]=o;else if(l.type==="number"||l.type==="integer"){const d=typeof o=="number"?o:Number(o);r[u]=Number.isNaN(d)?o:d}else l.type==="boolean"?r[u]=typeof o=="boolean"?o:o==="true"?!0:o==="false"?!1:!!o:r[u]=o}return r},S=n.initialValues??{},f=W({values:S,submitted:!1}),$=t=>{const r=f.get(),u={...r,values:{...r.values,...t}};return f.set(u),u};let g=null;const F=(t,r)=>{g?.emitFormEvent("form:error",{name:e,values:t,error:r})};let y=null;const I=async()=>{const{values:t}=f.get(),{complete:r,missing:u}=h(s,t);if(!r)return{ok:!1,missing:u};if(!i)return{ok:!1,error:"No submit target configured for this form collector."};const o=t;try{let l;if(i.via==="client")if("handler"in i)l=await i.handler(o);else{const d=await fetch(i.url,{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify(o)});if(!d.ok){const j=`Submit failed: HTTP ${d.status}`;return F(o,j),{ok:!1,error:j}}l=await d.json().catch(()=>{})}else{if(!g)return{ok:!1,error:"Backend submit requires install(client) (or useFormCollector) first."};l=await g.submitFormCollector(e,o)}return f.set({...f.get(),submitted:!0,submitResult:l}),g?.emitFormEvent("form:submitted",{name:e,values:o,result:l}),{ok:!0,result:l}}catch(l){const d=l instanceof Error?l.message:"Submit failed";return C.logger.error(`FormCollector "${e}" submit failed:`,l),F(o,d),{ok:!1,error:d}}},N=()=>y||(y=(async()=>{try{return await I()}finally{y=null}})(),y),k=async()=>{if(!c||!i)return null;const{values:t,submitted:r}=f.get();return r||!h(s,t).complete?null:N()},O={name:`update_${e}`,description:`Fill or update fields of the "${e}" form. ${a} Pass any subset of fields; call it repeatedly to fill the form as the user provides information. Returns the current values and which required fields are still missing.`,parameters:R(s),handler:async t=>{const r=$(m(t)),{missing:u}=h(s,r.values),o=await k();return o?o.ok?{ok:!0,values:r.values,missing:u,submitted:!0}:{ok:!0,values:r.values,missing:u,submitted:!1,submitError:o.error}:{ok:!0,values:r.values,missing:u}}},p=[O];i&&!c&&p.push({name:`submit_${e}`,description:`Submit the completed "${e}" form. Only call this once every required field is collected and the user has confirmed. If fields are missing it returns them instead of submitting.`,parameters:{type:"object",properties:{}},handler:()=>N()});const V="client__",q=i?`submit_${e}`:null,J=t=>{const r=t.functionName??t.toolName;if(r)return r.startsWith(V)?r.slice(8):r},_=t=>{let r={...S},u=!1;for(const o of t){const l=J(o);l===O.name?o.arguments&&(r={...r,...m(o.arguments)}):q&&l===q&&o.status?.toLowerCase()==="done"&&(u=!0)}f.set({values:r,submitted:u})},w=`form:${e}`,E=()=>{const{values:t,submitted:r}=f.get(),{missing:u,complete:o}=h(s,t),l=i?c?" The form is submitted automatically as soon as every required field is filled, so there is no submit function to call.":` When nothing is missing and the user confirms, call submit_${e}.`:"",d=r?`The "${e}" form has been submitted.`:`You are currently collecting information from the user to fill the "${e}" form.`;return{name:`Form: ${e}`,description:`${d} ${a} Some fields are conditionally required; the requiredWhen field in the schema tells you when each becomes required. The form schema is the following: ${JSON.stringify(s)}. Data collected so far: ${JSON.stringify(t)}. Call update_${e} with any fields the user provides; ask only for what is still missing.${l}`,data:{values:t,missing:u,complete:o,submitted:r}}},P=t=>{_((t.messages??[]).flatMap(r=>r.toolCalls??[]))};return{name:e,store:f,functions:p,contextKey:w,contextProvider:E,install:t=>{g=t;for(const u of p)t.register(u);t.addDynamicContext(w,E);const r=f.subscribe(()=>t.notifyContextChanged());return t.on("conversation:loaded",P),()=>{r();for(const u of p)t.unregisterFunction(u.name);t.removeDynamicContext(w),t.off("conversation:loaded",P),g===t&&(g=null)}},hydrate:_,submit:N,getValues:()=>f.get().values,setValues:t=>{$(m(t)),k()},reset:()=>{f.set({values:S,submitted:!1})},getStatus:()=>h(s,f.get().values)}}async function B(n,e){const a=await n.getFormCollector(e.name);return A({name:a.name,description:e.description??a.description,schema:e.schema??a.schema,submit:e.submit??a.submit,initialValues:e.initialValues,autoSubmit:e.autoSubmit??a.autoSubmit})}Object.defineProperty(exports,"createFormCollector",{enumerable:!0,get:function(){return A}});Object.defineProperty(exports,"createStore",{enumerable:!0,get:function(){return W}});Object.defineProperty(exports,"deriveFormStatus",{enumerable:!0,get:function(){return h}});Object.defineProperty(exports,"loadFormCollector",{enumerable:!0,get:function(){return B}});
|