@pagelines/sdk 1.0.663 → 1.0.665
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AgentProvider.vue_vue_type_script_setup_true_lang.js +4208 -0
- package/dist/AgentProvider.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/AgentWidgetInline.js +32 -44
- package/dist/AgentWidgetInline.js.map +1 -1
- package/dist/AgentWidgetModal.js +64 -75
- package/dist/AgentWidgetModal.js.map +1 -1
- package/dist/AgentWidgetOnboard.js +5 -0
- package/dist/AgentWidgetOnboard.js.map +1 -0
- package/dist/AgentWrap.vue_vue_type_script_setup_true_lang.js +5098 -0
- package/dist/AgentWrap.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/FModal.vue_vue_type_script_setup_true_lang.js +181 -0
- package/dist/FModal.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/agent/test/AgentController.test.d.ts +1 -0
- package/dist/agent/test/ChatRichText.client.test.d.ts +1 -0
- package/dist/agent/test/ChatVisualBlock.client.test.d.ts +1 -0
- package/dist/agent/test/ElAgentChat.client.test.d.ts +1 -0
- package/dist/agent/test/ElAgentChatPreview.client.test.d.ts +1 -0
- package/dist/agent/test/VoiceRecorderController.unit.test.d.ts +1 -0
- package/dist/agent/test/auth-inputs.test.d.ts +1 -0
- package/dist/agent/test/chat-visual-format.unit.test.d.ts +1 -0
- package/dist/agent/test/utils.test.d.ts +1 -0
- package/dist/agent/test/webhook.test.d.ts +1 -0
- package/dist/agent.js +186 -157
- package/dist/agent.js.map +1 -1
- package/dist/contract/regenerate.d.ts +2 -0
- package/dist/contract/test/build.unit.test.d.ts +1 -0
- package/dist/contract/test/conversation-wire-shapes.unit.test.d.ts +14 -0
- package/dist/contract/test/snapshot.unit.test.d.ts +1 -0
- package/dist/demo.js +259 -242
- package/dist/demo.js.map +1 -1
- package/dist/index.js +872 -0
- package/dist/index.js.map +1 -0
- package/dist/sdk.css +1 -2
- package/dist/sdk.js +14 -4
- package/dist/sdk.js.map +1 -0
- package/dist/sdkClient.js +867 -775
- package/dist/sdkClient.js.map +1 -1
- package/dist/socialPlatforms.js +82 -0
- package/dist/socialPlatforms.js.map +1 -0
- package/dist/test/agent-client.test.d.ts +4 -0
- package/dist/test/api.test.d.ts +1 -0
- package/dist/test/billing-client.test.d.ts +4 -0
- package/dist/test/build.test.d.ts +1 -0
- package/dist/test/chat-authenticated.test.d.ts +1 -0
- package/dist/test/chat-issue-presentation.test.d.ts +1 -0
- package/dist/test/derive-mode.test.d.ts +1 -0
- package/dist/test/sdk-token-capture.test.d.ts +13 -0
- package/dist/vite.config.sdk.d.ts +2 -0
- package/dist/vitest.config.d.ts +2 -0
- package/dist/widget.js +7 -721
- package/dist/widget.js.map +1 -1
- package/package.json +12 -12
- package/dist/AgentProvider.js +0 -2782
- package/dist/AgentProvider.js.map +0 -1
- package/dist/AgentWrap.js +0 -5251
- package/dist/AgentWrap.js.map +0 -1
- package/dist/FModal.js +0 -165
- package/dist/FModal.js.map +0 -1
- package/dist/constants.js +0 -80
- package/dist/constants.js.map +0 -1
- package/dist/contract.js +0 -6271
- package/dist/contract.js.map +0 -1
- package/dist/node_modules/.vue-global-types/vue_3.5_false.d.ts +0 -4
- package/dist/rolldown-runtime.js +0 -14
- package/dist/useWidgetState.js +0 -21
- package/dist/useWidgetState.js.map +0 -1
package/dist/sdkClient.js
CHANGED
|
@@ -1,787 +1,879 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
var Q = Object.defineProperty;
|
|
2
|
+
var ee = (i, e, t) => e in i ? Q(i, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : i[e] = t;
|
|
3
|
+
var u = (i, e) => Q(i, "name", { value: e, configurable: !0 });
|
|
4
|
+
var l = (i, e, t) => ee(i, typeof e != "symbol" ? e + "" : e, t);
|
|
5
|
+
import { APP_PORT as te, APP_PROD_URL as oe, cookieUtil as S, createLogger as re, shortId as se, runAuthenticatedChatTurnStream as ie, zChatEvent as ae, objectId as P, SettingsObject as ne } from "@pagelines/core";
|
|
6
|
+
import { watch as B, ref as b, computed as V } from "vue";
|
|
7
|
+
function p(i, e) {
|
|
8
|
+
return i || (e ? `http://localhost:${te}` : oe);
|
|
7
9
|
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
10
|
+
u(p, "resolveApiBase");
|
|
11
|
+
function ce(i, e, t) {
|
|
12
|
+
const o = p(i.apiBase, i.isDev);
|
|
13
|
+
return async (r, s) => {
|
|
14
|
+
const n = S.getAuthToken(), h = new Headers(s?.headers);
|
|
15
|
+
h.has("Content-Type") || h.set("Content-Type", "application/json"), n && !h.has("Authorization") && h.set("Authorization", `Bearer ${n}`);
|
|
16
|
+
const a = typeof r == "string" && r.startsWith("/") ? `${o}${r}` : r, c = await fetch(a, {
|
|
17
|
+
...s,
|
|
18
|
+
headers: h,
|
|
19
|
+
credentials: "include"
|
|
20
|
+
});
|
|
21
|
+
if (t && c.status === 401 && (await c.clone().json().catch(() => {
|
|
22
|
+
}))?.code === "TOKEN_ERROR" && t(), e) {
|
|
23
|
+
const d = c.json.bind(c);
|
|
24
|
+
c.json = async () => {
|
|
25
|
+
const f = await d();
|
|
26
|
+
return typeof f == "object" && f !== null && "ok" in f && ("user" in f || "token" in f) && e(f), f;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
return c;
|
|
30
|
+
};
|
|
27
31
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
32
|
+
u(ce, "createApiFetch");
|
|
33
|
+
const le = /* @__PURE__ */ Symbol("clean");
|
|
34
|
+
let v = [], w = 0;
|
|
35
|
+
const T = 4, ue = globalThis.nanostoresGlobal || (globalThis.nanostoresGlobal = { epoch: 0 }), N = /* @__PURE__ */ u(/* @__NO_SIDE_EFFECTS__ */ (i) => {
|
|
36
|
+
let e = [], t = {
|
|
37
|
+
get() {
|
|
38
|
+
return t.lc || t.listen(() => {
|
|
39
|
+
})(), t.value;
|
|
40
|
+
},
|
|
41
|
+
init: i,
|
|
42
|
+
lc: 0,
|
|
43
|
+
listen(o) {
|
|
44
|
+
return t.lc = e.push(o), () => {
|
|
45
|
+
for (let s = w + T; s < v.length; )
|
|
46
|
+
v[s] === o ? v.splice(s, T) : s += T;
|
|
47
|
+
let r = e.indexOf(o);
|
|
48
|
+
~r && (e.splice(r, 1), --t.lc || t.off());
|
|
49
|
+
};
|
|
50
|
+
},
|
|
51
|
+
notify(o, r) {
|
|
52
|
+
ue.epoch++;
|
|
53
|
+
let s = !v.length;
|
|
54
|
+
for (let n of e)
|
|
55
|
+
v.push(n, t.value, o, r);
|
|
56
|
+
if (s) {
|
|
57
|
+
for (w = 0; w < v.length; w += T)
|
|
58
|
+
v[w](
|
|
59
|
+
v[w + 1],
|
|
60
|
+
v[w + 2],
|
|
61
|
+
v[w + 3]
|
|
62
|
+
);
|
|
63
|
+
v.length = 0;
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
/* It will be called on last listener unsubscribing.
|
|
67
|
+
We will redefine it in onMount and onStop. */
|
|
68
|
+
off() {
|
|
69
|
+
},
|
|
70
|
+
set(o) {
|
|
71
|
+
let r = t.value;
|
|
72
|
+
r !== o && (t.value = o, t.notify(r));
|
|
73
|
+
},
|
|
74
|
+
subscribe(o) {
|
|
75
|
+
let r = t.listen(o);
|
|
76
|
+
return o(t.value), r;
|
|
77
|
+
},
|
|
78
|
+
value: i
|
|
79
|
+
};
|
|
80
|
+
return process.env.NODE_ENV !== "production" && (t[le] = () => {
|
|
81
|
+
e = [], t.lc = 0, t.off();
|
|
82
|
+
}), t;
|
|
83
|
+
}, "atom"), y = globalThis, U = y.__PL_AUTH_USER__ ?? (y.__PL_AUTH_USER__ = /* @__PURE__ */ N(void 0)), E = y.__PL_AUTH_TOKEN__ ?? (y.__PL_AUTH_TOKEN__ = /* @__PURE__ */ N(null)), A = y.__PL_AUTH_DEVICE_ID__ ?? (y.__PL_AUTH_DEVICE_ID__ = /* @__PURE__ */ N(null)), z = class z {
|
|
84
|
+
constructor() {
|
|
85
|
+
l(this, "logger", re("SDKStorage"));
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Check if localStorage is fully functional (some test environments provide partial mocks)
|
|
89
|
+
*/
|
|
90
|
+
isLocalStorageFunctional() {
|
|
91
|
+
return typeof window < "u" && typeof localStorage?.getItem == "function" && typeof localStorage?.setItem == "function" && typeof localStorage?.removeItem == "function";
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Sync Vue reactive refs with global nanostores for cross-bundle persistence.
|
|
95
|
+
*/
|
|
96
|
+
syncWithGlobalStores(e) {
|
|
97
|
+
const { activeUser: t, token: o, deviceId: r } = e, s = U.get(), n = E.get(), h = A.get();
|
|
98
|
+
s && (t.value = s), n && (o.value = n), h && (r.value = h), B(t, (a) => U.set(a), { immediate: !0 }), B(o, (a) => E.set(a), { immediate: !0 }), B(r, (a) => A.set(a), { immediate: !0 }), U.subscribe((a) => {
|
|
99
|
+
a !== t.value && (t.value = a);
|
|
100
|
+
}), E.subscribe((a) => {
|
|
101
|
+
a !== o.value && (o.value = a);
|
|
102
|
+
}), A.subscribe((a) => {
|
|
103
|
+
a !== r.value && (r.value = a);
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Load user and token from browser storage on initialization.
|
|
108
|
+
* deviceId comes from a server-set non-HttpOnly cookie (read-only for JS).
|
|
109
|
+
*/
|
|
110
|
+
loadFromStorage(e) {
|
|
111
|
+
if (typeof window > "u")
|
|
112
|
+
return;
|
|
113
|
+
const t = S.getAuthToken();
|
|
114
|
+
t && (e.token.value = t);
|
|
115
|
+
const o = S.getDeviceId();
|
|
116
|
+
if (o && (e.deviceId.value = o), this.isLocalStorageFunctional())
|
|
117
|
+
try {
|
|
118
|
+
const r = localStorage.getItem("pagelines-user");
|
|
119
|
+
r && (e.activeUser.value = JSON.parse(r));
|
|
120
|
+
} catch (r) {
|
|
121
|
+
this.logger.error("Failed to load user from localStorage", { data: r });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Save current user and the transitional JS session-token mirror to browser storage.
|
|
126
|
+
* deviceId is server-owned (Set-Cookie) — JS doesn't write it.
|
|
127
|
+
*/
|
|
128
|
+
saveToStorage(e) {
|
|
129
|
+
if (!(typeof window > "u") && (e.token.value ? S.setAuthToken(e.token.value) : S.removeAuthToken(), this.isLocalStorageFunctional()))
|
|
130
|
+
try {
|
|
131
|
+
e.activeUser.value ? localStorage.setItem("pagelines-user", JSON.stringify(e.activeUser.value)) : localStorage.removeItem("pagelines-user");
|
|
132
|
+
} catch (t) {
|
|
133
|
+
this.logger.error("Failed to save user to localStorage", { data: t });
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Clear local stored user data and JS-owned tokens. Server-owned cookies
|
|
138
|
+
* (pl-session, pl-device-id) are cleared by /api/auth/logout via
|
|
139
|
+
* Set-Cookie max-age=0 — JS can't touch them.
|
|
140
|
+
*/
|
|
141
|
+
clearStorage() {
|
|
142
|
+
if (!(typeof window > "u")) {
|
|
143
|
+
if (S.removeAuthToken(), this.isLocalStorageFunctional())
|
|
144
|
+
try {
|
|
145
|
+
localStorage.removeItem("pagelines-user");
|
|
146
|
+
} catch (e) {
|
|
147
|
+
this.logger.error("Failed to clear user from localStorage", { data: e });
|
|
148
|
+
}
|
|
149
|
+
U.set(void 0), E.set(null), A.set(null);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Generic localStorage getter
|
|
154
|
+
*/
|
|
155
|
+
getItem(e) {
|
|
156
|
+
if (!this.isLocalStorageFunctional())
|
|
157
|
+
return null;
|
|
158
|
+
try {
|
|
159
|
+
return localStorage.getItem(e);
|
|
160
|
+
} catch (t) {
|
|
161
|
+
return this.logger.error("Failed to get item from localStorage", { key: e, error: t }), null;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Generic localStorage setter
|
|
166
|
+
*/
|
|
167
|
+
setItem(e, t) {
|
|
168
|
+
if (this.isLocalStorageFunctional())
|
|
169
|
+
try {
|
|
170
|
+
localStorage.setItem(e, t);
|
|
171
|
+
} catch (o) {
|
|
172
|
+
this.logger.error("Failed to set item in localStorage", { key: e, error: o });
|
|
173
|
+
}
|
|
174
|
+
}
|
|
67
175
|
};
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
if (!this.isLocalStorageFunctional()) return null;
|
|
156
|
-
try {
|
|
157
|
-
return localStorage.getItem(e);
|
|
158
|
-
} catch (t) {
|
|
159
|
-
return this.logger.error("Failed to get item from localStorage", {
|
|
160
|
-
key: e,
|
|
161
|
-
error: t
|
|
162
|
-
}), null;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
setItem(e, t) {
|
|
166
|
-
if (this.isLocalStorageFunctional()) try {
|
|
167
|
-
localStorage.setItem(e, t);
|
|
168
|
-
} catch (t) {
|
|
169
|
-
this.logger.error("Failed to set item in localStorage", {
|
|
170
|
-
key: e,
|
|
171
|
-
error: t
|
|
172
|
-
});
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}, AgentClient = class {
|
|
176
|
-
constructor(e) {
|
|
177
|
-
_defineProperty(this, "ctx", void 0), this.ctx = e;
|
|
178
|
-
}
|
|
179
|
-
async create(e) {
|
|
180
|
-
let t = e.orgId || this.resolveOrgId(), n = resolveApiBase(this.ctx.apiBase, this.ctx.isDev), r = await (await fetch(`${n}/api/agents`, {
|
|
181
|
-
method: "POST",
|
|
182
|
-
headers: {
|
|
183
|
-
"Content-Type": "application/json",
|
|
184
|
-
...this.ctx.token.value && { Authorization: `Bearer ${this.ctx.token.value}` }
|
|
185
|
-
},
|
|
186
|
-
body: JSON.stringify({
|
|
187
|
-
name: e.name,
|
|
188
|
-
orgId: t
|
|
189
|
-
})
|
|
190
|
-
})).json();
|
|
191
|
-
if (!r.ok || !r.data?.[0]) {
|
|
192
|
-
let e = r.error || "Failed to create agent";
|
|
193
|
-
throw this.ctx.error.value = e, Error(e);
|
|
194
|
-
}
|
|
195
|
-
return this.ctx.processApiResponse(r), r.data[0];
|
|
196
|
-
}
|
|
197
|
-
async getLiveStatus(e) {
|
|
198
|
-
let t = resolveApiBase(this.ctx.apiBase, this.ctx.isDev);
|
|
199
|
-
try {
|
|
200
|
-
let n = await (await fetch(`${t}/api/agents/state?ids=${encodeURIComponent(e.agentId)}`, { headers: { ...this.ctx.token.value && { Authorization: `Bearer ${this.ctx.token.value}` } } })).json();
|
|
201
|
-
return n.ok ? n.data?.[e.agentId] ?? { lifecycle: "unknown" } : { lifecycle: "unknown" };
|
|
202
|
-
} catch (t) {
|
|
203
|
-
return this.ctx.logger.warn("agent.getLiveStatus failed", {
|
|
204
|
-
agentId: e.agentId,
|
|
205
|
-
error: t instanceof Error ? t.message : String(t)
|
|
206
|
-
}), { lifecycle: "unknown" };
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
async waitUntilReady(e) {
|
|
210
|
-
let { agentId: t, onStatus: n, timeoutMs: r = 3e5, pollIntervalMs: i = 3e3 } = e, a = Date.now(), o;
|
|
211
|
-
for (; Date.now() - a < r;) {
|
|
212
|
-
let e = await this.getLiveStatus({ agentId: t });
|
|
213
|
-
if (e.lifecycle === "running") {
|
|
214
|
-
n?.("running");
|
|
215
|
-
return;
|
|
216
|
-
}
|
|
217
|
-
if (e.lifecycle === "error") throw Error(e.detail || "Your assistant hit a problem starting");
|
|
218
|
-
e.lifecycle !== o && (n?.(e.lifecycle), o = e.lifecycle), await new Promise((e) => setTimeout(e, i));
|
|
219
|
-
}
|
|
220
|
-
throw Error("Your assistant is taking longer than expected — please try again");
|
|
221
|
-
}
|
|
222
|
-
async webhook(e) {
|
|
223
|
-
let t = `${resolveApiBase(this.ctx.apiBase, this.ctx.isDev)}/api/bot-api/webhooks/agents/${e.agentId}`, n = {
|
|
224
|
-
type: e.type,
|
|
225
|
-
data: e.data
|
|
226
|
-
};
|
|
227
|
-
e.meta && (n.meta = e.meta);
|
|
228
|
-
let r = await fetch(t, {
|
|
229
|
-
method: "POST",
|
|
230
|
-
headers: { "Content-Type": "application/json" },
|
|
231
|
-
body: JSON.stringify(n)
|
|
232
|
-
});
|
|
233
|
-
if (!r.ok) {
|
|
234
|
-
let e = await r.text().catch(() => "Unknown error");
|
|
235
|
-
throw Error(`Webhook delivery failed (${r.status}): ${e.slice(0, 200)}`);
|
|
236
|
-
}
|
|
237
|
-
return r.json();
|
|
238
|
-
}
|
|
239
|
-
resolveOrgId() {
|
|
240
|
-
let e = this.ctx.activeUser.value?.orgs?.[0]?.orgId;
|
|
241
|
-
if (!e) throw Error("No organization found. Please sign in first.");
|
|
242
|
-
return e;
|
|
243
|
-
}
|
|
176
|
+
u(z, "SDKStorage");
|
|
177
|
+
let D = z;
|
|
178
|
+
const J = class J {
|
|
179
|
+
constructor(e) {
|
|
180
|
+
l(this, "ctx");
|
|
181
|
+
this.ctx = e;
|
|
182
|
+
}
|
|
183
|
+
async create(e) {
|
|
184
|
+
const t = e.orgId || this.resolveOrgId(), o = p(this.ctx.apiBase, this.ctx.isDev), s = await (await fetch(`${o}/api/agents`, {
|
|
185
|
+
method: "POST",
|
|
186
|
+
headers: {
|
|
187
|
+
"Content-Type": "application/json",
|
|
188
|
+
...this.ctx.token.value && { Authorization: `Bearer ${this.ctx.token.value}` }
|
|
189
|
+
},
|
|
190
|
+
body: JSON.stringify({ name: e.name, orgId: t })
|
|
191
|
+
})).json();
|
|
192
|
+
if (!s.ok || !s.data?.[0]) {
|
|
193
|
+
const n = s.error || "Failed to create agent";
|
|
194
|
+
throw this.ctx.error.value = n, new Error(n);
|
|
195
|
+
}
|
|
196
|
+
return this.ctx.processApiResponse(s), s.data[0];
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Live runtime status — the same canonical `LiveStatus` shape every other
|
|
200
|
+
* status producer emits (`GET /agents` rows, SSE status frames, lifecycle
|
|
201
|
+
* action responses). See plans/bots/bot-state-management.md.
|
|
202
|
+
* `{ lifecycle: 'unknown' }` is the graceful degrade on any fetch failure.
|
|
203
|
+
*/
|
|
204
|
+
async getLiveStatus(e) {
|
|
205
|
+
const t = p(this.ctx.apiBase, this.ctx.isDev);
|
|
206
|
+
try {
|
|
207
|
+
const r = await (await fetch(`${t}/api/agents/state?ids=${encodeURIComponent(e.agentId)}`, {
|
|
208
|
+
headers: {
|
|
209
|
+
...this.ctx.token.value && { Authorization: `Bearer ${this.ctx.token.value}` }
|
|
210
|
+
}
|
|
211
|
+
})).json();
|
|
212
|
+
return r.ok ? r.data?.[e.agentId] ?? { lifecycle: "unknown" } : { lifecycle: "unknown" };
|
|
213
|
+
} catch (o) {
|
|
214
|
+
return this.ctx.logger.warn("agent.getLiveStatus failed", {
|
|
215
|
+
agentId: e.agentId,
|
|
216
|
+
error: o instanceof Error ? o.message : String(o)
|
|
217
|
+
}), { lifecycle: "unknown" };
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Poll until the agent's lifecycle reaches `running`. `onStatus` receives
|
|
222
|
+
* the server-reported lifecycle verbatim ('starting', 'running', …) so the
|
|
223
|
+
* caller renders feedback tied to actual provisioner state, not a rotating
|
|
224
|
+
* set of decorative messages. Per first-principles → "Always give feedback
|
|
225
|
+
* — no magic". Map lifecycle values to user copy at the call site.
|
|
226
|
+
*/
|
|
227
|
+
async waitUntilReady(e) {
|
|
228
|
+
const { agentId: t, onStatus: o, timeoutMs: r = 3e5, pollIntervalMs: s = 3e3 } = e, n = Date.now();
|
|
229
|
+
let h;
|
|
230
|
+
for (; Date.now() - n < r; ) {
|
|
231
|
+
const a = await this.getLiveStatus({ agentId: t });
|
|
232
|
+
if (a.lifecycle === "running") {
|
|
233
|
+
o?.("running");
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
if (a.lifecycle === "error")
|
|
237
|
+
throw new Error(a.detail || "Your assistant hit a problem starting");
|
|
238
|
+
a.lifecycle !== h && (o?.(a.lifecycle), h = a.lifecycle), await new Promise((c) => setTimeout(c, s));
|
|
239
|
+
}
|
|
240
|
+
throw new Error("Your assistant is taking longer than expected — please try again");
|
|
241
|
+
}
|
|
242
|
+
/** Send a typed webhook event to a bot agent. No auth required — the proxy is public. */
|
|
243
|
+
async webhook(e) {
|
|
244
|
+
const o = `${p(this.ctx.apiBase, this.ctx.isDev)}/api/bot-api/webhooks/agents/${e.agentId}`, r = { type: e.type, data: e.data };
|
|
245
|
+
e.meta && (r.meta = e.meta);
|
|
246
|
+
const s = await fetch(o, {
|
|
247
|
+
method: "POST",
|
|
248
|
+
headers: { "Content-Type": "application/json" },
|
|
249
|
+
body: JSON.stringify(r)
|
|
250
|
+
});
|
|
251
|
+
if (!s.ok) {
|
|
252
|
+
const n = await s.text().catch(() => "Unknown error");
|
|
253
|
+
throw new Error(`Webhook delivery failed (${s.status}): ${n.slice(0, 200)}`);
|
|
254
|
+
}
|
|
255
|
+
return s.json();
|
|
256
|
+
}
|
|
257
|
+
resolveOrgId() {
|
|
258
|
+
const t = this.ctx.activeUser.value?.orgs?.[0]?.orgId;
|
|
259
|
+
if (!t)
|
|
260
|
+
throw new Error("No organization found. Please sign in first.");
|
|
261
|
+
return t;
|
|
262
|
+
}
|
|
244
263
|
};
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
async function
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
264
|
+
u(J, "AgentClient");
|
|
265
|
+
let F = J;
|
|
266
|
+
async function k(i, e) {
|
|
267
|
+
i.loading.value = !0, i.error.value = null;
|
|
268
|
+
try {
|
|
269
|
+
return await e();
|
|
270
|
+
} finally {
|
|
271
|
+
i.loading.value = !1;
|
|
272
|
+
}
|
|
254
273
|
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
let e = this.ctx.activeUser.value?.orgs?.[0]?.orgId;
|
|
454
|
-
if (!e) throw Error("No organization found. Please sign in first.");
|
|
455
|
-
return e;
|
|
456
|
-
}
|
|
274
|
+
u(k, "withLoadingState");
|
|
275
|
+
const W = class W {
|
|
276
|
+
constructor(e) {
|
|
277
|
+
l(this, "ctx");
|
|
278
|
+
this.ctx = e;
|
|
279
|
+
}
|
|
280
|
+
async sendCode(e) {
|
|
281
|
+
return k(this.ctx, async () => {
|
|
282
|
+
try {
|
|
283
|
+
const o = await (await this.ctx.apiFetch("/api/auth/check-email", {
|
|
284
|
+
method: "POST",
|
|
285
|
+
body: JSON.stringify({ email: e })
|
|
286
|
+
})).json();
|
|
287
|
+
if (!o.ok)
|
|
288
|
+
throw this.ctx.error.value = o.error, new Error(o.error);
|
|
289
|
+
} catch (t) {
|
|
290
|
+
this.ctx.logger.error("Send code error", { data: t });
|
|
291
|
+
const o = t instanceof Error ? t.message : "Failed to send verification code";
|
|
292
|
+
throw this.ctx.error.value = o, t;
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
async verifyCode(e, t) {
|
|
297
|
+
return k(this.ctx, async () => {
|
|
298
|
+
try {
|
|
299
|
+
const r = await (await this.ctx.apiFetch("/api/auth/verify-code", {
|
|
300
|
+
method: "POST",
|
|
301
|
+
body: JSON.stringify({ email: e, code: t })
|
|
302
|
+
})).json();
|
|
303
|
+
if (!r.ok)
|
|
304
|
+
throw this.ctx.error.value = r.error, new Error(r.error);
|
|
305
|
+
} catch (o) {
|
|
306
|
+
this.ctx.logger.error("Verify code error", { data: o });
|
|
307
|
+
const r = o instanceof Error ? o.message : "Failed to verify code";
|
|
308
|
+
throw this.ctx.error.value = r, o;
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
async logout() {
|
|
313
|
+
return k(this.ctx, async () => {
|
|
314
|
+
try {
|
|
315
|
+
await this.ctx.apiFetch("/api/auth/logout", { method: "POST" });
|
|
316
|
+
} catch (e) {
|
|
317
|
+
this.ctx.logger.error("Logout error (user still logged out locally)", { data: e });
|
|
318
|
+
}
|
|
319
|
+
this.ctx.activeUser.value = void 0, this.ctx.token.value = null, this.ctx.storage.clearStorage();
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
async getCurrentUser() {
|
|
323
|
+
if (this.ctx.token.value)
|
|
324
|
+
return k(this.ctx, async () => {
|
|
325
|
+
try {
|
|
326
|
+
const t = await (await this.ctx.apiFetch("/api/users/me", {
|
|
327
|
+
method: "GET"
|
|
328
|
+
})).json();
|
|
329
|
+
if (!t.ok) {
|
|
330
|
+
this.ctx.error.value = t.error, t.error.includes("Authentication") && (this.ctx.activeUser.value = void 0, this.ctx.token.value = null, this.ctx.storage.clearStorage());
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
return this.ctx.token.value && (this.ctx.activeUser.value = t.data), t.data;
|
|
334
|
+
} catch (e) {
|
|
335
|
+
this.ctx.logger.error("Get current user error", { data: e }), this.ctx.error.value = e instanceof Error ? e.message : "Failed to get user info";
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
async requestAuthCode(e) {
|
|
341
|
+
return k(this.ctx, async () => {
|
|
342
|
+
try {
|
|
343
|
+
const o = await (await this.ctx.apiFetch("/api/auth/check-email", {
|
|
344
|
+
method: "POST",
|
|
345
|
+
body: JSON.stringify({ email: e.email })
|
|
346
|
+
})).json();
|
|
347
|
+
return o.ok ? (this.ctx.logger.info("Auth code requested successfully", { email: e.email }), !0) : (this.ctx.error.value = o.error, this.ctx.logger.error("Failed to request auth code", { email: e.email, error: o.error }), !1);
|
|
348
|
+
} catch (t) {
|
|
349
|
+
return this.ctx.logger.error("Request auth code error", { email: e.email, error: t }), this.ctx.error.value = t instanceof Error ? t.message : "Failed to request auth code", !1;
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
async loginWithCode(e) {
|
|
354
|
+
return k(this.ctx, async () => {
|
|
355
|
+
try {
|
|
356
|
+
const o = await (await this.ctx.apiFetch("/api/auth/verify-code", {
|
|
357
|
+
method: "POST",
|
|
358
|
+
body: JSON.stringify({ email: e.email, code: e.code })
|
|
359
|
+
})).json();
|
|
360
|
+
return o.ok ? (this.ctx.logger.info("Login successful", { email: e.email }), !0) : (this.ctx.error.value = o.error, this.ctx.logger.error("Login failed", { email: e.email, error: o.error }), !1);
|
|
361
|
+
} catch (t) {
|
|
362
|
+
return this.ctx.logger.error("Login with code error", { email: e.email, error: t }), this.ctx.error.value = t instanceof Error ? t.message : "Login failed", !1;
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
loginWithGoogle(e) {
|
|
367
|
+
if (typeof window > "u") {
|
|
368
|
+
this.ctx.logger.error("loginWithGoogle: Only available in browser");
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
const t = p(this.ctx.apiBase, this.ctx.isDev), o = window.location.origin, r = `${t}/auth/google-popup?origin=${encodeURIComponent(o)}`, s = 500, n = 600, h = window.screenX + (window.outerWidth - s) / 2, a = window.screenY + (window.outerHeight - n) / 2, c = window.open(
|
|
372
|
+
r,
|
|
373
|
+
"google-auth",
|
|
374
|
+
`width=${s},height=${n},left=${h},top=${a},popup=yes`
|
|
375
|
+
);
|
|
376
|
+
if (!c) {
|
|
377
|
+
const m = "Popup was blocked. Please allow popups for this site.";
|
|
378
|
+
this.ctx.error.value = m, e?.onError?.(m);
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
const d = /* @__PURE__ */ u((m) => {
|
|
382
|
+
const I = new URL(t).origin;
|
|
383
|
+
if (m.origin === I) {
|
|
384
|
+
if (m.data?.type === "auth-success") {
|
|
385
|
+
window.removeEventListener("message", d);
|
|
386
|
+
const { token: x, user: g } = m.data;
|
|
387
|
+
this.ctx.processApiResponse({ ok: !0, data: {}, token: x, user: g }), this.ctx.logger.info("Google login successful"), e?.onSuccess?.(g);
|
|
388
|
+
} else if (m.data?.type === "auth-error") {
|
|
389
|
+
window.removeEventListener("message", d);
|
|
390
|
+
const x = m.data.error || "Google authentication failed";
|
|
391
|
+
this.ctx.error.value = x, this.ctx.logger.error("Google login failed", { error: x }), e?.onError?.(x);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}, "handler");
|
|
395
|
+
window.addEventListener("message", d);
|
|
396
|
+
const f = setInterval(() => {
|
|
397
|
+
c.closed && (clearInterval(f), window.removeEventListener("message", d));
|
|
398
|
+
}, 500);
|
|
399
|
+
}
|
|
400
|
+
};
|
|
401
|
+
u(W, "AuthClient");
|
|
402
|
+
let R = W;
|
|
403
|
+
const G = class G {
|
|
404
|
+
constructor(e) {
|
|
405
|
+
l(this, "ctx");
|
|
406
|
+
this.ctx = e;
|
|
407
|
+
}
|
|
408
|
+
async startTrial(e) {
|
|
409
|
+
const t = this.resolveOrgId(), o = p(this.ctx.apiBase, this.ctx.isDev), s = await (await fetch(`${o}/api/billing/checkout/create`, {
|
|
410
|
+
method: "POST",
|
|
411
|
+
headers: {
|
|
412
|
+
"Content-Type": "application/json",
|
|
413
|
+
...this.ctx.token.value && { Authorization: `Bearer ${this.ctx.token.value}` }
|
|
414
|
+
},
|
|
415
|
+
body: JSON.stringify({
|
|
416
|
+
orgId: t,
|
|
417
|
+
...e?.returnUrl && { returnUrl: e.returnUrl }
|
|
418
|
+
})
|
|
419
|
+
})).json();
|
|
420
|
+
if (!s.ok || !s.data?.url) {
|
|
421
|
+
const n = s.error || "Failed to create checkout session";
|
|
422
|
+
throw this.ctx.error.value = n, new Error(n);
|
|
423
|
+
}
|
|
424
|
+
window.location.href = s.data.url;
|
|
425
|
+
}
|
|
426
|
+
async confirmCheckout(e) {
|
|
427
|
+
if (e?.sessionId) {
|
|
428
|
+
const t = p(this.ctx.apiBase, this.ctx.isDev), r = await (await fetch(`${t}/api/billing/complete-checkout`, {
|
|
429
|
+
method: "POST",
|
|
430
|
+
headers: {
|
|
431
|
+
"Content-Type": "application/json",
|
|
432
|
+
...this.ctx.token.value && { Authorization: `Bearer ${this.ctx.token.value}` }
|
|
433
|
+
},
|
|
434
|
+
body: JSON.stringify({ sessionId: e.sessionId })
|
|
435
|
+
})).json();
|
|
436
|
+
if (!r.ok) {
|
|
437
|
+
const s = r.error || "Failed to complete checkout";
|
|
438
|
+
throw this.ctx.error.value = s, new Error(s);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
return this.getStatus();
|
|
442
|
+
}
|
|
443
|
+
async getStatus() {
|
|
444
|
+
const e = this.resolveOrgId(), t = p(this.ctx.apiBase, this.ctx.isDev), r = await (await fetch(`${t}/api/billing/details/${e}`, {
|
|
445
|
+
headers: {
|
|
446
|
+
...this.ctx.token.value && { Authorization: `Bearer ${this.ctx.token.value}` }
|
|
447
|
+
}
|
|
448
|
+
})).json();
|
|
449
|
+
if (!r.ok || !r.data)
|
|
450
|
+
return {
|
|
451
|
+
plan: void 0,
|
|
452
|
+
status: "none",
|
|
453
|
+
hasActiveBilling: !1,
|
|
454
|
+
maxAgents: 0
|
|
455
|
+
};
|
|
456
|
+
const s = ["active", "trial", "canceling"];
|
|
457
|
+
return {
|
|
458
|
+
plan: r.data.plan,
|
|
459
|
+
status: r.data.status,
|
|
460
|
+
hasActiveBilling: s.includes(r.data.status),
|
|
461
|
+
maxAgents: r.data.maxAgents,
|
|
462
|
+
...r.data.trialEnd && { trialEnd: r.data.trialEnd },
|
|
463
|
+
...r.data.trialDaysRemaining !== void 0 && { trialDaysRemaining: r.data.trialDaysRemaining }
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
resolveOrgId() {
|
|
467
|
+
const t = this.ctx.activeUser.value?.orgs?.[0]?.orgId;
|
|
468
|
+
if (!t)
|
|
469
|
+
throw new Error("No organization found. Please sign in first.");
|
|
470
|
+
return t;
|
|
471
|
+
}
|
|
457
472
|
};
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
function
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
+
u(G, "BillingClient");
|
|
474
|
+
let L = G;
|
|
475
|
+
function de(i) {
|
|
476
|
+
const e = i.split(`
|
|
477
|
+
`).filter((r) => r.length > 0);
|
|
478
|
+
let t, o;
|
|
479
|
+
for (const r of e)
|
|
480
|
+
r.startsWith("event:") ? t = r.slice(6).trim() : r.startsWith("data:") && (o = r.slice(5).trim());
|
|
481
|
+
if (!t || o === void 0)
|
|
482
|
+
return null;
|
|
483
|
+
try {
|
|
484
|
+
const r = ae.safeParse({ event: t, data: JSON.parse(o) });
|
|
485
|
+
return r.success ? r.data : null;
|
|
486
|
+
} catch {
|
|
487
|
+
return null;
|
|
488
|
+
}
|
|
473
489
|
}
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
490
|
+
u(de, "parseChatEvent");
|
|
491
|
+
function Y(i) {
|
|
492
|
+
return {
|
|
493
|
+
code: i.code,
|
|
494
|
+
error: i.message,
|
|
495
|
+
...i.bucket ? { bucket: i.bucket } : {},
|
|
496
|
+
...i.actionLabel ? { actionLabel: i.actionLabel } : {},
|
|
497
|
+
...i.actionUrl ? { actionUrl: i.actionUrl } : {},
|
|
498
|
+
...i.help ? { help: i.help } : {}
|
|
499
|
+
};
|
|
483
500
|
}
|
|
484
|
-
|
|
485
|
-
|
|
501
|
+
u(Y, "toChatStreamError");
|
|
502
|
+
function he(i) {
|
|
503
|
+
return i.stage === "stream-open" && i.message.startsWith("HTTP ") ? `Stream failed: ${i.message}` : i.message;
|
|
486
504
|
}
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
505
|
+
u(he, "toAuthenticatedTransportError");
|
|
506
|
+
function ge() {
|
|
507
|
+
try {
|
|
508
|
+
return Intl.DateTimeFormat().resolvedOptions().timeZone || void 0;
|
|
509
|
+
} catch {
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
493
512
|
}
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
513
|
+
u(ge, "detectBrowserTimezone");
|
|
514
|
+
function X(i) {
|
|
515
|
+
if (!(i.role !== "assistant" && i.role !== "system"))
|
|
516
|
+
return {
|
|
517
|
+
id: i.messageId,
|
|
518
|
+
text: i.content,
|
|
519
|
+
sender: i.role === "system" ? "system" : "agent",
|
|
520
|
+
timestamp: i.createdAt,
|
|
521
|
+
conversationId: i.conversationId,
|
|
522
|
+
sequence: i.sequence,
|
|
523
|
+
systemKind: i.systemKind,
|
|
524
|
+
...i.metadata?.turnOutcome ? { turnOutcome: i.metadata.turnOutcome } : {},
|
|
525
|
+
...i.metadata?.attachments?.length ? { attachments: i.metadata.attachments } : {},
|
|
526
|
+
...i.metadata?.toolActivities?.length ? { toolActivities: i.metadata.toolActivities } : {},
|
|
527
|
+
...i.metadata?.issue ? { issue: i.metadata.issue } : {}
|
|
528
|
+
};
|
|
508
529
|
}
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
i = !0;
|
|
567
|
-
let t = toChatMessage(n.data.message);
|
|
568
|
-
t && e.onMessage?.(t);
|
|
569
|
-
} else if (n.event === "stream_end") break outer;
|
|
570
|
-
}
|
|
571
|
-
o = c.indexOf("\n\n");
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
!r && i ? e.onDone(n) : r || e.onError("Stream ended before reply arrived");
|
|
575
|
-
} catch (t) {
|
|
576
|
-
e.onError(t instanceof Error ? t.message : "Stream failed");
|
|
577
|
-
} finally {
|
|
578
|
-
try {
|
|
579
|
-
await a?.cancel();
|
|
580
|
-
} catch {}
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
|
-
async chatStreamAuthenticated(e) {
|
|
584
|
-
let t = resolveApiBase(this.ctx.apiBase, this.ctx.isDev), n = this.ctx.token.value ? { Authorization: `Bearer ${this.ctx.token.value}` } : {}, r, i = null;
|
|
585
|
-
try {
|
|
586
|
-
let a = await fetch(`${t}/api/conversations`, {
|
|
587
|
-
method: "POST",
|
|
588
|
-
headers: {
|
|
589
|
-
"Content-Type": "application/json",
|
|
590
|
-
...n
|
|
591
|
-
},
|
|
592
|
-
body: JSON.stringify({ agentId: e.agentId })
|
|
593
|
-
}), o = await a.json();
|
|
594
|
-
if (!o.ok) {
|
|
595
|
-
e.onError(o.error || `Conversation failed: HTTP ${a.status}`);
|
|
596
|
-
return;
|
|
597
|
-
}
|
|
598
|
-
r = o.data.conversationId, i = o.data.latestSequence ?? null;
|
|
599
|
-
} catch (t) {
|
|
600
|
-
e.onError(t instanceof Error ? t.message : "Conversation failed");
|
|
601
|
-
return;
|
|
602
|
-
}
|
|
603
|
-
let a = i ? `${t}/api/conversations/${encodeURIComponent(r)}/stream?since=${encodeURIComponent(i)}` : `${t}/api/conversations/${encodeURIComponent(r)}/stream`, c = `nonce_${s(16)}`, l = detectBrowserTimezone();
|
|
604
|
-
await o({
|
|
605
|
-
streamUrl: a,
|
|
606
|
-
sendUrl: `${t}/api/messages`,
|
|
607
|
-
headers: n,
|
|
608
|
-
sendBody: {
|
|
609
|
-
conversationId: r,
|
|
610
|
-
content: e.message,
|
|
611
|
-
clientNonce: c,
|
|
612
|
-
...l ? { viewerTimezone: l } : {},
|
|
613
|
-
...e.attachments && e.attachments.length > 0 ? { attachments: e.attachments } : {}
|
|
614
|
-
},
|
|
615
|
-
onStatus: e.onStatus,
|
|
616
|
-
onDelta: e.onDelta,
|
|
617
|
-
onToolActivity: e.onToolActivity,
|
|
618
|
-
onWorkingEnd: e.onWorkingEnd,
|
|
619
|
-
onMessage: (t) => {
|
|
620
|
-
let n = toChatMessage(t);
|
|
621
|
-
n && e.onMessage?.(n);
|
|
622
|
-
},
|
|
623
|
-
onDone: () => e.onDone(r),
|
|
624
|
-
onChatError: (t) => e.onError(toChatStreamError(t)),
|
|
625
|
-
onTransportError: (t) => e.onError(t.code ? {
|
|
626
|
-
code: t.code,
|
|
627
|
-
error: t.message
|
|
628
|
-
} : toAuthenticatedTransportError(t))
|
|
629
|
-
});
|
|
630
|
-
}
|
|
631
|
-
}, UserClient = class {
|
|
632
|
-
constructor(e) {
|
|
633
|
-
_defineProperty(this, "ctx", void 0), this.ctx = e;
|
|
634
|
-
}
|
|
635
|
-
async getPublicAgent(e) {
|
|
636
|
-
this.ctx.loading.value = !0, this.ctx.error.value = null;
|
|
637
|
-
try {
|
|
638
|
-
let t = await (await this.ctx.apiFetch(`/api/agents/public/${encodeURIComponent(e.handle)}`)).json();
|
|
639
|
-
if (!t.ok) {
|
|
640
|
-
this.ctx.error.value = t.error, this.ctx.logger.error("Failed to fetch public agent", {
|
|
641
|
-
handle: e.handle,
|
|
642
|
-
error: t.error
|
|
643
|
-
});
|
|
644
|
-
return;
|
|
645
|
-
}
|
|
646
|
-
return t.data;
|
|
647
|
-
} catch (t) {
|
|
648
|
-
this.ctx.logger.error("Get public agent error", {
|
|
649
|
-
handle: e.handle,
|
|
650
|
-
error: t
|
|
651
|
-
}), this.ctx.error.value = t instanceof Error ? t.message : "Failed to fetch agent";
|
|
652
|
-
return;
|
|
653
|
-
} finally {
|
|
654
|
-
this.ctx.loading.value = !1;
|
|
655
|
-
}
|
|
656
|
-
}
|
|
657
|
-
async getAgentByEmail(e) {
|
|
658
|
-
this.ctx.loading.value = !0, this.ctx.error.value = null;
|
|
659
|
-
try {
|
|
660
|
-
let t = await (await this.ctx.apiFetch(`/api/agents/by-email/${encodeURIComponent(e.email)}`)).json();
|
|
661
|
-
if (!t.ok) {
|
|
662
|
-
this.ctx.error.value = t.error, this.ctx.logger.error("Failed to fetch agent by email", {
|
|
663
|
-
email: e.email,
|
|
664
|
-
error: t.error
|
|
665
|
-
});
|
|
666
|
-
return;
|
|
667
|
-
}
|
|
668
|
-
return t.data;
|
|
669
|
-
} catch (t) {
|
|
670
|
-
this.ctx.logger.error("Get agent by email error", {
|
|
671
|
-
email: e.email,
|
|
672
|
-
error: t
|
|
673
|
-
}), this.ctx.error.value = t instanceof Error ? t.message : "Failed to fetch agent";
|
|
674
|
-
return;
|
|
675
|
-
} finally {
|
|
676
|
-
this.ctx.loading.value = !1;
|
|
677
|
-
}
|
|
678
|
-
}
|
|
679
|
-
generateAnonId() {
|
|
680
|
-
let e = "pagelinesAnonId", t = this.ctx.storage.getItem(e);
|
|
681
|
-
return t || (t = a({ prefix: "anon" }), this.ctx.storage.setItem(e, t)), t;
|
|
682
|
-
}
|
|
683
|
-
track(e) {
|
|
684
|
-
try {
|
|
685
|
-
typeof window < "u" && window.parent !== window && window.parent.postMessage({
|
|
686
|
-
type: "pagelines_track",
|
|
687
|
-
event: e.event,
|
|
688
|
-
agentId: e.agentId,
|
|
689
|
-
properties: e.properties || {}
|
|
690
|
-
}, "*"), this.ctx.logger.info("SDK event tracked", {
|
|
691
|
-
event: e.event,
|
|
692
|
-
agentId: e.agentId
|
|
693
|
-
});
|
|
694
|
-
} catch (t) {
|
|
695
|
-
this.ctx.logger.error("Track event error", {
|
|
696
|
-
error: t,
|
|
697
|
-
args: e
|
|
698
|
-
});
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
}, SDKGlobal = class {
|
|
702
|
-
constructor() {
|
|
703
|
-
_defineProperty(this, "key", "__PAGELINES_SDK__");
|
|
704
|
-
}
|
|
705
|
-
get() {
|
|
706
|
-
if (!(typeof window > "u")) return globalThis[this.key];
|
|
707
|
-
}
|
|
708
|
-
set(e) {
|
|
709
|
-
typeof window < "u" && (globalThis[this.key] = e);
|
|
710
|
-
}
|
|
711
|
-
delete() {
|
|
712
|
-
typeof window < "u" && delete globalThis[this.key];
|
|
713
|
-
}
|
|
714
|
-
}, S = new SDKGlobal(), C = class PageLinesSDK extends n {
|
|
715
|
-
static getInstance(e = {}) {
|
|
716
|
-
return S.get() || new PageLinesSDK(e);
|
|
717
|
-
}
|
|
718
|
-
get isDev() {
|
|
719
|
-
return this.settings.isDev ?? (typeof window < "u" ? window.location.hostname === "localhost" || window.location.hostname.includes("127.0.0.1") : !1);
|
|
720
|
-
}
|
|
721
|
-
constructor(e = {}) {
|
|
722
|
-
let t = S.get();
|
|
723
|
-
if (t) return console.debug("[PageLinesSDK] Returning existing singleton instance"), t;
|
|
724
|
-
super("PageLinesSDK", e), _defineProperty(this, "activeUser", u()), _defineProperty(this, "token", u(null)), _defineProperty(this, "deviceId", u(null)), _defineProperty(this, "loading", u(!1)), _defineProperty(this, "error", u(null)), _defineProperty(this, "apiBase", this.settings.apiBase || void 0), _defineProperty(this, "storage", new SDKStorage()), _defineProperty(this, "sessionId", a({ prefix: "ses" })), _defineProperty(this, "currentAgent", l(() => {
|
|
725
|
-
let e = this.activeUser.value;
|
|
726
|
-
if (!e?.agents) return;
|
|
727
|
-
let t = e.primaryAgentId || e.agents[0]?.agentId;
|
|
728
|
-
if (t) return e.agents.find((e) => e.agentId === t);
|
|
729
|
-
})), _defineProperty(this, "currentOrg", l(() => {
|
|
730
|
-
let e = this.currentAgent.value;
|
|
731
|
-
if (!e?.orgId) return;
|
|
732
|
-
let t = this.activeUser.value;
|
|
733
|
-
if (t?.orgs) return t.orgs.find((t) => t.orgId === e.orgId);
|
|
734
|
-
})), _defineProperty(this, "initialized", void 0), _defineProperty(this, "resolveUser", void 0), _defineProperty(this, "agent", void 0), _defineProperty(this, "auth", void 0), _defineProperty(this, "billing", void 0), _defineProperty(this, "chat", void 0), _defineProperty(this, "user", void 0), S.set(this);
|
|
735
|
-
let n = {
|
|
736
|
-
apiFetch: createApiFetch({
|
|
737
|
-
isDev: this.isDev,
|
|
738
|
-
apiBase: this.apiBase
|
|
739
|
-
}, this.processApiResponse.bind(this), () => this.clearSession()),
|
|
740
|
-
apiBase: this.apiBase,
|
|
741
|
-
isDev: this.isDev,
|
|
742
|
-
activeUser: this.activeUser,
|
|
743
|
-
token: this.token,
|
|
744
|
-
loading: this.loading,
|
|
745
|
-
error: this.error,
|
|
746
|
-
currentAgent: this.currentAgent,
|
|
747
|
-
storage: this.storage,
|
|
748
|
-
sessionId: this.sessionId,
|
|
749
|
-
logger: this.logger,
|
|
750
|
-
processApiResponse: this.processApiResponse.bind(this)
|
|
751
|
-
};
|
|
752
|
-
this.agent = new AgentClient(n), this.auth = new AuthClient(n), this.billing = new BillingClient(n), this.chat = new ChatClient(n), this.user = new UserClient(n), this.logger.info("PageLinesSDK initialized"), this.storage.loadFromStorage(this.authRefs()), this.storage.syncWithGlobalStores(this.authRefs()), this.initialized = new Promise((e) => {
|
|
753
|
-
this.resolveUser = e;
|
|
754
|
-
}), this.token.value && !this.activeUser.value ? this.auth.getCurrentUser().then((e) => {
|
|
755
|
-
this.resolveUser && (this.resolveUser(e), this.resolveUser = void 0);
|
|
756
|
-
}).catch((e) => {
|
|
757
|
-
this.logger.error("Auto user fetch failed", { data: e }), this.resolveUser && (this.resolveUser(void 0), this.resolveUser = void 0);
|
|
758
|
-
}) : this.activeUser.value ? this.resolveUser?.(this.activeUser.value) : this.resolveUser?.(void 0);
|
|
759
|
-
}
|
|
760
|
-
processApiResponse(e) {
|
|
761
|
-
if (!e.ok) return;
|
|
762
|
-
let t = !1;
|
|
763
|
-
e.user && (this.activeUser.value = e.user, this.logger.info("User updated from API response", { data: e.user }), t = !0), e.token && (this.token.value = e.token, this.logger.info("Token updated from API response"), t = !0);
|
|
764
|
-
let n = e.data?.deviceId;
|
|
765
|
-
n && (this.deviceId.value = n, t = !0), t && this.persistAuth(), this.resolveUser && (this.resolveUser(e.user), this.resolveUser = void 0);
|
|
766
|
-
}
|
|
767
|
-
authRefs() {
|
|
768
|
-
return {
|
|
769
|
-
activeUser: this.activeUser,
|
|
770
|
-
token: this.token,
|
|
771
|
-
deviceId: this.deviceId
|
|
772
|
-
};
|
|
773
|
-
}
|
|
774
|
-
persistAuth() {
|
|
775
|
-
this.storage.saveToStorage(this.authRefs());
|
|
776
|
-
}
|
|
777
|
-
clearSession() {
|
|
778
|
-
this.logger.info("Clearing session"), this.activeUser.value = void 0, this.token.value = null, this.deviceId.value = null, this.error.value = null, this.storage.clearStorage();
|
|
779
|
-
}
|
|
780
|
-
clear() {
|
|
781
|
-
this.logger.info("Clearing SDK completely"), this.clearSession(), this.loading.value = !1, this.sessionId = a({ prefix: "ses" }), S.delete();
|
|
782
|
-
}
|
|
783
|
-
};
|
|
784
|
-
//#endregion
|
|
785
|
-
export { AuthClient as a, resolveApiBase as c, BillingClient as i, UserClient as n, AgentClient as o, ChatClient as r, _defineProperty as s, C as t };
|
|
530
|
+
u(X, "toChatMessage");
|
|
531
|
+
const q = class q {
|
|
532
|
+
constructor(e) {
|
|
533
|
+
l(this, "ctx");
|
|
534
|
+
this.ctx = e;
|
|
535
|
+
}
|
|
536
|
+
async cancelConversationTurn(e) {
|
|
537
|
+
const t = p(this.ctx.apiBase, this.ctx.isDev), o = this.ctx.token.value ? { Authorization: `Bearer ${this.ctx.token.value}` } : {}, r = await fetch(`${t}/api/conversations/${encodeURIComponent(e.conversationId)}/cancel`, {
|
|
538
|
+
method: "POST",
|
|
539
|
+
headers: { "Content-Type": "application/json", ...o },
|
|
540
|
+
body: JSON.stringify(e.turnId ? { turnId: e.turnId } : {})
|
|
541
|
+
}), s = await r.json();
|
|
542
|
+
if (!s.ok)
|
|
543
|
+
throw new Error(s.error || `Cancel failed: HTTP ${r.status}`);
|
|
544
|
+
return s.data;
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* Public/visitor chat — anonymous chat against an agent's public handle,
|
|
548
|
+
* routed through the messaging substrate. Same SSE wire format as
|
|
549
|
+
* `chatStreamAuthenticated` — the only difference is the route (no auth,
|
|
550
|
+
* handle-based lookup, anonymousId instead of userId).
|
|
551
|
+
*
|
|
552
|
+
* The visitor identity is `anonymousId` — caller is responsible for
|
|
553
|
+
* generating + persisting it (typically `sdk.user.generateAnonId()`
|
|
554
|
+
* which stores a stable ID in localStorage).
|
|
555
|
+
*/
|
|
556
|
+
async chatStreamPublic(e) {
|
|
557
|
+
const o = `${p(this.ctx.apiBase, this.ctx.isDev)}/api/agents/public/${encodeURIComponent(e.handle)}/chat/v2/stream`;
|
|
558
|
+
let r = "", s = !1, n = !1, h;
|
|
559
|
+
try {
|
|
560
|
+
const a = await fetch(o, {
|
|
561
|
+
method: "POST",
|
|
562
|
+
headers: { "Content-Type": "application/json" },
|
|
563
|
+
body: JSON.stringify({
|
|
564
|
+
message: e.message,
|
|
565
|
+
anonymousId: e.anonymousId,
|
|
566
|
+
...e.attachments?.length ? { attachments: e.attachments } : {},
|
|
567
|
+
...e.context ? { context: e.context } : {}
|
|
568
|
+
})
|
|
569
|
+
});
|
|
570
|
+
if (!a.ok) {
|
|
571
|
+
const f = await a.json().catch(() => ({ error: "Request failed" }));
|
|
572
|
+
e.onError(f.error || `HTTP ${a.status}`);
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
if (r = a.headers.get("X-Conversation-Id") || "", h = a.body?.getReader(), !h) {
|
|
576
|
+
e.onError("No response stream");
|
|
577
|
+
return;
|
|
578
|
+
}
|
|
579
|
+
const c = new TextDecoder();
|
|
580
|
+
let d = "";
|
|
581
|
+
e: for (; ; ) {
|
|
582
|
+
const { done: f, value: m } = await h.read();
|
|
583
|
+
if (f)
|
|
584
|
+
break;
|
|
585
|
+
d += c.decode(m, { stream: !0 });
|
|
586
|
+
let I = d.indexOf(`
|
|
786
587
|
|
|
787
|
-
|
|
588
|
+
`);
|
|
589
|
+
for (; I !== -1; ) {
|
|
590
|
+
const x = d.slice(0, I);
|
|
591
|
+
d = d.slice(I + 2);
|
|
592
|
+
const g = de(x);
|
|
593
|
+
if (g) {
|
|
594
|
+
if (g.event === "working_state")
|
|
595
|
+
e.onStatus?.(g.data.description);
|
|
596
|
+
else if (g.event === "tool_activity")
|
|
597
|
+
e.onToolActivity?.(g.data);
|
|
598
|
+
else if (g.event === "working_end")
|
|
599
|
+
e.onWorkingEnd?.();
|
|
600
|
+
else if (g.event === "message_delta")
|
|
601
|
+
e.onDelta(g.data.delta, g.data.role);
|
|
602
|
+
else if (g.event === "error") {
|
|
603
|
+
s = !0, e.onError(Y(g.data));
|
|
604
|
+
break e;
|
|
605
|
+
} else if (g.event === "message" && (g.data.message.role === "assistant" || g.data.message.role === "system")) {
|
|
606
|
+
n = !0;
|
|
607
|
+
const K = X(g.data.message);
|
|
608
|
+
K && e.onMessage?.(K);
|
|
609
|
+
} else if (g.event === "stream_end")
|
|
610
|
+
break e;
|
|
611
|
+
}
|
|
612
|
+
I = d.indexOf(`
|
|
613
|
+
|
|
614
|
+
`);
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
!s && n ? e.onDone(r) : s || e.onError("Stream ended before reply arrived");
|
|
618
|
+
} catch (a) {
|
|
619
|
+
e.onError(a instanceof Error ? a.message : "Stream failed");
|
|
620
|
+
} finally {
|
|
621
|
+
try {
|
|
622
|
+
await h?.cancel();
|
|
623
|
+
} catch {
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* Authenticated chat — substrate-backed:
|
|
629
|
+
* POST /api/conversations, open SSE from that conversation's latest
|
|
630
|
+
* sequence, then POST /api/messages. Opening the stream before send keeps
|
|
631
|
+
* fast working_state / message_delta frames from outrunning the subscriber.
|
|
632
|
+
* Same callback contract as `chatStream` so callers don't need transport details.
|
|
633
|
+
* Mirrors `src/modules/agent/client.ts → sendChatMessageStream`.
|
|
634
|
+
*/
|
|
635
|
+
async chatStreamAuthenticated(e) {
|
|
636
|
+
const t = p(this.ctx.apiBase, this.ctx.isDev), o = this.ctx.token.value ? { Authorization: `Bearer ${this.ctx.token.value}` } : {};
|
|
637
|
+
let r, s = null;
|
|
638
|
+
try {
|
|
639
|
+
const c = await fetch(`${t}/api/conversations`, {
|
|
640
|
+
method: "POST",
|
|
641
|
+
headers: { "Content-Type": "application/json", ...o },
|
|
642
|
+
body: JSON.stringify({ agentId: e.agentId })
|
|
643
|
+
}), d = await c.json();
|
|
644
|
+
if (!d.ok) {
|
|
645
|
+
e.onError(d.error || `Conversation failed: HTTP ${c.status}`);
|
|
646
|
+
return;
|
|
647
|
+
}
|
|
648
|
+
r = d.data.conversationId, s = d.data.latestSequence ?? null;
|
|
649
|
+
} catch (c) {
|
|
650
|
+
e.onError(c instanceof Error ? c.message : "Conversation failed");
|
|
651
|
+
return;
|
|
652
|
+
}
|
|
653
|
+
const n = s ? `${t}/api/conversations/${encodeURIComponent(r)}/stream?since=${encodeURIComponent(s)}` : `${t}/api/conversations/${encodeURIComponent(r)}/stream`, h = `nonce_${se(16)}`, a = ge();
|
|
654
|
+
await ie({
|
|
655
|
+
streamUrl: n,
|
|
656
|
+
sendUrl: `${t}/api/messages`,
|
|
657
|
+
headers: o,
|
|
658
|
+
sendBody: {
|
|
659
|
+
conversationId: r,
|
|
660
|
+
content: e.message,
|
|
661
|
+
clientNonce: h,
|
|
662
|
+
...a ? { viewerTimezone: a } : {},
|
|
663
|
+
...e.attachments && e.attachments.length > 0 ? { attachments: e.attachments } : {}
|
|
664
|
+
},
|
|
665
|
+
onStatus: e.onStatus,
|
|
666
|
+
onDelta: e.onDelta,
|
|
667
|
+
onToolActivity: e.onToolActivity,
|
|
668
|
+
onWorkingEnd: e.onWorkingEnd,
|
|
669
|
+
onMessage: /* @__PURE__ */ u((c) => {
|
|
670
|
+
const d = X(c);
|
|
671
|
+
d && e.onMessage?.(d);
|
|
672
|
+
}, "onMessage"),
|
|
673
|
+
onDone: /* @__PURE__ */ u(() => e.onDone(r), "onDone"),
|
|
674
|
+
onChatError: /* @__PURE__ */ u((c) => e.onError(Y(c)), "onChatError"),
|
|
675
|
+
// A coded rejection (e.g. TURN_ACTIVE) stays structured so the
|
|
676
|
+
// controller can switch on it; only uncoded transport failures
|
|
677
|
+
// flatten to the legacy string path.
|
|
678
|
+
onTransportError: /* @__PURE__ */ u((c) => e.onError(c.code ? { code: c.code, error: c.message } : he(c)), "onTransportError")
|
|
679
|
+
});
|
|
680
|
+
}
|
|
681
|
+
};
|
|
682
|
+
u(q, "ChatClient");
|
|
683
|
+
let j = q;
|
|
684
|
+
const M = class M {
|
|
685
|
+
constructor(e) {
|
|
686
|
+
l(this, "ctx");
|
|
687
|
+
this.ctx = e;
|
|
688
|
+
}
|
|
689
|
+
async getPublicAgent(e) {
|
|
690
|
+
this.ctx.loading.value = !0, this.ctx.error.value = null;
|
|
691
|
+
try {
|
|
692
|
+
const o = await (await this.ctx.apiFetch(`/api/agents/public/${encodeURIComponent(e.handle)}`)).json();
|
|
693
|
+
if (!o.ok) {
|
|
694
|
+
this.ctx.error.value = o.error, this.ctx.logger.error("Failed to fetch public agent", { handle: e.handle, error: o.error });
|
|
695
|
+
return;
|
|
696
|
+
}
|
|
697
|
+
return o.data;
|
|
698
|
+
} catch (t) {
|
|
699
|
+
this.ctx.logger.error("Get public agent error", { handle: e.handle, error: t }), this.ctx.error.value = t instanceof Error ? t.message : "Failed to fetch agent";
|
|
700
|
+
return;
|
|
701
|
+
} finally {
|
|
702
|
+
this.ctx.loading.value = !1;
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
async getAgentByEmail(e) {
|
|
706
|
+
this.ctx.loading.value = !0, this.ctx.error.value = null;
|
|
707
|
+
try {
|
|
708
|
+
const o = await (await this.ctx.apiFetch(`/api/agents/by-email/${encodeURIComponent(e.email)}`)).json();
|
|
709
|
+
if (!o.ok) {
|
|
710
|
+
this.ctx.error.value = o.error, this.ctx.logger.error("Failed to fetch agent by email", { email: e.email, error: o.error });
|
|
711
|
+
return;
|
|
712
|
+
}
|
|
713
|
+
return o.data;
|
|
714
|
+
} catch (t) {
|
|
715
|
+
this.ctx.logger.error("Get agent by email error", { email: e.email, error: t }), this.ctx.error.value = t instanceof Error ? t.message : "Failed to fetch agent";
|
|
716
|
+
return;
|
|
717
|
+
} finally {
|
|
718
|
+
this.ctx.loading.value = !1;
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
generateAnonId() {
|
|
722
|
+
const e = "pagelinesAnonId";
|
|
723
|
+
let t = this.ctx.storage.getItem(e);
|
|
724
|
+
return t || (t = P({ prefix: "anon" }), this.ctx.storage.setItem(e, t)), t;
|
|
725
|
+
}
|
|
726
|
+
track(e) {
|
|
727
|
+
try {
|
|
728
|
+
typeof window < "u" && window.parent !== window && window.parent.postMessage({
|
|
729
|
+
type: "pagelines_track",
|
|
730
|
+
event: e.event,
|
|
731
|
+
agentId: e.agentId,
|
|
732
|
+
properties: e.properties || {}
|
|
733
|
+
}, "*"), this.ctx.logger.info("SDK event tracked", { event: e.event, agentId: e.agentId });
|
|
734
|
+
} catch (t) {
|
|
735
|
+
this.ctx.logger.error("Track event error", { error: t, args: e });
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
};
|
|
739
|
+
u(M, "UserClient");
|
|
740
|
+
let C = M;
|
|
741
|
+
const H = class H {
|
|
742
|
+
constructor() {
|
|
743
|
+
l(this, "key", "__PAGELINES_SDK__");
|
|
744
|
+
}
|
|
745
|
+
get() {
|
|
746
|
+
if (!(typeof window > "u"))
|
|
747
|
+
return globalThis[this.key];
|
|
748
|
+
}
|
|
749
|
+
set(e) {
|
|
750
|
+
typeof window < "u" && (globalThis[this.key] = e);
|
|
751
|
+
}
|
|
752
|
+
delete() {
|
|
753
|
+
typeof window < "u" && delete globalThis[this.key];
|
|
754
|
+
}
|
|
755
|
+
};
|
|
756
|
+
u(H, "SDKGlobal");
|
|
757
|
+
let _ = H;
|
|
758
|
+
const $ = new _(), O = class O extends ne {
|
|
759
|
+
constructor(t = {}) {
|
|
760
|
+
const o = $.get();
|
|
761
|
+
if (o)
|
|
762
|
+
return console.debug("[PageLinesSDK] Returning existing singleton instance"), o;
|
|
763
|
+
super("PageLinesSDK", t);
|
|
764
|
+
// Vue reactive state
|
|
765
|
+
l(this, "activeUser", b());
|
|
766
|
+
l(this, "token", b(null));
|
|
767
|
+
// Opaque session token for Bearer clients. Web may also have the same
|
|
768
|
+
// credential in the HttpOnly pl-session cookie, which JS cannot read.
|
|
769
|
+
l(this, "deviceId", b(null));
|
|
770
|
+
l(this, "loading", b(!1));
|
|
771
|
+
l(this, "error", b(null));
|
|
772
|
+
l(this, "apiBase", this.settings.apiBase || void 0);
|
|
773
|
+
// Storage handler for persistence
|
|
774
|
+
l(this, "storage", new D());
|
|
775
|
+
// Auto-managed session ID for usage tracking
|
|
776
|
+
l(this, "sessionId", P({ prefix: "ses" }));
|
|
777
|
+
// Computed properties derived from activeUser (matches UserClient pattern)
|
|
778
|
+
l(this, "currentAgent", V(() => {
|
|
779
|
+
const t = this.activeUser.value;
|
|
780
|
+
if (!t?.agents)
|
|
781
|
+
return;
|
|
782
|
+
const o = t.primaryAgentId || t.agents[0]?.agentId;
|
|
783
|
+
if (o)
|
|
784
|
+
return t.agents.find((r) => r.agentId === o);
|
|
785
|
+
}));
|
|
786
|
+
l(this, "currentOrg", V(() => {
|
|
787
|
+
const t = this.currentAgent.value;
|
|
788
|
+
if (!t?.orgId)
|
|
789
|
+
return;
|
|
790
|
+
const o = this.activeUser.value;
|
|
791
|
+
if (o?.orgs)
|
|
792
|
+
return o.orgs.find((r) => r.orgId === t.orgId);
|
|
793
|
+
}));
|
|
794
|
+
// Initialization state
|
|
795
|
+
l(this, "initialized");
|
|
796
|
+
l(this, "resolveUser");
|
|
797
|
+
// Sub-clients (new preferred API surface)
|
|
798
|
+
l(this, "agent");
|
|
799
|
+
l(this, "auth");
|
|
800
|
+
l(this, "billing");
|
|
801
|
+
l(this, "chat");
|
|
802
|
+
l(this, "user");
|
|
803
|
+
$.set(this);
|
|
804
|
+
const s = {
|
|
805
|
+
apiFetch: ce(
|
|
806
|
+
{ isDev: this.isDev, apiBase: this.apiBase },
|
|
807
|
+
this.processApiResponse.bind(this),
|
|
808
|
+
() => this.clearSession()
|
|
809
|
+
),
|
|
810
|
+
apiBase: this.apiBase,
|
|
811
|
+
isDev: this.isDev,
|
|
812
|
+
activeUser: this.activeUser,
|
|
813
|
+
token: this.token,
|
|
814
|
+
loading: this.loading,
|
|
815
|
+
error: this.error,
|
|
816
|
+
currentAgent: this.currentAgent,
|
|
817
|
+
storage: this.storage,
|
|
818
|
+
sessionId: this.sessionId,
|
|
819
|
+
logger: this.logger,
|
|
820
|
+
processApiResponse: this.processApiResponse.bind(this)
|
|
821
|
+
};
|
|
822
|
+
this.agent = new F(s), this.auth = new R(s), this.billing = new L(s), this.chat = new j(s), this.user = new C(s), this.logger.info("PageLinesSDK initialized"), this.storage.loadFromStorage(this.authRefs()), this.storage.syncWithGlobalStores(this.authRefs()), this.initialized = new Promise((n) => {
|
|
823
|
+
this.resolveUser = n;
|
|
824
|
+
}), this.token.value && !this.activeUser.value ? this.auth.getCurrentUser().then((n) => {
|
|
825
|
+
this.resolveUser && (this.resolveUser(n), this.resolveUser = void 0);
|
|
826
|
+
}).catch((n) => {
|
|
827
|
+
this.logger.error("Auto user fetch failed", { data: n }), this.resolveUser && (this.resolveUser(void 0), this.resolveUser = void 0);
|
|
828
|
+
}) : this.activeUser.value ? this.resolveUser?.(this.activeUser.value) : this.resolveUser?.(void 0);
|
|
829
|
+
}
|
|
830
|
+
/**
|
|
831
|
+
* Get singleton instance in browser (creates if doesn't exist)
|
|
832
|
+
* Node.js: Always creates new instance (no singleton)
|
|
833
|
+
* Recommended: Use this instead of constructor for shared state
|
|
834
|
+
*/
|
|
835
|
+
static getInstance(t = {}) {
|
|
836
|
+
return $.get() || new O(t);
|
|
837
|
+
}
|
|
838
|
+
get isDev() {
|
|
839
|
+
return this.settings.isDev ?? (typeof window < "u" ? window.location.hostname === "localhost" || window.location.hostname.includes("127.0.0.1") : !1);
|
|
840
|
+
}
|
|
841
|
+
// Process ApiResponse for automatic user/token updates - public for dependency injection
|
|
842
|
+
processApiResponse(t) {
|
|
843
|
+
if (!t.ok) return;
|
|
844
|
+
let o = !1;
|
|
845
|
+
t.user && (this.activeUser.value = t.user, this.logger.info("User updated from API response", { data: t.user }), o = !0), t.token && (this.token.value = t.token, this.logger.info("Token updated from API response"), o = !0);
|
|
846
|
+
const r = t.data?.deviceId;
|
|
847
|
+
r && (this.deviceId.value = r, o = !0), o && this.persistAuth(), this.resolveUser && (this.resolveUser(t.user), this.resolveUser = void 0);
|
|
848
|
+
}
|
|
849
|
+
authRefs() {
|
|
850
|
+
return {
|
|
851
|
+
activeUser: this.activeUser,
|
|
852
|
+
token: this.token,
|
|
853
|
+
deviceId: this.deviceId
|
|
854
|
+
};
|
|
855
|
+
}
|
|
856
|
+
persistAuth() {
|
|
857
|
+
this.storage.saveToStorage(this.authRefs());
|
|
858
|
+
}
|
|
859
|
+
// Clear all user data and tokens
|
|
860
|
+
clearSession() {
|
|
861
|
+
this.logger.info("Clearing session"), this.activeUser.value = void 0, this.token.value = null, this.deviceId.value = null, this.error.value = null, this.storage.clearStorage();
|
|
862
|
+
}
|
|
863
|
+
// Full reset - clears session + state + destroys singleton
|
|
864
|
+
clear() {
|
|
865
|
+
this.logger.info("Clearing SDK completely"), this.clearSession(), this.loading.value = !1, this.sessionId = P({ prefix: "ses" }), $.delete();
|
|
866
|
+
}
|
|
867
|
+
};
|
|
868
|
+
u(O, "PageLinesSDK");
|
|
869
|
+
let Z = O;
|
|
870
|
+
export {
|
|
871
|
+
F as A,
|
|
872
|
+
L as B,
|
|
873
|
+
j as C,
|
|
874
|
+
Z as P,
|
|
875
|
+
C as U,
|
|
876
|
+
R as a,
|
|
877
|
+
p as r
|
|
878
|
+
};
|
|
879
|
+
//# sourceMappingURL=sdkClient.js.map
|