@promte/app-library 0.1.5 → 0.1.7
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 +23 -0
- package/dist/index.d.ts +102 -1
- package/dist/index.mjs +274 -184
- package/dist/index.umd.cjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -105,6 +105,29 @@ const response = await client.embeddings.create({
|
|
|
105
105
|
const vectors = response.data.map((item) => item.embedding);
|
|
106
106
|
```
|
|
107
107
|
|
|
108
|
+
## Knowledge search
|
|
109
|
+
|
|
110
|
+
Apps can search an assistant/workspace knowledge base directly:
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
const client = usePromteClient();
|
|
114
|
+
|
|
115
|
+
const response = await client.knowledge.search({
|
|
116
|
+
workspaceId: "assistant-workspace-id",
|
|
117
|
+
query: "Hvad gælder for carporte i BR18?",
|
|
118
|
+
maxResults: 8,
|
|
119
|
+
generateSearchQuery: true,
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
for (const result of response.results) {
|
|
123
|
+
console.log(result.title, result.text, result.sourceUrl);
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
If `workspaceId` is omitted, the search uses the current app workspace. Searching
|
|
128
|
+
another workspace requires that the current user has access to that workspace.
|
|
129
|
+
Public app tokens can only search their own workspace.
|
|
130
|
+
|
|
108
131
|
## Return behavior
|
|
109
132
|
|
|
110
133
|
- `get()` returns the value at the current path, or `null` if missing.
|
package/dist/index.d.ts
CHANGED
|
@@ -18,11 +18,13 @@ export declare type AudioSttRequest = {
|
|
|
18
18
|
file: File | Blob;
|
|
19
19
|
language?: string;
|
|
20
20
|
prompt?: string;
|
|
21
|
+
responseFormat?: "json" | "verbose_json";
|
|
21
22
|
ext?: string;
|
|
22
23
|
};
|
|
23
24
|
|
|
24
25
|
export declare type AudioSttResponse = {
|
|
25
26
|
text: string;
|
|
27
|
+
language?: string;
|
|
26
28
|
raw: any;
|
|
27
29
|
};
|
|
28
30
|
|
|
@@ -68,9 +70,20 @@ export declare type ChatCompletionsRequest = {
|
|
|
68
70
|
|
|
69
71
|
export declare type ChatCompletionsResponse = any;
|
|
70
72
|
|
|
73
|
+
export declare type ChatContentPart = {
|
|
74
|
+
type: "text";
|
|
75
|
+
text: string;
|
|
76
|
+
} | {
|
|
77
|
+
type: "image_url";
|
|
78
|
+
image_url: {
|
|
79
|
+
url: string;
|
|
80
|
+
detail?: "auto" | "low" | "high" | "original";
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
|
|
71
84
|
export declare type ChatMessage = {
|
|
72
85
|
role: "system" | "user" | "assistant" | "tool";
|
|
73
|
-
content: string;
|
|
86
|
+
content: string | ChatContentPart[];
|
|
74
87
|
};
|
|
75
88
|
|
|
76
89
|
export declare type EmbeddingItem = {
|
|
@@ -99,6 +112,41 @@ export declare type EmbeddingsResponse = {
|
|
|
99
112
|
[key: string]: any;
|
|
100
113
|
};
|
|
101
114
|
|
|
115
|
+
export declare type KnowledgeSearchRequest = {
|
|
116
|
+
workspaceId?: string;
|
|
117
|
+
query: string;
|
|
118
|
+
maxResults?: number;
|
|
119
|
+
generateSearchQuery?: boolean;
|
|
120
|
+
sourceId?: string;
|
|
121
|
+
includeSourceUrls?: boolean;
|
|
122
|
+
queries?: string[];
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
export declare type KnowledgeSearchResponse = {
|
|
126
|
+
workspaceId: string;
|
|
127
|
+
workspaceName?: string;
|
|
128
|
+
query: string;
|
|
129
|
+
searchQueries: string[];
|
|
130
|
+
maxResults: number;
|
|
131
|
+
results: KnowledgeSearchResult[];
|
|
132
|
+
sourceIds: string[];
|
|
133
|
+
chunkIds: string[];
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
export declare type KnowledgeSearchResult = {
|
|
137
|
+
index: number;
|
|
138
|
+
id: string;
|
|
139
|
+
chunkId: string;
|
|
140
|
+
sourceWorkspaceId: string;
|
|
141
|
+
sourceId: string;
|
|
142
|
+
sourceName?: string;
|
|
143
|
+
title: string;
|
|
144
|
+
text: string;
|
|
145
|
+
relevance?: number;
|
|
146
|
+
link?: string;
|
|
147
|
+
sourceUrl?: string;
|
|
148
|
+
};
|
|
149
|
+
|
|
102
150
|
export declare function PromteAppProvider({ children, expectedParentOrigin, initTargetOrigin, retryInit, }: PromteAppProviderProps): JSX_2.Element;
|
|
103
151
|
|
|
104
152
|
export declare type PromteAppProviderProps = {
|
|
@@ -122,6 +170,16 @@ export declare type PromteClient = {
|
|
|
122
170
|
create(req: EmbeddingsRequest): Promise<EmbeddingsResponse>;
|
|
123
171
|
};
|
|
124
172
|
audio: {
|
|
173
|
+
speechToken(): Promise<{
|
|
174
|
+
token: string;
|
|
175
|
+
region: string;
|
|
176
|
+
}>;
|
|
177
|
+
voiceLiveSession(): Promise<{
|
|
178
|
+
sessionToken: string;
|
|
179
|
+
websocketUrl: string;
|
|
180
|
+
model: string;
|
|
181
|
+
transcriptionModel: string;
|
|
182
|
+
}>;
|
|
125
183
|
tts(req: AudioTtsRequest): Promise<AudioTtsResponse>;
|
|
126
184
|
stt(req: AudioSttRequest): Promise<AudioSttResponse>;
|
|
127
185
|
voices(req?: AudioVoicesRequest): Promise<AudioVoiceInfo[]>;
|
|
@@ -129,6 +187,18 @@ export declare type PromteClient = {
|
|
|
129
187
|
web: {
|
|
130
188
|
scrapeUrl(req: ScrapeUrlRequest): Promise<ScrapeUrlResponse>;
|
|
131
189
|
};
|
|
190
|
+
knowledge: {
|
|
191
|
+
search(req: KnowledgeSearchRequest): Promise<KnowledgeSearchResponse>;
|
|
192
|
+
};
|
|
193
|
+
translatorLiveShare: {
|
|
194
|
+
create(displayLanguage: string): Promise<{
|
|
195
|
+
shareId: string;
|
|
196
|
+
token: string;
|
|
197
|
+
expiresAt: string;
|
|
198
|
+
}>;
|
|
199
|
+
update(shareId: string, snapshot: TranslatorLiveShareSnapshot): Promise<void>;
|
|
200
|
+
revoke(shareId: string): Promise<void>;
|
|
201
|
+
};
|
|
132
202
|
data(scope?: AppDataScope): AppDataRef;
|
|
133
203
|
};
|
|
134
204
|
|
|
@@ -160,6 +230,20 @@ export declare type PromteModelsRequest = {
|
|
|
160
230
|
|
|
161
231
|
export declare type PromteModelType = "llm" | "embedding" | "image" | "stt" | "tts";
|
|
162
232
|
|
|
233
|
+
/**
|
|
234
|
+
* Provides the same Promte runtime to first-party, in-process features without
|
|
235
|
+
* duplicating the app client or emulating the iframe postMessage handshake.
|
|
236
|
+
*/
|
|
237
|
+
export declare function PromteNativeProvider({ children, settings, token, isDarkMode, user, }: PromteNativeProviderProps): JSX_2.Element;
|
|
238
|
+
|
|
239
|
+
export declare type PromteNativeProviderProps = {
|
|
240
|
+
children: default_2.ReactNode;
|
|
241
|
+
settings: PromteSettings;
|
|
242
|
+
token: string | null;
|
|
243
|
+
isDarkMode: boolean;
|
|
244
|
+
user: PromteUser | null;
|
|
245
|
+
};
|
|
246
|
+
|
|
163
247
|
export declare type PromteSettings = {
|
|
164
248
|
workspaceId: string;
|
|
165
249
|
version: number;
|
|
@@ -200,6 +284,23 @@ export declare type ScrapeUrlResponse = {
|
|
|
200
284
|
};
|
|
201
285
|
};
|
|
202
286
|
|
|
287
|
+
export declare type TranslatorLiveShareLine = {
|
|
288
|
+
id: string;
|
|
289
|
+
speaker: string;
|
|
290
|
+
language?: string;
|
|
291
|
+
text: string;
|
|
292
|
+
pending?: boolean;
|
|
293
|
+
edited?: boolean;
|
|
294
|
+
createdAt: string;
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
export declare type TranslatorLiveShareSnapshot = {
|
|
298
|
+
displayLanguage: string;
|
|
299
|
+
status: "active" | "ended";
|
|
300
|
+
lines: TranslatorLiveShareLine[];
|
|
301
|
+
revision: number;
|
|
302
|
+
};
|
|
303
|
+
|
|
203
304
|
export declare function usePromte(): PromteCtxValue;
|
|
204
305
|
|
|
205
306
|
export declare function usePromteClient(): PromteClient;
|
package/dist/index.mjs
CHANGED
|
@@ -1,133 +1,160 @@
|
|
|
1
1
|
import { jsx as B } from "react/jsx-runtime";
|
|
2
|
-
import { createContext as
|
|
3
|
-
const
|
|
4
|
-
function
|
|
5
|
-
children:
|
|
6
|
-
expectedParentOrigin:
|
|
7
|
-
initTargetOrigin:
|
|
8
|
-
retryInit:
|
|
2
|
+
import { createContext as J, useState as T, useMemo as P, useCallback as _, useEffect as $, useContext as D } from "react";
|
|
3
|
+
const x = J(null);
|
|
4
|
+
function W({
|
|
5
|
+
children: f,
|
|
6
|
+
expectedParentOrigin: l,
|
|
7
|
+
initTargetOrigin: g,
|
|
8
|
+
retryInit: c = { enabled: !0, intervalMs: 500, maxAttempts: 20 }
|
|
9
9
|
}) {
|
|
10
|
-
const [
|
|
11
|
-
var
|
|
10
|
+
const [p, k] = T(null), [y, v] = T(null), [b, E] = T(null), [S, t] = T(null), [r, e] = T(null), n = P(() => r ? "booting" : p ? y ? "ready" : "waiting_for_token" : "waiting_for_settings", [p, y, r]), o = n === "ready", a = P(() => g || l || "*", [g, l]), u = _(() => {
|
|
11
|
+
var d;
|
|
12
12
|
try {
|
|
13
|
-
const
|
|
14
|
-
(
|
|
15
|
-
} catch (
|
|
16
|
-
e((
|
|
13
|
+
const h = { type: "init" };
|
|
14
|
+
(d = window.parent) == null || d.postMessage(h, a);
|
|
15
|
+
} catch (h) {
|
|
16
|
+
e((h == null ? void 0 : h.message) || "Failed to post init");
|
|
17
17
|
}
|
|
18
|
-
}, [
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}, [
|
|
22
|
-
if (!(
|
|
23
|
-
const
|
|
24
|
-
let
|
|
25
|
-
const
|
|
26
|
-
if (
|
|
27
|
-
window.clearInterval(
|
|
18
|
+
}, [a]);
|
|
19
|
+
$(() => {
|
|
20
|
+
u();
|
|
21
|
+
}, [u]), $(() => {
|
|
22
|
+
if (!(c != null && c.enabled) || p) return;
|
|
23
|
+
const d = c.intervalMs ?? 500, h = c.maxAttempts ?? 20;
|
|
24
|
+
let s = 0;
|
|
25
|
+
const m = window.setInterval(() => {
|
|
26
|
+
if (p) {
|
|
27
|
+
window.clearInterval(m);
|
|
28
28
|
return;
|
|
29
29
|
}
|
|
30
|
-
if (
|
|
31
|
-
window.clearInterval(
|
|
30
|
+
if (s += 1, s > h) {
|
|
31
|
+
window.clearInterval(m);
|
|
32
32
|
return;
|
|
33
33
|
}
|
|
34
|
-
|
|
35
|
-
},
|
|
36
|
-
return () => window.clearInterval(
|
|
37
|
-
}, [
|
|
38
|
-
const
|
|
39
|
-
if (
|
|
40
|
-
const
|
|
41
|
-
if (!(!
|
|
42
|
-
if (
|
|
43
|
-
const
|
|
44
|
-
if (!(
|
|
34
|
+
u();
|
|
35
|
+
}, d);
|
|
36
|
+
return () => window.clearInterval(m);
|
|
37
|
+
}, [c, p, u]), $(() => {
|
|
38
|
+
const d = (h) => {
|
|
39
|
+
if (l && h.origin !== l) return;
|
|
40
|
+
const s = h.data;
|
|
41
|
+
if (!(!s || typeof s != "object")) {
|
|
42
|
+
if (s.type === "set-settings") {
|
|
43
|
+
const m = s.value;
|
|
44
|
+
if (!(m != null && m.backendUrl) || m.parentOrigin && l && m.parentOrigin !== l)
|
|
45
45
|
return;
|
|
46
|
-
|
|
46
|
+
k(m), m != null && m.user && t(m.user), e(null);
|
|
47
47
|
return;
|
|
48
48
|
}
|
|
49
|
-
if (
|
|
50
|
-
|
|
49
|
+
if (s.type === "set-token" && typeof s.value == "string") {
|
|
50
|
+
v(s.value), e(null);
|
|
51
51
|
return;
|
|
52
52
|
}
|
|
53
|
-
if (
|
|
54
|
-
|
|
53
|
+
if (s.type === "set-dark-mode" && typeof s.value == "boolean") {
|
|
54
|
+
E(s.value);
|
|
55
55
|
return;
|
|
56
56
|
}
|
|
57
|
-
if (
|
|
58
|
-
t(
|
|
57
|
+
if (s.type === "set-user" && typeof s.value == "object") {
|
|
58
|
+
t(s.value);
|
|
59
59
|
return;
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
};
|
|
63
|
-
return window.addEventListener("message",
|
|
64
|
-
}, [
|
|
65
|
-
const
|
|
66
|
-
() =>
|
|
63
|
+
return window.addEventListener("message", d), () => window.removeEventListener("message", d);
|
|
64
|
+
}, [l]);
|
|
65
|
+
const i = P(() => F(
|
|
66
|
+
() => p,
|
|
67
67
|
() => y
|
|
68
|
-
), [
|
|
68
|
+
), [p, y]), w = P(
|
|
69
69
|
() => ({
|
|
70
|
-
settings:
|
|
70
|
+
settings: p,
|
|
71
71
|
token: y,
|
|
72
|
-
isDarkMode:
|
|
73
|
-
user:
|
|
74
|
-
ready:
|
|
72
|
+
isDarkMode: b,
|
|
73
|
+
user: S,
|
|
74
|
+
ready: o,
|
|
75
75
|
state: n,
|
|
76
76
|
error: r,
|
|
77
|
-
client:
|
|
77
|
+
client: i
|
|
78
78
|
}),
|
|
79
|
-
[
|
|
79
|
+
[p, y, b, S, o, n, r, i]
|
|
80
80
|
);
|
|
81
|
-
return /* @__PURE__ */ B(
|
|
81
|
+
return /* @__PURE__ */ B(x.Provider, { value: w, children: f });
|
|
82
82
|
}
|
|
83
|
-
function
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
83
|
+
function K({
|
|
84
|
+
children: f,
|
|
85
|
+
settings: l,
|
|
86
|
+
token: g,
|
|
87
|
+
isDarkMode: c,
|
|
88
|
+
user: p
|
|
89
|
+
}) {
|
|
90
|
+
const k = P(
|
|
91
|
+
() => F(() => l, () => g),
|
|
92
|
+
[l, g]
|
|
93
|
+
), y = !!g, v = P(
|
|
94
|
+
() => ({
|
|
95
|
+
settings: l,
|
|
96
|
+
token: g,
|
|
97
|
+
isDarkMode: c,
|
|
98
|
+
user: p,
|
|
99
|
+
ready: y,
|
|
100
|
+
state: y ? "ready" : "waiting_for_token",
|
|
101
|
+
error: null,
|
|
102
|
+
client: k
|
|
103
|
+
}),
|
|
104
|
+
[k, c, y, l, g, p]
|
|
105
|
+
);
|
|
106
|
+
return /* @__PURE__ */ B(x.Provider, { value: v, children: f });
|
|
88
107
|
}
|
|
89
|
-
function
|
|
90
|
-
|
|
108
|
+
function j() {
|
|
109
|
+
const f = D(x);
|
|
110
|
+
if (!f)
|
|
111
|
+
throw new Error(
|
|
112
|
+
"usePromte must be used inside <PromteAppProvider> or <PromteNativeProvider>"
|
|
113
|
+
);
|
|
114
|
+
return f;
|
|
115
|
+
}
|
|
116
|
+
function Q() {
|
|
117
|
+
return j().settings;
|
|
91
118
|
}
|
|
92
|
-
function
|
|
93
|
-
return
|
|
119
|
+
function H() {
|
|
120
|
+
return j().token;
|
|
94
121
|
}
|
|
95
|
-
function
|
|
96
|
-
return
|
|
122
|
+
function X() {
|
|
123
|
+
return j().isDarkMode;
|
|
97
124
|
}
|
|
98
|
-
function
|
|
99
|
-
return
|
|
125
|
+
function Y() {
|
|
126
|
+
return j().user;
|
|
100
127
|
}
|
|
101
|
-
function
|
|
102
|
-
return
|
|
128
|
+
function G() {
|
|
129
|
+
return j().client;
|
|
103
130
|
}
|
|
104
|
-
function
|
|
105
|
-
const { ready:
|
|
106
|
-
if (!
|
|
107
|
-
y(!0),
|
|
131
|
+
function Z(f = {}) {
|
|
132
|
+
const { ready: l } = j(), g = G(), [c, p] = T([]), [k, y] = T(!1), [v, b] = T(null), E = P(() => (Array.isArray(f.type) ? f.type : f.type ? [f.type] : []).filter(Boolean).map((n) => String(n)).join(","), [f.type]), S = f.configuredOnly === !0, t = f.auto !== !1, r = _(async () => {
|
|
133
|
+
if (!l) return [];
|
|
134
|
+
y(!0), b(null);
|
|
108
135
|
try {
|
|
109
|
-
const e =
|
|
110
|
-
return
|
|
136
|
+
const e = E ? E.split(",").filter(Boolean) : void 0, n = await g.models({ type: e, configuredOnly: S });
|
|
137
|
+
return p(n), n;
|
|
111
138
|
} catch (e) {
|
|
112
139
|
const n = e instanceof Error ? e.message : String(e);
|
|
113
|
-
throw
|
|
140
|
+
throw b(n), e;
|
|
114
141
|
} finally {
|
|
115
142
|
y(!1);
|
|
116
143
|
}
|
|
117
|
-
}, [
|
|
118
|
-
return
|
|
119
|
-
!t || !
|
|
144
|
+
}, [g, S, l, E]);
|
|
145
|
+
return $(() => {
|
|
146
|
+
!t || !l || r().catch(() => {
|
|
120
147
|
});
|
|
121
|
-
}, [t,
|
|
148
|
+
}, [t, l, r]), { models: c, loading: k, error: v, reload: r };
|
|
122
149
|
}
|
|
123
|
-
function
|
|
124
|
-
const
|
|
125
|
-
async function
|
|
126
|
-
const e =
|
|
150
|
+
function F(f, l) {
|
|
151
|
+
const g = (t) => typeof t == "string" && (t.startsWith("gpt-5") || t.startsWith("gpt-6"));
|
|
152
|
+
async function c(t, r) {
|
|
153
|
+
const e = f(), n = l();
|
|
127
154
|
if (!e) throw new Error("Promte settings not received yet");
|
|
128
155
|
if (!n) throw new Error("Promte token not received yet");
|
|
129
|
-
const
|
|
130
|
-
return await fetch(
|
|
156
|
+
const o = e.backendUrl.replace(/\/+$/, ""), a = String(t || "").replace(/^\/+/, ""), u = `${o}/${a}`;
|
|
157
|
+
return await fetch(u, {
|
|
131
158
|
...r,
|
|
132
159
|
headers: {
|
|
133
160
|
...r.headers || {},
|
|
@@ -135,8 +162,8 @@ function _(p, d) {
|
|
|
135
162
|
}
|
|
136
163
|
});
|
|
137
164
|
}
|
|
138
|
-
async function
|
|
139
|
-
const e = await
|
|
165
|
+
async function p(t, r) {
|
|
166
|
+
const e = await c(`/app-api/data/${t}`, {
|
|
140
167
|
method: "POST",
|
|
141
168
|
headers: { "Content-Type": "application/json" },
|
|
142
169
|
body: JSON.stringify(r)
|
|
@@ -147,10 +174,10 @@ function _(p, d) {
|
|
|
147
174
|
);
|
|
148
175
|
return n == null ? void 0 : n.value;
|
|
149
176
|
}
|
|
150
|
-
async function
|
|
177
|
+
async function k(t) {
|
|
151
178
|
const r = new URLSearchParams();
|
|
152
179
|
t.scope && r.set("scope", t.scope), t.path && r.set("path", t.path);
|
|
153
|
-
const e = await
|
|
180
|
+
const e = await c(`/app-api/data?${r.toString()}`, {
|
|
154
181
|
method: "GET"
|
|
155
182
|
}), n = await e.json().catch(() => ({}));
|
|
156
183
|
if (!e.ok)
|
|
@@ -158,131 +185,131 @@ function _(p, d) {
|
|
|
158
185
|
return n == null ? void 0 : n.value;
|
|
159
186
|
}
|
|
160
187
|
async function y(t) {
|
|
161
|
-
const r = new URLSearchParams(), e =
|
|
162
|
-
|
|
163
|
-
const
|
|
188
|
+
const r = new URLSearchParams(), e = t == null ? void 0 : t.type, n = Array.isArray(e) ? e : e ? [e] : [];
|
|
189
|
+
n.length > 0 && r.set("type", n.join(",")), t != null && t.configuredOnly && r.set("configuredOnly", "true");
|
|
190
|
+
const o = await c(
|
|
164
191
|
`/app-api/models${r.toString() ? `?${r.toString()}` : ""}`,
|
|
165
192
|
{ method: "GET" }
|
|
166
|
-
),
|
|
167
|
-
if (!
|
|
168
|
-
throw new Error((
|
|
169
|
-
return (Array.isArray(
|
|
170
|
-
if (!
|
|
171
|
-
const
|
|
172
|
-
return !
|
|
173
|
-
id:
|
|
174
|
-
label:
|
|
175
|
-
type:
|
|
176
|
-
configured:
|
|
177
|
-
source:
|
|
193
|
+
), a = await o.json().catch(() => ({}));
|
|
194
|
+
if (!o.ok)
|
|
195
|
+
throw new Error((a == null ? void 0 : a.error) || `Request failed (${o.status})`);
|
|
196
|
+
return (Array.isArray(a == null ? void 0 : a.models) ? a.models : []).map((i) => {
|
|
197
|
+
if (!i || typeof i != "object") return null;
|
|
198
|
+
const w = typeof i.id == "string" ? i.id.trim() : "", d = typeof i.label == "string" ? i.label.trim() : w, h = i.type, s = i.configured === !0, m = typeof i.source == "string" && i.source.trim() ? i.source.trim() : void 0;
|
|
199
|
+
return !w || h !== "llm" && h !== "embedding" && h !== "image" && h !== "stt" && h !== "tts" ? null : {
|
|
200
|
+
id: w,
|
|
201
|
+
label: d || w,
|
|
202
|
+
type: h,
|
|
203
|
+
configured: s,
|
|
204
|
+
source: m
|
|
178
205
|
};
|
|
179
206
|
}).filter(
|
|
180
|
-
(
|
|
207
|
+
(i) => !!i
|
|
181
208
|
);
|
|
182
209
|
}
|
|
183
|
-
async function
|
|
184
|
-
const e = await
|
|
210
|
+
async function v(t, r) {
|
|
211
|
+
const e = await c(t, r), o = (e.headers.get("content-type") || "").includes("application/json") ? await e.json().catch(() => ({})) : await e.text();
|
|
185
212
|
if (!e.ok)
|
|
186
213
|
throw new Error(
|
|
187
|
-
typeof
|
|
214
|
+
typeof o == "string" ? o || `Request failed (${e.status})` : (o == null ? void 0 : o.error) || (o == null ? void 0 : o.message) || `Request failed (${e.status})`
|
|
188
215
|
);
|
|
189
|
-
return
|
|
216
|
+
return o;
|
|
190
217
|
}
|
|
191
|
-
const
|
|
192
|
-
const e =
|
|
218
|
+
const b = (t) => t ? t.split("/").map((r) => r.trim()).filter(Boolean).join("/") : "", E = (t, r) => {
|
|
219
|
+
const e = b(t), n = b(r);
|
|
193
220
|
return e ? n ? `${e}/${n}` : e : n;
|
|
194
|
-
},
|
|
221
|
+
}, S = (t, r) => {
|
|
195
222
|
const e = { scope: t };
|
|
196
223
|
return {
|
|
197
224
|
async get() {
|
|
198
|
-
const n =
|
|
199
|
-
return
|
|
225
|
+
const n = b(r);
|
|
226
|
+
return k({ ...e, path: n || void 0 });
|
|
200
227
|
},
|
|
201
228
|
async set(n) {
|
|
202
|
-
const
|
|
203
|
-
return
|
|
229
|
+
const o = b(r);
|
|
230
|
+
return p("set", {
|
|
204
231
|
...e,
|
|
205
|
-
path:
|
|
232
|
+
path: o || void 0,
|
|
206
233
|
value: n
|
|
207
234
|
});
|
|
208
235
|
},
|
|
209
236
|
async update(n) {
|
|
210
237
|
if (!n || typeof n != "object")
|
|
211
238
|
throw new Error("update requires an object");
|
|
212
|
-
const
|
|
213
|
-
for (const [
|
|
214
|
-
const
|
|
215
|
-
if (!
|
|
239
|
+
const o = {};
|
|
240
|
+
for (const [a, u] of Object.entries(n)) {
|
|
241
|
+
const i = E(r, a);
|
|
242
|
+
if (!i)
|
|
216
243
|
throw new Error("update paths must be non-empty");
|
|
217
|
-
|
|
244
|
+
o[i] = u;
|
|
218
245
|
}
|
|
219
|
-
return
|
|
246
|
+
return p("update", { ...e, updates: o });
|
|
220
247
|
},
|
|
221
248
|
async remove() {
|
|
222
|
-
const n =
|
|
223
|
-
return
|
|
249
|
+
const n = b(r);
|
|
250
|
+
return p("remove", { ...e, path: n || void 0 });
|
|
224
251
|
},
|
|
225
252
|
async push(n) {
|
|
226
|
-
const
|
|
227
|
-
if (!
|
|
228
|
-
return
|
|
253
|
+
const o = b(r);
|
|
254
|
+
if (!o) throw new Error("push requires a path");
|
|
255
|
+
return p("array-push", { ...e, path: o, value: n });
|
|
229
256
|
},
|
|
230
257
|
ref(n) {
|
|
231
|
-
const
|
|
232
|
-
if (!
|
|
233
|
-
return
|
|
258
|
+
const o = E(r, n);
|
|
259
|
+
if (!o) throw new Error("ref requires a path");
|
|
260
|
+
return S(t, o);
|
|
234
261
|
}
|
|
235
262
|
};
|
|
236
263
|
};
|
|
237
264
|
return {
|
|
238
265
|
isReady() {
|
|
239
|
-
return !!
|
|
266
|
+
return !!f() && !!l();
|
|
240
267
|
},
|
|
241
268
|
getBackendUrl() {
|
|
242
269
|
var t;
|
|
243
|
-
return ((t =
|
|
270
|
+
return ((t = f()) == null ? void 0 : t.backendUrl) ?? null;
|
|
244
271
|
},
|
|
245
272
|
async models(t) {
|
|
246
273
|
return y(t);
|
|
247
274
|
},
|
|
248
275
|
async chatCompletions(t) {
|
|
249
|
-
var
|
|
276
|
+
var d;
|
|
250
277
|
const {
|
|
251
278
|
reasoningEffort: r,
|
|
252
279
|
reasoning_effort: e,
|
|
253
280
|
...n
|
|
254
|
-
} = t,
|
|
281
|
+
} = t, o = r ?? e, a = {
|
|
255
282
|
...n,
|
|
256
283
|
stream: !1
|
|
257
284
|
};
|
|
258
|
-
|
|
259
|
-
const
|
|
285
|
+
o && g(t.model) && (a.reasoning_effort = o);
|
|
286
|
+
const u = await c("/openai/chat/completions", {
|
|
260
287
|
method: "POST",
|
|
261
288
|
headers: { "Content-Type": "application/json" },
|
|
262
|
-
body: JSON.stringify(
|
|
263
|
-
}),
|
|
264
|
-
if (!
|
|
289
|
+
body: JSON.stringify(a)
|
|
290
|
+
}), w = (u.headers.get("content-type") || "").includes("application/json") ? await u.json() : await u.text();
|
|
291
|
+
if (!u.ok)
|
|
265
292
|
throw new Error(
|
|
266
|
-
typeof
|
|
293
|
+
typeof w == "string" ? w : ((d = w == null ? void 0 : w.error) == null ? void 0 : d.message) || `Request failed (${u.status})`
|
|
267
294
|
);
|
|
268
|
-
return
|
|
295
|
+
return w;
|
|
269
296
|
},
|
|
270
297
|
async chatText(t) {
|
|
271
|
-
var e, n,
|
|
298
|
+
var e, n, o;
|
|
272
299
|
const r = await this.chatCompletions(t);
|
|
273
|
-
return ((
|
|
300
|
+
return ((o = (n = (e = r == null ? void 0 : r.choices) == null ? void 0 : e[0]) == null ? void 0 : n.message) == null ? void 0 : o.content) ?? "";
|
|
274
301
|
},
|
|
275
302
|
embeddings: {
|
|
276
303
|
async create(t) {
|
|
277
|
-
var
|
|
278
|
-
const r = (
|
|
304
|
+
var o;
|
|
305
|
+
const r = (o = t == null ? void 0 : t.model) == null ? void 0 : o.trim();
|
|
279
306
|
if (!r) throw new Error("embeddings.create requires a model");
|
|
280
307
|
const e = t == null ? void 0 : t.input;
|
|
281
|
-
if (!(typeof e == "string" ? e.length > 0 : Array.isArray(e) && e.length > 0 && e.every((
|
|
308
|
+
if (!(typeof e == "string" ? e.length > 0 : Array.isArray(e) && e.length > 0 && e.every((a) => typeof a == "string")))
|
|
282
309
|
throw new Error(
|
|
283
310
|
"embeddings.create requires input as a string or string[]"
|
|
284
311
|
);
|
|
285
|
-
return
|
|
312
|
+
return v("/openai/embeddings", {
|
|
286
313
|
method: "POST",
|
|
287
314
|
headers: { "Content-Type": "application/json" },
|
|
288
315
|
body: JSON.stringify({
|
|
@@ -294,11 +321,26 @@ function _(p, d) {
|
|
|
294
321
|
}
|
|
295
322
|
},
|
|
296
323
|
audio: {
|
|
324
|
+
async speechToken() {
|
|
325
|
+
const t = await c("/app-api/audio/speech-token", { method: "POST" });
|
|
326
|
+
if (!t.ok) throw new Error("Live talegenkendelse er ikke tilgængelig. Kontakt administratoren.");
|
|
327
|
+
return t.json();
|
|
328
|
+
},
|
|
329
|
+
async voiceLiveSession() {
|
|
330
|
+
const t = await c("/app-api/audio/voice-live-session", {
|
|
331
|
+
method: "POST"
|
|
332
|
+
});
|
|
333
|
+
if (!t.ok) {
|
|
334
|
+
const r = await t.text();
|
|
335
|
+
throw new Error(r || "Voice Live er ikke tilgængelig.");
|
|
336
|
+
}
|
|
337
|
+
return t.json();
|
|
338
|
+
},
|
|
297
339
|
async tts(t) {
|
|
298
|
-
var
|
|
299
|
-
const r = (
|
|
340
|
+
var o;
|
|
341
|
+
const r = (o = t == null ? void 0 : t.text) == null ? void 0 : o.trim();
|
|
300
342
|
if (!r) throw new Error("audio.tts requires non-empty text");
|
|
301
|
-
const e = await
|
|
343
|
+
const e = await c("/app-api/audio/tts", {
|
|
302
344
|
method: "POST",
|
|
303
345
|
headers: { "Content-Type": "application/json" },
|
|
304
346
|
body: JSON.stringify({
|
|
@@ -308,8 +350,8 @@ function _(p, d) {
|
|
|
308
350
|
})
|
|
309
351
|
});
|
|
310
352
|
if (!e.ok) {
|
|
311
|
-
const
|
|
312
|
-
throw new Error(
|
|
353
|
+
const a = await e.text();
|
|
354
|
+
throw new Error(a || `Request failed (${e.status})`);
|
|
313
355
|
}
|
|
314
356
|
return {
|
|
315
357
|
audio: await e.arrayBuffer(),
|
|
@@ -317,35 +359,38 @@ function _(p, d) {
|
|
|
317
359
|
};
|
|
318
360
|
},
|
|
319
361
|
async stt(t) {
|
|
320
|
-
var
|
|
362
|
+
var R, C, U, O;
|
|
321
363
|
if (!(t != null && t.file)) throw new Error("audio.stt requires a file");
|
|
322
|
-
const r = (R) => {
|
|
323
|
-
if (!
|
|
324
|
-
const
|
|
325
|
-
if (!
|
|
326
|
-
const
|
|
327
|
-
return
|
|
328
|
-
},
|
|
329
|
-
|
|
330
|
-
const
|
|
331
|
-
|
|
332
|
-
const
|
|
333
|
-
|
|
364
|
+
const r = (R = t.language) == null ? void 0 : R.trim(), e = (A) => {
|
|
365
|
+
if (!A) return;
|
|
366
|
+
const L = A.trim();
|
|
367
|
+
if (!L) return;
|
|
368
|
+
const M = L.toLowerCase(), N = M.split("-")[0];
|
|
369
|
+
return N.length === 2 ? N : M;
|
|
370
|
+
}, n = typeof File < "u" && t.file instanceof File, o = n && t.file.name.split(".").pop() || "webm", a = t.ext || o, u = new FormData();
|
|
371
|
+
n ? u.set("file", t.file) : u.set("file", t.file, `audio.${a}`);
|
|
372
|
+
const i = e(r);
|
|
373
|
+
i && u.set("language", i), t.prompt && u.set("prompt", t.prompt), t.responseFormat && u.set("response_format", t.responseFormat);
|
|
374
|
+
const w = new URLSearchParams({ ext: a });
|
|
375
|
+
r && w.set("locale", r);
|
|
376
|
+
const d = await c(
|
|
377
|
+
`/app-api/audio/stt?${w.toString()}`,
|
|
334
378
|
{
|
|
335
379
|
method: "POST",
|
|
336
|
-
body:
|
|
380
|
+
body: u
|
|
337
381
|
}
|
|
338
|
-
),
|
|
339
|
-
if (!
|
|
382
|
+
), s = (d.headers.get("content-type") || "").includes("application/json") ? await d.json() : await d.text();
|
|
383
|
+
if (!d.ok)
|
|
340
384
|
throw new Error(
|
|
341
|
-
typeof
|
|
385
|
+
typeof s == "string" ? s : ((C = s == null ? void 0 : s.error) == null ? void 0 : C.message) || `Request failed (${d.status})`
|
|
342
386
|
);
|
|
343
|
-
|
|
387
|
+
const m = typeof s == "string" ? s : (s == null ? void 0 : s.text) || (s == null ? void 0 : s.original) || ((O = (U = s == null ? void 0 : s.results) == null ? void 0 : U[0]) == null ? void 0 : O.text) || "", I = typeof s == "object" && typeof (s == null ? void 0 : s.language) == "string" ? s.language : void 0;
|
|
388
|
+
return { text: m, language: I, raw: s };
|
|
344
389
|
},
|
|
345
390
|
async voices(t) {
|
|
346
391
|
const r = new URLSearchParams();
|
|
347
392
|
t != null && t.locale && r.set("locale", t.locale);
|
|
348
|
-
const e = await
|
|
393
|
+
const e = await c(
|
|
349
394
|
`/app-api/audio/tts/voices${r.toString() ? `?${r}` : ""}`,
|
|
350
395
|
{ method: "GET" }
|
|
351
396
|
), n = await e.json().catch(() => []);
|
|
@@ -361,7 +406,7 @@ function _(p, d) {
|
|
|
361
406
|
var e;
|
|
362
407
|
const r = (e = t == null ? void 0 : t.url) == null ? void 0 : e.trim();
|
|
363
408
|
if (!r) throw new Error("web.scrapeUrl requires a url");
|
|
364
|
-
return
|
|
409
|
+
return v(
|
|
365
410
|
"/app-api/web/scrape-url",
|
|
366
411
|
{
|
|
367
412
|
method: "POST",
|
|
@@ -374,18 +419,63 @@ function _(p, d) {
|
|
|
374
419
|
);
|
|
375
420
|
}
|
|
376
421
|
},
|
|
422
|
+
knowledge: {
|
|
423
|
+
async search(t) {
|
|
424
|
+
var e;
|
|
425
|
+
const r = (e = t == null ? void 0 : t.query) == null ? void 0 : e.trim();
|
|
426
|
+
if (!r) throw new Error("knowledge.search requires a query");
|
|
427
|
+
return v(
|
|
428
|
+
"/app-api/knowledge/search",
|
|
429
|
+
{
|
|
430
|
+
method: "POST",
|
|
431
|
+
headers: { "Content-Type": "application/json" },
|
|
432
|
+
body: JSON.stringify({
|
|
433
|
+
workspaceId: t.workspaceId,
|
|
434
|
+
query: r,
|
|
435
|
+
maxResults: t.maxResults,
|
|
436
|
+
generateSearchQuery: t.generateSearchQuery,
|
|
437
|
+
sourceId: t.sourceId,
|
|
438
|
+
includeSourceUrls: t.includeSourceUrls,
|
|
439
|
+
queries: t.queries
|
|
440
|
+
})
|
|
441
|
+
}
|
|
442
|
+
);
|
|
443
|
+
}
|
|
444
|
+
},
|
|
445
|
+
translatorLiveShare: {
|
|
446
|
+
async create(t) {
|
|
447
|
+
return v("/app-api/translator/live-share", {
|
|
448
|
+
method: "POST",
|
|
449
|
+
headers: { "Content-Type": "application/json" },
|
|
450
|
+
body: JSON.stringify({ displayLanguage: t })
|
|
451
|
+
});
|
|
452
|
+
},
|
|
453
|
+
async update(t, r) {
|
|
454
|
+
await v(`/app-api/translator/live-share/${encodeURIComponent(t)}`, {
|
|
455
|
+
method: "PUT",
|
|
456
|
+
headers: { "Content-Type": "application/json" },
|
|
457
|
+
body: JSON.stringify(r)
|
|
458
|
+
});
|
|
459
|
+
},
|
|
460
|
+
async revoke(t) {
|
|
461
|
+
await v(`/app-api/translator/live-share/${encodeURIComponent(t)}`, {
|
|
462
|
+
method: "DELETE"
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
},
|
|
377
466
|
data(t = "private") {
|
|
378
|
-
return
|
|
467
|
+
return S(t, "");
|
|
379
468
|
}
|
|
380
469
|
};
|
|
381
470
|
}
|
|
382
471
|
export {
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
472
|
+
W as PromteAppProvider,
|
|
473
|
+
K as PromteNativeProvider,
|
|
474
|
+
j as usePromte,
|
|
475
|
+
G as usePromteClient,
|
|
476
|
+
X as usePromteDarkMode,
|
|
477
|
+
Z as usePromteModels,
|
|
478
|
+
Q as usePromteSettings,
|
|
479
|
+
H as usePromteToken,
|
|
480
|
+
Y as usePromteUser
|
|
391
481
|
};
|
package/dist/index.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(w,T){typeof exports=="object"&&typeof module<"u"?T(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],T):(w=typeof globalThis<"u"?globalThis:w||self,T(w.PromteAppLibrary={},w.jsxRuntime,w.react))})(this,function(w,T,a){"use strict";const M=a.createContext(null);function L({children:d,expectedParentOrigin:m,initTargetOrigin:E,retryInit:l={enabled:!0,intervalMs:500,maxAttempts:20}}){const[y,$]=a.useState(null),[v,j]=a.useState(null),[g,S]=a.useState(null),[P,t]=a.useState(null),[s,e]=a.useState(null),n=a.useMemo(()=>s?"booting":y?v?"ready":"waiting_for_token":"waiting_for_settings",[y,v,s]),r=n==="ready",c=a.useMemo(()=>E||m||"*",[E,m]),i=a.useCallback(()=>{var o;try{const h={type:"init"};(o=window.parent)==null||o.postMessage(h,c)}catch(h){e((h==null?void 0:h.message)||"Failed to post init")}},[c]);a.useEffect(()=>{i()},[i]),a.useEffect(()=>{if(!(l!=null&&l.enabled)||y)return;const o=l.intervalMs??500,h=l.maxAttempts??20;let u=0;const p=window.setInterval(()=>{if(y){window.clearInterval(p);return}if(u+=1,u>h){window.clearInterval(p);return}i()},o);return()=>window.clearInterval(p)},[l,y,i]),a.useEffect(()=>{const o=h=>{if(m&&h.origin!==m)return;const u=h.data;if(!(!u||typeof u!="object")){if(u.type==="set-settings"){const p=u.value;if(!(p!=null&&p.backendUrl)||p.parentOrigin&&m&&p.parentOrigin!==m)return;$(p),p!=null&&p.user&&t(p.user),e(null);return}if(u.type==="set-token"&&typeof u.value=="string"){j(u.value),e(null);return}if(u.type==="set-dark-mode"&&typeof u.value=="boolean"){S(u.value);return}if(u.type==="set-user"&&typeof u.value=="object"){t(u.value);return}}};return window.addEventListener("message",o),()=>window.removeEventListener("message",o)},[m]);const f=a.useMemo(()=>J(()=>y,()=>v),[y,v]),b=a.useMemo(()=>({settings:y,token:v,isDarkMode:g,user:P,ready:r,state:n,error:s,client:f}),[y,v,g,P,r,n,s,f]);return T.jsx(M.Provider,{value:b,children:d})}function k(){const d=a.useContext(M);if(!d)throw new Error("usePromte must be used inside <PromteAppProvider>");return d}function B(){return k().settings}function D(){return k().token}function F(){return k().isDarkMode}function _(){return k().user}function C(){return k().client}function G(d={}){const{ready:m}=k(),E=C(),[l,y]=a.useState([]),[$,v]=a.useState(!1),[j,g]=a.useState(null),S=a.useMemo(()=>(Array.isArray(d.type)?d.type:d.type?[d.type]:[]).filter(Boolean).map(n=>String(n)).join(","),[d.type]),P=d.configuredOnly===!0,t=d.auto!==!1,s=a.useCallback(async()=>{if(!m)return[];v(!0),g(null);try{const e=S?S.split(",").filter(Boolean):void 0,n=await E.models({type:e,configuredOnly:P});return y(n),n}catch(e){const n=e instanceof Error?e.message:String(e);throw g(n),e}finally{v(!1)}},[E,P,m,S]);return a.useEffect(()=>{!t||!m||s().catch(()=>{})},[t,m,s]),{models:l,loading:$,error:j,reload:s}}function J(d,m){const E=t=>typeof t=="string"&&t.startsWith("gpt-5");async function l(t,s){const e=d(),n=m();if(!e)throw new Error("Promte settings not received yet");if(!n)throw new Error("Promte token not received yet");const r=e.backendUrl.replace(/\/+$/,""),c=String(t||"").replace(/^\/+/,""),i=`${r}/${c}`;return await fetch(i,{...s,headers:{...s.headers||{},Authorization:`Bearer ${n}`}})}async function y(t,s){const e=await l(`/app-api/data/${t}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)}),n=await e.json().catch(()=>({}));if(!e.ok)throw new Error((n==null?void 0:n.error)||`Request failed (${e.status})`);return n==null?void 0:n.value}async function $(t){const s=new URLSearchParams;t.scope&&s.set("scope",t.scope),t.path&&s.set("path",t.path);const e=await l(`/app-api/data?${s.toString()}`,{method:"GET"}),n=await e.json().catch(()=>({}));if(!e.ok)throw new Error((n==null?void 0:n.error)||`Request failed (${e.status})`);return n==null?void 0:n.value}async function v(t){const s=new URLSearchParams,e=Array.isArray(t==null?void 0:t.type)?t==null?void 0:t.type:t!=null&&t.type?[t.type]:[];e.length>0&&s.set("type",e.join(",")),t!=null&&t.configuredOnly&&s.set("configuredOnly","true");const n=await l(`/app-api/models${s.toString()?`?${s.toString()}`:""}`,{method:"GET"}),r=await n.json().catch(()=>({}));if(!n.ok)throw new Error((r==null?void 0:r.error)||`Request failed (${n.status})`);return(Array.isArray(r==null?void 0:r.models)?r.models:[]).map(i=>{if(!i||typeof i!="object")return null;const f=typeof i.id=="string"?i.id.trim():"",b=typeof i.label=="string"?i.label.trim():f,o=i.type,h=i.configured===!0,u=typeof i.source=="string"&&i.source.trim()?i.source.trim():void 0;return!f||o!=="llm"&&o!=="embedding"&&o!=="image"&&o!=="stt"&&o!=="tts"?null:{id:f,label:b||f,type:o,configured:h,source:u}}).filter(i=>!!i)}async function j(t,s){const e=await l(t,s),r=(e.headers.get("content-type")||"").includes("application/json")?await e.json().catch(()=>({})):await e.text();if(!e.ok)throw new Error(typeof r=="string"?r||`Request failed (${e.status})`:(r==null?void 0:r.error)||(r==null?void 0:r.message)||`Request failed (${e.status})`);return r}const g=t=>t?t.split("/").map(s=>s.trim()).filter(Boolean).join("/"):"",S=(t,s)=>{const e=g(t),n=g(s);return e?n?`${e}/${n}`:e:n},P=(t,s)=>{const e={scope:t};return{async get(){const n=g(s);return $({...e,path:n||void 0})},async set(n){const r=g(s);return y("set",{...e,path:r||void 0,value:n})},async update(n){if(!n||typeof n!="object")throw new Error("update requires an object");const r={};for(const[c,i]of Object.entries(n)){const f=S(s,c);if(!f)throw new Error("update paths must be non-empty");r[f]=i}return y("update",{...e,updates:r})},async remove(){const n=g(s);return y("remove",{...e,path:n||void 0})},async push(n){const r=g(s);if(!r)throw new Error("push requires a path");return y("array-push",{...e,path:r,value:n})},ref(n){const r=S(s,n);if(!r)throw new Error("ref requires a path");return P(t,r)}}};return{isReady(){return!!d()&&!!m()},getBackendUrl(){var t;return((t=d())==null?void 0:t.backendUrl)??null},async models(t){return v(t)},async chatCompletions(t){var o;const{reasoningEffort:s,reasoning_effort:e,...n}=t,r=s??e,c={...n,stream:!1};r&&E(t.model)&&(c.reasoning_effort=r);const i=await l("/openai/chat/completions",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(c)}),b=(i.headers.get("content-type")||"").includes("application/json")?await i.json():await i.text();if(!i.ok)throw new Error(typeof b=="string"?b:((o=b==null?void 0:b.error)==null?void 0:o.message)||`Request failed (${i.status})`);return b},async chatText(t){var e,n,r;const s=await this.chatCompletions(t);return((r=(n=(e=s==null?void 0:s.choices)==null?void 0:e[0])==null?void 0:n.message)==null?void 0:r.content)??""},embeddings:{async create(t){var r;const s=(r=t==null?void 0:t.model)==null?void 0:r.trim();if(!s)throw new Error("embeddings.create requires a model");const e=t==null?void 0:t.input;if(!(typeof e=="string"?e.length>0:Array.isArray(e)&&e.length>0&&e.every(c=>typeof c=="string")))throw new Error("embeddings.create requires input as a string or string[]");return j("/openai/embeddings",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({...t,model:s,input:e})})}},audio:{async tts(t){var r;const s=(r=t==null?void 0:t.text)==null?void 0:r.trim();if(!s)throw new Error("audio.tts requires non-empty text");const e=await l("/app-api/audio/tts",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({text:s,voice:t.voice,lang:t.lang})});if(!e.ok){const c=await e.text();throw new Error(c||`Request failed (${e.status})`)}return{audio:await e.arrayBuffer(),contentType:e.headers.get("content-type")}},async stt(t){var u,p,R;if(!(t!=null&&t.file))throw new Error("audio.stt requires a file");const s=x=>{if(!x)return;const A=x.trim();if(!A)return;const U=A.toLowerCase(),O=U.split("-")[0];return O.length===2?O:U},e=typeof File<"u"&&t.file instanceof File,n=e&&t.file.name.split(".").pop()||"webm",r=t.ext||n,c=new FormData;e?c.set("file",t.file):c.set("file",t.file,`audio.${r}`);const i=s(t.language);i&&c.set("language",i),t.prompt&&c.set("prompt",t.prompt);const f=await l(`/app-api/audio/stt?ext=${encodeURIComponent(r)}`,{method:"POST",body:c}),o=(f.headers.get("content-type")||"").includes("application/json")?await f.json():await f.text();if(!f.ok)throw new Error(typeof o=="string"?o:((u=o==null?void 0:o.error)==null?void 0:u.message)||`Request failed (${f.status})`);return{text:typeof o=="string"?o:(o==null?void 0:o.text)||(o==null?void 0:o.original)||((R=(p=o==null?void 0:o.results)==null?void 0:p[0])==null?void 0:R.text)||"",raw:o}},async voices(t){const s=new URLSearchParams;t!=null&&t.locale&&s.set("locale",t.locale);const e=await l(`/app-api/audio/tts/voices${s.toString()?`?${s}`:""}`,{method:"GET"}),n=await e.json().catch(()=>[]);if(!e.ok)throw new Error((n==null?void 0:n.error)||`Request failed (${e.status})`);return Array.isArray(n)?n:(n==null?void 0:n.voices)||[]}},web:{async scrapeUrl(t){var e;const s=(e=t==null?void 0:t.url)==null?void 0:e.trim();if(!s)throw new Error("web.scrapeUrl requires a url");return j("/app-api/web/scrape-url",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({url:s,maxChars:t.maxChars})})}},data(t="private"){return P(t,"")}}}w.PromteAppProvider=L,w.usePromte=k,w.usePromteClient=C,w.usePromteDarkMode=F,w.usePromteModels=G,w.usePromteSettings=B,w.usePromteToken=D,w.usePromteUser=_,Object.defineProperty(w,Symbol.toStringTag,{value:"Module"})});
|
|
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"})});
|