@promte/app-library 0.1.3 → 0.1.5
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 +24 -0
- package/dist/index.d.ts +55 -0
- package/dist/index.mjs +244 -197
- package/dist/index.umd.cjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -68,6 +68,10 @@ You can fetch configured models/capabilities from backend:
|
|
|
68
68
|
const client = usePromteClient();
|
|
69
69
|
const allModels = await client.models();
|
|
70
70
|
const llmsOnly = await client.models({ type: "llm", configuredOnly: true });
|
|
71
|
+
const embeddingsOnly = await client.models({
|
|
72
|
+
type: "embedding",
|
|
73
|
+
configuredOnly: true,
|
|
74
|
+
});
|
|
71
75
|
```
|
|
72
76
|
|
|
73
77
|
Or use the built-in hook:
|
|
@@ -81,6 +85,26 @@ const { models, loading, error, reload } = usePromteModels({
|
|
|
81
85
|
|
|
82
86
|
Each model includes `id`, `label`, `type` (`llm` | `embedding` | `image` | `stt` | `tts`) and `configured`.
|
|
83
87
|
|
|
88
|
+
## Embeddings
|
|
89
|
+
|
|
90
|
+
Embeddings use the same app token/auth flow as LLM requests. Fetch an available
|
|
91
|
+
embedding model, then create embeddings:
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
const client = usePromteClient();
|
|
95
|
+
const [model] = await client.models({
|
|
96
|
+
type: "embedding",
|
|
97
|
+
configuredOnly: true,
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
const response = await client.embeddings.create({
|
|
101
|
+
model: model.id,
|
|
102
|
+
input: ["First text", "Second text"],
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
const vectors = response.data.map((item) => item.embedding);
|
|
106
|
+
```
|
|
107
|
+
|
|
84
108
|
## Return behavior
|
|
85
109
|
|
|
86
110
|
- `get()` returns the value at the current path, or `null` if missing.
|
package/dist/index.d.ts
CHANGED
|
@@ -73,6 +73,32 @@ export declare type ChatMessage = {
|
|
|
73
73
|
content: string;
|
|
74
74
|
};
|
|
75
75
|
|
|
76
|
+
export declare type EmbeddingItem = {
|
|
77
|
+
object?: string;
|
|
78
|
+
embedding: number[] | string;
|
|
79
|
+
index: number;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export declare type EmbeddingsRequest = {
|
|
83
|
+
model: string;
|
|
84
|
+
input: string | string[];
|
|
85
|
+
encoding_format?: "float" | "base64";
|
|
86
|
+
dimensions?: number;
|
|
87
|
+
user?: string;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export declare type EmbeddingsResponse = {
|
|
91
|
+
object?: string;
|
|
92
|
+
data: EmbeddingItem[];
|
|
93
|
+
model?: string;
|
|
94
|
+
usage?: {
|
|
95
|
+
prompt_tokens?: number;
|
|
96
|
+
total_tokens?: number;
|
|
97
|
+
[key: string]: any;
|
|
98
|
+
};
|
|
99
|
+
[key: string]: any;
|
|
100
|
+
};
|
|
101
|
+
|
|
76
102
|
export declare function PromteAppProvider({ children, expectedParentOrigin, initTargetOrigin, retryInit, }: PromteAppProviderProps): JSX_2.Element;
|
|
77
103
|
|
|
78
104
|
export declare type PromteAppProviderProps = {
|
|
@@ -92,11 +118,17 @@ export declare type PromteClient = {
|
|
|
92
118
|
models(req?: PromteModelsRequest): Promise<PromteModelInfo[]>;
|
|
93
119
|
chatCompletions(req: ChatCompletionsRequest): Promise<ChatCompletionsResponse>;
|
|
94
120
|
chatText(req: ChatCompletionsRequest): Promise<string>;
|
|
121
|
+
embeddings: {
|
|
122
|
+
create(req: EmbeddingsRequest): Promise<EmbeddingsResponse>;
|
|
123
|
+
};
|
|
95
124
|
audio: {
|
|
96
125
|
tts(req: AudioTtsRequest): Promise<AudioTtsResponse>;
|
|
97
126
|
stt(req: AudioSttRequest): Promise<AudioSttResponse>;
|
|
98
127
|
voices(req?: AudioVoicesRequest): Promise<AudioVoiceInfo[]>;
|
|
99
128
|
};
|
|
129
|
+
web: {
|
|
130
|
+
scrapeUrl(req: ScrapeUrlRequest): Promise<ScrapeUrlResponse>;
|
|
131
|
+
};
|
|
100
132
|
data(scope?: AppDataScope): AppDataRef;
|
|
101
133
|
};
|
|
102
134
|
|
|
@@ -145,6 +177,29 @@ export declare type PromteUser = {
|
|
|
145
177
|
|
|
146
178
|
export declare type ReasoningEffort = "minimal" | "low" | "medium" | "high";
|
|
147
179
|
|
|
180
|
+
export declare type ScrapeUrlRequest = {
|
|
181
|
+
url: string;
|
|
182
|
+
maxChars?: number;
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
export declare type ScrapeUrlResponse = {
|
|
186
|
+
requestedUrl: string;
|
|
187
|
+
url: string;
|
|
188
|
+
label: string;
|
|
189
|
+
text: string;
|
|
190
|
+
title?: string;
|
|
191
|
+
status?: number;
|
|
192
|
+
extractor?: string;
|
|
193
|
+
warning?: string;
|
|
194
|
+
cached?: boolean;
|
|
195
|
+
fallback?: {
|
|
196
|
+
provider?: string;
|
|
197
|
+
enabled?: boolean;
|
|
198
|
+
attempted?: boolean;
|
|
199
|
+
used?: boolean;
|
|
200
|
+
};
|
|
201
|
+
};
|
|
202
|
+
|
|
148
203
|
export declare function usePromte(): PromteCtxValue;
|
|
149
204
|
|
|
150
205
|
export declare function usePromteClient(): PromteClient;
|
package/dist/index.mjs
CHANGED
|
@@ -1,275 +1,304 @@
|
|
|
1
1
|
import { jsx as B } from "react/jsx-runtime";
|
|
2
|
-
import { createContext as L, useState as
|
|
3
|
-
const
|
|
4
|
-
function
|
|
5
|
-
children:
|
|
6
|
-
expectedParentOrigin:
|
|
7
|
-
initTargetOrigin:
|
|
8
|
-
retryInit:
|
|
2
|
+
import { createContext as L, useState as k, useMemo as x, useCallback as U, useEffect as T, useContext as D } from "react";
|
|
3
|
+
const O = L(null);
|
|
4
|
+
function N({
|
|
5
|
+
children: p,
|
|
6
|
+
expectedParentOrigin: d,
|
|
7
|
+
initTargetOrigin: v,
|
|
8
|
+
retryInit: l = { enabled: !0, intervalMs: 500, maxAttempts: 20 }
|
|
9
9
|
}) {
|
|
10
|
-
const [m,
|
|
11
|
-
var
|
|
10
|
+
const [m, $] = k(null), [y, j] = k(null), [h, b] = k(null), [E, t] = k(null), [r, e] = k(null), n = x(() => r ? "booting" : m ? y ? "ready" : "waiting_for_token" : "waiting_for_settings", [m, y, r]), s = n === "ready", c = x(() => v || d || "*", [v, d]), a = U(() => {
|
|
11
|
+
var o;
|
|
12
12
|
try {
|
|
13
13
|
const w = { type: "init" };
|
|
14
|
-
(
|
|
14
|
+
(o = window.parent) == null || o.postMessage(w, c);
|
|
15
15
|
} catch (w) {
|
|
16
16
|
e((w == null ? void 0 : w.message) || "Failed to post init");
|
|
17
17
|
}
|
|
18
|
-
}, [
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}, [
|
|
22
|
-
if (!(
|
|
23
|
-
const
|
|
24
|
-
let
|
|
25
|
-
const
|
|
18
|
+
}, [c]);
|
|
19
|
+
T(() => {
|
|
20
|
+
a();
|
|
21
|
+
}, [a]), T(() => {
|
|
22
|
+
if (!(l != null && l.enabled) || m) return;
|
|
23
|
+
const o = l.intervalMs ?? 500, w = l.maxAttempts ?? 20;
|
|
24
|
+
let i = 0;
|
|
25
|
+
const f = window.setInterval(() => {
|
|
26
26
|
if (m) {
|
|
27
|
-
window.clearInterval(
|
|
27
|
+
window.clearInterval(f);
|
|
28
28
|
return;
|
|
29
29
|
}
|
|
30
|
-
if (
|
|
31
|
-
window.clearInterval(
|
|
30
|
+
if (i += 1, i > w) {
|
|
31
|
+
window.clearInterval(f);
|
|
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
|
+
a();
|
|
35
|
+
}, o);
|
|
36
|
+
return () => window.clearInterval(f);
|
|
37
|
+
}, [l, m, a]), T(() => {
|
|
38
|
+
const o = (w) => {
|
|
39
|
+
if (d && w.origin !== d) return;
|
|
40
|
+
const i = w.data;
|
|
41
|
+
if (!(!i || typeof i != "object")) {
|
|
42
|
+
if (i.type === "set-settings") {
|
|
43
|
+
const f = i.value;
|
|
44
|
+
if (!(f != null && f.backendUrl) || f.parentOrigin && d && f.parentOrigin !== d)
|
|
45
45
|
return;
|
|
46
|
-
|
|
46
|
+
$(f), f != null && f.user && t(f.user), e(null);
|
|
47
47
|
return;
|
|
48
48
|
}
|
|
49
|
-
if (
|
|
50
|
-
|
|
49
|
+
if (i.type === "set-token" && typeof i.value == "string") {
|
|
50
|
+
j(i.value), e(null);
|
|
51
51
|
return;
|
|
52
52
|
}
|
|
53
|
-
if (
|
|
54
|
-
b(
|
|
53
|
+
if (i.type === "set-dark-mode" && typeof i.value == "boolean") {
|
|
54
|
+
b(i.value);
|
|
55
55
|
return;
|
|
56
56
|
}
|
|
57
|
-
if (
|
|
58
|
-
|
|
57
|
+
if (i.type === "set-user" && typeof i.value == "object") {
|
|
58
|
+
t(i.value);
|
|
59
59
|
return;
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
};
|
|
63
|
-
return window.addEventListener("message",
|
|
64
|
-
}, [
|
|
65
|
-
const
|
|
63
|
+
return window.addEventListener("message", o), () => window.removeEventListener("message", o);
|
|
64
|
+
}, [d]);
|
|
65
|
+
const u = x(() => _(
|
|
66
66
|
() => m,
|
|
67
|
-
() =>
|
|
68
|
-
), [m,
|
|
67
|
+
() => y
|
|
68
|
+
), [m, y]), g = x(
|
|
69
69
|
() => ({
|
|
70
70
|
settings: m,
|
|
71
|
-
token:
|
|
72
|
-
isDarkMode:
|
|
73
|
-
user:
|
|
74
|
-
ready:
|
|
75
|
-
state:
|
|
76
|
-
error:
|
|
77
|
-
client:
|
|
71
|
+
token: y,
|
|
72
|
+
isDarkMode: h,
|
|
73
|
+
user: E,
|
|
74
|
+
ready: s,
|
|
75
|
+
state: n,
|
|
76
|
+
error: r,
|
|
77
|
+
client: u
|
|
78
78
|
}),
|
|
79
|
-
[m,
|
|
79
|
+
[m, y, h, E, s, n, r, u]
|
|
80
80
|
);
|
|
81
|
-
return /* @__PURE__ */ B(
|
|
81
|
+
return /* @__PURE__ */ B(O.Provider, { value: g, children: p });
|
|
82
82
|
}
|
|
83
|
-
function
|
|
84
|
-
const
|
|
85
|
-
if (!
|
|
83
|
+
function S() {
|
|
84
|
+
const p = D(O);
|
|
85
|
+
if (!p)
|
|
86
86
|
throw new Error("usePromte must be used inside <PromteAppProvider>");
|
|
87
|
-
return
|
|
87
|
+
return p;
|
|
88
88
|
}
|
|
89
|
-
function
|
|
90
|
-
return
|
|
89
|
+
function z() {
|
|
90
|
+
return S().settings;
|
|
91
91
|
}
|
|
92
|
-
function
|
|
93
|
-
return
|
|
92
|
+
function I() {
|
|
93
|
+
return S().token;
|
|
94
94
|
}
|
|
95
95
|
function V() {
|
|
96
|
-
return
|
|
96
|
+
return S().isDarkMode;
|
|
97
97
|
}
|
|
98
|
-
function
|
|
99
|
-
return
|
|
98
|
+
function W() {
|
|
99
|
+
return S().user;
|
|
100
100
|
}
|
|
101
101
|
function F() {
|
|
102
|
-
return
|
|
102
|
+
return S().client;
|
|
103
103
|
}
|
|
104
|
-
function K(
|
|
105
|
-
const { ready:
|
|
106
|
-
if (!
|
|
107
|
-
|
|
104
|
+
function K(p = {}) {
|
|
105
|
+
const { ready: d } = S(), v = F(), [l, m] = k([]), [$, y] = k(!1), [j, h] = k(null), b = x(() => (Array.isArray(p.type) ? p.type : p.type ? [p.type] : []).filter(Boolean).map((n) => String(n)).join(","), [p.type]), E = p.configuredOnly === !0, t = p.auto !== !1, r = U(async () => {
|
|
106
|
+
if (!d) return [];
|
|
107
|
+
y(!0), h(null);
|
|
108
108
|
try {
|
|
109
|
-
const e = b ? b.split(",").filter(Boolean) : void 0,
|
|
110
|
-
return m(
|
|
109
|
+
const e = b ? b.split(",").filter(Boolean) : void 0, n = await v.models({ type: e, configuredOnly: E });
|
|
110
|
+
return m(n), n;
|
|
111
111
|
} catch (e) {
|
|
112
|
-
const
|
|
113
|
-
throw
|
|
112
|
+
const n = e instanceof Error ? e.message : String(e);
|
|
113
|
+
throw h(n), e;
|
|
114
114
|
} finally {
|
|
115
|
-
|
|
115
|
+
y(!1);
|
|
116
116
|
}
|
|
117
|
-
}, [
|
|
118
|
-
return
|
|
119
|
-
!
|
|
117
|
+
}, [v, E, d, b]);
|
|
118
|
+
return T(() => {
|
|
119
|
+
!t || !d || r().catch(() => {
|
|
120
120
|
});
|
|
121
|
-
}, [
|
|
121
|
+
}, [t, d, r]), { models: l, loading: $, error: j, reload: r };
|
|
122
122
|
}
|
|
123
|
-
function
|
|
124
|
-
const
|
|
125
|
-
async function
|
|
126
|
-
const
|
|
127
|
-
if (!
|
|
128
|
-
if (!
|
|
129
|
-
const
|
|
130
|
-
return await fetch(
|
|
123
|
+
function _(p, d) {
|
|
124
|
+
const v = (t) => typeof t == "string" && t.startsWith("gpt-5");
|
|
125
|
+
async function l(t, r) {
|
|
126
|
+
const e = p(), n = d();
|
|
127
|
+
if (!e) throw new Error("Promte settings not received yet");
|
|
128
|
+
if (!n) throw new Error("Promte token not received yet");
|
|
129
|
+
const s = e.backendUrl.replace(/\/+$/, ""), c = String(t || "").replace(/^\/+/, ""), a = `${s}/${c}`;
|
|
130
|
+
return await fetch(a, {
|
|
131
131
|
...r,
|
|
132
132
|
headers: {
|
|
133
133
|
...r.headers || {},
|
|
134
|
-
Authorization: `Bearer ${
|
|
134
|
+
Authorization: `Bearer ${n}`
|
|
135
135
|
}
|
|
136
136
|
});
|
|
137
137
|
}
|
|
138
138
|
async function m(t, r) {
|
|
139
|
-
const
|
|
139
|
+
const e = await l(`/app-api/data/${t}`, {
|
|
140
140
|
method: "POST",
|
|
141
141
|
headers: { "Content-Type": "application/json" },
|
|
142
142
|
body: JSON.stringify(r)
|
|
143
|
-
}),
|
|
144
|
-
if (!
|
|
143
|
+
}), n = await e.json().catch(() => ({}));
|
|
144
|
+
if (!e.ok)
|
|
145
145
|
throw new Error(
|
|
146
|
-
(
|
|
146
|
+
(n == null ? void 0 : n.error) || `Request failed (${e.status})`
|
|
147
147
|
);
|
|
148
|
-
return
|
|
148
|
+
return n == null ? void 0 : n.value;
|
|
149
149
|
}
|
|
150
|
-
async function
|
|
150
|
+
async function $(t) {
|
|
151
151
|
const r = new URLSearchParams();
|
|
152
152
|
t.scope && r.set("scope", t.scope), t.path && r.set("path", t.path);
|
|
153
|
-
const
|
|
153
|
+
const e = await l(`/app-api/data?${r.toString()}`, {
|
|
154
154
|
method: "GET"
|
|
155
|
-
}),
|
|
156
|
-
if (!
|
|
157
|
-
throw new Error((
|
|
158
|
-
return
|
|
155
|
+
}), n = await e.json().catch(() => ({}));
|
|
156
|
+
if (!e.ok)
|
|
157
|
+
throw new Error((n == null ? void 0 : n.error) || `Request failed (${e.status})`);
|
|
158
|
+
return n == null ? void 0 : n.value;
|
|
159
159
|
}
|
|
160
|
-
async function
|
|
161
|
-
const r = new URLSearchParams(),
|
|
162
|
-
|
|
163
|
-
const
|
|
160
|
+
async function y(t) {
|
|
161
|
+
const r = new URLSearchParams(), e = Array.isArray(t == null ? void 0 : t.type) ? t == null ? void 0 : t.type : t != null && t.type ? [t.type] : [];
|
|
162
|
+
e.length > 0 && r.set("type", e.join(",")), t != null && t.configuredOnly && r.set("configuredOnly", "true");
|
|
163
|
+
const n = await l(
|
|
164
164
|
`/app-api/models${r.toString() ? `?${r.toString()}` : ""}`,
|
|
165
165
|
{ 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:
|
|
166
|
+
), s = await n.json().catch(() => ({}));
|
|
167
|
+
if (!n.ok)
|
|
168
|
+
throw new Error((s == null ? void 0 : s.error) || `Request failed (${n.status})`);
|
|
169
|
+
return (Array.isArray(s == null ? void 0 : s.models) ? s.models : []).map((a) => {
|
|
170
|
+
if (!a || typeof a != "object") return null;
|
|
171
|
+
const u = typeof a.id == "string" ? a.id.trim() : "", g = typeof a.label == "string" ? a.label.trim() : u, o = a.type, w = a.configured === !0, i = typeof a.source == "string" && a.source.trim() ? a.source.trim() : void 0;
|
|
172
|
+
return !u || o !== "llm" && o !== "embedding" && o !== "image" && o !== "stt" && o !== "tts" ? null : {
|
|
173
|
+
id: u,
|
|
174
|
+
label: g || u,
|
|
175
|
+
type: o,
|
|
176
|
+
configured: w,
|
|
177
|
+
source: i
|
|
178
178
|
};
|
|
179
179
|
}).filter(
|
|
180
|
-
(
|
|
180
|
+
(a) => !!a
|
|
181
181
|
);
|
|
182
182
|
}
|
|
183
|
-
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
183
|
+
async function j(t, r) {
|
|
184
|
+
const e = await l(t, r), s = (e.headers.get("content-type") || "").includes("application/json") ? await e.json().catch(() => ({})) : await e.text();
|
|
185
|
+
if (!e.ok)
|
|
186
|
+
throw new Error(
|
|
187
|
+
typeof s == "string" ? s || `Request failed (${e.status})` : (s == null ? void 0 : s.error) || (s == null ? void 0 : s.message) || `Request failed (${e.status})`
|
|
188
|
+
);
|
|
189
|
+
return s;
|
|
190
|
+
}
|
|
191
|
+
const h = (t) => t ? t.split("/").map((r) => r.trim()).filter(Boolean).join("/") : "", b = (t, r) => {
|
|
192
|
+
const e = h(t), n = h(r);
|
|
193
|
+
return e ? n ? `${e}/${n}` : e : n;
|
|
194
|
+
}, E = (t, r) => {
|
|
195
|
+
const e = { scope: t };
|
|
188
196
|
return {
|
|
189
197
|
async get() {
|
|
190
|
-
const
|
|
191
|
-
return
|
|
198
|
+
const n = h(r);
|
|
199
|
+
return $({ ...e, path: n || void 0 });
|
|
192
200
|
},
|
|
193
|
-
async set(
|
|
194
|
-
const
|
|
201
|
+
async set(n) {
|
|
202
|
+
const s = h(r);
|
|
195
203
|
return m("set", {
|
|
196
|
-
...
|
|
197
|
-
path:
|
|
198
|
-
value:
|
|
204
|
+
...e,
|
|
205
|
+
path: s || void 0,
|
|
206
|
+
value: n
|
|
199
207
|
});
|
|
200
208
|
},
|
|
201
|
-
async update(
|
|
202
|
-
if (!
|
|
209
|
+
async update(n) {
|
|
210
|
+
if (!n || typeof n != "object")
|
|
203
211
|
throw new Error("update requires an object");
|
|
204
|
-
const
|
|
205
|
-
for (const [
|
|
206
|
-
const
|
|
207
|
-
if (!
|
|
212
|
+
const s = {};
|
|
213
|
+
for (const [c, a] of Object.entries(n)) {
|
|
214
|
+
const u = b(r, c);
|
|
215
|
+
if (!u)
|
|
208
216
|
throw new Error("update paths must be non-empty");
|
|
209
|
-
|
|
217
|
+
s[u] = a;
|
|
210
218
|
}
|
|
211
|
-
return m("update", { ...
|
|
219
|
+
return m("update", { ...e, updates: s });
|
|
212
220
|
},
|
|
213
221
|
async remove() {
|
|
214
|
-
const
|
|
215
|
-
return m("remove", { ...
|
|
222
|
+
const n = h(r);
|
|
223
|
+
return m("remove", { ...e, path: n || void 0 });
|
|
216
224
|
},
|
|
217
|
-
async push(
|
|
218
|
-
const
|
|
219
|
-
if (!
|
|
220
|
-
return m("array-push", { ...
|
|
225
|
+
async push(n) {
|
|
226
|
+
const s = h(r);
|
|
227
|
+
if (!s) throw new Error("push requires a path");
|
|
228
|
+
return m("array-push", { ...e, path: s, value: n });
|
|
221
229
|
},
|
|
222
|
-
ref(
|
|
223
|
-
const
|
|
224
|
-
if (!
|
|
225
|
-
return
|
|
230
|
+
ref(n) {
|
|
231
|
+
const s = b(r, n);
|
|
232
|
+
if (!s) throw new Error("ref requires a path");
|
|
233
|
+
return E(t, s);
|
|
226
234
|
}
|
|
227
235
|
};
|
|
228
236
|
};
|
|
229
237
|
return {
|
|
230
238
|
isReady() {
|
|
231
|
-
return !!
|
|
239
|
+
return !!p() && !!d();
|
|
232
240
|
},
|
|
233
241
|
getBackendUrl() {
|
|
234
242
|
var t;
|
|
235
|
-
return ((t =
|
|
243
|
+
return ((t = p()) == null ? void 0 : t.backendUrl) ?? null;
|
|
236
244
|
},
|
|
237
245
|
async models(t) {
|
|
238
|
-
return
|
|
246
|
+
return y(t);
|
|
239
247
|
},
|
|
240
248
|
async chatCompletions(t) {
|
|
241
|
-
var
|
|
249
|
+
var o;
|
|
242
250
|
const {
|
|
243
251
|
reasoningEffort: r,
|
|
244
|
-
reasoning_effort:
|
|
245
|
-
...
|
|
246
|
-
} = t,
|
|
247
|
-
...
|
|
252
|
+
reasoning_effort: e,
|
|
253
|
+
...n
|
|
254
|
+
} = t, s = r ?? e, c = {
|
|
255
|
+
...n,
|
|
248
256
|
stream: !1
|
|
249
257
|
};
|
|
250
|
-
|
|
251
|
-
const
|
|
258
|
+
s && v(t.model) && (c.reasoning_effort = s);
|
|
259
|
+
const a = await l("/openai/chat/completions", {
|
|
252
260
|
method: "POST",
|
|
253
261
|
headers: { "Content-Type": "application/json" },
|
|
254
|
-
body: JSON.stringify(
|
|
255
|
-
}),
|
|
256
|
-
if (!
|
|
262
|
+
body: JSON.stringify(c)
|
|
263
|
+
}), g = (a.headers.get("content-type") || "").includes("application/json") ? await a.json() : await a.text();
|
|
264
|
+
if (!a.ok)
|
|
257
265
|
throw new Error(
|
|
258
|
-
typeof
|
|
266
|
+
typeof g == "string" ? g : ((o = g == null ? void 0 : g.error) == null ? void 0 : o.message) || `Request failed (${a.status})`
|
|
259
267
|
);
|
|
260
|
-
return
|
|
268
|
+
return g;
|
|
261
269
|
},
|
|
262
270
|
async chatText(t) {
|
|
263
|
-
var
|
|
271
|
+
var e, n, s;
|
|
264
272
|
const r = await this.chatCompletions(t);
|
|
265
|
-
return ((
|
|
273
|
+
return ((s = (n = (e = r == null ? void 0 : r.choices) == null ? void 0 : e[0]) == null ? void 0 : n.message) == null ? void 0 : s.content) ?? "";
|
|
274
|
+
},
|
|
275
|
+
embeddings: {
|
|
276
|
+
async create(t) {
|
|
277
|
+
var s;
|
|
278
|
+
const r = (s = t == null ? void 0 : t.model) == null ? void 0 : s.trim();
|
|
279
|
+
if (!r) throw new Error("embeddings.create requires a model");
|
|
280
|
+
const e = t == null ? void 0 : t.input;
|
|
281
|
+
if (!(typeof e == "string" ? e.length > 0 : Array.isArray(e) && e.length > 0 && e.every((c) => typeof c == "string")))
|
|
282
|
+
throw new Error(
|
|
283
|
+
"embeddings.create requires input as a string or string[]"
|
|
284
|
+
);
|
|
285
|
+
return j("/openai/embeddings", {
|
|
286
|
+
method: "POST",
|
|
287
|
+
headers: { "Content-Type": "application/json" },
|
|
288
|
+
body: JSON.stringify({
|
|
289
|
+
...t,
|
|
290
|
+
model: r,
|
|
291
|
+
input: e
|
|
292
|
+
})
|
|
293
|
+
});
|
|
294
|
+
}
|
|
266
295
|
},
|
|
267
296
|
audio: {
|
|
268
297
|
async tts(t) {
|
|
269
|
-
var
|
|
270
|
-
const r = (
|
|
298
|
+
var s;
|
|
299
|
+
const r = (s = t == null ? void 0 : t.text) == null ? void 0 : s.trim();
|
|
271
300
|
if (!r) throw new Error("audio.tts requires non-empty text");
|
|
272
|
-
const
|
|
301
|
+
const e = await l("/app-api/audio/tts", {
|
|
273
302
|
method: "POST",
|
|
274
303
|
headers: { "Content-Type": "application/json" },
|
|
275
304
|
body: JSON.stringify({
|
|
@@ -278,67 +307,85 @@ function O(f, p) {
|
|
|
278
307
|
lang: t.lang
|
|
279
308
|
})
|
|
280
309
|
});
|
|
281
|
-
if (!
|
|
282
|
-
const
|
|
283
|
-
throw new Error(
|
|
310
|
+
if (!e.ok) {
|
|
311
|
+
const c = await e.text();
|
|
312
|
+
throw new Error(c || `Request failed (${e.status})`);
|
|
284
313
|
}
|
|
285
314
|
return {
|
|
286
|
-
audio: await
|
|
287
|
-
contentType:
|
|
315
|
+
audio: await e.arrayBuffer(),
|
|
316
|
+
contentType: e.headers.get("content-type")
|
|
288
317
|
};
|
|
289
318
|
},
|
|
290
319
|
async stt(t) {
|
|
291
|
-
var
|
|
320
|
+
var i, f, P;
|
|
292
321
|
if (!(t != null && t.file)) throw new Error("audio.stt requires a file");
|
|
293
322
|
const r = (R) => {
|
|
294
323
|
if (!R) return;
|
|
295
|
-
const
|
|
296
|
-
if (!
|
|
297
|
-
const A =
|
|
298
|
-
return
|
|
299
|
-
},
|
|
300
|
-
|
|
301
|
-
const
|
|
302
|
-
|
|
303
|
-
const
|
|
304
|
-
`/app-api/audio/stt?ext=${encodeURIComponent(
|
|
324
|
+
const C = R.trim();
|
|
325
|
+
if (!C) return;
|
|
326
|
+
const A = C.toLowerCase(), M = A.split("-")[0];
|
|
327
|
+
return M.length === 2 ? M : A;
|
|
328
|
+
}, e = typeof File < "u" && t.file instanceof File, n = e && t.file.name.split(".").pop() || "webm", s = t.ext || n, c = new FormData();
|
|
329
|
+
e ? c.set("file", t.file) : c.set("file", t.file, `audio.${s}`);
|
|
330
|
+
const a = r(t.language);
|
|
331
|
+
a && c.set("language", a), t.prompt && c.set("prompt", t.prompt);
|
|
332
|
+
const u = await l(
|
|
333
|
+
`/app-api/audio/stt?ext=${encodeURIComponent(s)}`,
|
|
305
334
|
{
|
|
306
335
|
method: "POST",
|
|
307
|
-
body:
|
|
336
|
+
body: c
|
|
308
337
|
}
|
|
309
|
-
),
|
|
310
|
-
if (!
|
|
338
|
+
), o = (u.headers.get("content-type") || "").includes("application/json") ? await u.json() : await u.text();
|
|
339
|
+
if (!u.ok)
|
|
311
340
|
throw new Error(
|
|
312
|
-
typeof
|
|
341
|
+
typeof o == "string" ? o : ((i = o == null ? void 0 : o.error) == null ? void 0 : i.message) || `Request failed (${u.status})`
|
|
313
342
|
);
|
|
314
|
-
return { text: typeof
|
|
343
|
+
return { text: typeof o == "string" ? o : (o == null ? void 0 : o.text) || (o == null ? void 0 : o.original) || ((P = (f = o == null ? void 0 : o.results) == null ? void 0 : f[0]) == null ? void 0 : P.text) || "", raw: o };
|
|
315
344
|
},
|
|
316
345
|
async voices(t) {
|
|
317
346
|
const r = new URLSearchParams();
|
|
318
347
|
t != null && t.locale && r.set("locale", t.locale);
|
|
319
|
-
const
|
|
348
|
+
const e = await l(
|
|
320
349
|
`/app-api/audio/tts/voices${r.toString() ? `?${r}` : ""}`,
|
|
321
350
|
{ method: "GET" }
|
|
322
|
-
),
|
|
323
|
-
if (!
|
|
351
|
+
), n = await e.json().catch(() => []);
|
|
352
|
+
if (!e.ok)
|
|
324
353
|
throw new Error(
|
|
325
|
-
(
|
|
354
|
+
(n == null ? void 0 : n.error) || `Request failed (${e.status})`
|
|
326
355
|
);
|
|
327
|
-
return Array.isArray(
|
|
356
|
+
return Array.isArray(n) ? n : (n == null ? void 0 : n.voices) || [];
|
|
357
|
+
}
|
|
358
|
+
},
|
|
359
|
+
web: {
|
|
360
|
+
async scrapeUrl(t) {
|
|
361
|
+
var e;
|
|
362
|
+
const r = (e = t == null ? void 0 : t.url) == null ? void 0 : e.trim();
|
|
363
|
+
if (!r) throw new Error("web.scrapeUrl requires a url");
|
|
364
|
+
return j(
|
|
365
|
+
"/app-api/web/scrape-url",
|
|
366
|
+
{
|
|
367
|
+
method: "POST",
|
|
368
|
+
headers: { "Content-Type": "application/json" },
|
|
369
|
+
body: JSON.stringify({
|
|
370
|
+
url: r,
|
|
371
|
+
maxChars: t.maxChars
|
|
372
|
+
})
|
|
373
|
+
}
|
|
374
|
+
);
|
|
328
375
|
}
|
|
329
376
|
},
|
|
330
377
|
data(t = "private") {
|
|
331
|
-
return
|
|
378
|
+
return E(t, "");
|
|
332
379
|
}
|
|
333
380
|
};
|
|
334
381
|
}
|
|
335
382
|
export {
|
|
336
|
-
|
|
337
|
-
|
|
383
|
+
N as PromteAppProvider,
|
|
384
|
+
S as usePromte,
|
|
338
385
|
F as usePromteClient,
|
|
339
386
|
V as usePromteDarkMode,
|
|
340
387
|
K as usePromteModels,
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
388
|
+
z as usePromteSettings,
|
|
389
|
+
I as usePromteToken,
|
|
390
|
+
W as usePromteUser
|
|
344
391
|
};
|
package/dist/index.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(
|
|
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"})});
|