@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 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 j, useMemo as P, useCallback as M, useEffect as S, useContext as D } from "react";
3
- const U = L(null);
4
- function z({
5
- children: f,
6
- expectedParentOrigin: p,
7
- initTargetOrigin: E,
8
- retryInit: d = { enabled: !0, intervalMs: 500, maxAttempts: 20 }
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, x] = j(null), [h, g] = j(null), [k, b] = j(null), [t, r] = j(null), [n, e] = j(null), o = P(() => n ? "booting" : m ? h ? "ready" : "waiting_for_token" : "waiting_for_settings", [m, h, n]), u = o === "ready", s = P(() => E || p || "*", [E, p]), i = M(() => {
11
- var v;
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
- (v = window.parent) == null || v.postMessage(w, s);
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
- }, [s]);
19
- S(() => {
20
- i();
21
- }, [i]), S(() => {
22
- if (!(d != null && d.enabled) || m) return;
23
- const v = d.intervalMs ?? 500, w = d.maxAttempts ?? 20;
24
- let c = 0;
25
- const l = window.setInterval(() => {
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(l);
27
+ window.clearInterval(f);
28
28
  return;
29
29
  }
30
- if (c += 1, c > w) {
31
- window.clearInterval(l);
30
+ if (i += 1, i > w) {
31
+ window.clearInterval(f);
32
32
  return;
33
33
  }
34
- i();
35
- }, v);
36
- return () => window.clearInterval(l);
37
- }, [d, m, i]), S(() => {
38
- const v = (w) => {
39
- if (p && w.origin !== p) return;
40
- const c = w.data;
41
- if (!(!c || typeof c != "object")) {
42
- if (c.type === "set-settings") {
43
- const l = c.value;
44
- if (!(l != null && l.backendUrl) || l.parentOrigin && p && l.parentOrigin !== p)
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
- x(l), l != null && l.user && r(l.user), e(null);
46
+ $(f), f != null && f.user && t(f.user), e(null);
47
47
  return;
48
48
  }
49
- if (c.type === "set-token" && typeof c.value == "string") {
50
- g(c.value), e(null);
49
+ if (i.type === "set-token" && typeof i.value == "string") {
50
+ j(i.value), e(null);
51
51
  return;
52
52
  }
53
- if (c.type === "set-dark-mode" && typeof c.value == "boolean") {
54
- b(c.value);
53
+ if (i.type === "set-dark-mode" && typeof i.value == "boolean") {
54
+ b(i.value);
55
55
  return;
56
56
  }
57
- if (c.type === "set-user" && typeof c.value == "object") {
58
- r(c.value);
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", v), () => window.removeEventListener("message", v);
64
- }, [p]);
65
- const y = P(() => O(
63
+ return window.addEventListener("message", o), () => window.removeEventListener("message", o);
64
+ }, [d]);
65
+ const u = x(() => _(
66
66
  () => m,
67
- () => h
68
- ), [m, h]), a = P(
67
+ () => y
68
+ ), [m, y]), g = x(
69
69
  () => ({
70
70
  settings: m,
71
- token: h,
72
- isDarkMode: k,
73
- user: t,
74
- ready: u,
75
- state: o,
76
- error: n,
77
- client: y
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, h, k, t, u, o, n, y]
79
+ [m, y, h, E, s, n, r, u]
80
80
  );
81
- return /* @__PURE__ */ B(U.Provider, { value: a, children: f });
81
+ return /* @__PURE__ */ B(O.Provider, { value: g, children: p });
82
82
  }
83
- function $() {
84
- const f = D(U);
85
- if (!f)
83
+ function S() {
84
+ const p = D(O);
85
+ if (!p)
86
86
  throw new Error("usePromte must be used inside <PromteAppProvider>");
87
- return f;
87
+ return p;
88
88
  }
89
- function J() {
90
- return $().settings;
89
+ function z() {
90
+ return S().settings;
91
91
  }
92
- function N() {
93
- return $().token;
92
+ function I() {
93
+ return S().token;
94
94
  }
95
95
  function V() {
96
- return $().isDarkMode;
96
+ return S().isDarkMode;
97
97
  }
98
- function I() {
99
- return $().user;
98
+ function W() {
99
+ return S().user;
100
100
  }
101
101
  function F() {
102
- return $().client;
102
+ return S().client;
103
103
  }
104
- function K(f = {}) {
105
- const { ready: p } = $(), E = F(), [d, m] = j([]), [x, h] = j(!1), [g, k] = j(null), b = P(() => (Array.isArray(f.type) ? f.type : f.type ? [f.type] : []).filter(Boolean).map((o) => String(o)).join(","), [f.type]), t = f.configuredOnly === !0, r = f.auto !== !1, n = M(async () => {
106
- if (!p) return [];
107
- h(!0), k(null);
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, o = await E.models({ type: e, configuredOnly: t });
110
- return m(o), o;
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 o = e instanceof Error ? e.message : String(e);
113
- throw k(o), e;
112
+ const n = e instanceof Error ? e.message : String(e);
113
+ throw h(n), e;
114
114
  } finally {
115
- h(!1);
115
+ y(!1);
116
116
  }
117
- }, [E, t, p, b]);
118
- return S(() => {
119
- !r || !p || n().catch(() => {
117
+ }, [v, E, d, b]);
118
+ return T(() => {
119
+ !t || !d || r().catch(() => {
120
120
  });
121
- }, [r, p, n]), { models: d, loading: x, error: g, reload: n };
121
+ }, [t, d, r]), { models: l, loading: $, error: j, reload: r };
122
122
  }
123
- function O(f, p) {
124
- const E = (t) => typeof t == "string" && t.startsWith("gpt-5");
125
- async function d(t, r) {
126
- const n = f(), e = p();
127
- if (!n) throw new Error("Promte settings not received yet");
128
- if (!e) throw new Error("Promte token not received yet");
129
- const o = n.backendUrl.replace(/\/+$/, ""), u = String(t || "").replace(/^\/+/, ""), s = `${o}/${u}`;
130
- return await fetch(s, {
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 ${e}`
134
+ Authorization: `Bearer ${n}`
135
135
  }
136
136
  });
137
137
  }
138
138
  async function m(t, r) {
139
- const n = await d(`/app-api/data/${t}`, {
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
- }), e = await n.json().catch(() => ({}));
144
- if (!n.ok)
143
+ }), n = await e.json().catch(() => ({}));
144
+ if (!e.ok)
145
145
  throw new Error(
146
- (e == null ? void 0 : e.error) || `Request failed (${n.status})`
146
+ (n == null ? void 0 : n.error) || `Request failed (${e.status})`
147
147
  );
148
- return e == null ? void 0 : e.value;
148
+ return n == null ? void 0 : n.value;
149
149
  }
150
- async function x(t) {
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 n = await d(`/app-api/data?${r.toString()}`, {
153
+ const e = await l(`/app-api/data?${r.toString()}`, {
154
154
  method: "GET"
155
- }), e = await n.json().catch(() => ({}));
156
- if (!n.ok)
157
- throw new Error((e == null ? void 0 : e.error) || `Request failed (${n.status})`);
158
- return e == null ? void 0 : e.value;
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 h(t) {
161
- const r = new URLSearchParams(), n = Array.isArray(t == null ? void 0 : t.type) ? t == null ? void 0 : t.type : t != null && t.type ? [t.type] : [];
162
- n.length > 0 && r.set("type", n.join(",")), t != null && t.configuredOnly && r.set("configuredOnly", "true");
163
- const e = await d(
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
- ), o = await e.json().catch(() => ({}));
167
- if (!e.ok)
168
- throw new Error((o == null ? void 0 : o.error) || `Request failed (${e.status})`);
169
- return (Array.isArray(o == null ? void 0 : o.models) ? o.models : []).map((s) => {
170
- if (!s || typeof s != "object") return null;
171
- const i = typeof s.id == "string" ? s.id.trim() : "", y = typeof s.label == "string" ? s.label.trim() : i, a = s.type, v = s.configured === !0, w = typeof s.source == "string" && s.source.trim() ? s.source.trim() : void 0;
172
- return !i || a !== "llm" && a !== "embedding" && a !== "image" && a !== "stt" && a !== "tts" ? null : {
173
- id: i,
174
- label: y || i,
175
- type: a,
176
- configured: v,
177
- source: w
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
- (s) => !!s
180
+ (a) => !!a
181
181
  );
182
182
  }
183
- const g = (t) => t ? t.split("/").map((r) => r.trim()).filter(Boolean).join("/") : "", k = (t, r) => {
184
- const n = g(t), e = g(r);
185
- return n ? e ? `${n}/${e}` : n : e;
186
- }, b = (t, r) => {
187
- const n = { scope: t };
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 e = g(r);
191
- return x({ ...n, path: e || void 0 });
198
+ const n = h(r);
199
+ return $({ ...e, path: n || void 0 });
192
200
  },
193
- async set(e) {
194
- const o = g(r);
201
+ async set(n) {
202
+ const s = h(r);
195
203
  return m("set", {
196
- ...n,
197
- path: o || void 0,
198
- value: e
204
+ ...e,
205
+ path: s || void 0,
206
+ value: n
199
207
  });
200
208
  },
201
- async update(e) {
202
- if (!e || typeof e != "object")
209
+ async update(n) {
210
+ if (!n || typeof n != "object")
203
211
  throw new Error("update requires an object");
204
- const o = {};
205
- for (const [u, s] of Object.entries(e)) {
206
- const i = k(r, u);
207
- if (!i)
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
- o[i] = s;
217
+ s[u] = a;
210
218
  }
211
- return m("update", { ...n, updates: o });
219
+ return m("update", { ...e, updates: s });
212
220
  },
213
221
  async remove() {
214
- const e = g(r);
215
- return m("remove", { ...n, path: e || void 0 });
222
+ const n = h(r);
223
+ return m("remove", { ...e, path: n || void 0 });
216
224
  },
217
- async push(e) {
218
- const o = g(r);
219
- if (!o) throw new Error("push requires a path");
220
- return m("array-push", { ...n, path: o, value: e });
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(e) {
223
- const o = k(r, e);
224
- if (!o) throw new Error("ref requires a path");
225
- return b(t, o);
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 !!f() && !!p();
239
+ return !!p() && !!d();
232
240
  },
233
241
  getBackendUrl() {
234
242
  var t;
235
- return ((t = f()) == null ? void 0 : t.backendUrl) ?? null;
243
+ return ((t = p()) == null ? void 0 : t.backendUrl) ?? null;
236
244
  },
237
245
  async models(t) {
238
- return h(t);
246
+ return y(t);
239
247
  },
240
248
  async chatCompletions(t) {
241
- var a;
249
+ var o;
242
250
  const {
243
251
  reasoningEffort: r,
244
- reasoning_effort: n,
245
- ...e
246
- } = t, o = r ?? n, u = {
247
- ...e,
252
+ reasoning_effort: e,
253
+ ...n
254
+ } = t, s = r ?? e, c = {
255
+ ...n,
248
256
  stream: !1
249
257
  };
250
- o && E(t.model) && (u.reasoning_effort = o);
251
- const s = await d("/openai/chat/completions", {
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(u)
255
- }), y = (s.headers.get("content-type") || "").includes("application/json") ? await s.json() : await s.text();
256
- if (!s.ok)
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 y == "string" ? y : ((a = y == null ? void 0 : y.error) == null ? void 0 : a.message) || `Request failed (${s.status})`
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 y;
268
+ return g;
261
269
  },
262
270
  async chatText(t) {
263
- var n, e, o;
271
+ var e, n, s;
264
272
  const r = await this.chatCompletions(t);
265
- return ((o = (e = (n = r == null ? void 0 : r.choices) == null ? void 0 : n[0]) == null ? void 0 : e.message) == null ? void 0 : o.content) ?? "";
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 o;
270
- const r = (o = t == null ? void 0 : t.text) == null ? void 0 : o.trim();
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 n = await d("/app-api/audio/tts", {
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 (!n.ok) {
282
- const u = await n.text();
283
- throw new Error(u || `Request failed (${n.status})`);
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 n.arrayBuffer(),
287
- contentType: n.headers.get("content-type")
315
+ audio: await e.arrayBuffer(),
316
+ contentType: e.headers.get("content-type")
288
317
  };
289
318
  },
290
319
  async stt(t) {
291
- var w, c, l;
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 T = R.trim();
296
- if (!T) return;
297
- const A = T.toLowerCase(), C = A.split("-")[0];
298
- return C.length === 2 ? C : A;
299
- }, n = typeof File < "u" && t.file instanceof File, e = n && t.file.name.split(".").pop() || "webm", o = t.ext || e, u = new FormData();
300
- n ? u.set("file", t.file) : u.set("file", t.file, `audio.${o}`);
301
- const s = r(t.language);
302
- s && u.set("language", s), t.prompt && u.set("prompt", t.prompt);
303
- const i = await d(
304
- `/app-api/audio/stt?ext=${encodeURIComponent(o)}`,
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: u
336
+ body: c
308
337
  }
309
- ), a = (i.headers.get("content-type") || "").includes("application/json") ? await i.json() : await i.text();
310
- if (!i.ok)
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 a == "string" ? a : ((w = a == null ? void 0 : a.error) == null ? void 0 : w.message) || `Request failed (${i.status})`
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 a == "string" ? a : (a == null ? void 0 : a.text) || (a == null ? void 0 : a.original) || ((l = (c = a == null ? void 0 : a.results) == null ? void 0 : c[0]) == null ? void 0 : l.text) || "", raw: a };
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 n = await d(
348
+ const e = await l(
320
349
  `/app-api/audio/tts/voices${r.toString() ? `?${r}` : ""}`,
321
350
  { method: "GET" }
322
- ), e = await n.json().catch(() => []);
323
- if (!n.ok)
351
+ ), n = await e.json().catch(() => []);
352
+ if (!e.ok)
324
353
  throw new Error(
325
- (e == null ? void 0 : e.error) || `Request failed (${n.status})`
354
+ (n == null ? void 0 : n.error) || `Request failed (${e.status})`
326
355
  );
327
- return Array.isArray(e) ? e : (e == null ? void 0 : e.voices) || [];
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 b(t, "");
378
+ return E(t, "");
332
379
  }
333
380
  };
334
381
  }
335
382
  export {
336
- z as PromteAppProvider,
337
- $ as usePromte,
383
+ N as PromteAppProvider,
384
+ S as usePromte,
338
385
  F as usePromteClient,
339
386
  V as usePromteDarkMode,
340
387
  K as usePromteModels,
341
- J as usePromteSettings,
342
- N as usePromteToken,
343
- I as usePromteUser
388
+ z as usePromteSettings,
389
+ I as usePromteToken,
390
+ W as usePromteUser
344
391
  };
@@ -1 +1 @@
1
- (function(y,M){typeof exports=="object"&&typeof module<"u"?M(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],M):(y=typeof globalThis<"u"?globalThis:y||self,M(y.PromteAppLibrary={},y.jsxRuntime,y.react))})(this,function(y,M,i){"use strict";const T=i.createContext(null);function L({children:p,expectedParentOrigin:d,initTargetOrigin:P,retryInit:m={enabled:!0,intervalMs:500,maxAttempts:20}}){const[w,$]=i.useState(null),[v,E]=i.useState(null),[b,S]=i.useState(null),[t,s]=i.useState(null),[n,e]=i.useState(null),o=i.useMemo(()=>n?"booting":w?v?"ready":"waiting_for_token":"waiting_for_settings",[w,v,n]),f=o==="ready",r=i.useMemo(()=>P||d||"*",[P,d]),u=i.useCallback(()=>{var k;try{const h={type:"init"};(k=window.parent)==null||k.postMessage(h,r)}catch(h){e((h==null?void 0:h.message)||"Failed to post init")}},[r]);i.useEffect(()=>{u()},[u]),i.useEffect(()=>{if(!(m!=null&&m.enabled)||w)return;const k=m.intervalMs??500,h=m.maxAttempts??20;let c=0;const l=window.setInterval(()=>{if(w){window.clearInterval(l);return}if(c+=1,c>h){window.clearInterval(l);return}u()},k);return()=>window.clearInterval(l)},[m,w,u]),i.useEffect(()=>{const k=h=>{if(d&&h.origin!==d)return;const c=h.data;if(!(!c||typeof c!="object")){if(c.type==="set-settings"){const l=c.value;if(!(l!=null&&l.backendUrl)||l.parentOrigin&&d&&l.parentOrigin!==d)return;$(l),l!=null&&l.user&&s(l.user),e(null);return}if(c.type==="set-token"&&typeof c.value=="string"){E(c.value),e(null);return}if(c.type==="set-dark-mode"&&typeof c.value=="boolean"){S(c.value);return}if(c.type==="set-user"&&typeof c.value=="object"){s(c.value);return}}};return window.addEventListener("message",k),()=>window.removeEventListener("message",k)},[d]);const g=i.useMemo(()=>G(()=>w,()=>v),[w,v]),a=i.useMemo(()=>({settings:w,token:v,isDarkMode:b,user:t,ready:f,state:o,error:n,client:g}),[w,v,b,t,f,o,n,g]);return M.jsx(T.Provider,{value:a,children:p})}function j(){const p=i.useContext(T);if(!p)throw new Error("usePromte must be used inside <PromteAppProvider>");return p}function B(){return j().settings}function D(){return j().token}function O(){return j().isDarkMode}function F(){return j().user}function R(){return j().client}function _(p={}){const{ready:d}=j(),P=R(),[m,w]=i.useState([]),[$,v]=i.useState(!1),[E,b]=i.useState(null),S=i.useMemo(()=>(Array.isArray(p.type)?p.type:p.type?[p.type]:[]).filter(Boolean).map(o=>String(o)).join(","),[p.type]),t=p.configuredOnly===!0,s=p.auto!==!1,n=i.useCallback(async()=>{if(!d)return[];v(!0),b(null);try{const e=S?S.split(",").filter(Boolean):void 0,o=await P.models({type:e,configuredOnly:t});return w(o),o}catch(e){const o=e instanceof Error?e.message:String(e);throw b(o),e}finally{v(!1)}},[P,t,d,S]);return i.useEffect(()=>{!s||!d||n().catch(()=>{})},[s,d,n]),{models:m,loading:$,error:E,reload:n}}function G(p,d){const P=t=>typeof t=="string"&&t.startsWith("gpt-5");async function m(t,s){const n=p(),e=d();if(!n)throw new Error("Promte settings not received yet");if(!e)throw new Error("Promte token not received yet");const o=n.backendUrl.replace(/\/+$/,""),f=String(t||"").replace(/^\/+/,""),r=`${o}/${f}`;return await fetch(r,{...s,headers:{...s.headers||{},Authorization:`Bearer ${e}`}})}async function w(t,s){const n=await m(`/app-api/data/${t}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)}),e=await n.json().catch(()=>({}));if(!n.ok)throw new Error((e==null?void 0:e.error)||`Request failed (${n.status})`);return e==null?void 0:e.value}async function $(t){const s=new URLSearchParams;t.scope&&s.set("scope",t.scope),t.path&&s.set("path",t.path);const n=await m(`/app-api/data?${s.toString()}`,{method:"GET"}),e=await n.json().catch(()=>({}));if(!n.ok)throw new Error((e==null?void 0:e.error)||`Request failed (${n.status})`);return e==null?void 0:e.value}async function v(t){const s=new URLSearchParams,n=Array.isArray(t==null?void 0:t.type)?t==null?void 0:t.type:t!=null&&t.type?[t.type]:[];n.length>0&&s.set("type",n.join(",")),t!=null&&t.configuredOnly&&s.set("configuredOnly","true");const e=await m(`/app-api/models${s.toString()?`?${s.toString()}`:""}`,{method:"GET"}),o=await e.json().catch(()=>({}));if(!e.ok)throw new Error((o==null?void 0:o.error)||`Request failed (${e.status})`);return(Array.isArray(o==null?void 0:o.models)?o.models:[]).map(r=>{if(!r||typeof r!="object")return null;const u=typeof r.id=="string"?r.id.trim():"",g=typeof r.label=="string"?r.label.trim():u,a=r.type,k=r.configured===!0,h=typeof r.source=="string"&&r.source.trim()?r.source.trim():void 0;return!u||a!=="llm"&&a!=="embedding"&&a!=="image"&&a!=="stt"&&a!=="tts"?null:{id:u,label:g||u,type:a,configured:k,source:h}}).filter(r=>!!r)}const E=t=>t?t.split("/").map(s=>s.trim()).filter(Boolean).join("/"):"",b=(t,s)=>{const n=E(t),e=E(s);return n?e?`${n}/${e}`:n:e},S=(t,s)=>{const n={scope:t};return{async get(){const e=E(s);return $({...n,path:e||void 0})},async set(e){const o=E(s);return w("set",{...n,path:o||void 0,value:e})},async update(e){if(!e||typeof e!="object")throw new Error("update requires an object");const o={};for(const[f,r]of Object.entries(e)){const u=b(s,f);if(!u)throw new Error("update paths must be non-empty");o[u]=r}return w("update",{...n,updates:o})},async remove(){const e=E(s);return w("remove",{...n,path:e||void 0})},async push(e){const o=E(s);if(!o)throw new Error("push requires a path");return w("array-push",{...n,path:o,value:e})},ref(e){const o=b(s,e);if(!o)throw new Error("ref requires a path");return S(t,o)}}};return{isReady(){return!!p()&&!!d()},getBackendUrl(){var t;return((t=p())==null?void 0:t.backendUrl)??null},async models(t){return v(t)},async chatCompletions(t){var a;const{reasoningEffort:s,reasoning_effort:n,...e}=t,o=s??n,f={...e,stream:!1};o&&P(t.model)&&(f.reasoning_effort=o);const r=await m("/openai/chat/completions",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(f)}),g=(r.headers.get("content-type")||"").includes("application/json")?await r.json():await r.text();if(!r.ok)throw new Error(typeof g=="string"?g:((a=g==null?void 0:g.error)==null?void 0:a.message)||`Request failed (${r.status})`);return g},async chatText(t){var n,e,o;const s=await this.chatCompletions(t);return((o=(e=(n=s==null?void 0:s.choices)==null?void 0:n[0])==null?void 0:e.message)==null?void 0:o.content)??""},audio:{async tts(t){var o;const s=(o=t==null?void 0:t.text)==null?void 0:o.trim();if(!s)throw new Error("audio.tts requires non-empty text");const n=await m("/app-api/audio/tts",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({text:s,voice:t.voice,lang:t.lang})});if(!n.ok){const f=await n.text();throw new Error(f||`Request failed (${n.status})`)}return{audio:await n.arrayBuffer(),contentType:n.headers.get("content-type")}},async stt(t){var h,c,l;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 C=A.toLowerCase(),U=C.split("-")[0];return U.length===2?U:C},n=typeof File<"u"&&t.file instanceof File,e=n&&t.file.name.split(".").pop()||"webm",o=t.ext||e,f=new FormData;n?f.set("file",t.file):f.set("file",t.file,`audio.${o}`);const r=s(t.language);r&&f.set("language",r),t.prompt&&f.set("prompt",t.prompt);const u=await m(`/app-api/audio/stt?ext=${encodeURIComponent(o)}`,{method:"POST",body:f}),a=(u.headers.get("content-type")||"").includes("application/json")?await u.json():await u.text();if(!u.ok)throw new Error(typeof a=="string"?a:((h=a==null?void 0:a.error)==null?void 0:h.message)||`Request failed (${u.status})`);return{text:typeof a=="string"?a:(a==null?void 0:a.text)||(a==null?void 0:a.original)||((l=(c=a==null?void 0:a.results)==null?void 0:c[0])==null?void 0:l.text)||"",raw:a}},async voices(t){const s=new URLSearchParams;t!=null&&t.locale&&s.set("locale",t.locale);const n=await m(`/app-api/audio/tts/voices${s.toString()?`?${s}`:""}`,{method:"GET"}),e=await n.json().catch(()=>[]);if(!n.ok)throw new Error((e==null?void 0:e.error)||`Request failed (${n.status})`);return Array.isArray(e)?e:(e==null?void 0:e.voices)||[]}},data(t="private"){return S(t,"")}}}y.PromteAppProvider=L,y.usePromte=j,y.usePromteClient=R,y.usePromteDarkMode=O,y.usePromteModels=_,y.usePromteSettings=B,y.usePromteToken=D,y.usePromteUser=F,Object.defineProperty(y,Symbol.toStringTag,{value:"Module"})});
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"})});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@promte/app-library",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "files": [