@aippy/runtime 0.4.2-dev.1 → 0.4.2-dev.2

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
@@ -129,7 +129,7 @@ console.log(image.image?.base64);
129
129
 
130
130
  The AI module adds `getCredits` and `deductCredits` in the unreleased source; published `@aippy/runtime@0.4.1` does not include them. Use them only after installing a published release containing both exports (`>= 0.4.2`), and verify the installed module declarations before importing.
131
131
 
132
- The server checks the balance atomically and prevents duplicate charges for the same event and amount; changed charge details return HTTP 409. Insufficient balance uses the existing runtime error and host notification. Call credits functions from UI handlers with error handling. Use explicit deductions for custom actions; model generation already charges credits. See the [AI module](./src/ai/README.md) and `aippy-ai-sdk` skill for usage.
132
+ The server checks the balance atomically and prevents duplicate charges for the same event and amount; changed charge details return HTTP 409. Insufficient balance uses the existing runtime error, the host `container.message` notification, and a native `wallet.showRecharge` command on the shared iOS/Android `aippyListener`. Call credits functions from UI handlers with error handling. Use explicit deductions for custom actions; model generation already charges credits. See the [AI module](./src/ai/README.md) and `aippy-ai-sdk` skill for usage.
133
133
 
134
134
  ## Packages
135
135
 
@@ -2,6 +2,7 @@ import { AISDKError } from 'ai';
2
2
  /**
3
3
  * Normalizes a backend error response into an AISDKError.
4
4
  * Extracts and sends appMessage to container if present in the error response.
5
+ * Insufficient credits also asks the native host to open the recharge sheet.
5
6
  * Uses [Aippy Runtime] prefix - these errors are NOT reported to LLM.
6
7
  */
7
8
  export declare function normalizeError(response: Response, body?: unknown): AISDKError;
package/dist/ai/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { D as r, d as i, e as n, c as A, U as C, a as t, b as g, m as I, h as f, i as _, j as p, k as E, g as T, l as U, n as d, p as D, r as l, f as L, s as m, v } from "../helper-CALy6Ol_.js";
1
+ import { D as r, d as i, e as n, c as A, U as C, a as t, b as g, m as I, h as f, i as _, j as p, k as E, g as T, l as U, n as d, p as D, r as l, f as L, s as m, v } from "../helper-CCuf-R6I.js";
2
2
  import "react";
3
3
  import "../bridge-CtB9L5kL.js";
