@promte/app-library 0.1.7 → 0.1.8
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 +17 -0
- package/dist/index.d.ts +58 -0
- package/dist/index.mjs +412 -271
- package/dist/index.umd.cjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -60,6 +60,23 @@ await client.data().ref("sessions/session-1/events").push({
|
|
|
60
60
|
});
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
+
## Backend functions
|
|
64
|
+
|
|
65
|
+
Call an approved app function or a configured shared-function alias after the provider is ready:
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
const { ready } = usePromte();
|
|
69
|
+
const client = usePromteClient();
|
|
70
|
+
if (ready) {
|
|
71
|
+
const output = await client.functions.invoke("hello", { name: "Ada" });
|
|
72
|
+
// output is the handler result, not the administration run envelope.
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
The running app is bound to its authorized release. In coding preview, calls use the saved draft and the test environment, which can contact real test APIs. Personal sign-in, workspace access and current function governance are required. Credentials stay in administrator-managed connections and must never be placed in browser code.
|
|
77
|
+
|
|
78
|
+
See [App backend functions](../docs/app-functions.md) for manifests, handlers, controlled connections, data scopes, testing, releases, sharing and schedules.
|
|
79
|
+
|
|
63
80
|
## Models/capabilities
|
|
64
81
|
|
|
65
82
|
You can fetch configured models/capabilities from backend:
|
package/dist/index.d.ts
CHANGED
|
@@ -14,6 +14,38 @@ export declare type AppDataScope = "private" | "public";
|
|
|
14
14
|
|
|
15
15
|
export declare type AppDataUpdateMap = Record<string, any>;
|
|
16
16
|
|
|
17
|
+
/** A stored file. Names may contain folders, e.g. "corpus/2024/report.pdf". */
|
|
18
|
+
export declare type AppFile = {
|
|
19
|
+
id: string;
|
|
20
|
+
name: string;
|
|
21
|
+
contentType: string;
|
|
22
|
+
size: number;
|
|
23
|
+
sha256: string;
|
|
24
|
+
createdAt: string;
|
|
25
|
+
updatedAt: string;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* File storage for larger or binary content (documents, images, exports).
|
|
30
|
+
* "private" files belong to the signed-in user; "public" files are shared in the
|
|
31
|
+
* app workspace and only workspace administrators can change them.
|
|
32
|
+
* Uploading a file with an existing name replaces it.
|
|
33
|
+
*/
|
|
34
|
+
export declare type AppFiles = {
|
|
35
|
+
upload(file: Blob, options?: {
|
|
36
|
+
name?: string;
|
|
37
|
+
contentType?: string;
|
|
38
|
+
signal?: AbortSignal;
|
|
39
|
+
}): Promise<AppFile>;
|
|
40
|
+
list(options?: {
|
|
41
|
+
prefix?: string;
|
|
42
|
+
}): Promise<AppFile[]>;
|
|
43
|
+
download(id: string, options?: {
|
|
44
|
+
signal?: AbortSignal;
|
|
45
|
+
}): Promise<Blob>;
|
|
46
|
+
remove(id: string): Promise<void>;
|
|
47
|
+
};
|
|
48
|
+
|
|
17
49
|
export declare type AudioSttRequest = {
|
|
18
50
|
file: File | Blob;
|
|
19
51
|
language?: string;
|
|
@@ -162,6 +194,9 @@ export declare type PromteAppProviderProps = {
|
|
|
162
194
|
|
|
163
195
|
export declare type PromteClient = {
|
|
164
196
|
isReady(): boolean;
|
|
197
|
+
functions: {
|
|
198
|
+
invoke<TInput = unknown, TResult = unknown>(name: string, input: TInput): Promise<TResult>;
|
|
199
|
+
};
|
|
165
200
|
getBackendUrl(): string | null;
|
|
166
201
|
models(req?: PromteModelsRequest): Promise<PromteModelInfo[]>;
|
|
167
202
|
chatCompletions(req: ChatCompletionsRequest): Promise<ChatCompletionsResponse>;
|
|
@@ -199,7 +234,11 @@ export declare type PromteClient = {
|
|
|
199
234
|
update(shareId: string, snapshot: TranslatorLiveShareSnapshot): Promise<void>;
|
|
200
235
|
revoke(shareId: string): Promise<void>;
|
|
201
236
|
};
|
|
237
|
+
guardrails: {
|
|
238
|
+
check(value: unknown): Promise<PromteGuardrailsResult>;
|
|
239
|
+
};
|
|
202
240
|
data(scope?: AppDataScope): AppDataRef;
|
|
241
|
+
files(scope?: AppDataScope): AppFiles;
|
|
203
242
|
};
|
|
204
243
|
|
|
205
244
|
declare type PromteCtxValue = {
|
|
@@ -213,6 +252,19 @@ declare type PromteCtxValue = {
|
|
|
213
252
|
client: PromteClient;
|
|
214
253
|
};
|
|
215
254
|
|
|
255
|
+
export declare type PromteGuardrailsResult = {
|
|
256
|
+
enabled: boolean;
|
|
257
|
+
allowed: boolean;
|
|
258
|
+
outcome: "allow" | "warn" | "block";
|
|
259
|
+
checks: Array<{
|
|
260
|
+
id: string;
|
|
261
|
+
mode: "warn" | "block";
|
|
262
|
+
result: "violation" | "inconclusive";
|
|
263
|
+
matches?: number;
|
|
264
|
+
}>;
|
|
265
|
+
revision: string;
|
|
266
|
+
};
|
|
267
|
+
|
|
216
268
|
export declare type PromteHandshakeState = "booting" | "waiting_for_settings" | "waiting_for_token" | "ready";
|
|
217
269
|
|
|
218
270
|
export declare type PromteModelInfo = {
|
|
@@ -250,6 +302,8 @@ export declare type PromteSettings = {
|
|
|
250
302
|
backendUrl: string;
|
|
251
303
|
parentOrigin?: string;
|
|
252
304
|
user?: PromteUser;
|
|
305
|
+
/** Set by Promte pages that can send backend requests for the app. */
|
|
306
|
+
fetchProxy?: boolean;
|
|
253
307
|
};
|
|
254
308
|
|
|
255
309
|
export declare type PromteUser = {
|
|
@@ -320,6 +374,10 @@ export declare type UsePromteModelsOptions = PromteModelsRequest & {
|
|
|
320
374
|
|
|
321
375
|
export declare function usePromteSettings(): PromteSettings;
|
|
322
376
|
|
|
377
|
+
/**
|
|
378
|
+
* @deprecated Promte sends backend requests for the app and no longer gives
|
|
379
|
+
* the app a token, so this returns null inside current Promte versions.
|
|
380
|
+
*/
|
|
323
381
|
export declare function usePromteToken(): string;
|
|
324
382
|
|
|
325
383
|
export declare function usePromteUser(): PromteUser;
|
package/dist/index.mjs
CHANGED
|
@@ -1,418 +1,508 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import { createContext as
|
|
3
|
-
const
|
|
4
|
-
function
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import { jsx as I } from "react/jsx-runtime";
|
|
2
|
+
import { createContext as G, useState as $, useMemo as x, useCallback as _, useEffect as R, useContext as z } from "react";
|
|
3
|
+
const V = "promte-fetch-request", W = "promte-fetch-response", H = /* @__PURE__ */ new Set([101, 103, 204, 205, 304]);
|
|
4
|
+
function Q() {
|
|
5
|
+
return typeof crypto < "u" && "randomUUID" in crypto ? crypto.randomUUID() : `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
|
|
6
|
+
}
|
|
7
|
+
function F(i) {
|
|
8
|
+
return i.reason ?? new DOMException("The operation was aborted.", "AbortError");
|
|
9
|
+
}
|
|
10
|
+
function K(i, p) {
|
|
11
|
+
if (i == null) return null;
|
|
12
|
+
if (typeof i == "string" || i instanceof Blob || i instanceof ArrayBuffer || ArrayBuffer.isView(i))
|
|
13
|
+
return i;
|
|
14
|
+
if (i instanceof URLSearchParams)
|
|
15
|
+
return p.has("content-type") || p.set("content-type", "application/x-www-form-urlencoded;charset=UTF-8"), i.toString();
|
|
16
|
+
if (i instanceof FormData) {
|
|
17
|
+
const w = [];
|
|
18
|
+
return i.forEach((h, a) => w.push([a, h])), { form: w };
|
|
19
|
+
}
|
|
20
|
+
throw new TypeError("This request body cannot be sent through Promte.");
|
|
21
|
+
}
|
|
22
|
+
function X({ target: i, origin: p }, w, h) {
|
|
23
|
+
return new Promise((a, y) => {
|
|
24
|
+
const l = h.signal;
|
|
25
|
+
if (l != null && l.aborted) return y(F(l));
|
|
26
|
+
const P = Q(), g = new Headers(h.headers);
|
|
27
|
+
g.delete("authorization");
|
|
28
|
+
let v;
|
|
29
|
+
try {
|
|
30
|
+
v = K(h.body, g);
|
|
31
|
+
} catch (r) {
|
|
32
|
+
return y(r);
|
|
33
|
+
}
|
|
34
|
+
const S = () => {
|
|
35
|
+
window.removeEventListener("message", t), l == null || l.removeEventListener("abort", k);
|
|
36
|
+
}, k = () => {
|
|
37
|
+
S(), y(F(l));
|
|
38
|
+
}, t = (r) => {
|
|
39
|
+
if (r.source !== i || r.origin !== p) return;
|
|
40
|
+
const e = r.data;
|
|
41
|
+
if (!e || e.type !== W || e.id !== P) return;
|
|
42
|
+
if (S(), typeof e.error == "string")
|
|
43
|
+
return y(new TypeError(e.error));
|
|
44
|
+
const o = Number(e.status);
|
|
45
|
+
if (!Number.isInteger(o) || o < 200 || o > 599)
|
|
46
|
+
return y(new TypeError("Promte returned an invalid response."));
|
|
47
|
+
try {
|
|
48
|
+
a(
|
|
49
|
+
new Response(H.has(o) ? null : e.body ?? null, {
|
|
50
|
+
status: o,
|
|
51
|
+
statusText: typeof e.statusText == "string" ? e.statusText : "",
|
|
52
|
+
headers: Array.isArray(e.headers) ? e.headers : []
|
|
53
|
+
})
|
|
54
|
+
);
|
|
55
|
+
} catch {
|
|
56
|
+
y(new TypeError("Promte returned an invalid response."));
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
window.addEventListener("message", t), l == null || l.addEventListener("abort", k, { once: !0 });
|
|
60
|
+
const n = [];
|
|
61
|
+
g.forEach((r, e) => n.push([e, r]));
|
|
62
|
+
try {
|
|
63
|
+
i.postMessage(
|
|
64
|
+
{
|
|
65
|
+
type: V,
|
|
66
|
+
id: P,
|
|
67
|
+
path: w,
|
|
68
|
+
method: (h.method || "GET").toUpperCase(),
|
|
69
|
+
headers: n,
|
|
70
|
+
body: v
|
|
71
|
+
},
|
|
72
|
+
p
|
|
73
|
+
);
|
|
74
|
+
} catch (r) {
|
|
75
|
+
S(), y(r);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
const j = G(null);
|
|
80
|
+
function tt({
|
|
81
|
+
children: i,
|
|
82
|
+
expectedParentOrigin: p,
|
|
83
|
+
initTargetOrigin: w,
|
|
84
|
+
retryInit: h = { enabled: !0, intervalMs: 500, maxAttempts: 20 }
|
|
9
85
|
}) {
|
|
10
|
-
const [
|
|
11
|
-
var
|
|
86
|
+
const [a, y] = $(null), [l, P] = $(null), [g, v] = $(null), [S, k] = $(null), [t, n] = $(null), [r, e] = $(null), o = x(() => t ? "booting" : a ? !l && !a.fetchProxy ? "waiting_for_token" : "ready" : "waiting_for_settings", [a, l, t]), u = o === "ready", d = x(() => w || p || "*", [w, p]), c = _(() => {
|
|
87
|
+
var T;
|
|
12
88
|
try {
|
|
13
|
-
const
|
|
14
|
-
(
|
|
15
|
-
} catch (
|
|
16
|
-
|
|
89
|
+
const s = { type: "init", fetchProxy: !0 };
|
|
90
|
+
(T = window.parent) == null || T.postMessage(s, d);
|
|
91
|
+
} catch (s) {
|
|
92
|
+
n((s == null ? void 0 : s.message) || "Failed to post init");
|
|
17
93
|
}
|
|
18
|
-
}, [
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}, [
|
|
22
|
-
if (!(
|
|
23
|
-
const
|
|
24
|
-
let
|
|
25
|
-
const
|
|
26
|
-
if (
|
|
27
|
-
window.clearInterval(
|
|
94
|
+
}, [d]);
|
|
95
|
+
R(() => {
|
|
96
|
+
c();
|
|
97
|
+
}, [c]), R(() => {
|
|
98
|
+
if (!(h != null && h.enabled) || a) return;
|
|
99
|
+
const T = h.intervalMs ?? 500, s = h.maxAttempts ?? 20;
|
|
100
|
+
let m = 0;
|
|
101
|
+
const E = window.setInterval(() => {
|
|
102
|
+
if (a) {
|
|
103
|
+
window.clearInterval(E);
|
|
28
104
|
return;
|
|
29
105
|
}
|
|
30
|
-
if (
|
|
31
|
-
window.clearInterval(
|
|
106
|
+
if (m += 1, m > s) {
|
|
107
|
+
window.clearInterval(E);
|
|
32
108
|
return;
|
|
33
109
|
}
|
|
34
|
-
|
|
35
|
-
},
|
|
36
|
-
return () => window.clearInterval(
|
|
37
|
-
}, [
|
|
38
|
-
const
|
|
39
|
-
if (
|
|
40
|
-
const
|
|
41
|
-
if (!(!
|
|
42
|
-
if (
|
|
43
|
-
const
|
|
44
|
-
if (!(
|
|
110
|
+
c();
|
|
111
|
+
}, T);
|
|
112
|
+
return () => window.clearInterval(E);
|
|
113
|
+
}, [h, a, c]), R(() => {
|
|
114
|
+
const T = (s) => {
|
|
115
|
+
if (p && s.origin !== p) return;
|
|
116
|
+
const m = s.data;
|
|
117
|
+
if (!(!m || typeof m != "object")) {
|
|
118
|
+
if (m.type === "set-settings") {
|
|
119
|
+
const E = m.value;
|
|
120
|
+
if (!(E != null && E.backendUrl) || E.parentOrigin && p && E.parentOrigin !== p)
|
|
45
121
|
return;
|
|
46
|
-
|
|
122
|
+
y(E), e(s.source === window.parent ? s.origin : null), E != null && E.user && k(E.user), n(null);
|
|
47
123
|
return;
|
|
48
124
|
}
|
|
49
|
-
if (
|
|
50
|
-
|
|
125
|
+
if (m.type === "set-token" && typeof m.value == "string") {
|
|
126
|
+
P(m.value), n(null);
|
|
51
127
|
return;
|
|
52
128
|
}
|
|
53
|
-
if (
|
|
54
|
-
|
|
129
|
+
if (m.type === "set-dark-mode" && typeof m.value == "boolean") {
|
|
130
|
+
v(m.value);
|
|
55
131
|
return;
|
|
56
132
|
}
|
|
57
|
-
if (
|
|
58
|
-
|
|
133
|
+
if (m.type === "set-user" && typeof m.value == "object") {
|
|
134
|
+
k(m.value);
|
|
59
135
|
return;
|
|
60
136
|
}
|
|
61
137
|
}
|
|
62
138
|
};
|
|
63
|
-
return window.addEventListener("message",
|
|
64
|
-
}, [
|
|
65
|
-
const
|
|
66
|
-
() =>
|
|
67
|
-
() =>
|
|
68
|
-
|
|
139
|
+
return window.addEventListener("message", T), () => window.removeEventListener("message", T);
|
|
140
|
+
}, [p]);
|
|
141
|
+
const f = x(() => J(
|
|
142
|
+
() => a,
|
|
143
|
+
() => l,
|
|
144
|
+
() => a != null && a.fetchProxy && r && window.parent !== window ? { target: window.parent, origin: r } : null
|
|
145
|
+
), [a, l, r]), b = x(
|
|
69
146
|
() => ({
|
|
70
|
-
settings:
|
|
71
|
-
token:
|
|
72
|
-
isDarkMode:
|
|
147
|
+
settings: a,
|
|
148
|
+
token: l,
|
|
149
|
+
isDarkMode: g,
|
|
73
150
|
user: S,
|
|
74
|
-
ready:
|
|
75
|
-
state:
|
|
76
|
-
error:
|
|
77
|
-
client:
|
|
151
|
+
ready: u,
|
|
152
|
+
state: o,
|
|
153
|
+
error: t,
|
|
154
|
+
client: f
|
|
78
155
|
}),
|
|
79
|
-
[
|
|
156
|
+
[a, l, g, S, u, o, t, f]
|
|
80
157
|
);
|
|
81
|
-
return /* @__PURE__ */
|
|
158
|
+
return /* @__PURE__ */ I(j.Provider, { value: b, children: i });
|
|
82
159
|
}
|
|
83
|
-
function
|
|
84
|
-
children:
|
|
85
|
-
settings:
|
|
86
|
-
token:
|
|
87
|
-
isDarkMode:
|
|
88
|
-
user:
|
|
160
|
+
function et({
|
|
161
|
+
children: i,
|
|
162
|
+
settings: p,
|
|
163
|
+
token: w,
|
|
164
|
+
isDarkMode: h,
|
|
165
|
+
user: a
|
|
89
166
|
}) {
|
|
90
|
-
const
|
|
91
|
-
() =>
|
|
92
|
-
[
|
|
93
|
-
),
|
|
167
|
+
const y = x(
|
|
168
|
+
() => J(() => p, () => w),
|
|
169
|
+
[p, w]
|
|
170
|
+
), l = !!w, P = x(
|
|
94
171
|
() => ({
|
|
95
|
-
settings:
|
|
96
|
-
token:
|
|
97
|
-
isDarkMode:
|
|
98
|
-
user:
|
|
99
|
-
ready:
|
|
100
|
-
state:
|
|
172
|
+
settings: p,
|
|
173
|
+
token: w,
|
|
174
|
+
isDarkMode: h,
|
|
175
|
+
user: a,
|
|
176
|
+
ready: l,
|
|
177
|
+
state: l ? "ready" : "waiting_for_token",
|
|
101
178
|
error: null,
|
|
102
|
-
client:
|
|
179
|
+
client: y
|
|
103
180
|
}),
|
|
104
|
-
[
|
|
181
|
+
[y, h, l, p, w, a]
|
|
105
182
|
);
|
|
106
|
-
return /* @__PURE__ */
|
|
183
|
+
return /* @__PURE__ */ I(j.Provider, { value: P, children: i });
|
|
107
184
|
}
|
|
108
|
-
function
|
|
109
|
-
const
|
|
110
|
-
if (!
|
|
185
|
+
function C() {
|
|
186
|
+
const i = z(j);
|
|
187
|
+
if (!i)
|
|
111
188
|
throw new Error(
|
|
112
189
|
"usePromte must be used inside <PromteAppProvider> or <PromteNativeProvider>"
|
|
113
190
|
);
|
|
114
|
-
return
|
|
191
|
+
return i;
|
|
115
192
|
}
|
|
116
|
-
function
|
|
117
|
-
return
|
|
193
|
+
function rt() {
|
|
194
|
+
return C().settings;
|
|
118
195
|
}
|
|
119
|
-
function
|
|
120
|
-
return
|
|
196
|
+
function nt() {
|
|
197
|
+
return C().token;
|
|
121
198
|
}
|
|
122
|
-
function
|
|
123
|
-
return
|
|
199
|
+
function ot() {
|
|
200
|
+
return C().isDarkMode;
|
|
124
201
|
}
|
|
125
|
-
function
|
|
126
|
-
return
|
|
202
|
+
function st() {
|
|
203
|
+
return C().user;
|
|
127
204
|
}
|
|
128
|
-
function
|
|
129
|
-
return
|
|
205
|
+
function Y() {
|
|
206
|
+
return C().client;
|
|
130
207
|
}
|
|
131
|
-
function
|
|
132
|
-
const { ready:
|
|
133
|
-
if (!
|
|
134
|
-
|
|
208
|
+
function at(i = {}) {
|
|
209
|
+
const { ready: p } = C(), w = Y(), [h, a] = $([]), [y, l] = $(!1), [P, g] = $(null), v = x(() => (Array.isArray(i.type) ? i.type : i.type ? [i.type] : []).filter(Boolean).map((r) => String(r)).join(","), [i.type]), S = i.configuredOnly === !0, k = i.auto !== !1, t = _(async () => {
|
|
210
|
+
if (!p) return [];
|
|
211
|
+
l(!0), g(null);
|
|
135
212
|
try {
|
|
136
|
-
const
|
|
137
|
-
return
|
|
138
|
-
} catch (
|
|
139
|
-
const
|
|
140
|
-
throw
|
|
213
|
+
const n = v ? v.split(",").filter(Boolean) : void 0, r = await w.models({ type: n, configuredOnly: S });
|
|
214
|
+
return a(r), r;
|
|
215
|
+
} catch (n) {
|
|
216
|
+
const r = n instanceof Error ? n.message : String(n);
|
|
217
|
+
throw g(r), n;
|
|
141
218
|
} finally {
|
|
142
|
-
|
|
219
|
+
l(!1);
|
|
143
220
|
}
|
|
144
|
-
}, [
|
|
145
|
-
return
|
|
146
|
-
!
|
|
221
|
+
}, [w, S, p, v]);
|
|
222
|
+
return R(() => {
|
|
223
|
+
!k || !p || t().catch(() => {
|
|
147
224
|
});
|
|
148
|
-
}, [
|
|
225
|
+
}, [k, p, t]), { models: h, loading: y, error: P, reload: t };
|
|
149
226
|
}
|
|
150
|
-
function
|
|
151
|
-
const
|
|
152
|
-
async function
|
|
153
|
-
const
|
|
154
|
-
if (!
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
...
|
|
227
|
+
function J(i, p, w = () => null) {
|
|
228
|
+
const h = (t) => typeof t == "string" && (t.startsWith("gpt-5") || t.startsWith("gpt-6"));
|
|
229
|
+
async function a(t, n) {
|
|
230
|
+
const r = i(), e = p();
|
|
231
|
+
if (!r) throw new Error("Promte settings not received yet");
|
|
232
|
+
const o = r.backendUrl.replace(/\/+$/, ""), u = String(t || "").replace(/^\/+/, ""), d = `${o}/${u}`, c = w();
|
|
233
|
+
if (!c && !e) throw new Error("Promte token not received yet");
|
|
234
|
+
const f = c ? await X(c, u, n) : await fetch(d, {
|
|
235
|
+
...n,
|
|
159
236
|
headers: {
|
|
160
|
-
...
|
|
161
|
-
Authorization: `Bearer ${
|
|
237
|
+
...n.headers || {},
|
|
238
|
+
Authorization: `Bearer ${e}`
|
|
162
239
|
}
|
|
163
240
|
});
|
|
241
|
+
return f.headers.get("X-Promte-Governance-Warning") && (typeof window < "u" && window.dispatchEvent(new CustomEvent("promte:governance-warning", { detail: { endpoint: t } })), console.warn("Promte governance: this request triggered a warning policy.")), f;
|
|
164
242
|
}
|
|
165
|
-
async function
|
|
166
|
-
const
|
|
243
|
+
async function y(t, n) {
|
|
244
|
+
const r = await a(`/app-api/data/${t}`, {
|
|
167
245
|
method: "POST",
|
|
168
246
|
headers: { "Content-Type": "application/json" },
|
|
169
|
-
body: JSON.stringify(
|
|
170
|
-
}),
|
|
171
|
-
if (!
|
|
247
|
+
body: JSON.stringify(n)
|
|
248
|
+
}), e = await r.json().catch(() => ({}));
|
|
249
|
+
if (!r.ok)
|
|
172
250
|
throw new Error(
|
|
173
|
-
(
|
|
251
|
+
(e == null ? void 0 : e.error) || `Request failed (${r.status})`
|
|
174
252
|
);
|
|
175
|
-
return
|
|
253
|
+
return e == null ? void 0 : e.value;
|
|
176
254
|
}
|
|
177
|
-
async function
|
|
178
|
-
const
|
|
179
|
-
t.scope &&
|
|
180
|
-
const
|
|
255
|
+
async function l(t) {
|
|
256
|
+
const n = new URLSearchParams();
|
|
257
|
+
t.scope && n.set("scope", t.scope), t.path && n.set("path", t.path);
|
|
258
|
+
const r = await a(`/app-api/data?${n.toString()}`, {
|
|
181
259
|
method: "GET"
|
|
182
|
-
}),
|
|
183
|
-
if (!
|
|
184
|
-
throw new Error((
|
|
185
|
-
return
|
|
260
|
+
}), e = await r.json().catch(() => ({}));
|
|
261
|
+
if (!r.ok)
|
|
262
|
+
throw new Error((e == null ? void 0 : e.error) || `Request failed (${r.status})`);
|
|
263
|
+
return e == null ? void 0 : e.value;
|
|
186
264
|
}
|
|
187
|
-
async function
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
const o = await
|
|
191
|
-
`/app-api/models${
|
|
265
|
+
async function P(t) {
|
|
266
|
+
const n = new URLSearchParams(), r = t == null ? void 0 : t.type, e = Array.isArray(r) ? r : r ? [r] : [];
|
|
267
|
+
e.length > 0 && n.set("type", e.join(",")), t != null && t.configuredOnly && n.set("configuredOnly", "true");
|
|
268
|
+
const o = await a(
|
|
269
|
+
`/app-api/models${n.toString() ? `?${n.toString()}` : ""}`,
|
|
192
270
|
{ method: "GET" }
|
|
193
|
-
),
|
|
271
|
+
), u = await o.json().catch(() => ({}));
|
|
194
272
|
if (!o.ok)
|
|
195
|
-
throw new Error((
|
|
196
|
-
return (Array.isArray(
|
|
197
|
-
if (!
|
|
198
|
-
const
|
|
199
|
-
return !
|
|
200
|
-
id:
|
|
201
|
-
label:
|
|
202
|
-
type:
|
|
273
|
+
throw new Error((u == null ? void 0 : u.error) || `Request failed (${o.status})`);
|
|
274
|
+
return (Array.isArray(u == null ? void 0 : u.models) ? u.models : []).map((c) => {
|
|
275
|
+
if (!c || typeof c != "object") return null;
|
|
276
|
+
const f = typeof c.id == "string" ? c.id.trim() : "", b = typeof c.label == "string" ? c.label.trim() : f, T = c.type, s = c.configured === !0, m = typeof c.source == "string" && c.source.trim() ? c.source.trim() : void 0;
|
|
277
|
+
return !f || T !== "llm" && T !== "embedding" && T !== "image" && T !== "stt" && T !== "tts" ? null : {
|
|
278
|
+
id: f,
|
|
279
|
+
label: b || f,
|
|
280
|
+
type: T,
|
|
203
281
|
configured: s,
|
|
204
282
|
source: m
|
|
205
283
|
};
|
|
206
284
|
}).filter(
|
|
207
|
-
(
|
|
285
|
+
(c) => !!c
|
|
208
286
|
);
|
|
209
287
|
}
|
|
210
|
-
async function
|
|
211
|
-
const
|
|
212
|
-
if (!
|
|
288
|
+
async function g(t, n) {
|
|
289
|
+
const r = await a(t, n), o = (r.headers.get("content-type") || "").includes("application/json") ? await r.json().catch(() => ({})) : await r.text();
|
|
290
|
+
if (!r.ok)
|
|
213
291
|
throw new Error(
|
|
214
|
-
typeof o == "string" ? o || `Request failed (${
|
|
292
|
+
typeof o == "string" ? o || `Request failed (${r.status})` : (o == null ? void 0 : o.error) || (o == null ? void 0 : o.message) || `Request failed (${r.status})`
|
|
215
293
|
);
|
|
216
294
|
return o;
|
|
217
295
|
}
|
|
218
|
-
const
|
|
219
|
-
const
|
|
220
|
-
return
|
|
221
|
-
},
|
|
222
|
-
const
|
|
296
|
+
const v = (t) => t ? t.split("/").map((n) => n.trim()).filter(Boolean).join("/") : "", S = (t, n) => {
|
|
297
|
+
const r = v(t), e = v(n);
|
|
298
|
+
return r ? e ? `${r}/${e}` : r : e;
|
|
299
|
+
}, k = (t, n) => {
|
|
300
|
+
const r = { scope: t };
|
|
223
301
|
return {
|
|
224
302
|
async get() {
|
|
225
|
-
const
|
|
226
|
-
return
|
|
303
|
+
const e = v(n);
|
|
304
|
+
return l({ ...r, path: e || void 0 });
|
|
227
305
|
},
|
|
228
|
-
async set(
|
|
229
|
-
const o =
|
|
230
|
-
return
|
|
231
|
-
...
|
|
306
|
+
async set(e) {
|
|
307
|
+
const o = v(n);
|
|
308
|
+
return y("set", {
|
|
309
|
+
...r,
|
|
232
310
|
path: o || void 0,
|
|
233
|
-
value:
|
|
311
|
+
value: e
|
|
234
312
|
});
|
|
235
313
|
},
|
|
236
|
-
async update(
|
|
237
|
-
if (!
|
|
314
|
+
async update(e) {
|
|
315
|
+
if (!e || typeof e != "object")
|
|
238
316
|
throw new Error("update requires an object");
|
|
239
317
|
const o = {};
|
|
240
|
-
for (const [
|
|
241
|
-
const
|
|
242
|
-
if (!
|
|
318
|
+
for (const [u, d] of Object.entries(e)) {
|
|
319
|
+
const c = S(n, u);
|
|
320
|
+
if (!c)
|
|
243
321
|
throw new Error("update paths must be non-empty");
|
|
244
|
-
o[
|
|
322
|
+
o[c] = d;
|
|
245
323
|
}
|
|
246
|
-
return
|
|
324
|
+
return y("update", { ...r, updates: o });
|
|
247
325
|
},
|
|
248
326
|
async remove() {
|
|
249
|
-
const
|
|
250
|
-
return
|
|
327
|
+
const e = v(n);
|
|
328
|
+
return y("remove", { ...r, path: e || void 0 });
|
|
251
329
|
},
|
|
252
|
-
async push(
|
|
253
|
-
const o =
|
|
330
|
+
async push(e) {
|
|
331
|
+
const o = v(n);
|
|
254
332
|
if (!o) throw new Error("push requires a path");
|
|
255
|
-
return
|
|
333
|
+
return y("array-push", { ...r, path: o, value: e });
|
|
256
334
|
},
|
|
257
|
-
ref(
|
|
258
|
-
const o =
|
|
335
|
+
ref(e) {
|
|
336
|
+
const o = S(n, e);
|
|
259
337
|
if (!o) throw new Error("ref requires a path");
|
|
260
|
-
return
|
|
338
|
+
return k(t, o);
|
|
261
339
|
}
|
|
262
340
|
};
|
|
263
341
|
};
|
|
264
342
|
return {
|
|
343
|
+
functions: {
|
|
344
|
+
async invoke(t, n) {
|
|
345
|
+
if (!/^[a-z][a-z0-9-]{0,63}$/.test(t)) throw new Error("Choose a valid function name or configured binding alias.");
|
|
346
|
+
const r = await a("/app-api/functions/invoke", {
|
|
347
|
+
method: "POST",
|
|
348
|
+
headers: { "Content-Type": "application/json" },
|
|
349
|
+
body: JSON.stringify({ name: t, input: n })
|
|
350
|
+
}), e = await r.json().catch(() => ({}));
|
|
351
|
+
if (!r.ok) throw new Error((e == null ? void 0 : e.error) || `Function call failed (${r.status})`);
|
|
352
|
+
return e.output;
|
|
353
|
+
}
|
|
354
|
+
},
|
|
265
355
|
isReady() {
|
|
266
|
-
return !!
|
|
356
|
+
return !!i() && (!!p() || !!w());
|
|
267
357
|
},
|
|
268
358
|
getBackendUrl() {
|
|
269
359
|
var t;
|
|
270
|
-
return ((t =
|
|
360
|
+
return ((t = i()) == null ? void 0 : t.backendUrl) ?? null;
|
|
271
361
|
},
|
|
272
362
|
async models(t) {
|
|
273
|
-
return
|
|
363
|
+
return P(t);
|
|
274
364
|
},
|
|
275
365
|
async chatCompletions(t) {
|
|
276
|
-
var
|
|
366
|
+
var b;
|
|
277
367
|
const {
|
|
278
|
-
reasoningEffort:
|
|
279
|
-
reasoning_effort:
|
|
280
|
-
...
|
|
281
|
-
} = t, o =
|
|
282
|
-
...
|
|
368
|
+
reasoningEffort: n,
|
|
369
|
+
reasoning_effort: r,
|
|
370
|
+
...e
|
|
371
|
+
} = t, o = n ?? r, u = {
|
|
372
|
+
...e,
|
|
283
373
|
stream: !1
|
|
284
374
|
};
|
|
285
|
-
o &&
|
|
286
|
-
const
|
|
375
|
+
o && h(t.model) && (u.reasoning_effort = o);
|
|
376
|
+
const d = await a("/openai/chat/completions", {
|
|
287
377
|
method: "POST",
|
|
288
378
|
headers: { "Content-Type": "application/json" },
|
|
289
|
-
body: JSON.stringify(
|
|
290
|
-
}),
|
|
291
|
-
if (!
|
|
379
|
+
body: JSON.stringify(u)
|
|
380
|
+
}), f = (d.headers.get("content-type") || "").includes("application/json") ? await d.json() : await d.text();
|
|
381
|
+
if (!d.ok)
|
|
292
382
|
throw new Error(
|
|
293
|
-
typeof
|
|
383
|
+
typeof f == "string" ? f : (typeof (f == null ? void 0 : f.error) == "string" ? f.error : (b = f == null ? void 0 : f.error) == null ? void 0 : b.message) || `Request failed (${d.status})`
|
|
294
384
|
);
|
|
295
|
-
return
|
|
385
|
+
return f;
|
|
296
386
|
},
|
|
297
387
|
async chatText(t) {
|
|
298
|
-
var
|
|
299
|
-
const
|
|
300
|
-
return ((o = (
|
|
388
|
+
var r, e, o;
|
|
389
|
+
const n = await this.chatCompletions(t);
|
|
390
|
+
return ((o = (e = (r = n == null ? void 0 : n.choices) == null ? void 0 : r[0]) == null ? void 0 : e.message) == null ? void 0 : o.content) ?? "";
|
|
301
391
|
},
|
|
302
392
|
embeddings: {
|
|
303
393
|
async create(t) {
|
|
304
394
|
var o;
|
|
305
|
-
const
|
|
306
|
-
if (!
|
|
307
|
-
const
|
|
308
|
-
if (!(typeof
|
|
395
|
+
const n = (o = t == null ? void 0 : t.model) == null ? void 0 : o.trim();
|
|
396
|
+
if (!n) throw new Error("embeddings.create requires a model");
|
|
397
|
+
const r = t == null ? void 0 : t.input;
|
|
398
|
+
if (!(typeof r == "string" ? r.length > 0 : Array.isArray(r) && r.length > 0 && r.every((u) => typeof u == "string")))
|
|
309
399
|
throw new Error(
|
|
310
400
|
"embeddings.create requires input as a string or string[]"
|
|
311
401
|
);
|
|
312
|
-
return
|
|
402
|
+
return g("/openai/embeddings", {
|
|
313
403
|
method: "POST",
|
|
314
404
|
headers: { "Content-Type": "application/json" },
|
|
315
405
|
body: JSON.stringify({
|
|
316
406
|
...t,
|
|
317
|
-
model:
|
|
318
|
-
input:
|
|
407
|
+
model: n,
|
|
408
|
+
input: r
|
|
319
409
|
})
|
|
320
410
|
});
|
|
321
411
|
}
|
|
322
412
|
},
|
|
323
413
|
audio: {
|
|
324
414
|
async speechToken() {
|
|
325
|
-
const t = await
|
|
415
|
+
const t = await a("/app-api/audio/speech-token", { method: "POST" });
|
|
326
416
|
if (!t.ok) throw new Error("Live talegenkendelse er ikke tilgængelig. Kontakt administratoren.");
|
|
327
417
|
return t.json();
|
|
328
418
|
},
|
|
329
419
|
async voiceLiveSession() {
|
|
330
|
-
const t = await
|
|
420
|
+
const t = await a("/app-api/audio/voice-live-session", {
|
|
331
421
|
method: "POST"
|
|
332
422
|
});
|
|
333
423
|
if (!t.ok) {
|
|
334
|
-
const
|
|
335
|
-
throw new Error(
|
|
424
|
+
const n = await t.text();
|
|
425
|
+
throw new Error(n || "Voice Live er ikke tilgængelig.");
|
|
336
426
|
}
|
|
337
427
|
return t.json();
|
|
338
428
|
},
|
|
339
429
|
async tts(t) {
|
|
340
430
|
var o;
|
|
341
|
-
const
|
|
342
|
-
if (!
|
|
343
|
-
const
|
|
431
|
+
const n = (o = t == null ? void 0 : t.text) == null ? void 0 : o.trim();
|
|
432
|
+
if (!n) throw new Error("audio.tts requires non-empty text");
|
|
433
|
+
const r = await a("/app-api/audio/tts", {
|
|
344
434
|
method: "POST",
|
|
345
435
|
headers: { "Content-Type": "application/json" },
|
|
346
436
|
body: JSON.stringify({
|
|
347
|
-
text:
|
|
437
|
+
text: n,
|
|
348
438
|
voice: t.voice,
|
|
349
439
|
lang: t.lang
|
|
350
440
|
})
|
|
351
441
|
});
|
|
352
|
-
if (!
|
|
353
|
-
const
|
|
354
|
-
throw new Error(
|
|
442
|
+
if (!r.ok) {
|
|
443
|
+
const u = await r.text();
|
|
444
|
+
throw new Error(u || `Request failed (${r.status})`);
|
|
355
445
|
}
|
|
356
446
|
return {
|
|
357
|
-
audio: await
|
|
358
|
-
contentType:
|
|
447
|
+
audio: await r.arrayBuffer(),
|
|
448
|
+
contentType: r.headers.get("content-type")
|
|
359
449
|
};
|
|
360
450
|
},
|
|
361
451
|
async stt(t) {
|
|
362
|
-
var
|
|
452
|
+
var U, O, L, A;
|
|
363
453
|
if (!(t != null && t.file)) throw new Error("audio.stt requires a file");
|
|
364
|
-
const
|
|
365
|
-
if (!
|
|
366
|
-
const
|
|
367
|
-
if (!
|
|
368
|
-
const
|
|
369
|
-
return
|
|
370
|
-
},
|
|
371
|
-
|
|
372
|
-
const
|
|
373
|
-
|
|
374
|
-
const
|
|
375
|
-
|
|
376
|
-
const
|
|
377
|
-
`/app-api/audio/stt?${
|
|
454
|
+
const n = (U = t.language) == null ? void 0 : U.trim(), r = (M) => {
|
|
455
|
+
if (!M) return;
|
|
456
|
+
const N = M.trim();
|
|
457
|
+
if (!N) return;
|
|
458
|
+
const B = N.toLowerCase(), D = B.split("-")[0];
|
|
459
|
+
return D.length === 2 ? D : B;
|
|
460
|
+
}, e = typeof File < "u" && t.file instanceof File, o = e && t.file.name.split(".").pop() || "webm", u = t.ext || o, d = new FormData();
|
|
461
|
+
e ? d.set("file", t.file) : d.set("file", t.file, `audio.${u}`);
|
|
462
|
+
const c = r(n);
|
|
463
|
+
c && d.set("language", c), t.prompt && d.set("prompt", t.prompt), t.responseFormat && d.set("response_format", t.responseFormat);
|
|
464
|
+
const f = new URLSearchParams({ ext: u });
|
|
465
|
+
n && f.set("locale", n);
|
|
466
|
+
const b = await a(
|
|
467
|
+
`/app-api/audio/stt?${f.toString()}`,
|
|
378
468
|
{
|
|
379
469
|
method: "POST",
|
|
380
|
-
body:
|
|
470
|
+
body: d
|
|
381
471
|
}
|
|
382
|
-
), s = (
|
|
383
|
-
if (!
|
|
472
|
+
), s = (b.headers.get("content-type") || "").includes("application/json") ? await b.json() : await b.text();
|
|
473
|
+
if (!b.ok)
|
|
384
474
|
throw new Error(
|
|
385
|
-
typeof s == "string" ? s : ((
|
|
475
|
+
typeof s == "string" ? s : (typeof (s == null ? void 0 : s.error) == "string" ? s.error : (O = s == null ? void 0 : s.error) == null ? void 0 : O.message) || `Request failed (${b.status})`
|
|
386
476
|
);
|
|
387
|
-
const m = typeof s == "string" ? s : (s == null ? void 0 : s.text) || (s == null ? void 0 : s.original) || ((
|
|
388
|
-
return { text: m, language:
|
|
477
|
+
const m = typeof s == "string" ? s : (s == null ? void 0 : s.text) || (s == null ? void 0 : s.original) || ((A = (L = s == null ? void 0 : s.results) == null ? void 0 : L[0]) == null ? void 0 : A.text) || "", E = typeof s == "object" && typeof (s == null ? void 0 : s.language) == "string" ? s.language : void 0;
|
|
478
|
+
return { text: m, language: E, raw: s };
|
|
389
479
|
},
|
|
390
480
|
async voices(t) {
|
|
391
|
-
const
|
|
392
|
-
t != null && t.locale &&
|
|
393
|
-
const
|
|
394
|
-
`/app-api/audio/tts/voices${
|
|
481
|
+
const n = new URLSearchParams();
|
|
482
|
+
t != null && t.locale && n.set("locale", t.locale);
|
|
483
|
+
const r = await a(
|
|
484
|
+
`/app-api/audio/tts/voices${n.toString() ? `?${n}` : ""}`,
|
|
395
485
|
{ method: "GET" }
|
|
396
|
-
),
|
|
397
|
-
if (!
|
|
486
|
+
), e = await r.json().catch(() => []);
|
|
487
|
+
if (!r.ok)
|
|
398
488
|
throw new Error(
|
|
399
|
-
(
|
|
489
|
+
(e == null ? void 0 : e.error) || `Request failed (${r.status})`
|
|
400
490
|
);
|
|
401
|
-
return Array.isArray(
|
|
491
|
+
return Array.isArray(e) ? e : (e == null ? void 0 : e.voices) || [];
|
|
402
492
|
}
|
|
403
493
|
},
|
|
404
494
|
web: {
|
|
405
495
|
async scrapeUrl(t) {
|
|
406
|
-
var
|
|
407
|
-
const
|
|
408
|
-
if (!
|
|
409
|
-
return
|
|
496
|
+
var r;
|
|
497
|
+
const n = (r = t == null ? void 0 : t.url) == null ? void 0 : r.trim();
|
|
498
|
+
if (!n) throw new Error("web.scrapeUrl requires a url");
|
|
499
|
+
return g(
|
|
410
500
|
"/app-api/web/scrape-url",
|
|
411
501
|
{
|
|
412
502
|
method: "POST",
|
|
413
503
|
headers: { "Content-Type": "application/json" },
|
|
414
504
|
body: JSON.stringify({
|
|
415
|
-
url:
|
|
505
|
+
url: n,
|
|
416
506
|
maxChars: t.maxChars
|
|
417
507
|
})
|
|
418
508
|
}
|
|
@@ -421,17 +511,17 @@ function F(f, l) {
|
|
|
421
511
|
},
|
|
422
512
|
knowledge: {
|
|
423
513
|
async search(t) {
|
|
424
|
-
var
|
|
425
|
-
const
|
|
426
|
-
if (!
|
|
427
|
-
return
|
|
514
|
+
var r;
|
|
515
|
+
const n = (r = t == null ? void 0 : t.query) == null ? void 0 : r.trim();
|
|
516
|
+
if (!n) throw new Error("knowledge.search requires a query");
|
|
517
|
+
return g(
|
|
428
518
|
"/app-api/knowledge/search",
|
|
429
519
|
{
|
|
430
520
|
method: "POST",
|
|
431
521
|
headers: { "Content-Type": "application/json" },
|
|
432
522
|
body: JSON.stringify({
|
|
433
523
|
workspaceId: t.workspaceId,
|
|
434
|
-
query:
|
|
524
|
+
query: n,
|
|
435
525
|
maxResults: t.maxResults,
|
|
436
526
|
generateSearchQuery: t.generateSearchQuery,
|
|
437
527
|
sourceId: t.sourceId,
|
|
@@ -444,38 +534,89 @@ function F(f, l) {
|
|
|
444
534
|
},
|
|
445
535
|
translatorLiveShare: {
|
|
446
536
|
async create(t) {
|
|
447
|
-
return
|
|
537
|
+
return g("/app-api/translator/live-share", {
|
|
448
538
|
method: "POST",
|
|
449
539
|
headers: { "Content-Type": "application/json" },
|
|
450
540
|
body: JSON.stringify({ displayLanguage: t })
|
|
451
541
|
});
|
|
452
542
|
},
|
|
453
|
-
async update(t,
|
|
454
|
-
await
|
|
543
|
+
async update(t, n) {
|
|
544
|
+
await g(`/app-api/translator/live-share/${encodeURIComponent(t)}`, {
|
|
455
545
|
method: "PUT",
|
|
456
546
|
headers: { "Content-Type": "application/json" },
|
|
457
|
-
body: JSON.stringify(
|
|
547
|
+
body: JSON.stringify(n)
|
|
458
548
|
});
|
|
459
549
|
},
|
|
460
550
|
async revoke(t) {
|
|
461
|
-
await
|
|
551
|
+
await g(`/app-api/translator/live-share/${encodeURIComponent(t)}`, {
|
|
462
552
|
method: "DELETE"
|
|
463
553
|
});
|
|
464
554
|
}
|
|
465
555
|
},
|
|
556
|
+
guardrails: {
|
|
557
|
+
async check(t) {
|
|
558
|
+
return g("/app-api/guardrails/check", {
|
|
559
|
+
method: "POST",
|
|
560
|
+
headers: { "Content-Type": "application/json" },
|
|
561
|
+
body: JSON.stringify({ value: t })
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
},
|
|
466
565
|
data(t = "private") {
|
|
467
|
-
return
|
|
566
|
+
return k(t, "");
|
|
567
|
+
},
|
|
568
|
+
files(t = "private") {
|
|
569
|
+
const n = (e = {}) => new URLSearchParams({ scope: t, ...e }).toString(), r = async (e) => {
|
|
570
|
+
const o = await e.json().catch(() => ({}));
|
|
571
|
+
return new Error((o == null ? void 0 : o.error) || `Request failed (${e.status})`);
|
|
572
|
+
};
|
|
573
|
+
return {
|
|
574
|
+
async upload(e, o = {}) {
|
|
575
|
+
const u = o.name || e.name;
|
|
576
|
+
if (!u) throw new Error("A file name is required.");
|
|
577
|
+
const d = o.contentType || e.type || "application/octet-stream", c = await a(`/app-api/files?${n({ name: u, contentType: d })}`, {
|
|
578
|
+
method: "POST",
|
|
579
|
+
headers: { "Content-Type": "application/octet-stream" },
|
|
580
|
+
body: e,
|
|
581
|
+
signal: o.signal
|
|
582
|
+
});
|
|
583
|
+
if (!c.ok) throw await r(c);
|
|
584
|
+
return (await c.json()).file;
|
|
585
|
+
},
|
|
586
|
+
async list(e = {}) {
|
|
587
|
+
const o = await a(
|
|
588
|
+
`/app-api/files?${n(e.prefix ? { prefix: e.prefix } : {})}`,
|
|
589
|
+
{ method: "GET" }
|
|
590
|
+
);
|
|
591
|
+
if (!o.ok) throw await r(o);
|
|
592
|
+
return (await o.json()).files;
|
|
593
|
+
},
|
|
594
|
+
async download(e, o = {}) {
|
|
595
|
+
const u = await a(`/app-api/files/${encodeURIComponent(e)}?${n()}`, {
|
|
596
|
+
method: "GET",
|
|
597
|
+
signal: o.signal
|
|
598
|
+
});
|
|
599
|
+
if (!u.ok) throw await r(u);
|
|
600
|
+
return u.blob();
|
|
601
|
+
},
|
|
602
|
+
async remove(e) {
|
|
603
|
+
const o = await a(`/app-api/files/${encodeURIComponent(e)}?${n()}`, {
|
|
604
|
+
method: "DELETE"
|
|
605
|
+
});
|
|
606
|
+
if (!o.ok) throw await r(o);
|
|
607
|
+
}
|
|
608
|
+
};
|
|
468
609
|
}
|
|
469
610
|
};
|
|
470
611
|
}
|
|
471
612
|
export {
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
613
|
+
tt as PromteAppProvider,
|
|
614
|
+
et as PromteNativeProvider,
|
|
615
|
+
C as usePromte,
|
|
616
|
+
Y as usePromteClient,
|
|
617
|
+
ot as usePromteDarkMode,
|
|
618
|
+
at as usePromteModels,
|
|
619
|
+
rt as usePromteSettings,
|
|
620
|
+
nt as usePromteToken,
|
|
621
|
+
st as usePromteUser
|
|
481
622
|
};
|
package/dist/index.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(w,$){typeof exports=="object"&&typeof module<"u"?$(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],$):(w=typeof globalThis<"u"?globalThis:w||self,$(w.PromteAppLibrary={},w.jsxRuntime,w.react))})(this,function(w,$,u){"use strict";const C=u.createContext(null);function D({children:d,expectedParentOrigin:f,initTargetOrigin:S,retryInit:c={enabled:!0,intervalMs:500,maxAttempts:20}}){const[p,k]=u.useState(null),[v,P]=u.useState(null),[b,E]=u.useState(null),[T,e]=u.useState(null),[r,t]=u.useState(null),n=u.useMemo(()=>r?"booting":p?v?"ready":"waiting_for_token":"waiting_for_settings",[p,v,r]),o=n==="ready",a=u.useMemo(()=>S||f||"*",[S,f]),l=u.useCallback(()=>{var m;try{const h={type:"init"};(m=window.parent)==null||m.postMessage(h,a)}catch(h){t((h==null?void 0:h.message)||"Failed to post init")}},[a]);u.useEffect(()=>{l()},[l]),u.useEffect(()=>{if(!(c!=null&&c.enabled)||p)return;const m=c.intervalMs??500,h=c.maxAttempts??20;let s=0;const y=window.setInterval(()=>{if(p){window.clearInterval(y);return}if(s+=1,s>h){window.clearInterval(y);return}l()},m);return()=>window.clearInterval(y)},[c,p,l]),u.useEffect(()=>{const m=h=>{if(f&&h.origin!==f)return;const s=h.data;if(!(!s||typeof s!="object")){if(s.type==="set-settings"){const y=s.value;if(!(y!=null&&y.backendUrl)||y.parentOrigin&&f&&y.parentOrigin!==f)return;k(y),y!=null&&y.user&&e(y.user),t(null);return}if(s.type==="set-token"&&typeof s.value=="string"){P(s.value),t(null);return}if(s.type==="set-dark-mode"&&typeof s.value=="boolean"){E(s.value);return}if(s.type==="set-user"&&typeof s.value=="object"){e(s.value);return}}};return window.addEventListener("message",m),()=>window.removeEventListener("message",m)},[f]);const i=u.useMemo(()=>M(()=>p,()=>v),[p,v]),g=u.useMemo(()=>({settings:p,token:v,isDarkMode:b,user:T,ready:o,state:n,error:r,client:i}),[p,v,b,T,o,n,r,i]);return $.jsx(C.Provider,{value:g,children:d})}function F({children:d,settings:f,token:S,isDarkMode:c,user:p}){const k=u.useMemo(()=>M(()=>f,()=>S),[f,S]),v=!!S,P=u.useMemo(()=>({settings:f,token:S,isDarkMode:c,user:p,ready:v,state:v?"ready":"waiting_for_token",error:null,client:k}),[k,c,v,f,S,p]);return $.jsx(C.Provider,{value:P,children:d})}function j(){const d=u.useContext(C);if(!d)throw new Error("usePromte must be used inside <PromteAppProvider> or <PromteNativeProvider>");return d}function I(){return j().settings}function J(){return j().token}function G(){return j().isDarkMode}function V(){return j().user}function R(){return j().client}function z(d={}){const{ready:f}=j(),S=R(),[c,p]=u.useState([]),[k,v]=u.useState(!1),[P,b]=u.useState(null),E=u.useMemo(()=>(Array.isArray(d.type)?d.type:d.type?[d.type]:[]).filter(Boolean).map(n=>String(n)).join(","),[d.type]),T=d.configuredOnly===!0,e=d.auto!==!1,r=u.useCallback(async()=>{if(!f)return[];v(!0),b(null);try{const t=E?E.split(",").filter(Boolean):void 0,n=await S.models({type:t,configuredOnly:T});return p(n),n}catch(t){const n=t instanceof Error?t.message:String(t);throw b(n),t}finally{v(!1)}},[S,T,f,E]);return u.useEffect(()=>{!e||!f||r().catch(()=>{})},[e,f,r]),{models:c,loading:k,error:P,reload:r}}function M(d,f){const S=e=>typeof e=="string"&&(e.startsWith("gpt-5")||e.startsWith("gpt-6"));async function c(e,r){const t=d(),n=f();if(!t)throw new Error("Promte settings not received yet");if(!n)throw new Error("Promte token not received yet");const o=t.backendUrl.replace(/\/+$/,""),a=String(e||"").replace(/^\/+/,""),l=`${o}/${a}`;return await fetch(l,{...r,headers:{...r.headers||{},Authorization:`Bearer ${n}`}})}async function p(e,r){const t=await c(`/app-api/data/${e}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)}),n=await t.json().catch(()=>({}));if(!t.ok)throw new Error((n==null?void 0:n.error)||`Request failed (${t.status})`);return n==null?void 0:n.value}async function k(e){const r=new URLSearchParams;e.scope&&r.set("scope",e.scope),e.path&&r.set("path",e.path);const t=await c(`/app-api/data?${r.toString()}`,{method:"GET"}),n=await t.json().catch(()=>({}));if(!t.ok)throw new Error((n==null?void 0:n.error)||`Request failed (${t.status})`);return n==null?void 0:n.value}async function v(e){const r=new URLSearchParams,t=e==null?void 0:e.type,n=Array.isArray(t)?t:t?[t]:[];n.length>0&&r.set("type",n.join(",")),e!=null&&e.configuredOnly&&r.set("configuredOnly","true");const o=await c(`/app-api/models${r.toString()?`?${r.toString()}`:""}`,{method:"GET"}),a=await o.json().catch(()=>({}));if(!o.ok)throw new Error((a==null?void 0:a.error)||`Request failed (${o.status})`);return(Array.isArray(a==null?void 0:a.models)?a.models:[]).map(i=>{if(!i||typeof i!="object")return null;const g=typeof i.id=="string"?i.id.trim():"",m=typeof i.label=="string"?i.label.trim():g,h=i.type,s=i.configured===!0,y=typeof i.source=="string"&&i.source.trim()?i.source.trim():void 0;return!g||h!=="llm"&&h!=="embedding"&&h!=="image"&&h!=="stt"&&h!=="tts"?null:{id:g,label:m||g,type:h,configured:s,source:y}}).filter(i=>!!i)}async function P(e,r){const t=await c(e,r),o=(t.headers.get("content-type")||"").includes("application/json")?await t.json().catch(()=>({})):await t.text();if(!t.ok)throw new Error(typeof o=="string"?o||`Request failed (${t.status})`:(o==null?void 0:o.error)||(o==null?void 0:o.message)||`Request failed (${t.status})`);return o}const b=e=>e?e.split("/").map(r=>r.trim()).filter(Boolean).join("/"):"",E=(e,r)=>{const t=b(e),n=b(r);return t?n?`${t}/${n}`:t:n},T=(e,r)=>{const t={scope:e};return{async get(){const n=b(r);return k({...t,path:n||void 0})},async set(n){const o=b(r);return p("set",{...t,path:o||void 0,value:n})},async update(n){if(!n||typeof n!="object")throw new Error("update requires an object");const o={};for(const[a,l]of Object.entries(n)){const i=E(r,a);if(!i)throw new Error("update paths must be non-empty");o[i]=l}return p("update",{...t,updates:o})},async remove(){const n=b(r);return p("remove",{...t,path:n||void 0})},async push(n){const o=b(r);if(!o)throw new Error("push requires a path");return p("array-push",{...t,path:o,value:n})},ref(n){const o=E(r,n);if(!o)throw new Error("ref requires a path");return T(e,o)}}};return{isReady(){return!!d()&&!!f()},getBackendUrl(){var e;return((e=d())==null?void 0:e.backendUrl)??null},async models(e){return v(e)},async chatCompletions(e){var m;const{reasoningEffort:r,reasoning_effort:t,...n}=e,o=r??t,a={...n,stream:!1};o&&S(e.model)&&(a.reasoning_effort=o);const l=await c("/openai/chat/completions",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)}),g=(l.headers.get("content-type")||"").includes("application/json")?await l.json():await l.text();if(!l.ok)throw new Error(typeof g=="string"?g:((m=g==null?void 0:g.error)==null?void 0:m.message)||`Request failed (${l.status})`);return g},async chatText(e){var t,n,o;const r=await this.chatCompletions(e);return((o=(n=(t=r==null?void 0:r.choices)==null?void 0:t[0])==null?void 0:n.message)==null?void 0:o.content)??""},embeddings:{async create(e){var o;const r=(o=e==null?void 0:e.model)==null?void 0:o.trim();if(!r)throw new Error("embeddings.create requires a model");const t=e==null?void 0:e.input;if(!(typeof t=="string"?t.length>0:Array.isArray(t)&&t.length>0&&t.every(a=>typeof a=="string")))throw new Error("embeddings.create requires input as a string or string[]");return P("/openai/embeddings",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({...e,model:r,input:t})})}},audio:{async speechToken(){const e=await c("/app-api/audio/speech-token",{method:"POST"});if(!e.ok)throw new Error("Live talegenkendelse er ikke tilgængelig. Kontakt administratoren.");return e.json()},async voiceLiveSession(){const e=await c("/app-api/audio/voice-live-session",{method:"POST"});if(!e.ok){const r=await e.text();throw new Error(r||"Voice Live er ikke tilgængelig.")}return e.json()},async tts(e){var o;const r=(o=e==null?void 0:e.text)==null?void 0:o.trim();if(!r)throw new Error("audio.tts requires non-empty text");const t=await c("/app-api/audio/tts",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({text:r,voice:e.voice,lang:e.lang})});if(!t.ok){const a=await t.text();throw new Error(a||`Request failed (${t.status})`)}return{audio:await t.arrayBuffer(),contentType:t.headers.get("content-type")}},async stt(e){var x,U,A,O;if(!(e!=null&&e.file))throw new Error("audio.stt requires a file");const r=(x=e.language)==null?void 0:x.trim(),t=L=>{if(!L)return;const N=L.trim();if(!N)return;const B=N.toLowerCase(),_=B.split("-")[0];return _.length===2?_:B},n=typeof File<"u"&&e.file instanceof File,o=n&&e.file.name.split(".").pop()||"webm",a=e.ext||o,l=new FormData;n?l.set("file",e.file):l.set("file",e.file,`audio.${a}`);const i=t(r);i&&l.set("language",i),e.prompt&&l.set("prompt",e.prompt),e.responseFormat&&l.set("response_format",e.responseFormat);const g=new URLSearchParams({ext:a});r&&g.set("locale",r);const m=await c(`/app-api/audio/stt?${g.toString()}`,{method:"POST",body:l}),s=(m.headers.get("content-type")||"").includes("application/json")?await m.json():await m.text();if(!m.ok)throw new Error(typeof s=="string"?s:((U=s==null?void 0:s.error)==null?void 0:U.message)||`Request failed (${m.status})`);const y=typeof s=="string"?s:(s==null?void 0:s.text)||(s==null?void 0:s.original)||((O=(A=s==null?void 0:s.results)==null?void 0:A[0])==null?void 0:O.text)||"",W=typeof s=="object"&&typeof(s==null?void 0:s.language)=="string"?s.language:void 0;return{text:y,language:W,raw:s}},async voices(e){const r=new URLSearchParams;e!=null&&e.locale&&r.set("locale",e.locale);const t=await c(`/app-api/audio/tts/voices${r.toString()?`?${r}`:""}`,{method:"GET"}),n=await t.json().catch(()=>[]);if(!t.ok)throw new Error((n==null?void 0:n.error)||`Request failed (${t.status})`);return Array.isArray(n)?n:(n==null?void 0:n.voices)||[]}},web:{async scrapeUrl(e){var t;const r=(t=e==null?void 0:e.url)==null?void 0:t.trim();if(!r)throw new Error("web.scrapeUrl requires a url");return P("/app-api/web/scrape-url",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({url:r,maxChars:e.maxChars})})}},knowledge:{async search(e){var t;const r=(t=e==null?void 0:e.query)==null?void 0:t.trim();if(!r)throw new Error("knowledge.search requires a query");return P("/app-api/knowledge/search",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({workspaceId:e.workspaceId,query:r,maxResults:e.maxResults,generateSearchQuery:e.generateSearchQuery,sourceId:e.sourceId,includeSourceUrls:e.includeSourceUrls,queries:e.queries})})}},translatorLiveShare:{async create(e){return P("/app-api/translator/live-share",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({displayLanguage:e})})},async update(e,r){await P(`/app-api/translator/live-share/${encodeURIComponent(e)}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)})},async revoke(e){await P(`/app-api/translator/live-share/${encodeURIComponent(e)}`,{method:"DELETE"})}},data(e="private"){return T(e,"")}}}w.PromteAppProvider=D,w.PromteNativeProvider=F,w.usePromte=j,w.usePromteClient=R,w.usePromteDarkMode=G,w.usePromteModels=z,w.usePromteSettings=I,w.usePromteToken=J,w.usePromteUser=V,Object.defineProperty(w,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
(function(E,R){typeof exports=="object"&&typeof module<"u"?R(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],R):(E=typeof globalThis<"u"?globalThis:E||self,R(E.PromteAppLibrary={},E.jsxRuntime,E.react))})(this,function(E,R,l){"use strict";const J="promte-fetch-request",G="promte-fetch-response",z=new Set([101,103,204,205,304]);function V(){return typeof crypto<"u"&&"randomUUID"in crypto?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}function x(i){return i.reason??new DOMException("The operation was aborted.","AbortError")}function W(i,f){if(i==null)return null;if(typeof i=="string"||i instanceof Blob||i instanceof ArrayBuffer||ArrayBuffer.isView(i))return i;if(i instanceof URLSearchParams)return f.has("content-type")||f.set("content-type","application/x-www-form-urlencoded;charset=UTF-8"),i.toString();if(i instanceof FormData){const w=[];return i.forEach((m,a)=>w.push([a,m])),{form:w}}throw new TypeError("This request body cannot be sent through Promte.")}function H({target:i,origin:f},w,m){return new Promise((a,g)=>{const p=m.signal;if(p!=null&&p.aborted)return g(x(p));const $=V(),v=new Headers(m.headers);v.delete("authorization");let T;try{T=W(m.body,v)}catch(n){return g(n)}const b=()=>{window.removeEventListener("message",e),p==null||p.removeEventListener("abort",j)},j=()=>{b(),g(x(p))},e=n=>{if(n.source!==i||n.origin!==f)return;const t=n.data;if(!t||t.type!==G||t.id!==$)return;if(b(),typeof t.error=="string")return g(new TypeError(t.error));const o=Number(t.status);if(!Number.isInteger(o)||o<200||o>599)return g(new TypeError("Promte returned an invalid response."));try{a(new Response(z.has(o)?null:t.body??null,{status:o,statusText:typeof t.statusText=="string"?t.statusText:"",headers:Array.isArray(t.headers)?t.headers:[]}))}catch{g(new TypeError("Promte returned an invalid response."))}};window.addEventListener("message",e),p==null||p.addEventListener("abort",j,{once:!0});const r=[];v.forEach((n,t)=>r.push([t,n]));try{i.postMessage({type:J,id:$,path:w,method:(m.method||"GET").toUpperCase(),headers:r,body:T},f)}catch(n){b(),g(n)}})}const U=l.createContext(null);function Q({children:i,expectedParentOrigin:f,initTargetOrigin:w,retryInit:m={enabled:!0,intervalMs:500,maxAttempts:20}}){const[a,g]=l.useState(null),[p,$]=l.useState(null),[v,T]=l.useState(null),[b,j]=l.useState(null),[e,r]=l.useState(null),[n,t]=l.useState(null),o=l.useMemo(()=>e?"booting":a?!p&&!a.fetchProxy?"waiting_for_token":"ready":"waiting_for_settings",[a,p,e]),u=o==="ready",h=l.useMemo(()=>w||f||"*",[w,f]),c=l.useCallback(()=>{var P;try{const s={type:"init",fetchProxy:!0};(P=window.parent)==null||P.postMessage(s,h)}catch(s){r((s==null?void 0:s.message)||"Failed to post init")}},[h]);l.useEffect(()=>{c()},[c]),l.useEffect(()=>{if(!(m!=null&&m.enabled)||a)return;const P=m.intervalMs??500,s=m.maxAttempts??20;let y=0;const S=window.setInterval(()=>{if(a){window.clearInterval(S);return}if(y+=1,y>s){window.clearInterval(S);return}c()},P);return()=>window.clearInterval(S)},[m,a,c]),l.useEffect(()=>{const P=s=>{if(f&&s.origin!==f)return;const y=s.data;if(!(!y||typeof y!="object")){if(y.type==="set-settings"){const S=y.value;if(!(S!=null&&S.backendUrl)||S.parentOrigin&&f&&S.parentOrigin!==f)return;g(S),t(s.source===window.parent?s.origin:null),S!=null&&S.user&&j(S.user),r(null);return}if(y.type==="set-token"&&typeof y.value=="string"){$(y.value),r(null);return}if(y.type==="set-dark-mode"&&typeof y.value=="boolean"){T(y.value);return}if(y.type==="set-user"&&typeof y.value=="object"){j(y.value);return}}};return window.addEventListener("message",P),()=>window.removeEventListener("message",P)},[f]);const d=l.useMemo(()=>L(()=>a,()=>p,()=>a!=null&&a.fetchProxy&&n&&window.parent!==window?{target:window.parent,origin:n}:null),[a,p,n]),k=l.useMemo(()=>({settings:a,token:p,isDarkMode:v,user:b,ready:u,state:o,error:e,client:d}),[a,p,v,b,u,o,e,d]);return R.jsx(U.Provider,{value:k,children:i})}function K({children:i,settings:f,token:w,isDarkMode:m,user:a}){const g=l.useMemo(()=>L(()=>f,()=>w),[f,w]),p=!!w,$=l.useMemo(()=>({settings:f,token:w,isDarkMode:m,user:a,ready:p,state:p?"ready":"waiting_for_token",error:null,client:g}),[g,m,p,f,w,a]);return R.jsx(U.Provider,{value:$,children:i})}function C(){const i=l.useContext(U);if(!i)throw new Error("usePromte must be used inside <PromteAppProvider> or <PromteNativeProvider>");return i}function X(){return C().settings}function Y(){return C().token}function Z(){return C().isDarkMode}function q(){return C().user}function O(){return C().client}function ee(i={}){const{ready:f}=C(),w=O(),[m,a]=l.useState([]),[g,p]=l.useState(!1),[$,v]=l.useState(null),T=l.useMemo(()=>(Array.isArray(i.type)?i.type:i.type?[i.type]:[]).filter(Boolean).map(n=>String(n)).join(","),[i.type]),b=i.configuredOnly===!0,j=i.auto!==!1,e=l.useCallback(async()=>{if(!f)return[];p(!0),v(null);try{const r=T?T.split(",").filter(Boolean):void 0,n=await w.models({type:r,configuredOnly:b});return a(n),n}catch(r){const n=r instanceof Error?r.message:String(r);throw v(n),r}finally{p(!1)}},[w,b,f,T]);return l.useEffect(()=>{!j||!f||e().catch(()=>{})},[j,f,e]),{models:m,loading:g,error:$,reload:e}}function L(i,f,w=()=>null){const m=e=>typeof e=="string"&&(e.startsWith("gpt-5")||e.startsWith("gpt-6"));async function a(e,r){const n=i(),t=f();if(!n)throw new Error("Promte settings not received yet");const o=n.backendUrl.replace(/\/+$/,""),u=String(e||"").replace(/^\/+/,""),h=`${o}/${u}`,c=w();if(!c&&!t)throw new Error("Promte token not received yet");const d=c?await H(c,u,r):await fetch(h,{...r,headers:{...r.headers||{},Authorization:`Bearer ${t}`}});return d.headers.get("X-Promte-Governance-Warning")&&(typeof window<"u"&&window.dispatchEvent(new CustomEvent("promte:governance-warning",{detail:{endpoint:e}})),console.warn("Promte governance: this request triggered a warning policy.")),d}async function g(e,r){const n=await a(`/app-api/data/${e}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)}),t=await n.json().catch(()=>({}));if(!n.ok)throw new Error((t==null?void 0:t.error)||`Request failed (${n.status})`);return t==null?void 0:t.value}async function p(e){const r=new URLSearchParams;e.scope&&r.set("scope",e.scope),e.path&&r.set("path",e.path);const n=await a(`/app-api/data?${r.toString()}`,{method:"GET"}),t=await n.json().catch(()=>({}));if(!n.ok)throw new Error((t==null?void 0:t.error)||`Request failed (${n.status})`);return t==null?void 0:t.value}async function $(e){const r=new URLSearchParams,n=e==null?void 0:e.type,t=Array.isArray(n)?n:n?[n]:[];t.length>0&&r.set("type",t.join(",")),e!=null&&e.configuredOnly&&r.set("configuredOnly","true");const o=await a(`/app-api/models${r.toString()?`?${r.toString()}`:""}`,{method:"GET"}),u=await o.json().catch(()=>({}));if(!o.ok)throw new Error((u==null?void 0:u.error)||`Request failed (${o.status})`);return(Array.isArray(u==null?void 0:u.models)?u.models:[]).map(c=>{if(!c||typeof c!="object")return null;const d=typeof c.id=="string"?c.id.trim():"",k=typeof c.label=="string"?c.label.trim():d,P=c.type,s=c.configured===!0,y=typeof c.source=="string"&&c.source.trim()?c.source.trim():void 0;return!d||P!=="llm"&&P!=="embedding"&&P!=="image"&&P!=="stt"&&P!=="tts"?null:{id:d,label:k||d,type:P,configured:s,source:y}}).filter(c=>!!c)}async function v(e,r){const n=await a(e,r),o=(n.headers.get("content-type")||"").includes("application/json")?await n.json().catch(()=>({})):await n.text();if(!n.ok)throw new Error(typeof o=="string"?o||`Request failed (${n.status})`:(o==null?void 0:o.error)||(o==null?void 0:o.message)||`Request failed (${n.status})`);return o}const T=e=>e?e.split("/").map(r=>r.trim()).filter(Boolean).join("/"):"",b=(e,r)=>{const n=T(e),t=T(r);return n?t?`${n}/${t}`:n:t},j=(e,r)=>{const n={scope:e};return{async get(){const t=T(r);return p({...n,path:t||void 0})},async set(t){const o=T(r);return g("set",{...n,path:o||void 0,value:t})},async update(t){if(!t||typeof t!="object")throw new Error("update requires an object");const o={};for(const[u,h]of Object.entries(t)){const c=b(r,u);if(!c)throw new Error("update paths must be non-empty");o[c]=h}return g("update",{...n,updates:o})},async remove(){const t=T(r);return g("remove",{...n,path:t||void 0})},async push(t){const o=T(r);if(!o)throw new Error("push requires a path");return g("array-push",{...n,path:o,value:t})},ref(t){const o=b(r,t);if(!o)throw new Error("ref requires a path");return j(e,o)}}};return{functions:{async invoke(e,r){if(!/^[a-z][a-z0-9-]{0,63}$/.test(e))throw new Error("Choose a valid function name or configured binding alias.");const n=await a("/app-api/functions/invoke",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:e,input:r})}),t=await n.json().catch(()=>({}));if(!n.ok)throw new Error((t==null?void 0:t.error)||`Function call failed (${n.status})`);return t.output}},isReady(){return!!i()&&(!!f()||!!w())},getBackendUrl(){var e;return((e=i())==null?void 0:e.backendUrl)??null},async models(e){return $(e)},async chatCompletions(e){var k;const{reasoningEffort:r,reasoning_effort:n,...t}=e,o=r??n,u={...t,stream:!1};o&&m(e.model)&&(u.reasoning_effort=o);const h=await a("/openai/chat/completions",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(u)}),d=(h.headers.get("content-type")||"").includes("application/json")?await h.json():await h.text();if(!h.ok)throw new Error(typeof d=="string"?d:(typeof(d==null?void 0:d.error)=="string"?d.error:(k=d==null?void 0:d.error)==null?void 0:k.message)||`Request failed (${h.status})`);return d},async chatText(e){var n,t,o;const r=await this.chatCompletions(e);return((o=(t=(n=r==null?void 0:r.choices)==null?void 0:n[0])==null?void 0:t.message)==null?void 0:o.content)??""},embeddings:{async create(e){var o;const r=(o=e==null?void 0:e.model)==null?void 0:o.trim();if(!r)throw new Error("embeddings.create requires a model");const n=e==null?void 0:e.input;if(!(typeof n=="string"?n.length>0:Array.isArray(n)&&n.length>0&&n.every(u=>typeof u=="string")))throw new Error("embeddings.create requires input as a string or string[]");return v("/openai/embeddings",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({...e,model:r,input:n})})}},audio:{async speechToken(){const e=await a("/app-api/audio/speech-token",{method:"POST"});if(!e.ok)throw new Error("Live talegenkendelse er ikke tilgængelig. Kontakt administratoren.");return e.json()},async voiceLiveSession(){const e=await a("/app-api/audio/voice-live-session",{method:"POST"});if(!e.ok){const r=await e.text();throw new Error(r||"Voice Live er ikke tilgængelig.")}return e.json()},async tts(e){var o;const r=(o=e==null?void 0:e.text)==null?void 0:o.trim();if(!r)throw new Error("audio.tts requires non-empty text");const n=await a("/app-api/audio/tts",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({text:r,voice:e.voice,lang:e.lang})});if(!n.ok){const u=await n.text();throw new Error(u||`Request failed (${n.status})`)}return{audio:await n.arrayBuffer(),contentType:n.headers.get("content-type")}},async stt(e){var A,M,N,D;if(!(e!=null&&e.file))throw new Error("audio.stt requires a file");const r=(A=e.language)==null?void 0:A.trim(),n=B=>{if(!B)return;const F=B.trim();if(!F)return;const I=F.toLowerCase(),_=I.split("-")[0];return _.length===2?_:I},t=typeof File<"u"&&e.file instanceof File,o=t&&e.file.name.split(".").pop()||"webm",u=e.ext||o,h=new FormData;t?h.set("file",e.file):h.set("file",e.file,`audio.${u}`);const c=n(r);c&&h.set("language",c),e.prompt&&h.set("prompt",e.prompt),e.responseFormat&&h.set("response_format",e.responseFormat);const d=new URLSearchParams({ext:u});r&&d.set("locale",r);const k=await a(`/app-api/audio/stt?${d.toString()}`,{method:"POST",body:h}),s=(k.headers.get("content-type")||"").includes("application/json")?await k.json():await k.text();if(!k.ok)throw new Error(typeof s=="string"?s:(typeof(s==null?void 0:s.error)=="string"?s.error:(M=s==null?void 0:s.error)==null?void 0:M.message)||`Request failed (${k.status})`);const y=typeof s=="string"?s:(s==null?void 0:s.text)||(s==null?void 0:s.original)||((D=(N=s==null?void 0:s.results)==null?void 0:N[0])==null?void 0:D.text)||"",S=typeof s=="object"&&typeof(s==null?void 0:s.language)=="string"?s.language:void 0;return{text:y,language:S,raw:s}},async voices(e){const r=new URLSearchParams;e!=null&&e.locale&&r.set("locale",e.locale);const n=await a(`/app-api/audio/tts/voices${r.toString()?`?${r}`:""}`,{method:"GET"}),t=await n.json().catch(()=>[]);if(!n.ok)throw new Error((t==null?void 0:t.error)||`Request failed (${n.status})`);return Array.isArray(t)?t:(t==null?void 0:t.voices)||[]}},web:{async scrapeUrl(e){var n;const r=(n=e==null?void 0:e.url)==null?void 0:n.trim();if(!r)throw new Error("web.scrapeUrl requires a url");return v("/app-api/web/scrape-url",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({url:r,maxChars:e.maxChars})})}},knowledge:{async search(e){var n;const r=(n=e==null?void 0:e.query)==null?void 0:n.trim();if(!r)throw new Error("knowledge.search requires a query");return v("/app-api/knowledge/search",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({workspaceId:e.workspaceId,query:r,maxResults:e.maxResults,generateSearchQuery:e.generateSearchQuery,sourceId:e.sourceId,includeSourceUrls:e.includeSourceUrls,queries:e.queries})})}},translatorLiveShare:{async create(e){return v("/app-api/translator/live-share",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({displayLanguage:e})})},async update(e,r){await v(`/app-api/translator/live-share/${encodeURIComponent(e)}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)})},async revoke(e){await v(`/app-api/translator/live-share/${encodeURIComponent(e)}`,{method:"DELETE"})}},guardrails:{async check(e){return v("/app-api/guardrails/check",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({value:e})})}},data(e="private"){return j(e,"")},files(e="private"){const r=(t={})=>new URLSearchParams({scope:e,...t}).toString(),n=async t=>{const o=await t.json().catch(()=>({}));return new Error((o==null?void 0:o.error)||`Request failed (${t.status})`)};return{async upload(t,o={}){const u=o.name||t.name;if(!u)throw new Error("A file name is required.");const h=o.contentType||t.type||"application/octet-stream",c=await a(`/app-api/files?${r({name:u,contentType:h})}`,{method:"POST",headers:{"Content-Type":"application/octet-stream"},body:t,signal:o.signal});if(!c.ok)throw await n(c);return(await c.json()).file},async list(t={}){const o=await a(`/app-api/files?${r(t.prefix?{prefix:t.prefix}:{})}`,{method:"GET"});if(!o.ok)throw await n(o);return(await o.json()).files},async download(t,o={}){const u=await a(`/app-api/files/${encodeURIComponent(t)}?${r()}`,{method:"GET",signal:o.signal});if(!u.ok)throw await n(u);return u.blob()},async remove(t){const o=await a(`/app-api/files/${encodeURIComponent(t)}?${r()}`,{method:"DELETE"});if(!o.ok)throw await n(o)}}}}}E.PromteAppProvider=Q,E.PromteNativeProvider=K,E.usePromte=C,E.usePromteClient=O,E.usePromteDarkMode=Z,E.usePromteModels=ee,E.usePromteSettings=X,E.usePromteToken=Y,E.usePromteUser=q,Object.defineProperty(E,Symbol.toStringTag,{value:"Module"})});
|