@watermarkinsights/ai-toolbox 0.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 ADDED
@@ -0,0 +1,5 @@
1
+ # @watermarkinsights/ai-toolbox
2
+
3
+ React component SDK for embedding Watermark AI Toolbox features into your application. Provides pre-built components for authentication and chat interfaces that connect to the AI Toolbox platform.
4
+
5
+ For installation and usage instructions, see the [documentation](https://ds-ai-api-dev.watermarkinsights.com/toolbox/sdk/docs/).
@@ -0,0 +1,112 @@
1
+ import { JSX } from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+ import { RunAgentResult } from '@copilotkit/react-core/v2';
4
+ import * as z from 'zod/mini';
5
+
6
+ declare type FileAttachment = File | FileAttachmentUrl;
7
+
8
+ declare type FileAttachmentUrl = {
9
+ url: string;
10
+ name: string;
11
+ mimeType: string;
12
+ };
13
+
14
+ declare type SendMessageOptions = {
15
+ files?: FileAttachment[];
16
+ };
17
+
18
+ declare const TOOLBOX_CHAT_SCHEMA: z.ZodMiniObject<{
19
+ product: z.ZodMiniString<string>;
20
+ sessionUrl: z.ZodMiniUnion<readonly [z.ZodMiniURL, z.ZodMiniCustom<() => Promise<{
21
+ sessionId: string;
22
+ institutionId: string;
23
+ }>, () => Promise<{
24
+ sessionId: string;
25
+ institutionId: string;
26
+ }>>]>;
27
+ fallback: z.ZodMiniOptional<z.ZodMiniCustom<ReactNode, ReactNode>>;
28
+ featureId: z.ZodMiniString<string>;
29
+ toolboxBaseUrl: z.ZodMiniOptional<z.ZodMiniURL>;
30
+ children: z.ZodMiniCustom<ReactNode, ReactNode>;
31
+ }, z.core.$strip>;
32
+
33
+ export declare const ToolboxChat: (props: ToolboxChatProps) => JSX.Element;
34
+
35
+ declare type ToolboxChatProps = z.infer<typeof TOOLBOX_CHAT_SCHEMA>;
36
+
37
+ export declare const useAgent: () => {
38
+ sendMessage: (message: string, options?: SendMessageOptions) => Promise<RunAgentResult>;
39
+ isRunning: boolean;
40
+ messages: ({
41
+ role: "developer";
42
+ content: string;
43
+ id: string;
44
+ name?: string | undefined;
45
+ encryptedValue?: string | undefined;
46
+ } | {
47
+ role: "system";
48
+ content: string;
49
+ id: string;
50
+ name?: string | undefined;
51
+ encryptedValue?: string | undefined;
52
+ } | {
53
+ role: "assistant";
54
+ id: string;
55
+ content?: string | undefined;
56
+ name?: string | undefined;
57
+ encryptedValue?: string | undefined;
58
+ toolCalls?: {
59
+ function: {
60
+ name: string;
61
+ arguments: string;
62
+ };
63
+ type: "function";
64
+ id: string;
65
+ encryptedValue?: string | undefined;
66
+ }[] | undefined;
67
+ } | {
68
+ role: "user";
69
+ content: string | ({
70
+ type: "text";
71
+ text: string;
72
+ } | {
73
+ type: "binary";
74
+ mimeType: string;
75
+ id?: string | undefined;
76
+ url?: string | undefined;
77
+ data?: string | undefined;
78
+ filename?: string | undefined;
79
+ })[];
80
+ id: string;
81
+ name?: string | undefined;
82
+ encryptedValue?: string | undefined;
83
+ } | {
84
+ role: "tool";
85
+ toolCallId: string;
86
+ content: string;
87
+ id: string;
88
+ encryptedValue?: string | undefined;
89
+ error?: string | undefined;
90
+ } | {
91
+ role: "activity";
92
+ content: Record<string, any>;
93
+ id: string;
94
+ activityType: string;
95
+ } | {
96
+ role: "reasoning";
97
+ content: string;
98
+ id: string;
99
+ encryptedValue?: string | undefined;
100
+ })[];
101
+ };
102
+
103
+ export declare function useLatestToolCall<T = unknown>(toolName: string): T | undefined;
104
+
105
+ export declare function useToolCall<T = unknown>(toolName: string): T[];
106
+
107
+ export declare const useToolResponse: (toolName: string) => {
108
+ isWaiting: boolean;
109
+ respond: (response: unknown) => void;
110
+ };
111
+
112
+ export { }
@@ -0,0 +1,276 @@
1
+ import { CopilotKit as e, useCopilotContext as t } from "@copilotkit/react-core";
2
+ import { createContext as n, useCallback as r, useContext as i, useEffect as a, useMemo as o, useReducer as s, useRef as c, useState as l } from "react";
3
+ import * as u from "zod/mini";
4
+ import { z as d } from "zod/mini";
5
+ import { jsx as f, jsxs as p } from "react/jsx-runtime";
6
+ import { useAgent as m, useCopilotKit as h } from "@copilotkit/react-core/v2";
7
+ import { parse as g } from "partial-json";
8
+ //#region src/utilities/constants.ts
9
+ var _ = "https://ai-toolbox-qa.watermarkinsights.com", v = n(void 0), y = () => {
10
+ let e = i(v);
11
+ if (!e) throw Error("useAuth must be used in an <Auth/> component");
12
+ return e;
13
+ }, b = async ({ sessionId: e, institutionId: t, product: n, toolboxBaseUrl: r }) => {
14
+ let i = `${r}/api/session/cookie`, a = await fetch(i, {
15
+ method: "POST",
16
+ headers: { "Content-Type": "application/json" },
17
+ credentials: "include",
18
+ body: JSON.stringify({
19
+ sessionId: e,
20
+ product: n,
21
+ institutionId: t
22
+ })
23
+ });
24
+ if (!a.ok) {
25
+ let e = await a.json().catch(() => ({ message: "Unknown error" }));
26
+ throw a.status === 400 ? Error(`Invalid session ID: ${e.message}`) : a.status === 404 ? Error(`Session not found: ${e.message}`) : Error(`Failed to set session cookie: ${e.message}`);
27
+ }
28
+ return a.json();
29
+ }, x = async (e) => {
30
+ let t = await fetch(e, {
31
+ method: "POST",
32
+ headers: {
33
+ Accept: "application/json",
34
+ "Content-Type": "application/json"
35
+ },
36
+ credentials: "include"
37
+ });
38
+ if (!t.ok) throw Error(`Failed to get toolbox session. Endpoint ${e} returned status ${t.status}.`);
39
+ let n;
40
+ try {
41
+ n = await t.json();
42
+ } catch (t) {
43
+ throw Error(`Could not parse JSON for toolbox session. Requested from ${e}`, { cause: t });
44
+ }
45
+ if (!n.sessionId || typeof n.sessionId != "string") throw Error(`Invalid sessionId received from ${e}. Received ${n.sessionId}`);
46
+ if (!n.institutionId || typeof n.institutionId != "string") throw Error(`Invalid institution received from ${e}. Received ${n.institutionId}`);
47
+ let { sessionId: r, institutionId: i } = n;
48
+ return {
49
+ sessionId: r,
50
+ institutionId: i
51
+ };
52
+ }, S = async (e) => {
53
+ if (typeof e == "function") {
54
+ let t = await e();
55
+ if (!t.sessionId || typeof t.sessionId != "string") throw Error(`Invalid sessionId returned from sessionUrl function. Received ${t.sessionId}`);
56
+ if (!t.institutionId || typeof t.institutionId != "string") throw Error(`Invalid institution returned from sessionUrl function. Received ${t.institutionId}`);
57
+ return {
58
+ sessionId: t.sessionId,
59
+ institutionId: t.institutionId
60
+ };
61
+ }
62
+ try {
63
+ new URL(e);
64
+ } catch (t) {
65
+ throw Error(`sessionUrl is not a valid url: ${e}`, { cause: t });
66
+ }
67
+ return x(e);
68
+ }, C = d.object({
69
+ product: d.string(),
70
+ sessionUrl: d.union([d.url(), d.custom((e) => typeof e == "function")]),
71
+ children: d.custom(),
72
+ fallback: d.optional(d.custom()),
73
+ toolboxBaseUrl: d.optional(d.url())
74
+ }), w = {}, T = (e) => {
75
+ let { product: t, sessionUrl: n, fallback: r, children: s, toolboxBaseUrl: u = _ } = d.parse(C, e), [p, m] = l(null), h = i(v), g = c(n);
76
+ a(() => {
77
+ g.current = n;
78
+ }, [n]);
79
+ let y = o(() => p ?? h, [h, p]);
80
+ return a(() => {
81
+ if (y) return;
82
+ let e = !1, n = g.current, r = u, i = `${t}-${typeof n == "string" ? n : "function"}-${r}`;
83
+ return w[i] || (w[i] = S(n).then(({ sessionId: e, institutionId: n }) => (b({
84
+ sessionId: e,
85
+ institutionId: n,
86
+ product: t,
87
+ toolboxBaseUrl: r
88
+ }), {
89
+ sessionId: e,
90
+ institutionId: n
91
+ }))), w[i].then((t) => {
92
+ e || m(t);
93
+ }), () => {
94
+ e = !0;
95
+ };
96
+ }, [
97
+ t,
98
+ y,
99
+ u
100
+ ]), h ? s : y ? /* @__PURE__ */ f(v.Provider, {
101
+ value: y,
102
+ children: s
103
+ }) : r ?? null;
104
+ }, E = "on_interrupt";
105
+ function D(e, t) {
106
+ switch (t.type) {
107
+ case "SET_INTERRUPT": return e.interruptedTool === null || e.interruptedTool.name === t.payload.name ? { interruptedTool: t.payload } : (console.error(`ToolboxInterruptProvider: Received interrupt for tool "${t.payload.name}" but tool "${e.interruptedTool.name}" is already interrupted. Ignoring.`), e);
108
+ case "CLEAR_INTERRUPT": return { interruptedTool: null };
109
+ default: return e;
110
+ }
111
+ }
112
+ var O = n({
113
+ interruptedTool: null,
114
+ dispatch: () => {}
115
+ });
116
+ function k({ children: e }) {
117
+ let [t, n] = s(D, { interruptedTool: null }), { agent: r } = m();
118
+ return a(() => {
119
+ let { unsubscribe: e } = r.subscribe({
120
+ onCustomEvent: ({ event: e }) => {
121
+ let t = e.value;
122
+ e.name === E && n({
123
+ type: "SET_INTERRUPT",
124
+ payload: {
125
+ name: t.tool,
126
+ value: t.toolArgs
127
+ }
128
+ });
129
+ },
130
+ onRunStartedEvent: () => {
131
+ n({ type: "CLEAR_INTERRUPT" });
132
+ },
133
+ onRunFailed: () => {
134
+ n({ type: "CLEAR_INTERRUPT" });
135
+ }
136
+ });
137
+ return () => {
138
+ e();
139
+ };
140
+ }, [r]), /* @__PURE__ */ f(O.Provider, {
141
+ value: {
142
+ interruptedTool: t.interruptedTool,
143
+ dispatch: n
144
+ },
145
+ children: e
146
+ });
147
+ }
148
+ var A = (e) => {
149
+ let { interruptedTool: n, dispatch: a } = i(O), { copilotkit: s } = h(), { copilotApiConfig: c } = t(), { agent: l } = m(), u = n?.name === e, d = r((e) => {
150
+ a({ type: "CLEAR_INTERRUPT" }), s.runAgent({
151
+ agent: l,
152
+ forwardedProps: { command: { resume: JSON.stringify({
153
+ response: e,
154
+ properties: c.properties ?? {}
155
+ }) } }
156
+ });
157
+ }, [
158
+ l,
159
+ c.properties,
160
+ s,
161
+ a
162
+ ]);
163
+ return o(() => ({
164
+ isWaiting: u,
165
+ respond: d
166
+ }), [u, d]);
167
+ }, j = u.object({
168
+ featureId: u.string({ error: "invalid feature id" }),
169
+ toolboxBaseUrl: u.optional(u.url()),
170
+ children: u.custom(),
171
+ ...u.pick(C, {
172
+ product: !0,
173
+ sessionUrl: !0,
174
+ fallback: !0
175
+ }).shape
176
+ }), M = (e) => {
177
+ let { product: t, sessionUrl: n, fallback: r, featureId: i, children: a, toolboxBaseUrl: o = _ } = u.parse(j, e);
178
+ return /* @__PURE__ */ f(T, {
179
+ product: t,
180
+ sessionUrl: n,
181
+ fallback: r,
182
+ toolboxBaseUrl: o,
183
+ children: /* @__PURE__ */ f(N, {
184
+ featureId: i,
185
+ runtimeUrl: `${o}/api/feature/chat`,
186
+ children: a
187
+ })
188
+ });
189
+ }, N = ({ featureId: t, runtimeUrl: n, children: r }) => {
190
+ let { institutionId: i, sessionId: a } = y();
191
+ return /* @__PURE__ */ p(e, {
192
+ agent: "default",
193
+ showDevConsole: !1,
194
+ runtimeUrl: n,
195
+ properties: {
196
+ featureId: t,
197
+ username: "toolbox-user",
198
+ sessionId: a,
199
+ institutionId: i
200
+ },
201
+ children: [/* @__PURE__ */ f("style", { children: "cpk-web-inspector {\n display: none !important;\n }" }), /* @__PURE__ */ f(k, { children: r })]
202
+ });
203
+ };
204
+ //#endregion
205
+ //#region src/hooks/use-tool-call.ts
206
+ function P(e) {
207
+ let { agent: t } = m();
208
+ return o(() => {
209
+ let n = t.messages ?? [], r = [];
210
+ for (let t = 0; t < n.length; t++) {
211
+ let i = n[t];
212
+ if (i.role !== "assistant" || !i.toolCalls) continue;
213
+ let a = t === n.length - 1;
214
+ for (let t of i.toolCalls) {
215
+ if (t.function?.name !== e) continue;
216
+ let n = t.function.arguments;
217
+ if (n) try {
218
+ let e = a ? g(n) : JSON.parse(n);
219
+ r.push(e);
220
+ } catch {}
221
+ }
222
+ }
223
+ return r;
224
+ }, [t.messages, e]);
225
+ }
226
+ //#endregion
227
+ //#region src/hooks/use-latest-tool-call.ts
228
+ function F(e) {
229
+ let t = P(e);
230
+ return t[t.length - 1];
231
+ }
232
+ //#endregion
233
+ //#region src/hooks/use-agent.ts
234
+ var I = () => {
235
+ let { agent: e } = m(), { copilotkit: t } = h(), n = r(async (n, r) => {
236
+ let i = r?.files ?? [], a;
237
+ if (i.length === 0) a = n;
238
+ else {
239
+ let e = [];
240
+ for (let t of i) if (t instanceof File) {
241
+ let n = await t.arrayBuffer(), r = new Uint8Array(n).reduce((e, t) => e + String.fromCharCode(t), ""), i = btoa(r);
242
+ e.push({
243
+ type: "binary",
244
+ mimeType: t.type,
245
+ data: i,
246
+ filename: t.name
247
+ });
248
+ } else e.push({
249
+ type: "binary",
250
+ mimeType: t.mimeType,
251
+ url: t.url,
252
+ filename: t.name
253
+ });
254
+ a = [{
255
+ type: "text",
256
+ text: n
257
+ }, ...e];
258
+ }
259
+ return e.addMessage({
260
+ id: crypto.randomUUID(),
261
+ role: "user",
262
+ content: a
263
+ }), t.runAgent({ agent: e });
264
+ }, [e, t]);
265
+ return o(() => ({
266
+ sendMessage: n,
267
+ isRunning: e.isRunning,
268
+ messages: e.messages ?? []
269
+ }), [
270
+ e.isRunning,
271
+ e.messages,
272
+ n
273
+ ]);
274
+ };
275
+ //#endregion
276
+ export { M as ToolboxChat, I as useAgent, F as useLatestToolCall, P as useToolCall, A as useToolResponse };
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "@watermarkinsights/ai-toolbox",
3
+ "version": "0.0.1",
4
+ "type": "module",
5
+ "files": [
6
+ "dist"
7
+ ],
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/ai-toolbox.js",
11
+ "types": "./dist/ai-toolbox.d.ts"
12
+ }
13
+ },
14
+ "publishConfig": {
15
+ "access": "public"
16
+ },
17
+ "scripts": {
18
+ "dev": "bunx --bun vite build --watch ",
19
+ "build": "bunx --bun vite build",
20
+ "typecheck": "bunx --bun tsc --noEmit --incremental -p tsconfig.app.json",
21
+ "lint": "bunx --bun eslint --cache .",
22
+ "lint:fix": "bunx --bun eslint --cache --fix .",
23
+ "preview": "vite preview",
24
+ "storybook": "storybook dev -p 6006",
25
+ "build-storybook": "storybook build"
26
+ },
27
+ "dependencies": {
28
+ "@copilotkit/react-core": "^1.53.0",
29
+ "partial-json": "^0.1.7",
30
+ "zod": "^4.3.6"
31
+ },
32
+ "peerDependencies": {
33
+ "react": ">=18",
34
+ "react-dom": ">=18"
35
+ },
36
+ "devDependencies": {
37
+ "@chromatic-com/storybook": "^5.0.1",
38
+ "@eslint/js": "catalog:",
39
+ "@storybook/addon-a11y": "^10.2.15",
40
+ "@storybook/addon-docs": "^10.2.15",
41
+ "@storybook/addon-onboarding": "^10.2.15",
42
+ "@storybook/addon-vitest": "^10.2.15",
43
+ "@storybook/react-vite": "^10.2.15",
44
+ "@types/node": "^24.10.1",
45
+ "@types/react": "catalog:",
46
+ "@types/react-dom": "catalog:",
47
+ "@vitejs/plugin-react": "catalog:",
48
+ "@vitejs/plugin-react-swc": "^4.2.2",
49
+ "@vitest/browser-playwright": "^4.0.18",
50
+ "@vitest/coverage-v8": "^4.0.18",
51
+ "eslint": "catalog:",
52
+ "eslint-plugin-react-hooks": "catalog:",
53
+ "eslint-plugin-react-refresh": "^0.4.24",
54
+ "eslint-plugin-storybook": "^10.2.15",
55
+ "globals": "catalog:",
56
+ "playwright": "^1.58.2",
57
+ "react": "catalog:",
58
+ "react-dom": "catalog:",
59
+ "storybook": "^10.2.15",
60
+ "typescript": "catalog:",
61
+ "typescript-eslint": "catalog:",
62
+ "vite": "^8.0.2",
63
+ "vite-bundle-analyzer": "^1.3.6",
64
+ "vite-plugin-dts": "^4.5.4",
65
+ "vite-plugin-externalize-deps": "^0.10.0",
66
+ "vitest": "^4.0.18"
67
+ }
68
+ }