4
4
  export {
@@ -1,6 +1,6 @@
1
1
  import "react";
2
2
  import { g as a } from "./bridge-CtB9L5kL.js";
3
- const r = "0.4.2-dev.1", i = {
3
+ const r = "0.4.2-dev.2", i = {
4
4
  version: r
5
5
  }, o = i.version, c = "@aippy/runtime";
6
6
  function w() {
@@ -1,7 +1,7 @@
1
1
  import { D as r, g as s, m as o } from "../config-B0A7gHQM.js";
2
2
  import { _ as t, r as i } from "../bridge-CtB9L5kL.js";
3
3
  import { A as R, a as E, E as c, b as m, c as A } from "../errors-B3bDbQbD.js";
4
- import { S as f, V as g, c as l, a as y, g as _, s as d } from "../container-message-C2rC9u_k.js";
4
+ import { S as f, V as g, c as l, a as y, g as _, s as d } from "../container-message-ChLaG4Ke.js";
5
5
  import { A as D, C as O, R as F, a as I, p as S } from "../runtime-CmoG3v2m.js";
6
6
  export {
7
7
  D as AippyRuntime,
@@ -1,25 +1,26 @@
1
- import { createOpenAICompatible as _ } from "@ai-sdk/openai-compatible";
2
- import { j as v } from "./url-c26cuIpu.js";
1
+ import { createOpenAICompatible as S } from "@ai-sdk/openai-compatible";
2
+ import { j as C } from "./url-c26cuIpu.js";
3
3
  import { AISDKError as u, DefaultChatTransport as T } from "ai";
4
4
  import { E as p, b as m, a as d } from "./errors-B3bDbQbD.js";
5
5
  import { r as g } from "./bridge-CtB9L5kL.js";
6
- import { s as I, a as U } from "./container-message-C2rC9u_k.js";
7
- const M = `${g()}/aisdk/v1/`, te = `${g()}/aisdk/v1/ui/`, N = "gpt-5-nano", $ = "";
8
- function C(t = {}) {
6
+ import { s as I, a as U } from "./container-message-ChLaG4Ke.js";
7
+ const M = `${g()}/aisdk/v1/`, oe = `${g()}/aisdk/v1/ui/`, N = "gpt-5-nano", D = "";
8
+ function v(t = {}) {
9
9
  return {
10
10
  baseUrl: t.baseUrl ?? `${g()}/aisdk/v1/`
11
11
  };
12
12
  }
13
- function D(t = {}) {
13
+ function R(t = {}) {
14
14
  return {
15
15
  baseUrl: t.baseUrl ?? `${g()}/aisdk/v1/ui/`
16
16
  };
17
17
  }
18
- function R(t, e) {
18
+ const $ = 100003, F = "insufficient_quota";
19
+ function L(t, e) {
19
20
  const r = t.status;
20
21
  if (e && typeof e == "object" && "error" in e) {
21
22
  const n = e, o = n.error.code, s = o != null ? `AippyAIError_${o}` : `AippyAIError_${r}`, a = e;
22
- return "appMessage" in a && a.appMessage !== void 0 && I(a.appMessage), new u({
23
+ return "appMessage" in a && a.appMessage !== void 0 && I(a.appMessage), j(n.error) && x(), new u({
23
24
  name: s,
24
25
  message: `${p.RUNTIME} ${n.error.message}`,
25
26
  cause: {
@@ -39,6 +40,23 @@ function R(t, e) {
39
40
  cause: { status: r }
40
41
  });
41
42
  }
43
+ function j(t) {
44
+ return t.code === $ || t.type === F;
45
+ }
46
+ function x() {
47
+ if (!(typeof window > "u"))
48
+ try {
49
+ const t = window.webkit?.messageHandlers?.aippyListener;
50
+ if (!t)
51
+ return;
52
+ t.postMessage({ command: "wallet.showRecharge" });
53
+ } catch (t) {
54
+ console.warn(
55
+ "⚠️ [Container Message] Failed to request native recharge:",
56
+ t
57
+ );
58
+ }
59
+ }
42
60
  function l() {
43
61
  return async (t, e) => {
44
62
  const r = await U(e?.headers), n = await globalThis.fetch(t, { ...e, headers: r });
@@ -51,20 +69,20 @@ function l() {
51
69
  } catch {
52
70
  s = { message: o };
53
71
  }
54
- throw R(n, s);
72
+ throw L(n, s);
55
73
  }
56
74
  return n;
57
75
  };
58
76
  }
59
- const L = [
77
+ const P = [
60
78
  "gpt-image-1",
61
79
  "gpt-image-1-mini",
62
80
  "gpt-image-1.5"
63
81
  ];
64
- function j(t) {
82
+ function B(t) {
65
83
  try {
66
84
  const e = JSON.parse(t);
67
- if (e.model && L.some((r) => e.model.startsWith(r))) {
85
+ if (e.model && P.some((r) => e.model.startsWith(r))) {
68
86
  const { response_format: r, ...n } = e;
69
87
  return JSON.stringify(n);
70
88
  }
@@ -72,23 +90,23 @@ function j(t) {
72
90
  }
73
91
  return t;
74
92
  }
75
- function re(t = {}) {
76
- const { baseUrl: e } = C(t), r = l();
77
- return _({
93
+ function ae(t = {}) {
94
+ const { baseUrl: e } = v(t), r = l();
95
+ return S({
78
96
  name: "aippy",
79
97
  baseURL: e,
80
98
  fetch: async (o, s) => o.toString().includes("/images/generations") && s?.method?.toUpperCase() === "POST" && s?.body ? r(o, {
81
99
  ...s,
82
- body: j(s.body)
100
+ body: B(s.body)
83
101
  }) : r(o, s),
84
102
  // Enable structured outputs support (json_schema response format)
85
103
  // This is required for Output.object() and Output.array() to work properly
86
104
  supportsStructuredOutputs: !0
87
105
  });
88
106
  }
89
- const F = "/chat";
90
- function ne(t = {}) {
91
- const { baseUrl: e } = D(t), r = t.model ?? N, n = t.system ?? $, o = t.api ?? v(e, F), s = { model: r, system: n }, a = l();
107
+ const J = "/chat";
108
+ function ie(t = {}) {
109
+ const { baseUrl: e } = R(t), r = t.model ?? N, n = t.system ?? D, o = t.api ?? C(e, J), s = { model: r, system: n }, a = l();
92
110
  return {
93
111
  transport: new T({
94
112
  api: o,
@@ -98,11 +116,11 @@ function ne(t = {}) {
98
116
  })
99
117
  };
100
118
  }
101
- async function se(t = {}) {
119
+ async function ce(t = {}) {
102
120
  const e = await E("GET", "credits", t);
103
121
  return (!e || typeof e != "object" || !("credits" in e) || !Number.isSafeInteger(e.credits)) && b(), e.credits;
104
122
  }
105
- async function oe(t, e) {
123
+ async function ue(t, e) {
106
124
  (!Number.isSafeInteger(t) || t <= 0) && w("deductCredits amount must be a positive safe integer"), (typeof e?.eventId != "string" || !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(
107
125
  e.eventId
108
126
  )) && w("deductCredits eventId must be a UUID");
@@ -113,7 +131,7 @@ async function oe(t, e) {
113
131
  (!r || typeof r != "object" || !("success" in r) || r.success !== !0) && b();
114
132
  }
115
133
  async function E(t, e, r, n) {
116
- const { baseUrl: o } = C(r), s = await l()(v(o, e), {
134
+ const { baseUrl: o } = v(r), s = await l()(C(o, e), {
117
135
  method: t,
118
136
  cache: "no-store",
119
137
  signal: r.signal,
@@ -145,24 +163,24 @@ function b() {
145
163
  function y(t) {
146
164
  return [...t].length;
147
165
  }
148
- const x = 3e3, B = 5e3, J = 300 * 1e3, P = 360 * 1e3;
149
- async function ae(t) {
166
+ const H = 3e3, V = 5e3, k = 300 * 1e3, q = 360 * 1e3;
167
+ async function pe(t) {
150
168
  const e = t.prompt?.trim() ?? "", r = t.imageUrl?.trim() ?? "", n = t.image;
151
169
  y(e) > 1e3 && c("generateCharacter3D prompt must be at most 1000 characters"), n != null && !(n instanceof Blob) && c("generateCharacter3D image must be a file"), n instanceof Blob && n.size === 0 && c("generateCharacter3D image is empty");
152
170
  const o = t;
153
171
  return O(
154
172
  "viggle/characters",
155
- n instanceof Blob ? H(n, e) : V(r, e),
156
- o.pollIntervalMs ?? x,
157
- o.timeoutMs ?? J,
173
+ n instanceof Blob ? G(n, e) : z(r, e),
174
+ o.pollIntervalMs ?? H,
175
+ o.timeoutMs ?? k,
158
176
  t.signal
159
177
  );
160
178
  }
161
- function H(t, e) {
179
+ function G(t, e) {
162
180
  const r = new FormData(), n = t instanceof File && t.name ? t.name : "image.png";
163
181
  return r.append("image", t, n), e && r.append("prompt", e), { body: r };
164
182
  }
165
- function V(t, e) {
183
+ function z(t, e) {
166
184
  !e && !t && c(
167
185
  "generateCharacter3D requires an image, an https imageUrl, or a prompt"
168
186
  ), t && !t.startsWith("https://") && c("generateCharacter3D imageUrl must be an https URL");
@@ -172,7 +190,7 @@ function V(t, e) {
172
190
  body: JSON.stringify(r)
173
191
  };
174
192
  }
175
- async function ie(t) {
193
+ async function fe(t) {
176
194
  const e = t.text?.trim() ?? "";
177
195
  (y(e) < 1 || y(e) > 400) && c("generateMotion text must be 1 to 400 characters"), t.durationSeconds != null && (!Number.isInteger(t.durationSeconds) || t.durationSeconds < 3 || t.durationSeconds > 60) && c("generateMotion durationSeconds must be an integer from 3 to 60");
178
196
  const r = { text: e };
@@ -184,8 +202,8 @@ async function ie(t) {
184
202
  headers: { "Content-Type": "application/json" },
185
203
  body: JSON.stringify(r)
186
204
  },
187
- n.pollIntervalMs ?? B,
188
- n.timeoutMs ?? P,
205
+ n.pollIntervalMs ?? V,
206
+ n.timeoutMs ?? q,
189
207
  t.signal
190
208
  );
191
209
  }
@@ -197,22 +215,22 @@ async function O(t, e, r, n, o) {
197
215
  signal: o
198
216
  });
199
217
  for (; i.status !== "ready"; )
200
- i.status === "failed" && h(i.error || "Viggle generation failed"), Date.now() - a > n && h("Viggle generation timed out"), await G(r, o), i = await A(s, `${t}/${i.id}`, {
218
+ i.status === "failed" && h(i.error || "Viggle generation failed"), Date.now() - a > n && h("Viggle generation timed out"), await K(r, o), i = await A(s, `${t}/${i.id}`, {
201
219
  method: "GET",
202
220
  signal: o
203
221
  });
204
222
  return i.url || h("Viggle generation finished without a file URL"), { url: i.url, thumbnailUrl: i.thumbnailUrl };
205
223
  }
206
224
  async function A(t, e, r) {
207
- return await (await t(k(M, e), {
225
+ return await (await t(W(M, e), {
208
226
  ...r,
209
227
  cache: "no-store"
210
228
  })).json();
211
229
  }
212
- function k(t, e) {
230
+ function W(t, e) {
213
231
  return `${t.replace(/\/$/, "")}/${e.replace(/^\//, "")}`;
214
232
  }
215
- function G(t, e) {
233
+ function K(t, e) {
216
234
  if (e?.aborted)
217
235
  throw e.reason ?? new DOMException("The operation was aborted", "AbortError");
218
236
  return new Promise((r, n) => {
@@ -240,7 +258,7 @@ function h(t) {
240
258
  message: `${p.RUNTIME} ${t}`
241
259
  });
242
260
  }
243
- function S(t) {
261
+ function _(t) {
244
262
  const e = [];
245
263
  if (!t || typeof t != "object")
246
264
  throw m("AIConfig must be an object", d.INVALID_CONFIG);
@@ -291,7 +309,7 @@ function S(t) {
291
309
  { errors: e }
292
310
  );
293
311
  }
294
- function ce(t) {
312
+ function me(t) {
295
313
  let e;
296
314
  try {
297
315
  e = JSON.parse(t);
@@ -301,12 +319,12 @@ function ce(t) {
301
319
  d.INVALID_CONFIG
302
320
  );
303
321
  }
304
- return S(e), e;
322
+ return _(e), e;
305
323
  }
306
- function q(t) {
307
- return S(t), t;
324
+ function Y(t) {
325
+ return _(t), t;
308
326
  }
309
- function z(t, e) {
327
+ function X(t, e) {
310
328
  const r = t[e];
311
329
  if (!r)
312
330
  throw m(
@@ -316,7 +334,7 @@ function z(t, e) {
316
334
  );
317
335
  return r.value;
318
336
  }
319
- function W(t) {
337
+ function Q(t) {
320
338
  if (!(typeof window > "u"))
321
339
  try {
322
340
  const e = window.webkit?.messageHandlers?.aippyListener;
@@ -344,13 +362,13 @@ function W(t) {
344
362
  console.warn("⚠️ [Aippy AI Config] Failed to send config:", e);
345
363
  }
346
364
  }
347
- function ue(t) {
348
- const e = q(t);
349
- return W(e), new Proxy({}, {
365
+ function de(t) {
366
+ const e = Y(t);
367
+ return Q(e), new Proxy({}, {
350
368
  get(r, n) {
351
369
  if (typeof n == "string")
352
370
  try {
353
- return z(e, n);
371
+ return X(e, n);
354
372
  } catch {
355
373
  return;
356
374
  }
@@ -365,23 +383,23 @@ function ue(t) {
365
383
  }
366
384
  export {
367
385
  M as D,
368
- F as U,
369
- re as a,
370
- ne as b,
371
- te as c,
386
+ J as U,
387
+ ae as a,
388
+ ie as b,
389
+ oe as c,
372
390
  N as d,
373
- $ as e,
374
- D as f,
375
- se as g,
376
- oe as h,
377
- ae as i,
378
- ie as j,
379
- z as k,
380
- q as l,
381
- ue as m,
382
- R as n,
383
- ce as p,
384
- C as r,
385
- W as s,
386
- S as v
391
+ D as e,
392
+ R as f,
393
+ ce as g,
394
+ ue as h,
395
+ pe as i,
396
+ fe as j,
397
+ X as k,
398
+ Y as l,
399
+ de as m,
400
+ L as n,
401
+ me as p,
402
+ v as r,
403
+ Q as s,
404
+ _ as v
387
405
  };
@@ -1,7 +1,7 @@
1
1
  import { D as r, g as s, m as o } from "../config-B0A7gHQM.js";
2
2
  import { _ as i, g as n, r as p } from "../bridge-CtB9L5kL.js";
3
3
  import { A as m, a as c, E as f, b as C, c as g } from "../errors-B3bDbQbD.js";
4
- import { S as d, V as l, c as I, a as E, g as S, s as x } from "../container-message-C2rC9u_k.js";
4
+ import { S as d, V as l, c as I, a as E, g as S, s as x } from "../container-message-ChLaG4Ke.js";
5
5
  import { A as U, C as _, R as D, a as T, p as h } from "../runtime-CmoG3v2m.js";
6
6
  import { CameraAPI as y, FileSystemAPI as F, GeolocationAPI as M, SensorsAPI as P, camera as O, fileSystem as b, geolocation as L, isMotionSupported as w, isOrientationSupported as H, requestMotionPermission as N, sensors as V, vibrate as k, watchMotion as B, watchOrientation as j } from "../device/index.js";
7
7
  import { P as G, a as z, c as K, b as W, g as X, i as Y, p as J, r as Q, s as Z } from "../app-version-checker-Bz7FrEZz.js";
@@ -10,7 +10,7 @@ import { j as te } from "../url-c26cuIpu.js";
10
10
  import { a as ne, b as pe } from "../useTweaks-C7BEMpV3.js";
11
11
  import { c as me, b as ce, i as fe, p as Ce, u as ge, a as ue } from "../useSound-z_eIn0KH.js";
12
12
  import { reportScore as le, sendEvent as Ie, updateScore as Ee } from "../leaderboard/index.js";
13
- import { D as xe, d as Re, e as Ue, c as _e, U as De, a as Te, b as he, m as ve, h as ye, i as Fe, j as Me, k as Pe, g as Oe, l as be, n as Le, p as we, r as He, f as Ne, s as Ve, v as ke } from "../helper-CALy6Ol_.js";
13
+ import { D as xe, d as Re, e as Ue, c as _e, U as De, a as Te, b as he, m as ve, h as ye, i as Fe, j as Me, k as Pe, g as Oe, l as be, n as Le, p as we, r as He, f as Ne, s as Ve, v as ke } from "../helper-CCuf-R6I.js";
14
14
  import { c as je, u as qe } from "../hooks-D5lkty5r.js";
15
15
  import { hasNativeBridge as ze } from "../native-bridge-BnvipFJc.js";
16
16
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aippy/runtime",
3
- "version": "0.4.2-dev.1",
3
+ "version": "0.4.2-dev.2",
4
4
  "description": "Aippy Runtime SDK - Runtime SDK for Aippy projects",
5
5
  "private": false,
6
6
  "type": "module",