@useago/sdk 1.0.0 → 1.0.1
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 +103 -74
- package/dist/{AgoClient-CPqPT5s6.cjs → AgoClient-0x2Du_62.cjs} +1 -1
- package/dist/{AgoClient-BrYhSO5M.js → AgoClient-CZYNL25R.js} +29 -20
- package/dist/angular.cjs +1 -1
- package/dist/angular.d.cts +89 -0
- package/dist/angular.d.ts +89 -0
- package/dist/angular.js +1 -1
- package/dist/{createConversationSession-CGRO0bs2.cjs → createConversationSession-BLZvXMmM.cjs} +1 -1
- package/dist/{createConversationSession-Dmqd80DX.js → createConversationSession-Bmqj2rSS.js} +1 -1
- package/dist/createFormCollector-Bk0DRhUf.js +257 -0
- package/dist/createFormCollector-Ca8wRrxc.cjs +1 -0
- package/dist/devtools.d.cts +89 -0
- package/dist/devtools.d.ts +89 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +47 -0
- package/dist/index.d.ts +47 -0
- package/dist/index.js +68 -67
- package/dist/react.cjs +23 -23
- package/dist/react.d.cts +74 -23
- package/dist/react.d.ts +74 -23
- package/dist/react.js +2154 -2075
- package/dist/testing.d.cts +89 -0
- package/dist/testing.d.ts +89 -0
- package/dist/vue.cjs +1 -1
- package/dist/vue.d.cts +89 -0
- package/dist/vue.d.ts +89 -0
- package/dist/vue.js +1 -1
- package/dist/widget.cjs +4 -4
- package/dist/widget.d.cts +73 -4
- package/dist/widget.d.ts +73 -4
- package/dist/widget.js +410 -317
- package/package.json +1 -1
- package/dist/createFormCollector-CPS2phYq.js +0 -245
- package/dist/createFormCollector-DaWZsBsI.cjs +0 -1
package/README.md
CHANGED
|
@@ -1,97 +1,115 @@
|
|
|
1
1
|
# @useago/sdk
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@useago/sdk)
|
|
4
|
-
[](./LICENSE)
|
|
5
4
|
[](https://www.npmjs.com/package/@useago/sdk)
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
about what the user is doing.
|
|
6
|
+
**The agent layer for your frontend stack.** AGO's agents plug into React, Vue,
|
|
7
|
+
Angular or plain TypeScript like any other dependency: send a message, stream
|
|
8
|
+
the reply, and let the agent call **your** code and navigate **your** UI.
|
|
11
9
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
same
|
|
10
|
+
In two minutes you'll have a working chat on your page and an agent that can
|
|
11
|
+
navigate your app. The quickstart below uses **React**; every other stack gets
|
|
12
|
+
the same two steps through its own guide:
|
|
13
|
+
|
|
14
|
+
| Stack | Guide |
|
|
15
|
+
| --- | --- |
|
|
16
|
+
| <img src="https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/react/react-original.svg" width="14" /> React | **you're reading it**, just scroll down |
|
|
17
|
+
| <img src="https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/vuejs/vuejs-original.svg" width="14" /> Vue 3 | [Vue guide](docs/frameworks/vue.md) |
|
|
18
|
+
| <img src="https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/angular/angular-original.svg" width="14" /> Angular | [Angular guide](docs/frameworks/angular.md) |
|
|
19
|
+
| <img src="https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/typescript/typescript-original.svg" width="14" /> Plain JavaScript / TypeScript | [Core guide](docs/general/core.md) |
|
|
20
|
+
| <img src="https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/html5/html5-original.svg" width="14" /> Any website, no build step (`<script>`) | [Widget guide](docs/general/widget.md) |
|
|
21
|
+
|
|
22
|
+
## <img src="https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/react/react-original.svg" width="22" /> Try it in 30 seconds
|
|
15
23
|
|
|
16
24
|
```bash
|
|
17
25
|
npm install @useago/sdk
|
|
18
26
|
```
|
|
19
27
|
|
|
20
|
-
|
|
21
|
-
|
|
28
|
+
The SDK has no framework dependency of its own. The React bindings need `react`
|
|
29
|
+
and `react-dom` (>=17): already there in an existing React app, otherwise
|
|
30
|
+
install them too.
|
|
31
|
+
|
|
32
|
+
```tsx
|
|
33
|
+
// App.tsx
|
|
34
|
+
import { AgoProvider, ChatWidget } from "@useago/sdk/react";
|
|
35
|
+
|
|
36
|
+
export default function App() {
|
|
37
|
+
return (
|
|
38
|
+
<AgoProvider baseUrl="https://ago.api.useago.com" agent="generic-guide">
|
|
39
|
+
<ChatWidget title="AGO" welcomeMessage="Ask me anything!" height={500} />
|
|
40
|
+
</AgoProvider>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
```
|
|
22
44
|
|
|
23
|
-
|
|
45
|
+
Start your dev server. A chat panel renders on the page; type a message and
|
|
46
|
+
watch the reply stream in. That's a complete integration. (`generic-guide` is a
|
|
47
|
+
public demo agent; swap `baseUrl` and `agent` for your own once you have a tenant.)
|
|
24
48
|
|
|
25
|
-
##
|
|
49
|
+
## Let the agent drive your existing routes
|
|
26
50
|
|
|
27
|
-
|
|
51
|
+
This is the part existing apps care about. You already have a router and pages;
|
|
52
|
+
describe them to the agent and *"show me my invoices"* actually navigates there.
|
|
53
|
+
One hook in the layout you already have, nothing to restructure:
|
|
28
54
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
| React | [docs/frameworks/react.md](docs/frameworks/react.md) |
|
|
33
|
-
| Vue 3 | [docs/frameworks/vue.md](docs/frameworks/vue.md) |
|
|
34
|
-
| Angular | [docs/frameworks/angular.md](docs/frameworks/angular.md) |
|
|
35
|
-
| Embeddable widget (`<script>`) | [docs/general/widget.md](docs/general/widget.md) |
|
|
55
|
+
```tsx
|
|
56
|
+
import { Outlet, useNavigate } from "react-router-dom";
|
|
57
|
+
import { useAgoNavigation } from "@useago/sdk/react";
|
|
36
58
|
|
|
37
|
-
|
|
59
|
+
// Your existing layout component. Only the hook is new.
|
|
60
|
+
function AppLayout() {
|
|
61
|
+
const navigate = useNavigate();
|
|
38
62
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
63
|
+
useAgoNavigation(navigate, [
|
|
64
|
+
{ name: "dashboard", path: "/dashboard", description: "KPIs and recent activity" },
|
|
65
|
+
{ name: "invoices", path: "/invoices", description: "List, search and download invoices" },
|
|
66
|
+
{ name: "settings", path: "/settings", description: "Account, billing and team settings" },
|
|
67
|
+
]);
|
|
44
68
|
|
|
45
|
-
|
|
69
|
+
return <Outlet />; // your existing routes render as before
|
|
70
|
+
}
|
|
71
|
+
```
|
|
46
72
|
|
|
47
|
-
|
|
48
|
-
|
|
73
|
+
Each route needs a `name`, its existing `path`, and a `description` the agent
|
|
74
|
+
uses to pick the right page. It calls **your** `navigate` function, so route
|
|
75
|
+
guards, auth and layouts keep working exactly as they do today.
|
|
76
|
+
`react-router-dom` here is *your* router, not an SDK dependency:
|
|
77
|
+
`useAgoNavigation` accepts any `(path: string) => void` function.
|
|
49
78
|
|
|
50
|
-
|
|
79
|
+
**Next: the [Getting started guide](docs/general/getting-started.md)** has both
|
|
80
|
+
examples assembled into a running app, plus everything else the SDK can do, in
|
|
81
|
+
about 5 minutes.
|
|
51
82
|
|
|
52
|
-
|
|
83
|
+
## Or clone a running example
|
|
53
84
|
|
|
54
|
-
|
|
55
|
-
|
|
85
|
+
```bash
|
|
86
|
+
git clone https://github.com/useago/ago-sdk.git
|
|
87
|
+
cd ago-sdk && npm install && npm run build # build the SDK once
|
|
88
|
+
cd examples/simple-react
|
|
89
|
+
npm install && npm run dev
|
|
56
90
|
```
|
|
57
91
|
|
|
92
|
+
The examples ship pre-configured against the demo backend, so they answer
|
|
93
|
+
immediately. [`examples/`](examples/) has one per stack: React (with
|
|
94
|
+
react-router navigation), Vue, Angular, plain TypeScript, and no-build HTML.
|
|
95
|
+
|
|
58
96
|
---
|
|
59
97
|
|
|
60
|
-
##
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
| Send message (streaming) | ✅ | ✅ `useChat`/`useMessages` | ✅ `useChat`/`useMessages` | ✅ `AgoService.sendMessage` |
|
|
71
|
-
| File attachments | ✅ | ✅ | ✅ | ✅ |
|
|
72
|
-
| List / load conversations | ✅ | ✅ `useConversation` | ✅ `useConversation` | ✅ `AgoService` |
|
|
73
|
-
| All-in-one chat state | — | ✅ `useChat` | ✅ `useChat` | ➖ compose manually |
|
|
74
|
-
| Pre-built `<ChatWidget>` UI | — | ✅ | ➖ see example | — |
|
|
75
|
-
| Markdown / `<Message>` / `<ChatInput>` | — | ✅ | — | — |
|
|
76
|
-
| Client-side functions | ✅ `registerFunction` | ✅ `useAgoFunction` | ✅ `useAgoFunction` | ✅ `AgoService` |
|
|
77
|
-
| `defineFunction` / `withHandler` | ✅ | ✅ | ✅ | ✅ |
|
|
78
|
-
| Pre-built helpers (`showToast`, …) | ✅ | ✅ `helpers` prop | ✅ | ✅ |
|
|
79
|
-
| Navigation function | ✅ `registerNavigationFunction` | ✅ `useAgoNavigation` | ✅ `useAgoNavigation` | ✅ `AgoService` |
|
|
80
|
-
| Client context | ✅ `setContext` / `addDynamicContext` | ✅ `useAgoContext` | ✅ core API | ✅ core API |
|
|
81
|
-
| Auto page context | ✅ `enableAutoPageContext()` | ✅ `pageContext="auto"` | ✅ core API | ✅ core API |
|
|
82
|
-
| Events (`on`/`off`/`once`/`waitFor`) | ✅ | ✅ (via client) | ✅ `useAgoEvents` | ✅ `messages$` Observables |
|
|
83
|
-
| Streaming helpers / async generator | ✅ | ✅ | ✅ | ✅ |
|
|
84
|
-
| Tool calls (form/confirm/reject) | ✅ | ✅ | ✅ | ✅ `AgoService` |
|
|
85
|
-
| Message feedback | ✅ `submitFeedback` | ✅ | ✅ | ✅ `AgoService` |
|
|
86
|
-
| Observable store | ✅ `createStore` | ✅ `useAgoStore` | ✅ `useAgoStore` | ➖ core API |
|
|
87
|
-
| Dev panel / devtools | ✅ `initDevPanel` (`/devtools`) | ✅ | ✅ | ✅ |
|
|
88
|
-
| Testing mock client | ✅ `createMockClient` | ✅ | ✅ | ✅ |
|
|
89
|
-
|
|
90
|
-
Legend: ✅ first-class binding · ➖ supported via the core API, no dedicated sugar · — not applicable.
|
|
98
|
+
## Docs
|
|
99
|
+
|
|
100
|
+
- [**Getting started**](docs/general/getting-started.md): send a message, wire the router, see the feature map
|
|
101
|
+
- [**Feature matrix**](docs/general/feature-matrix.md): everything that ships, per stack
|
|
102
|
+
- [**Functions & context**](docs/general/functions-and-context.md): let the agent run your code and see what the user sees
|
|
103
|
+
- [**Events & streaming**](docs/general/events-and-streaming.md): low-level hooks into the message stream
|
|
104
|
+
- [**Testing**](docs/general/testing.md): mock client for unit tests
|
|
105
|
+
- [**Configuration & auth**](docs/general/configuration.md): every `AgoConfig` option, headers, errors
|
|
106
|
+
|
|
107
|
+
Full documentation: [ago.mintlify.app](https://ago.mintlify.app/)
|
|
91
108
|
|
|
92
109
|
---
|
|
93
110
|
|
|
94
|
-
|
|
111
|
+
<details>
|
|
112
|
+
<summary><strong>Package entry points</strong> (subpath exports)</summary>
|
|
95
113
|
|
|
96
114
|
The package is published with several subpath exports so bundlers only pull in
|
|
97
115
|
what you use:
|
|
@@ -104,20 +122,31 @@ what you use:
|
|
|
104
122
|
| `@useago/sdk/angular` | Angular service and provider |
|
|
105
123
|
| `@useago/sdk/helpers` | Pre-built client functions only |
|
|
106
124
|
| `@useago/sdk/widget` | `window.AGO` widget config types |
|
|
107
|
-
| `@useago/sdk/devtools` | `initDevPanel
|
|
108
|
-
| `@useago/sdk/testing` | `createMockClient
|
|
125
|
+
| `@useago/sdk/devtools` | `initDevPanel`, an in-browser debug overlay (DOM/CSS) |
|
|
126
|
+
| `@useago/sdk/testing` | `createMockClient`, a mock client for tests |
|
|
109
127
|
|
|
110
128
|
ESM and CJS builds are both shipped, with full TypeScript declarations.
|
|
111
129
|
|
|
112
|
-
|
|
130
|
+
</details>
|
|
113
131
|
|
|
114
|
-
##
|
|
132
|
+
## Dependencies
|
|
115
133
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
134
|
+
The core SDK depends on nothing but the platform: `fetch` and `ReadableStream`,
|
|
135
|
+
so any modern browser or Node 18+. Framework packages are **optional peer
|
|
136
|
+
dependencies**; you only need the one whose bindings you import:
|
|
137
|
+
|
|
138
|
+
| You import | Needs | Notes |
|
|
139
|
+
| --- | --- | --- |
|
|
140
|
+
| `@useago/sdk` (core, widget, helpers, testing) | nothing | works everywhere |
|
|
141
|
+
| `@useago/sdk/react` | `react` + `react-dom` `>=17` | already present in any React app |
|
|
142
|
+
| `@useago/sdk/vue` | `vue` `>=3.3` | already present in any Vue 3 app |
|
|
143
|
+
| `@useago/sdk/angular` | nothing | no hard Angular dependency, works with any DI container |
|
|
144
|
+
|
|
145
|
+
Your router (`react-router-dom`, `vue-router`, Angular Router) is **never** an
|
|
146
|
+
SDK dependency: the navigation helpers just take your navigate function.
|
|
147
|
+
|
|
148
|
+
---
|
|
120
149
|
|
|
121
150
|
## License
|
|
122
151
|
|
|
123
|
-
[Apache 2.0](./LICENSE) · [Documentation](https://
|
|
152
|
+
[Apache 2.0](./LICENSE) · [Documentation](https://ago.mintlify.app/) · [Website](https://useago.com)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
var u=class extends Error{constructor(e,t,s){super(e),this.code=t,this.statusCode=s,this.name="AgoError"}},h=class p extends u{constructor(t,s,r,n,o,a){super(t,s,r),this.type=n,this.param=o,this.docUrl=a,this.name="AgoApiError"}static fromResponse(t,s){const r=t.error;return new p(r.message,r.code,s,r.type,r.param,r.doc_url)}},d=class extends u{constructor(e,t){super(e,"network_error"),this.originalError=t,this.name="AgoNetworkError"}},g=class extends u{constructor(e){super(e,"stream_error"),this.name="AgoStreamError"}},m=class extends u{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)}},i=new _,f="ago_widget_id";function S(){if(typeof localStorage<"u"){const t=localStorage.getItem(f);if(t)return t}const e=crypto.randomUUID();if(typeof localStorage<"u")try{localStorage.setItem(f,e)}catch{}return e}var k=class{constructor(e){this.baseUrl=e.baseUrl.replace(/\/$/,""),this.headers={"X-Widget-Id":e.widgetId||S()},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-Widget-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}`;i.debug("POST (stream)",s,t);try{const r=await fetch(s,{method:"POST",headers:{...this.headers,"Content-Type":"application/json"},body:t?JSON.stringify(t):void 0});return r.ok||await this.handleErrorResponse(r),r}catch(r){throw r instanceof h?r:new d(`Network error: ${r instanceof Error?r.message:"Unknown error"}`,r instanceof Error?r:void 0)}}async postFormData(e,t){const s=`${this.baseUrl}${e}`;i.debug("POST (formData)",s);const r={...this.headers};try{const n=await fetch(s,{method:"POST",headers:r,body:t});return n.ok||await this.handleErrorResponse(n),n}catch(n){throw n instanceof h?n:new d(`Network error: ${n instanceof Error?n.message:"Unknown error"}`,n instanceof Error?n:void 0)}}async request(e,t,s){const r=`${this.baseUrl}${t}`;i.debug(e,r,s);try{const n=await fetch(r,{method:e,headers:{...this.headers,"Content-Type":"application/json"},body:s?JSON.stringify(s):void 0});return n.ok||await this.handleErrorResponse(n),n.status===204?void 0:n.json()}catch(n){throw n instanceof h?n:new d(`Network error: ${n instanceof Error?n.message:"Unknown error"}`,n instanceof Error?n:void 0)}}async handleErrorResponse(e){let t;try{t=await e.json()}catch{}throw t?.error?h.fromResponse(t,e.status):new h(`HTTP ${e.status}: ${e.statusText}`,"http_error",e.status,"api_error")}},y=class{constructor(){this.functions=new Map}register(e,t,s){if(typeof e=="object"){const{name:n,handler:o,description:a,parameters:c}=e;return this.register(n,o,{description:a,parameters:c})}const r=e;if(!t||!s)throw new Error("handler and schema are required");this.functions.has(r)&&i.warn(`Function "${r}" is being overwritten`),this.functions.set(r,{schema:{...s,name:r},handler:t}),i.log(`Registered function: ${r}`)}unregister(e){const t=this.functions.delete(e);return t&&i.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 m(`Function "${e}" is not registered`,e);i.log(`Executing function: ${e}`,t);try{const r=await s.handler(t);return i.log(`Function ${e} completed:`,r),r}catch(r){throw i.error(`Function ${e} failed:`,r),new m(`Function "${e}" execution failed: ${r instanceof Error?r.message:"Unknown error"}`,e,r instanceof Error?r:void 0)}}clear(){this.functions.clear(),i.log("Cleared all registered functions")}get size(){return this.functions.size}},w=class{constructor(){this.entries=new Map,this.dynamicProviders=new Map}set(e,t){this.entries.set(e,t),i.log(`ClientContext set: ${e}`)}remove(e){const t=this.entries.delete(e);return t&&i.log(`ClientContext removed: ${e}`),t}addDynamicProvider(e,t){this.dynamicProviders.set(e,t),i.log(`DynamicContext provider added: ${e}`)}removeDynamicProvider(e){const t=this.dynamicProviders.delete(e);return t&&i.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 r=s();r&&(e[t]=r)}catch(r){i.error(`DynamicContext provider "${t}" threw:`,r)}return Object.keys(e).length===0?null:{entries:e}}clear(){this.entries.clear(),this.dynamicProviders.clear(),i.log("ClientContext cleared")}},v=class{constructor(e){this.callbacks=e,this.buffer="",this.message={},this.toolCalls=[],this.sources=[],this.followUpReplies=[],this.isFirstChunk=!0,this.answerCompleteEmitted=!1}async processStream(e){if(!e.body)throw new g("Response has no body");const t=e.body.getReader(),s=new TextDecoder;try{for(;;){const{done:r,value:n}=await t.read();if(r)break;const o=s.decode(n,{stream:!0});this.buffer+=o,this.processBuffer()}return this.buffer.trim()&&this.processBuffer(),this.buildFinalMessage()}catch(r){const n=r instanceof Error?r:new g("Stream processing failed");throw this.callbacks.onError?.(n),n}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 r of s)if(!r.startsWith(": ")&&r.startsWith("data: ")){const n=r.slice(6);try{const o=JSON.parse(n);this.handleChunk(o)}catch(o){i.warn("Failed to parse SSE data:",n,o)}}}}handleChunk(e){if(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&&this.callbacks.onClientFunction?.({invocationId:e.id||"",functionName:e.function_name,arguments:e.arguments||{},conversationId:this.message.conversationId||""}),e.tool_call_data&&e.type&&e.type!=="client_function"){const t=this.parseToolCall(e);this.callbacks.onToolCall?.(t);const s=this.toolCalls.findIndex(r=>r.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 x(e){const t=e.message.toLowerCase();return t.includes("load failed")||t.includes("failed to fetch")||t.includes("network")||t.includes("abort")}var C=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(r=>{try{r(t)}catch(n){console.error(`Error in event handler for ${String(e)}:`,n)}})}once(e,t){const s=(r=>{this.off(e,s),t(r)});this.on(e,s)}waitFor(e,t){return new Promise((s,r)=>{let n;const o=(a=>{n&&clearTimeout(n),s(a)});this.once(e,o),t?.timeout&&(n=setTimeout(()=>{this.off(e,o),r(new Error(`waitFor("${String(e)}") timed out after ${t.timeout}ms`))},t.timeout))})}removeAllListeners(e){e?this.handlers.delete(e):this.handlers.clear()}},A=class b{constructor(t){this.config=t,this.httpClient=new k(t),this.functionRegistry=new y,this.contextRegistry=new w,this.eventEmitter=new C,t.debug&&i.enable(),i.log("AgoClient initialized")}async sendMessage(t,s){const r=this.functionRegistry.getSchemas(),n=this.contextRegistry.getSnapshot(),o=this.config.agent||this.config.defaultAgentId,a={content:t,conversation_id:s?.conversationId,agent_id:s?.agentId||o};r.length>0&&(a.client_functions=r),n&&(a.client_context=n);let c;if(s?.files&&s.files.length>0){const l=new FormData;l.append("content",t),s.conversationId&&l.append("conversation_id",s.conversationId),(s.agentId||o)&&l.append("agent_id",s.agentId||o||""),r.length>0&&l.append("client_functions",JSON.stringify(r)),n&&l.append("client_context",JSON.stringify(n));for(const E of s.files)l.append("files",E);c=await this.httpClient.postFormData("/api/sdk/v1/messages",l)}else c=await this.httpClient.postStream("/api/sdk/v1/messages",a);return this.processSSEResponse(c)}async processSSEResponse(t){return new v({onStart:s=>{this.eventEmitter.emit("message:start",s)},onChunk:s=>{this.eventEmitter.emit("message:chunk",s)},onToolCall:s=>{this.eventEmitter.emit("toolCall:received",s),s.type==="form"&&this.eventEmitter.emit("toolCall:form",s)},onClientFunction:async s=>{this.eventEmitter.emit("function:invoke",s),await this.handleClientFunctionInvocation(s)},onAnswerComplete:s=>{this.eventEmitter.emit("message:answer-complete",s)},onComplete:s=>{this.eventEmitter.emit("message:complete",s)},onError:s=>{this.eventEmitter.emit("message:error",{error:s.message})}}).processStream(t)}async handleClientFunctionInvocation(t){let s,r;try{s=await this.functionRegistry.execute(t.functionName,t.arguments)}catch(n){r=n instanceof Error?n.message:"Unknown error",i.error("Client function execution failed:",n)}if(t.invocationId)try{await this.submitToolCallForm(t.invocationId,{result:s,error:r,_type:"client_function_result"})}catch(n){i.error("Failed to submit function result:",n)}this.eventEmitter.emit("function:result",{invocationId:t.invocationId,result:s,error:r})}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}`),r={id:s.id,title:s.title,lastMessageDate:new Date(s.last_message_date),messages:s.messages.map(n=>({id:n.id,conversationId:s.id,content:n.content,role:n.role,status:n.status,createdAt:new Date(n.created_at),toolCalls:b.mapPersistedToolCalls(n.tool_call_data)}))};return this.eventEmitter.emit("conversation:loaded",r),r}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 submitFormCollector(t,s){return this.httpClient.post("/api/sdk/v1/forms/submit",{destination:t,values:s})}async submitFeedback(t,s){await this.httpClient.post(`/api/sdk/v1/messages/${t}/feedback`,{rating:s})}registerFunction(t,s,r){typeof t=="object"?this.functionRegistry.register(t):this.functionRegistry.register(t,s,r)}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 r=s.map(o=>o.name),n=s.map(o=>`- "${o.name}": ${o.description}`).join(`
|
|
4
|
+
`);for(const r of s)if(!r.startsWith(": ")&&r.startsWith("data: ")){const n=r.slice(6);try{const o=JSON.parse(n);this.handleChunk(o)}catch(o){i.warn("Failed to parse SSE data:",n,o)}}}}handleChunk(e){if(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&&this.callbacks.onClientFunction?.({invocationId:e.id||"",functionName:e.function_name,arguments:e.arguments||{},conversationId:this.message.conversationId||""}),e.tool_call_data&&e.type&&e.type!=="client_function"){const t=this.parseToolCall(e);this.callbacks.onToolCall?.(t);const s=this.toolCalls.findIndex(r=>r.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 x(e){const t=e.message.toLowerCase();return t.includes("load failed")||t.includes("failed to fetch")||t.includes("network")||t.includes("abort")}var C=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(r=>{try{r(t)}catch(n){console.error(`Error in event handler for ${String(e)}:`,n)}})}once(e,t){const s=(r=>{this.off(e,s),t(r)});this.on(e,s)}waitFor(e,t){return new Promise((s,r)=>{let n;const o=(a=>{n&&clearTimeout(n),s(a)});this.once(e,o),t?.timeout&&(n=setTimeout(()=>{this.off(e,o),r(new Error(`waitFor("${String(e)}") timed out after ${t.timeout}ms`))},t.timeout))})}removeAllListeners(e){e?this.handlers.delete(e):this.handlers.clear()}},A=class b{constructor(t){this.config=t,this.httpClient=new k(t),this.functionRegistry=new y,this.contextRegistry=new w,this.eventEmitter=new C,t.debug&&i.enable(),i.log("AgoClient initialized")}async sendMessage(t,s){const r=this.functionRegistry.getSchemas(),n=this.contextRegistry.getSnapshot(),o=this.config.agent||this.config.defaultAgentId,a={content:t,conversation_id:s?.conversationId,agent_id:s?.agentId||o};r.length>0&&(a.client_functions=r),n&&(a.client_context=n);let c;if(s?.files&&s.files.length>0){const l=new FormData;l.append("content",t),s.conversationId&&l.append("conversation_id",s.conversationId),(s.agentId||o)&&l.append("agent_id",s.agentId||o||""),r.length>0&&l.append("client_functions",JSON.stringify(r)),n&&l.append("client_context",JSON.stringify(n));for(const E of s.files)l.append("files",E);c=await this.httpClient.postFormData("/api/sdk/v1/messages",l)}else c=await this.httpClient.postStream("/api/sdk/v1/messages",a);return this.processSSEResponse(c)}async processSSEResponse(t){return new v({onStart:s=>{this.eventEmitter.emit("message:start",s)},onChunk:s=>{this.eventEmitter.emit("message:chunk",s)},onToolCall:s=>{this.eventEmitter.emit("toolCall:received",s),s.type==="form"&&this.eventEmitter.emit("toolCall:form",s)},onClientFunction:async s=>{this.eventEmitter.emit("function:invoke",s),await this.handleClientFunctionInvocation(s)},onAnswerComplete:s=>{this.eventEmitter.emit("message:answer-complete",s)},onComplete:s=>{this.eventEmitter.emit("message:complete",s)},onError:s=>{this.eventEmitter.emit("message:error",{error:s.message})}}).processStream(t)}async handleClientFunctionInvocation(t){let s,r;try{s=await this.functionRegistry.execute(t.functionName,t.arguments)}catch(n){r=n instanceof Error?n.message:"Unknown error",i.error("Client function execution failed:",n)}if(t.invocationId)try{await this.submitToolCallForm(t.invocationId,{result:s,error:r,_type:"client_function_result"})}catch(n){i.error("Failed to submit function result:",n)}this.eventEmitter.emit("function:result",{invocationId:t.invocationId,result:s,error:r})}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}`),r={id:s.id,title:s.title,lastMessageDate:new Date(s.last_message_date),messages:s.messages.map(n=>({id:n.id,conversationId:s.id,content:n.content,role:n.role,status:n.status,createdAt:new Date(n.created_at),toolCalls:b.mapPersistedToolCalls(n.tool_call_data)}))};return this.eventEmitter.emit("conversation:loaded",r),r}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",{destination:t,values:s})}async submitFeedback(t,s){await this.httpClient.post(`/api/sdk/v1/messages/${t}/feedback`,{rating:s})}registerFunction(t,s,r){typeof t=="object"?this.functionRegistry.register(t):this.functionRegistry.register(t,s,r)}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 r=s.map(o=>o.name),n=s.map(o=>`- "${o.name}": ${o.description}`).join(`
|
|
5
5
|
`);this.registerFunction("navigateToPage",async o=>{const a=o.page,c=s.find(l=>l.name===a);return c?(t(c.path),{success:!0,navigatedTo:c.path}):{success:!1,error:`Unknown page: ${a}`}},{description:`Navigate the user to a page in the application. Available pages:
|
|
6
6
|
${n}`,parameters:{type:"object",properties:{page:{type:"string",description:"The page to navigate to",enum:r}},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){this.config={...this.config,...t},this.httpClient.updateConfig(t),t.debug!==void 0&&(t.debug?i.enable():i.disable())}destroy(){this.eventEmitter.removeAllListeners(),this.functionRegistry.clear(),this.contextRegistry.clear(),i.log("AgoClient destroyed")}};Object.defineProperty(exports,"AgoApiError",{enumerable:!0,get:function(){return h}});Object.defineProperty(exports,"AgoClient",{enumerable:!0,get:function(){return A}});Object.defineProperty(exports,"AgoError",{enumerable:!0,get:function(){return u}});Object.defineProperty(exports,"AgoFunctionError",{enumerable:!0,get:function(){return m}});Object.defineProperty(exports,"AgoNetworkError",{enumerable:!0,get:function(){return d}});Object.defineProperty(exports,"AgoStreamError",{enumerable:!0,get:function(){return g}});Object.defineProperty(exports,"ClientContextRegistry",{enumerable:!0,get:function(){return w}});Object.defineProperty(exports,"EventEmitter",{enumerable:!0,get:function(){return C}});Object.defineProperty(exports,"FunctionRegistry",{enumerable:!0,get:function(){return y}});Object.defineProperty(exports,"SSEHandler",{enumerable:!0,get:function(){return v}});Object.defineProperty(exports,"isStreamNetworkError",{enumerable:!0,get:function(){return x}});Object.defineProperty(exports,"logger",{enumerable:!0,get:function(){return i}});
|
|
@@ -14,11 +14,11 @@ var d = class extends Error {
|
|
|
14
14
|
constructor(e, t) {
|
|
15
15
|
super(e, "network_error"), this.originalError = t, this.name = "AgoNetworkError";
|
|
16
16
|
}
|
|
17
|
-
},
|
|
17
|
+
}, m = class extends d {
|
|
18
18
|
constructor(e) {
|
|
19
19
|
super(e, "stream_error"), this.name = "AgoStreamError";
|
|
20
20
|
}
|
|
21
|
-
},
|
|
21
|
+
}, g = class extends d {
|
|
22
22
|
constructor(e, t, s) {
|
|
23
23
|
super(e, "function_error"), this.functionName = t, this.originalError = s, this.name = "AgoFunctionError";
|
|
24
24
|
}
|
|
@@ -133,10 +133,10 @@ var E = class {
|
|
|
133
133
|
}
|
|
134
134
|
register(e, t, s) {
|
|
135
135
|
if (typeof e == "object") {
|
|
136
|
-
const { name: i, handler: o, description: a, parameters:
|
|
136
|
+
const { name: i, handler: o, description: a, parameters: c } = e;
|
|
137
137
|
return this.register(i, o, {
|
|
138
138
|
description: a,
|
|
139
|
-
parameters:
|
|
139
|
+
parameters: c
|
|
140
140
|
});
|
|
141
141
|
}
|
|
142
142
|
const r = e;
|
|
@@ -164,13 +164,13 @@ var E = class {
|
|
|
164
164
|
}
|
|
165
165
|
async execute(e, t) {
|
|
166
166
|
const s = this.functions.get(e);
|
|
167
|
-
if (!s) throw new
|
|
167
|
+
if (!s) throw new g(`Function "${e}" is not registered`, e);
|
|
168
168
|
n.log(`Executing function: ${e}`, t);
|
|
169
169
|
try {
|
|
170
170
|
const r = await s.handler(t);
|
|
171
171
|
return n.log(`Function ${e} completed:`, r), r;
|
|
172
172
|
} catch (r) {
|
|
173
|
-
throw n.error(`Function ${e} failed:`, r), new
|
|
173
|
+
throw n.error(`Function ${e} failed:`, r), new g(`Function "${e}" execution failed: ${r instanceof Error ? r.message : "Unknown error"}`, e, r instanceof Error ? r : void 0);
|
|
174
174
|
}
|
|
175
175
|
}
|
|
176
176
|
clear() {
|
|
@@ -217,7 +217,7 @@ var E = class {
|
|
|
217
217
|
this.callbacks = e, this.buffer = "", this.message = {}, this.toolCalls = [], this.sources = [], this.followUpReplies = [], this.isFirstChunk = !0, this.answerCompleteEmitted = !1;
|
|
218
218
|
}
|
|
219
219
|
async processStream(e) {
|
|
220
|
-
if (!e.body) throw new
|
|
220
|
+
if (!e.body) throw new m("Response has no body");
|
|
221
221
|
const t = e.body.getReader(), s = new TextDecoder();
|
|
222
222
|
try {
|
|
223
223
|
for (; ; ) {
|
|
@@ -228,7 +228,7 @@ var E = class {
|
|
|
228
228
|
}
|
|
229
229
|
return this.buffer.trim() && this.processBuffer(), this.buildFinalMessage();
|
|
230
230
|
} catch (r) {
|
|
231
|
-
const i = r instanceof Error ? r : new
|
|
231
|
+
const i = r instanceof Error ? r : new m("Stream processing failed");
|
|
232
232
|
throw this.callbacks.onError?.(i), i;
|
|
233
233
|
} finally {
|
|
234
234
|
t.releaseLock();
|
|
@@ -376,14 +376,14 @@ var S = class {
|
|
|
376
376
|
agent_id: s?.agentId || o
|
|
377
377
|
};
|
|
378
378
|
r.length > 0 && (a.client_functions = r), i && (a.client_context = i);
|
|
379
|
-
let
|
|
379
|
+
let c;
|
|
380
380
|
if (s?.files && s.files.length > 0) {
|
|
381
|
-
const
|
|
382
|
-
|
|
383
|
-
for (const v of s.files)
|
|
384
|
-
|
|
385
|
-
} else
|
|
386
|
-
return this.processSSEResponse(
|
|
381
|
+
const l = new FormData();
|
|
382
|
+
l.append("content", t), s.conversationId && l.append("conversation_id", s.conversationId), (s.agentId || o) && l.append("agent_id", s.agentId || o || ""), r.length > 0 && l.append("client_functions", JSON.stringify(r)), i && l.append("client_context", JSON.stringify(i));
|
|
383
|
+
for (const v of s.files) l.append("files", v);
|
|
384
|
+
c = await this.httpClient.postFormData("/api/sdk/v1/messages", l);
|
|
385
|
+
} else c = await this.httpClient.postStream("/api/sdk/v1/messages", a);
|
|
386
|
+
return this.processSSEResponse(c);
|
|
387
387
|
}
|
|
388
388
|
async processSSEResponse(t) {
|
|
389
389
|
return new k({
|
|
@@ -483,6 +483,15 @@ var S = class {
|
|
|
483
483
|
async rejectToolCall(t) {
|
|
484
484
|
await this.httpClient.post(`/api/tool-calls/${t}/reject/`);
|
|
485
485
|
}
|
|
486
|
+
async getFormCollector(t) {
|
|
487
|
+
const s = await this.httpClient.get(`/api/sdk/v1/forms/${encodeURIComponent(t)}`);
|
|
488
|
+
return {
|
|
489
|
+
name: s.name,
|
|
490
|
+
description: s.description,
|
|
491
|
+
schema: s.schema,
|
|
492
|
+
submit: s.submit ?? void 0
|
|
493
|
+
};
|
|
494
|
+
}
|
|
486
495
|
async submitFormCollector(t, s) {
|
|
487
496
|
return this.httpClient.post("/api/sdk/v1/forms/submit", {
|
|
488
497
|
destination: t,
|
|
@@ -509,10 +518,10 @@ var S = class {
|
|
|
509
518
|
const r = s.map((o) => o.name), i = s.map((o) => `- "${o.name}": ${o.description}`).join(`
|
|
510
519
|
`);
|
|
511
520
|
this.registerFunction("navigateToPage", async (o) => {
|
|
512
|
-
const a = o.page,
|
|
513
|
-
return
|
|
521
|
+
const a = o.page, c = s.find((l) => l.name === a);
|
|
522
|
+
return c ? (t(c.path), {
|
|
514
523
|
success: !0,
|
|
515
|
-
navigatedTo:
|
|
524
|
+
navigatedTo: c.path
|
|
516
525
|
}) : {
|
|
517
526
|
success: !1,
|
|
518
527
|
error: `Unknown page: ${a}`
|
|
@@ -590,7 +599,7 @@ export {
|
|
|
590
599
|
_ as a,
|
|
591
600
|
h as c,
|
|
592
601
|
u as d,
|
|
593
|
-
|
|
602
|
+
m as f,
|
|
594
603
|
x as i,
|
|
595
604
|
d as l,
|
|
596
605
|
S as n,
|
|
@@ -598,5 +607,5 @@ export {
|
|
|
598
607
|
k as r,
|
|
599
608
|
n as s,
|
|
600
609
|
$ as t,
|
|
601
|
-
|
|
610
|
+
g as u
|
|
602
611
|
};
|
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-0x2Du_62.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
|
@@ -53,6 +53,13 @@ declare class AgoClient {
|
|
|
53
53
|
* Reject a tool call
|
|
54
54
|
*/
|
|
55
55
|
rejectToolCall(toolCallId: string): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Fetch a backend-stored form collector definition by name (the single source
|
|
58
|
+
* of truth for the form's description, schema, and submit target). Used by
|
|
59
|
+
* `loadFormCollector` / the name-only form of `useFormCollector` so the schema
|
|
60
|
+
* lives in the backend instead of being hardcoded in client code.
|
|
61
|
+
*/
|
|
62
|
+
getFormCollector(name: string): Promise<FormCollectorDefinition>;
|
|
56
63
|
/**
|
|
57
64
|
* Relay a completed form collector's values to a server-configured destination.
|
|
58
65
|
*
|
|
@@ -477,6 +484,30 @@ export declare interface Conversation {
|
|
|
477
484
|
*/
|
|
478
485
|
declare type DynamicContextProvider = () => ContextEntry | null | undefined;
|
|
479
486
|
|
|
487
|
+
/**
|
|
488
|
+
* The backend-stored shape returned by `GET /api/sdk/v1/forms/{name}` (see
|
|
489
|
+
* {@link AgoClient.getFormCollector}). Mirrors the persistable subset of
|
|
490
|
+
* {@link CreateFormCollectorOptions}: the `submit` here is never the client-only
|
|
491
|
+
* `handler` variant (a function can't be stored server-side).
|
|
492
|
+
*/
|
|
493
|
+
declare interface FormCollectorDefinition<V = Record<string, unknown>> {
|
|
494
|
+
name: string;
|
|
495
|
+
description: string;
|
|
496
|
+
schema: FormCollectorSchema;
|
|
497
|
+
/** Server-stored submit target, if any. Absent means collect-only. */
|
|
498
|
+
submit?: SubmitConfig<V>;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* Shape of a form's fields. Mirrors a client function's `parameters` (so the same
|
|
503
|
+
* object feeds the store, the update function, and the dynamic context). Additionally allows the SDK-only per-field `requiredWhen`, which {@link toWireParameters} removes before the schema reaches the LLM.
|
|
504
|
+
*/
|
|
505
|
+
declare interface FormCollectorSchema {
|
|
506
|
+
type: "object";
|
|
507
|
+
properties: Record<string, FormFieldSchema>;
|
|
508
|
+
required?: string[];
|
|
509
|
+
}
|
|
510
|
+
|
|
480
511
|
declare interface FormField {
|
|
481
512
|
type: "string" | "number" | "boolean" | "array";
|
|
482
513
|
title?: string;
|
|
@@ -485,6 +516,43 @@ declare interface FormField {
|
|
|
485
516
|
default?: unknown;
|
|
486
517
|
}
|
|
487
518
|
|
|
519
|
+
/**
|
|
520
|
+
* A field's conditional-requiredness rule. The field becomes required exactly
|
|
521
|
+
* when the controlling `property` matches `value` against the answers collected
|
|
522
|
+
* so far:
|
|
523
|
+
* - a single `value`, no `op` — equality (compared as strings);
|
|
524
|
+
* - a single `value` with `op` — numeric comparison (both sides coerced to numbers);
|
|
525
|
+
* - an array `value`, no `op` — "one of": matches when the property equals any
|
|
526
|
+
* listed value.
|
|
527
|
+
*
|
|
528
|
+
* SDK-only — it is stripped from the schema before it reaches the LLM tool
|
|
529
|
+
*/
|
|
530
|
+
declare interface FormFieldCondition {
|
|
531
|
+
/** The controlling field whose value the rule tests. */
|
|
532
|
+
property: string;
|
|
533
|
+
/** Comparison operator; omitted means equality. Ignored when `value` is an array. */
|
|
534
|
+
op?: ">=" | "<=" | ">" | "<";
|
|
535
|
+
/**
|
|
536
|
+
* The value(s) to test the controlling field against. A single value is an
|
|
537
|
+
* equality (or, with `op`, a numeric comparison); an array is an "is one of"
|
|
538
|
+
* membership test, e.g. `value: ["1", "2", "3"]`.
|
|
539
|
+
*/
|
|
540
|
+
value: string | number | Array<string | number>;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
/** A single field's schema: the wire-legal keys plus the SDK-only `requiredWhen`. */
|
|
544
|
+
declare interface FormFieldSchema {
|
|
545
|
+
type: string;
|
|
546
|
+
description?: string;
|
|
547
|
+
enum?: string[];
|
|
548
|
+
default?: unknown;
|
|
549
|
+
/**
|
|
550
|
+
* Makes the field required only while this condition holds. Drives the dynamic
|
|
551
|
+
* `missing` list; stripped before the LLM tool — see {@link toWireParameters}.
|
|
552
|
+
*/
|
|
553
|
+
requiredWhen?: FormFieldCondition;
|
|
554
|
+
}
|
|
555
|
+
|
|
488
556
|
/**
|
|
489
557
|
* Form schema for tool calls requiring user input
|
|
490
558
|
*/
|
|
@@ -541,6 +609,27 @@ declare interface SendMessageOptions {
|
|
|
541
609
|
files?: File[];
|
|
542
610
|
}
|
|
543
611
|
|
|
612
|
+
/**
|
|
613
|
+
* Where a completed form is sent.
|
|
614
|
+
* - `"https://..."` (a bare string) — shorthand for `{ via: "client", url }`: the browser
|
|
615
|
+
* POSTs the values to that URL.
|
|
616
|
+
* - `{ via: "client", url }` — same, written out.
|
|
617
|
+
* - `{ via: "client", handler }` — the browser runs your own submit logic.
|
|
618
|
+
* - `{ via: "backend", destination }` — the browser relays the values to the backend,
|
|
619
|
+
* which forwards them to the server-configured destination (URL + secret stay server-side).
|
|
620
|
+
* - `false` — collect only, no submit function.
|
|
621
|
+
*/
|
|
622
|
+
declare type SubmitConfig<V = Record<string, unknown>> = string | {
|
|
623
|
+
via: "client";
|
|
624
|
+
url: string;
|
|
625
|
+
} | {
|
|
626
|
+
via: "client";
|
|
627
|
+
handler: (values: V) => Promise<unknown> | unknown;
|
|
628
|
+
} | {
|
|
629
|
+
via: "backend";
|
|
630
|
+
destination: string;
|
|
631
|
+
} | false;
|
|
632
|
+
|
|
544
633
|
/**
|
|
545
634
|
* Tool call data from SSE stream
|
|
546
635
|
*/
|