@aippy/runtime 0.2.7-dev.4 → 0.2.7-dev.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 +3 -3
- package/dist/ai/errors.d.ts +1 -57
- package/dist/ai/index.d.ts +1 -3
- package/dist/ai/index.js +15 -20
- package/dist/ai/shared/fetch.d.ts +2 -21
- package/dist/audio/index.d.ts +1 -1
- package/dist/audio/index.js +5 -6
- package/dist/audio/utils.d.ts +0 -7
- package/dist/core/index.js +1 -1
- package/dist/helper-BENVYOU-.js +247 -0
- package/dist/index/index.js +51 -57
- package/dist/{useAudioContext-CNQQSTab.js → useAudioContext-D9F3x80Y.js} +38 -42
- package/package.json +1 -1
- package/dist/helper-CIt1_T-j.js +0 -275
package/README.md
CHANGED
|
@@ -93,13 +93,13 @@ button.onclick = async () => {
|
|
|
93
93
|
// Default base URL: https://api.aippy.dev/api/aisdk/v1
|
|
94
94
|
|
|
95
95
|
import { streamText, experimental_generateImage as generateImage } from 'ai';
|
|
96
|
-
import {
|
|
96
|
+
import { aippyAIProvider } from '@aippy/runtime/ai';
|
|
97
97
|
|
|
98
98
|
// Create provider (reads from env vars automatically)
|
|
99
|
-
const provider =
|
|
99
|
+
const provider = aippyAIProvider();
|
|
100
100
|
|
|
101
101
|
// Or override with config
|
|
102
|
-
// const provider =
|
|
102
|
+
// const provider = aippyAIProvider({ baseUrl: '...', userToken: '...' });
|
|
103
103
|
|
|
104
104
|
// Streaming text generation (uses Vercel AI SDK)
|
|
105
105
|
const result = await streamText({
|
package/dist/ai/errors.d.ts
CHANGED
|
@@ -1,62 +1,6 @@
|
|
|
1
1
|
import { AISDKError } from 'ai';
|
|
2
2
|
/**
|
|
3
3
|
* Normalizes a backend error response into an AISDKError.
|
|
4
|
-
*
|
|
5
|
-
* If the backend error response includes container message data (e.g., `appMessage` field),
|
|
6
|
-
* it will be automatically sent to the app container for user-facing UI (e.g., payment dialog,
|
|
7
|
-
* error popup, success notification).
|
|
8
|
-
*
|
|
9
|
-
* @example appMessage structure:
|
|
10
|
-
* ```ts
|
|
11
|
-
* interface AppMessage {
|
|
12
|
-
* // Message type determines UI behavior
|
|
13
|
-
* type: 'error' | 'success' | 'warning' | 'info';
|
|
14
|
-
*
|
|
15
|
-
* // Required: User-facing title and message
|
|
16
|
-
* title: string;
|
|
17
|
-
* message: string;
|
|
18
|
-
*
|
|
19
|
-
* // Optional: Action to trigger in the container
|
|
20
|
-
* action?: string; // e.g., 'showPaymentDialog', 'showUpgradeDialog', 'redirect'
|
|
21
|
-
*
|
|
22
|
-
* // Optional: URL for redirect actions
|
|
23
|
-
* redirectUrl?: string;
|
|
24
|
-
*
|
|
25
|
-
* // Optional: Custom button text for action dialogs
|
|
26
|
-
* buttonText?: string;
|
|
27
|
-
*
|
|
28
|
-
* // Optional: Auto-dismiss duration in milliseconds (for success/info messages)
|
|
29
|
-
* duration?: number;
|
|
30
|
-
*
|
|
31
|
-
* // Optional: Additional metadata for container processing
|
|
32
|
-
* metadata?: Record<string, unknown>;
|
|
33
|
-
* }
|
|
34
|
-
*
|
|
35
|
-
* // Example error message with payment action:
|
|
36
|
-
* {
|
|
37
|
-
* type: 'error',
|
|
38
|
-
* title: 'Insufficient Balance',
|
|
39
|
-
* message: 'Your account balance is insufficient. Please top up to continue.',
|
|
40
|
-
* action: 'showPaymentDialog',
|
|
41
|
-
* redirectUrl: '/payment',
|
|
42
|
-
* buttonText: 'Top Up Now'
|
|
43
|
-
* }
|
|
44
|
-
* ```
|
|
4
|
+
* Extracts and sends appMessage to container if present in the error response.
|
|
45
5
|
*/
|
|
46
6
|
export declare function normalizeError(response: Response, body?: unknown): AISDKError;
|
|
47
|
-
/**
|
|
48
|
-
* Creates an error for missing user token.
|
|
49
|
-
*/
|
|
50
|
-
export declare function missingTokenError(): AISDKError;
|
|
51
|
-
/**
|
|
52
|
-
* Creates an error for aborted requests.
|
|
53
|
-
*/
|
|
54
|
-
export declare function abortedError(): AISDKError;
|
|
55
|
-
/**
|
|
56
|
-
* Creates an error for network failures.
|
|
57
|
-
*/
|
|
58
|
-
export declare function networkError(cause?: unknown): AISDKError;
|
|
59
|
-
/**
|
|
60
|
-
* Creates an error for parse failures.
|
|
61
|
-
*/
|
|
62
|
-
export declare function parseError(message: string): AISDKError;
|
package/dist/ai/index.d.ts
CHANGED
|
@@ -38,9 +38,7 @@
|
|
|
38
38
|
*/
|
|
39
39
|
export { aippyAIProvider, type AippyProvider } from './openai';
|
|
40
40
|
export type { AippyOpenAIConfig } from './openai';
|
|
41
|
-
/** @deprecated Use aippyAIProvider() instead */
|
|
42
|
-
export { aippyAIProvider as aippy } from './openai';
|
|
43
41
|
export { aippyChatConfig, type AippyUseChatOptions, type AippyUIConfig, type AippyChatConfig, UI_CHAT_ENDPOINT, } from './ui';
|
|
44
42
|
export { DEFAULT_BASE_URL, DEFAULT_UI_BASE_URL, DEFAULT_CHAT_MODEL, DEFAULT_CHAT_SYSTEM, } from './shared';
|
|
45
|
-
export { normalizeError
|
|
43
|
+
export { normalizeError } from './errors';
|
|
46
44
|
export { type AIConfig, type AIConfigValue, type AIConfigItem, type NumberAIConfigItem, type BooleanAIConfigItem, type TextAIConfigItem, type EnumAIConfigItem, type AIConfigError, type AIConfigValues, AIConfigValidationError, validateAIConfig, parseAIConfig, loadAIConfig, getAIConfigValue, sendAIConfigToContainer, createAIConfig, } from './config';
|
package/dist/ai/index.js
CHANGED
|
@@ -1,25 +1,20 @@
|
|
|
1
|
-
import { A
|
|
1
|
+
import { A, D as r, d as n, e as C, c as e, U as E, a as I, b as _, f, g, l as T, n as p, p as t, s as U, v as D } from "../helper-BENVYOU-.js";
|
|
2
2
|
import "react";
|
|
3
3
|
import "../bridge-Ca3H2iN1.js";
|
|
4
4
|
export {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
A as AIConfigValidationError,
|
|
6
|
+
r as DEFAULT_BASE_URL,
|
|
7
7
|
n as DEFAULT_CHAT_MODEL,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
T as
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
U as
|
|
19
|
-
|
|
20
|
-
D as normalizeError,
|
|
21
|
-
L as parseAIConfig,
|
|
22
|
-
l as parseError,
|
|
23
|
-
m as sendAIConfigToContainer,
|
|
24
|
-
F as validateAIConfig
|
|
8
|
+
C as DEFAULT_CHAT_SYSTEM,
|
|
9
|
+
e as DEFAULT_UI_BASE_URL,
|
|
10
|
+
E as UI_CHAT_ENDPOINT,
|
|
11
|
+
I as aippyAIProvider,
|
|
12
|
+
_ as aippyChatConfig,
|
|
13
|
+
f as createAIConfig,
|
|
14
|
+
g as getAIConfigValue,
|
|
15
|
+
T as loadAIConfig,
|
|
16
|
+
p as normalizeError,
|
|
17
|
+
t as parseAIConfig,
|
|
18
|
+
U as sendAIConfigToContainer,
|
|
19
|
+
D as validateAIConfig
|
|
25
20
|
};
|
|
@@ -4,31 +4,12 @@
|
|
|
4
4
|
*/
|
|
5
5
|
/**
|
|
6
6
|
* Joins a base URL with a path segment.
|
|
7
|
-
* Uses native URL API for reliable URL resolution.
|
|
8
|
-
*
|
|
9
|
-
* @param baseUrl - The base URL (e.g., 'https://api.aippy.dev/api/aisdk/v1/ui/')
|
|
10
|
-
* @param path - The path segment to append (e.g., '/chat' or 'chat')
|
|
11
|
-
* @returns The joined URL string
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* joinUrl('https://api.aippy.dev/api/aisdk/v1/ui/', '/chat')
|
|
15
|
-
* // => 'https://api.aippy.dev/api/aisdk/v1/ui/chat'
|
|
16
7
|
*/
|
|
17
8
|
export declare function joinUrl(baseUrl: string, path: string): string;
|
|
18
9
|
/**
|
|
19
|
-
* Creates a fetch wrapper that injects Authorization header
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* This wrapper also automatically handles error responses by:
|
|
23
|
-
* 1. Detecting error responses (!response.ok)
|
|
24
|
-
* 2. Parsing error body and calling normalizeError() to extract appMessage
|
|
25
|
-
* 3. Sending appMessage to container if present
|
|
26
|
-
* 4. Returning the original response for downstream error handling
|
|
10
|
+
* Creates a fetch wrapper that injects Authorization header and handles error responses.
|
|
11
|
+
* Error responses are intercepted and normalized errors are thrown immediately.
|
|
27
12
|
*
|
|
28
13
|
* @returns A fetch function compatible with globalThis.fetch signature
|
|
29
|
-
*
|
|
30
|
-
* @example
|
|
31
|
-
* const authFetch = createAuthFetch();
|
|
32
|
-
* const response = await authFetch('https://api.example.com/endpoint', { method: 'POST' });
|
|
33
14
|
*/
|
|
34
15
|
export declare function createAuthFetch(): typeof globalThis.fetch;
|
package/dist/audio/index.d.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
export { patchAudioContext } from './patchAudioContext';
|
|
10
10
|
export type { AudioContextPatchOptions, AutoPauseOptions, MediaElementType, PatchedAudioContext, } from './types';
|
|
11
|
-
export { createHiddenMediaElement,
|
|
11
|
+
export { createHiddenMediaElement, isMediaStreamAudioSupported, } from './utils';
|
|
12
12
|
export { useAudioContext } from './useAudioContext';
|
|
13
13
|
export type { UseAudioContextOptions, UseAudioContextReturn } from './useAudioContext';
|
|
14
14
|
export { isIOSDevice } from './utils';
|
package/dist/audio/index.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { c as i, a as t,
|
|
1
|
+
import { c as i, a as t, i as d, p as o, u as s } from "../useAudioContext-D9F3x80Y.js";
|
|
2
2
|
export {
|
|
3
3
|
i as createHiddenMediaElement,
|
|
4
|
-
t as
|
|
5
|
-
d as
|
|
6
|
-
o as
|
|
7
|
-
s as
|
|
8
|
-
n as useAudioContext
|
|
4
|
+
t as isIOSDevice,
|
|
5
|
+
d as isMediaStreamAudioSupported,
|
|
6
|
+
o as patchAudioContext,
|
|
7
|
+
s as useAudioContext
|
|
9
8
|
};
|
package/dist/audio/utils.d.ts
CHANGED
|
@@ -15,10 +15,3 @@ export declare function isMediaStreamAudioSupported(): boolean;
|
|
|
15
15
|
* @returns HTMLMediaElement (HTMLVideoElement or HTMLAudioElement)
|
|
16
16
|
*/
|
|
17
17
|
export declare function createHiddenMediaElement(type?: 'video' | 'audio', debug?: boolean): HTMLVideoElement | HTMLAudioElement;
|
|
18
|
-
/**
|
|
19
|
-
* @deprecated Use createHiddenMediaElement instead
|
|
20
|
-
* Creates a hidden video element for MediaStream playback
|
|
21
|
-
* @param debug - If true, makes the video element visible for debugging
|
|
22
|
-
* @returns HTMLVideoElement
|
|
23
|
-
*/
|
|
24
|
-
export declare function createHiddenVideoElement(debug?: boolean): HTMLVideoElement;
|
package/dist/core/index.js
CHANGED
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import { createOpenAICompatible as l } from "@ai-sdk/openai-compatible";
|
|
2
|
+
import "react";
|
|
3
|
+
import { getAuthTokenAsync as y } from "./bridge-Ca3H2iN1.js";
|
|
4
|
+
import { AISDKError as u, DefaultChatTransport as d } from "ai";
|
|
5
|
+
import { s as f } from "./container-message-DGrno17o.js";
|
|
6
|
+
const c = "https://api.aippy.dev", h = `${c}/aisdk/v1/`, b = `${c}/aisdk/v1/ui/`, A = "gpt-5-nano", w = "";
|
|
7
|
+
function v(n = {}) {
|
|
8
|
+
return {
|
|
9
|
+
baseUrl: n.baseUrl ?? h
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function I(n = {}) {
|
|
13
|
+
return {
|
|
14
|
+
baseUrl: n.baseUrl ?? b
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function C(n, e) {
|
|
18
|
+
const s = n.status;
|
|
19
|
+
if (e && typeof e == "object" && "error" in e) {
|
|
20
|
+
const t = e, o = t.error.code, r = o != null ? `AippyAIError_${o}` : `AippyAIError_${s}`, a = e;
|
|
21
|
+
return "appMessage" in a && a.appMessage !== void 0 && f(a.appMessage), new u({
|
|
22
|
+
name: r,
|
|
23
|
+
message: t.error.message,
|
|
24
|
+
cause: {
|
|
25
|
+
type: t.error.type ?? void 0,
|
|
26
|
+
param: t.error.param ?? void 0,
|
|
27
|
+
status: s
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
if (e && typeof e == "object" && e !== null) {
|
|
32
|
+
const t = e;
|
|
33
|
+
"appMessage" in t && t.appMessage !== void 0 && f(t.appMessage);
|
|
34
|
+
}
|
|
35
|
+
return new u({
|
|
36
|
+
name: `AippyAIError_${s}`,
|
|
37
|
+
message: `Request failed with status ${s}`,
|
|
38
|
+
cause: { status: s }
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
function E(n, e) {
|
|
42
|
+
const s = n.endsWith("/") ? n : `${n}/`, t = e.startsWith("/") ? e.slice(1) : e;
|
|
43
|
+
return new URL(t, s).href;
|
|
44
|
+
}
|
|
45
|
+
function m() {
|
|
46
|
+
return async (n, e) => {
|
|
47
|
+
const s = await y(), t = new Headers(e?.headers);
|
|
48
|
+
t.set("Aippy-Runtime-Authorization", `Bearer ${s}`);
|
|
49
|
+
const o = await globalThis.fetch(n, { ...e, headers: t });
|
|
50
|
+
if (!o.ok) {
|
|
51
|
+
const r = await o.text().catch(() => null);
|
|
52
|
+
let a = null;
|
|
53
|
+
if (r)
|
|
54
|
+
try {
|
|
55
|
+
a = JSON.parse(r);
|
|
56
|
+
} catch {
|
|
57
|
+
a = { message: r };
|
|
58
|
+
}
|
|
59
|
+
throw C(o, a);
|
|
60
|
+
}
|
|
61
|
+
return o;
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
const S = [
|
|
65
|
+
"gpt-image-1",
|
|
66
|
+
"gpt-image-1-mini",
|
|
67
|
+
"gpt-image-1.5"
|
|
68
|
+
];
|
|
69
|
+
function O(n) {
|
|
70
|
+
try {
|
|
71
|
+
const e = JSON.parse(n);
|
|
72
|
+
if (e.model && S.some((s) => e.model.startsWith(s))) {
|
|
73
|
+
const { response_format: s, ...t } = e;
|
|
74
|
+
return JSON.stringify(t);
|
|
75
|
+
}
|
|
76
|
+
} catch {
|
|
77
|
+
}
|
|
78
|
+
return n;
|
|
79
|
+
}
|
|
80
|
+
function N(n = {}) {
|
|
81
|
+
const { baseUrl: e } = v(n), s = m();
|
|
82
|
+
return l({
|
|
83
|
+
name: "aippy",
|
|
84
|
+
baseURL: e,
|
|
85
|
+
fetch: async (o, r) => o.toString().includes("/images/generations") && r?.method?.toUpperCase() === "POST" && r?.body ? s(o, {
|
|
86
|
+
...r,
|
|
87
|
+
body: O(r.body)
|
|
88
|
+
}) : s(o, r),
|
|
89
|
+
// Enable structured outputs support (json_schema response format)
|
|
90
|
+
// This is required for Output.object() and Output.array() to work properly
|
|
91
|
+
supportsStructuredOutputs: !0
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
const _ = "/chat";
|
|
95
|
+
function D(n = {}) {
|
|
96
|
+
const { baseUrl: e } = I(n), s = n.model ?? A, t = n.system ?? w, o = n.api ?? E(e, _), r = { model: s, system: t }, a = m();
|
|
97
|
+
return {
|
|
98
|
+
transport: new d({
|
|
99
|
+
api: o,
|
|
100
|
+
body: r,
|
|
101
|
+
// Ensure token is fetched fresh for every request
|
|
102
|
+
fetch: a
|
|
103
|
+
})
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
class p extends Error {
|
|
107
|
+
constructor(e, s) {
|
|
108
|
+
super(e), this.errors = s, this.name = "AIConfigValidationError";
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
function g(n) {
|
|
112
|
+
const e = [];
|
|
113
|
+
if (!n || typeof n != "object")
|
|
114
|
+
throw new p("AIConfig must be an object", []);
|
|
115
|
+
const s = n;
|
|
116
|
+
for (const [t, o] of Object.entries(s)) {
|
|
117
|
+
if (!o || typeof o != "object") {
|
|
118
|
+
e.push({ key: t, message: "Item must be an object" });
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
const r = o;
|
|
122
|
+
typeof r.index != "number" && e.push({ key: t, message: "index must be a number" }), typeof r.name != "string" && e.push({ key: t, message: "name must be a string" }), typeof r.description != "string" && e.push({ key: t, message: "description must be a string" });
|
|
123
|
+
const a = r.type;
|
|
124
|
+
if (!["number", "boolean", "text", "enum"].includes(a)) {
|
|
125
|
+
e.push({
|
|
126
|
+
key: t,
|
|
127
|
+
message: `type must be one of: number, boolean, text, enum (got: ${a})`
|
|
128
|
+
});
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
if (a === "number")
|
|
132
|
+
typeof r.value != "number" && e.push({ key: t, message: 'value must be a number for type "number"' }), r.min !== void 0 && typeof r.min != "number" && e.push({ key: t, message: "min must be a number" }), r.max !== void 0 && typeof r.max != "number" && e.push({ key: t, message: "max must be a number" }), r.step !== void 0 && typeof r.step != "number" && e.push({ key: t, message: "step must be a number" });
|
|
133
|
+
else if (a === "boolean")
|
|
134
|
+
typeof r.value != "boolean" && e.push({ key: t, message: 'value must be a boolean for type "boolean"' });
|
|
135
|
+
else if (a === "text")
|
|
136
|
+
typeof r.value != "string" && e.push({ key: t, message: 'value must be a string for type "text"' });
|
|
137
|
+
else if (a === "enum") {
|
|
138
|
+
if (!Array.isArray(r.options))
|
|
139
|
+
e.push({ key: t, message: 'options must be an array for type "enum"' });
|
|
140
|
+
else if (r.options.length === 0)
|
|
141
|
+
e.push({ key: t, message: 'options array cannot be empty for type "enum"' });
|
|
142
|
+
else
|
|
143
|
+
for (let i = 0; i < r.options.length; i++)
|
|
144
|
+
typeof r.options[i] != "string" && e.push({
|
|
145
|
+
key: t,
|
|
146
|
+
message: `options[${i}] must be a string`
|
|
147
|
+
});
|
|
148
|
+
typeof r.value != "string" ? e.push({ key: t, message: 'value must be a string for type "enum"' }) : Array.isArray(r.options) && !r.options.includes(r.value) && e.push({
|
|
149
|
+
key: t,
|
|
150
|
+
message: `value "${r.value}" is not in options: [${r.options.join(", ")}]`
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
r.group !== void 0 && typeof r.group != "string" && e.push({ key: t, message: "group must be a string" });
|
|
154
|
+
}
|
|
155
|
+
if (e.length > 0)
|
|
156
|
+
throw new p(
|
|
157
|
+
`AIConfig validation failed with ${e.length} error(s)`,
|
|
158
|
+
e
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
function R(n) {
|
|
162
|
+
let e;
|
|
163
|
+
try {
|
|
164
|
+
e = JSON.parse(n);
|
|
165
|
+
} catch (s) {
|
|
166
|
+
throw new p("Invalid JSON", [
|
|
167
|
+
{
|
|
168
|
+
key: "",
|
|
169
|
+
message: `JSON parse error: ${s instanceof Error ? s.message : String(s)}`
|
|
170
|
+
}
|
|
171
|
+
]);
|
|
172
|
+
}
|
|
173
|
+
return g(e), e;
|
|
174
|
+
}
|
|
175
|
+
function U(n) {
|
|
176
|
+
return g(n), n;
|
|
177
|
+
}
|
|
178
|
+
function T(n, e) {
|
|
179
|
+
const s = n[e];
|
|
180
|
+
if (!s)
|
|
181
|
+
throw new Error(`AIConfig key "${e}" not found`);
|
|
182
|
+
return s.value;
|
|
183
|
+
}
|
|
184
|
+
function $(n) {
|
|
185
|
+
if (!(typeof window > "u"))
|
|
186
|
+
try {
|
|
187
|
+
const e = window.webkit?.messageHandlers?.aippyListener;
|
|
188
|
+
if (e)
|
|
189
|
+
try {
|
|
190
|
+
const s = {
|
|
191
|
+
command: "ai.initialize",
|
|
192
|
+
parameters: JSON.stringify(n)
|
|
193
|
+
};
|
|
194
|
+
e.postMessage(s);
|
|
195
|
+
} catch (s) {
|
|
196
|
+
console.warn("❌ [Aippy AI Config] Failed to send config to iOS app:", s);
|
|
197
|
+
}
|
|
198
|
+
if (window.parent && window.parent !== window)
|
|
199
|
+
try {
|
|
200
|
+
const s = {
|
|
201
|
+
type: "ai.initialize",
|
|
202
|
+
config: JSON.stringify(n)
|
|
203
|
+
};
|
|
204
|
+
window.parent.postMessage(s, "*");
|
|
205
|
+
} catch (s) {
|
|
206
|
+
console.warn("❌ [Aippy AI Config] Failed to send config to parent window:", s);
|
|
207
|
+
}
|
|
208
|
+
} catch (e) {
|
|
209
|
+
console.warn("⚠️ [Aippy AI Config] Failed to send config:", e);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
function B(n) {
|
|
213
|
+
const e = U(n);
|
|
214
|
+
return $(e), new Proxy({}, {
|
|
215
|
+
get(s, t) {
|
|
216
|
+
if (typeof t == "string")
|
|
217
|
+
try {
|
|
218
|
+
return T(e, t);
|
|
219
|
+
} catch {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
has(s, t) {
|
|
224
|
+
return typeof t != "string" ? !1 : t in e;
|
|
225
|
+
},
|
|
226
|
+
ownKeys(s) {
|
|
227
|
+
return Object.keys(e);
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
export {
|
|
232
|
+
p as A,
|
|
233
|
+
h as D,
|
|
234
|
+
_ as U,
|
|
235
|
+
N as a,
|
|
236
|
+
D as b,
|
|
237
|
+
b as c,
|
|
238
|
+
A as d,
|
|
239
|
+
w as e,
|
|
240
|
+
B as f,
|
|
241
|
+
T as g,
|
|
242
|
+
U as l,
|
|
243
|
+
C as n,
|
|
244
|
+
R as p,
|
|
245
|
+
$ as s,
|
|
246
|
+
g as v
|
|
247
|
+
};
|
package/dist/index/index.js
CHANGED
|
@@ -1,88 +1,82 @@
|
|
|
1
1
|
import { DEFAULT_CONFIG as o, SDK_NAME as r, VERSION as s, getConfigFromEnv as t, getVersionInfo as i, mergeConfig as n } from "../core/index.js";
|
|
2
|
-
import { A
|
|
3
|
-
import { s as
|
|
4
|
-
import { A as
|
|
2
|
+
import { A, E as f, c as m } from "../errors-CDEBaBxB.js";
|
|
3
|
+
import { s as C } from "../container-message-DGrno17o.js";
|
|
4
|
+
import { A as E, C as d, R as l, a as g, p as u } from "../runtime-CmoG3v2m.js";
|
|
5
5
|
import { CameraAPI as x, FileSystemAPI as T, GeolocationAPI as _, SensorsAPI as D, camera as U, fileSystem as M, geolocation as P, isMotionSupported as R, isOrientationSupported as y, requestMotionPermission as h, sensors as v, vibrate as O, watchMotion as F, watchOrientation as L } from "../device/index.js";
|
|
6
|
-
import { P as
|
|
7
|
-
import { a as G, P as
|
|
8
|
-
import { a as
|
|
9
|
-
import { c as Q, a as X,
|
|
10
|
-
import { reportScore as
|
|
11
|
-
import { A as
|
|
12
|
-
import { c as
|
|
13
|
-
import { getAuthTokenAsync as
|
|
14
|
-
import { hasNativeBridge as
|
|
6
|
+
import { P as N, c as b, i as V, p as H, s as k } from "../ui-y5N62DqC.js";
|
|
7
|
+
import { a as G, P as q, p as z, b as K } from "../pwa-CilSlaik.js";
|
|
8
|
+
import { a as Y, b as j } from "../useTweaks-QxMRmg7i.js";
|
|
9
|
+
import { c as Q, a as X, i as Z, p as $, u as ee } from "../useAudioContext-D9F3x80Y.js";
|
|
10
|
+
import { reportScore as oe, sendEvent as re, updateScore as se } from "../leaderboard/index.js";
|
|
11
|
+
import { A as ie, D as ne, d as pe, e as Ae, c as fe, U as me, a as ce, b as Ce, f as Ie, g as Ee, l as de, n as le, p as ge, s as ue, v as Se } from "../helper-BENVYOU-.js";
|
|
12
|
+
import { c as Te, u as _e } from "../hooks-CE9cjXHP.js";
|
|
13
|
+
import { getAuthTokenAsync as Ue } from "../bridge-Ca3H2iN1.js";
|
|
14
|
+
import { hasNativeBridge as Pe } from "../native-bridge-BnvipFJc.js";
|
|
15
15
|
export {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
ie as AIConfigValidationError,
|
|
17
|
+
E as AippyRuntime,
|
|
18
|
+
A as AippyRuntimeError,
|
|
19
19
|
x as CameraAPI,
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
d as Cancellable,
|
|
21
|
+
ne as DEFAULT_BASE_URL,
|
|
22
|
+
pe as DEFAULT_CHAT_MODEL,
|
|
23
23
|
Ae as DEFAULT_CHAT_SYSTEM,
|
|
24
24
|
o as DEFAULT_CONFIG,
|
|
25
25
|
fe as DEFAULT_UI_BASE_URL,
|
|
26
|
-
|
|
26
|
+
f as ERROR_CODES,
|
|
27
27
|
T as FileSystemAPI,
|
|
28
28
|
_ as GeolocationAPI,
|
|
29
29
|
G as PWAUtils,
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
q as PerformanceMonitor,
|
|
31
|
+
N as PlatformDetector,
|
|
32
32
|
l as ReceiveChannel,
|
|
33
33
|
r as SDK_NAME,
|
|
34
34
|
D as SensorsAPI,
|
|
35
|
-
|
|
35
|
+
me as UI_CHAT_ENDPOINT,
|
|
36
36
|
s as VERSION,
|
|
37
|
-
|
|
38
|
-
Ce as
|
|
39
|
-
de as aippyAIProvider,
|
|
40
|
-
Ie as aippyChatConfig,
|
|
37
|
+
ce as aippyAIProvider,
|
|
38
|
+
Ce as aippyChatConfig,
|
|
41
39
|
g as aippyRuntime,
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
Y as aippyTweaks,
|
|
41
|
+
j as aippyTweaksRuntime,
|
|
44
42
|
U as camera,
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
43
|
+
Te as clearUserInfoCache,
|
|
44
|
+
b as compareVersions,
|
|
45
|
+
Ie as createAIConfig,
|
|
46
|
+
m as createError,
|
|
49
47
|
Q as createHiddenMediaElement,
|
|
50
|
-
X as createHiddenVideoElement,
|
|
51
48
|
M as fileSystem,
|
|
52
49
|
P as geolocation,
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
Ee as getAIConfigValue,
|
|
51
|
+
Ue as getAuthTokenAsync,
|
|
55
52
|
t as getConfigFromEnv,
|
|
56
53
|
i as getVersionInfo,
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
Pe as hasNativeBridge,
|
|
55
|
+
X as isIOSDevice,
|
|
59
56
|
V as isInIframe,
|
|
60
|
-
|
|
57
|
+
Z as isMediaStreamAudioSupported,
|
|
61
58
|
R as isMotionSupported,
|
|
62
59
|
y as isOrientationSupported,
|
|
63
|
-
|
|
60
|
+
de as loadAIConfig,
|
|
64
61
|
n as mergeConfig,
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
ee as patchAudioContext,
|
|
71
|
-
q as performanceMonitor,
|
|
72
|
-
k as platform,
|
|
62
|
+
le as normalizeError,
|
|
63
|
+
ge as parseAIConfig,
|
|
64
|
+
$ as patchAudioContext,
|
|
65
|
+
z as performanceMonitor,
|
|
66
|
+
H as platform,
|
|
73
67
|
u as processMotionData,
|
|
74
|
-
|
|
75
|
-
|
|
68
|
+
K as pwa,
|
|
69
|
+
oe as reportScore,
|
|
76
70
|
h as requestMotionPermission,
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
71
|
+
ue as sendAIConfigToContainer,
|
|
72
|
+
re as sendEvent,
|
|
73
|
+
C as sendMessageToContainer,
|
|
80
74
|
v as sensors,
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
75
|
+
k as showAlert,
|
|
76
|
+
se as updateScore,
|
|
77
|
+
ee as useAudioContext,
|
|
78
|
+
_e as useUserInfo,
|
|
79
|
+
Se as validateAIConfig,
|
|
86
80
|
O as vibrate,
|
|
87
81
|
F as watchMotion,
|
|
88
82
|
L as watchOrientation
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { useState as k, useRef as
|
|
5
|
-
function
|
|
1
|
+
var D = Object.defineProperty;
|
|
2
|
+
var b = (e, t, n) => t in e ? D(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n;
|
|
3
|
+
var i = (e, t, n) => b(e, typeof t != "symbol" ? t + "" : t, n);
|
|
4
|
+
import { useState as k, useRef as w, useEffect as p } from "react";
|
|
5
|
+
function T() {
|
|
6
6
|
const e = navigator.userAgent;
|
|
7
7
|
return !!(/iPad|iPhone|iPod/.test(e) || navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1);
|
|
8
8
|
}
|
|
@@ -16,33 +16,30 @@ function P() {
|
|
|
16
16
|
return !1;
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
|
-
function
|
|
19
|
+
function E(e = "video", t = !1) {
|
|
20
20
|
const n = document.createElement(e);
|
|
21
21
|
return n.muted = !1, n.autoplay = !0, e === "video" && (n.playsInline = !0), t ? n.style.cssText = "position:fixed;bottom:10px;right:10px;width:200px;background:#ff0000;z-index:9999;" : n.style.cssText = "position:fixed;width:1px;height:1px;opacity:0;pointer-events:none;", n;
|
|
22
22
|
}
|
|
23
|
-
function C(e = !1) {
|
|
24
|
-
return v("video", e);
|
|
25
|
-
}
|
|
26
23
|
class I {
|
|
27
|
-
constructor(t, n,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
24
|
+
constructor(t, n, s, o = !1) {
|
|
25
|
+
i(this, "analyser");
|
|
26
|
+
i(this, "dataArray");
|
|
27
|
+
i(this, "rafId", null);
|
|
28
|
+
i(this, "silenceStartTime", 0);
|
|
29
|
+
i(this, "isPaused", !1);
|
|
30
|
+
i(this, "lastCheckTime", 0);
|
|
31
|
+
i(this, "silenceThreshold");
|
|
32
|
+
i(this, "silenceDuration");
|
|
33
|
+
i(this, "checkInterval");
|
|
34
|
+
i(this, "debug");
|
|
38
35
|
/**
|
|
39
36
|
* Check audio levels and pause/resume as needed
|
|
40
37
|
*/
|
|
41
|
-
|
|
38
|
+
i(this, "check", () => {
|
|
42
39
|
const t = performance.now();
|
|
43
40
|
t - this.lastCheckTime >= this.checkInterval && (this.lastCheckTime = t, this.getAudioLevel() < this.silenceThreshold ? this.silenceStartTime === 0 ? this.silenceStartTime = t : t - this.silenceStartTime >= this.silenceDuration && !this.isPaused && this.pauseMedia() : (this.silenceStartTime = 0, this.isPaused && this.resumeMedia())), this.rafId = requestAnimationFrame(this.check);
|
|
44
41
|
});
|
|
45
|
-
this.audioContext = t, this.mediaElement = n, this.silenceThreshold =
|
|
42
|
+
this.audioContext = t, this.mediaElement = n, this.silenceThreshold = s.silenceThreshold, this.silenceDuration = s.silenceDuration, this.checkInterval = s.checkInterval, this.debug = o, this.analyser = t.createAnalyser(), this.analyser.fftSize = 512, this.analyser.smoothingTimeConstant = 0.3, this.dataArray = new Uint8Array(this.analyser.frequencyBinCount);
|
|
46
43
|
}
|
|
47
44
|
/**
|
|
48
45
|
* Connect the detector to the audio stream
|
|
@@ -75,8 +72,8 @@ class I {
|
|
|
75
72
|
this.analyser.getByteTimeDomainData(this.dataArray);
|
|
76
73
|
let t = 0;
|
|
77
74
|
for (let n = 0; n < this.dataArray.length; n++) {
|
|
78
|
-
const
|
|
79
|
-
t +=
|
|
75
|
+
const s = (this.dataArray[n] - 128) / 128;
|
|
76
|
+
t += s * s;
|
|
80
77
|
}
|
|
81
78
|
return Math.sqrt(t / this.dataArray.length);
|
|
82
79
|
}
|
|
@@ -106,7 +103,7 @@ class I {
|
|
|
106
103
|
function S(e, t = {}) {
|
|
107
104
|
const {
|
|
108
105
|
forceEnable: n = !1,
|
|
109
|
-
autoCleanup:
|
|
106
|
+
autoCleanup: s = !0,
|
|
110
107
|
debug: o = !1,
|
|
111
108
|
mediaElementType: m = "video",
|
|
112
109
|
autoPause: d = {}
|
|
@@ -116,7 +113,7 @@ function S(e, t = {}) {
|
|
|
116
113
|
silenceDuration: d.silenceDuration ?? 50,
|
|
117
114
|
checkInterval: d.checkInterval ?? 16
|
|
118
115
|
};
|
|
119
|
-
if (!(n ||
|
|
116
|
+
if (!(n || T()))
|
|
120
117
|
return Object.assign(e, {
|
|
121
118
|
unlock: async () => {
|
|
122
119
|
e.state === "suspended" && await e.resume();
|
|
@@ -138,7 +135,7 @@ function S(e, t = {}) {
|
|
|
138
135
|
});
|
|
139
136
|
const c = e.destination, y = e.createMediaStreamDestination(), f = e.createGain();
|
|
140
137
|
f.gain.value = 1, f.connect(y);
|
|
141
|
-
const l =
|
|
138
|
+
const l = E(m, o);
|
|
142
139
|
l.srcObject = y.stream, document.body.appendChild(l);
|
|
143
140
|
let u = null;
|
|
144
141
|
h.enabled && (u = new I(
|
|
@@ -155,7 +152,7 @@ function S(e, t = {}) {
|
|
|
155
152
|
enumerable: !0
|
|
156
153
|
});
|
|
157
154
|
let g = !1;
|
|
158
|
-
const
|
|
155
|
+
const v = async () => {
|
|
159
156
|
if (!g)
|
|
160
157
|
try {
|
|
161
158
|
await l.play(), e.state === "suspended" && await e.resume(), u && u.start(), g = !0;
|
|
@@ -169,55 +166,54 @@ function S(e, t = {}) {
|
|
|
169
166
|
console.error("[AudioContext] Cleanup error:", a);
|
|
170
167
|
}
|
|
171
168
|
};
|
|
172
|
-
if (
|
|
169
|
+
if (s) {
|
|
173
170
|
const a = e.close.bind(e);
|
|
174
171
|
e.close = async () => (A(), a());
|
|
175
172
|
}
|
|
176
173
|
return Object.assign(e, {
|
|
177
|
-
unlock:
|
|
174
|
+
unlock: v,
|
|
178
175
|
cleanup: A,
|
|
179
176
|
isPatched: !0,
|
|
180
177
|
originalDestination: c
|
|
181
178
|
});
|
|
182
179
|
}
|
|
183
|
-
function
|
|
184
|
-
const { autoUnlock: t = !0, ...n } = e, [
|
|
180
|
+
function C(e = {}) {
|
|
181
|
+
const { autoUnlock: t = !0, ...n } = e, [s, o] = k(null), [m, d] = k(!1), h = w(null);
|
|
185
182
|
return p(() => {
|
|
186
183
|
const r = new AudioContext(), c = S(r, n);
|
|
187
184
|
return o(c), () => {
|
|
188
185
|
c.cleanup(), c.close();
|
|
189
186
|
};
|
|
190
187
|
}, []), p(() => {
|
|
191
|
-
|
|
188
|
+
s && (h.current = async () => {
|
|
192
189
|
if (!m)
|
|
193
190
|
try {
|
|
194
|
-
await
|
|
191
|
+
await s.unlock(), d(!0);
|
|
195
192
|
} catch (r) {
|
|
196
193
|
if (r instanceof DOMException && r.name === "NotAllowedError")
|
|
197
194
|
return;
|
|
198
195
|
console.warn("Failed to unlock audio:", r);
|
|
199
196
|
}
|
|
200
197
|
});
|
|
201
|
-
}, [
|
|
202
|
-
if (!t || !
|
|
198
|
+
}, [s, m]), p(() => {
|
|
199
|
+
if (!t || !s) return;
|
|
203
200
|
const r = async (c) => {
|
|
204
201
|
c.isTrusted && await h.current?.();
|
|
205
202
|
};
|
|
206
203
|
return document.addEventListener("click", r, { once: !0, capture: !0 }), document.addEventListener("touchstart", r, { once: !0, capture: !0 }), () => {
|
|
207
204
|
document.removeEventListener("click", r, { capture: !0 }), document.removeEventListener("touchstart", r, { capture: !0 });
|
|
208
205
|
};
|
|
209
|
-
}, [t,
|
|
210
|
-
audioContext:
|
|
206
|
+
}, [t, s]), {
|
|
207
|
+
audioContext: s,
|
|
211
208
|
isUnlocked: m,
|
|
212
209
|
unlock: h.current || (async () => {
|
|
213
210
|
})
|
|
214
211
|
};
|
|
215
212
|
}
|
|
216
213
|
export {
|
|
217
|
-
|
|
218
|
-
E as
|
|
219
|
-
v as c,
|
|
214
|
+
T as a,
|
|
215
|
+
E as c,
|
|
220
216
|
P as i,
|
|
221
217
|
S as p,
|
|
222
|
-
|
|
218
|
+
C as u
|
|
223
219
|
};
|
package/package.json
CHANGED
package/dist/helper-CIt1_T-j.js
DELETED
|
@@ -1,275 +0,0 @@
|
|
|
1
|
-
import { createOpenAICompatible as l } from "@ai-sdk/openai-compatible";
|
|
2
|
-
import "react";
|
|
3
|
-
import { getAuthTokenAsync as d } from "./bridge-Ca3H2iN1.js";
|
|
4
|
-
import { AISDKError as p, DefaultChatTransport as y } from "ai";
|
|
5
|
-
import { s as c } from "./container-message-DGrno17o.js";
|
|
6
|
-
const f = "https://api.aippy.dev", h = `${f}/aisdk/v1/`, A = `${f}/aisdk/v1/ui/`, b = "gpt-5-nano", w = "";
|
|
7
|
-
function E(t = {}) {
|
|
8
|
-
return {
|
|
9
|
-
baseUrl: t.baseUrl ?? h
|
|
10
|
-
};
|
|
11
|
-
}
|
|
12
|
-
function I(t = {}) {
|
|
13
|
-
return {
|
|
14
|
-
baseUrl: t.baseUrl ?? A
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
function v(t, e) {
|
|
18
|
-
const s = t.status;
|
|
19
|
-
if (e && typeof e == "object" && "error" in e) {
|
|
20
|
-
const r = e, o = r.error.code, n = o != null ? `AippyAIError_${o}` : `AippyAIError_${s}`, a = e;
|
|
21
|
-
return "appMessage" in a && a.appMessage !== void 0 && c(a.appMessage), new p({
|
|
22
|
-
name: n,
|
|
23
|
-
message: r.error.message,
|
|
24
|
-
cause: {
|
|
25
|
-
type: r.error.type ?? void 0,
|
|
26
|
-
param: r.error.param ?? void 0,
|
|
27
|
-
status: s
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
if (e && typeof e == "object" && e !== null) {
|
|
32
|
-
const r = e;
|
|
33
|
-
"appMessage" in r && r.appMessage !== void 0 && c(r.appMessage);
|
|
34
|
-
}
|
|
35
|
-
return new p({
|
|
36
|
-
name: `AippyAIError_${s}`,
|
|
37
|
-
message: `Request failed with status ${s}`,
|
|
38
|
-
cause: { status: s }
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
function F() {
|
|
42
|
-
return new p({
|
|
43
|
-
name: "AippyAIError_MISSING_TOKEN",
|
|
44
|
-
message: "User token is required. Ensure user credentials are available via initUserBridge()."
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
function L() {
|
|
48
|
-
return new p({
|
|
49
|
-
name: "AippyAIError_REQUEST_ABORTED",
|
|
50
|
-
message: "Request was aborted"
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
function k(t) {
|
|
54
|
-
const e = t instanceof Error ? t.message : "Network request failed";
|
|
55
|
-
return new p({
|
|
56
|
-
name: "AippyAIError_NETWORK_ERROR",
|
|
57
|
-
message: e,
|
|
58
|
-
cause: t instanceof Error ? t : String(t)
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
function D(t) {
|
|
62
|
-
return new p({
|
|
63
|
-
name: "AippyAIError_PARSE_ERROR",
|
|
64
|
-
message: `Failed to parse response: ${t}`
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
function _(t, e) {
|
|
68
|
-
const s = t.endsWith("/") ? t : `${t}/`, r = e.startsWith("/") ? e.slice(1) : e;
|
|
69
|
-
return new URL(r, s).href;
|
|
70
|
-
}
|
|
71
|
-
function m() {
|
|
72
|
-
return async (t, e) => {
|
|
73
|
-
const s = await d(), r = new Headers(e?.headers);
|
|
74
|
-
r.set("Aippy-Runtime-Authorization", `Bearer ${s}`);
|
|
75
|
-
const o = await globalThis.fetch(t, { ...e, headers: r });
|
|
76
|
-
if (!o.ok) {
|
|
77
|
-
const a = await o.clone().text().catch(() => null);
|
|
78
|
-
if (a)
|
|
79
|
-
try {
|
|
80
|
-
const i = JSON.parse(a);
|
|
81
|
-
v(o, i);
|
|
82
|
-
} catch {
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
return o;
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
const S = [
|
|
89
|
-
"gpt-image-1",
|
|
90
|
-
"gpt-image-1-mini",
|
|
91
|
-
"gpt-image-1.5"
|
|
92
|
-
];
|
|
93
|
-
function O(t) {
|
|
94
|
-
try {
|
|
95
|
-
const e = JSON.parse(t);
|
|
96
|
-
if (e.model && S.some((s) => e.model.startsWith(s))) {
|
|
97
|
-
const { response_format: s, ...r } = e;
|
|
98
|
-
return JSON.stringify(r);
|
|
99
|
-
}
|
|
100
|
-
} catch {
|
|
101
|
-
}
|
|
102
|
-
return t;
|
|
103
|
-
}
|
|
104
|
-
function B(t = {}) {
|
|
105
|
-
const { baseUrl: e } = E(t), s = m();
|
|
106
|
-
return l({
|
|
107
|
-
name: "aippy",
|
|
108
|
-
baseURL: e,
|
|
109
|
-
fetch: async (o, n) => o.toString().includes("/images/generations") && n?.method?.toUpperCase() === "POST" && n?.body ? s(o, {
|
|
110
|
-
...n,
|
|
111
|
-
body: O(n.body)
|
|
112
|
-
}) : s(o, n),
|
|
113
|
-
// Enable structured outputs support (json_schema response format)
|
|
114
|
-
// This is required for Output.object() and Output.array() to work properly
|
|
115
|
-
supportsStructuredOutputs: !0
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
const C = "/chat";
|
|
119
|
-
function J(t = {}) {
|
|
120
|
-
const { baseUrl: e } = I(t), s = t.model ?? b, r = t.system ?? w, o = t.api ?? _(e, C), n = { model: s, system: r }, a = m();
|
|
121
|
-
return {
|
|
122
|
-
transport: new y({
|
|
123
|
-
api: o,
|
|
124
|
-
body: n,
|
|
125
|
-
// Ensure token is fetched fresh for every request
|
|
126
|
-
fetch: a
|
|
127
|
-
})
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
class u extends Error {
|
|
131
|
-
constructor(e, s) {
|
|
132
|
-
super(e), this.errors = s, this.name = "AIConfigValidationError";
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
function g(t) {
|
|
136
|
-
const e = [];
|
|
137
|
-
if (!t || typeof t != "object")
|
|
138
|
-
throw new u("AIConfig must be an object", []);
|
|
139
|
-
const s = t;
|
|
140
|
-
for (const [r, o] of Object.entries(s)) {
|
|
141
|
-
if (!o || typeof o != "object") {
|
|
142
|
-
e.push({ key: r, message: "Item must be an object" });
|
|
143
|
-
continue;
|
|
144
|
-
}
|
|
145
|
-
const n = o;
|
|
146
|
-
typeof n.index != "number" && e.push({ key: r, message: "index must be a number" }), typeof n.name != "string" && e.push({ key: r, message: "name must be a string" }), typeof n.description != "string" && e.push({ key: r, message: "description must be a string" });
|
|
147
|
-
const a = n.type;
|
|
148
|
-
if (!["number", "boolean", "text", "enum"].includes(a)) {
|
|
149
|
-
e.push({
|
|
150
|
-
key: r,
|
|
151
|
-
message: `type must be one of: number, boolean, text, enum (got: ${a})`
|
|
152
|
-
});
|
|
153
|
-
continue;
|
|
154
|
-
}
|
|
155
|
-
if (a === "number")
|
|
156
|
-
typeof n.value != "number" && e.push({ key: r, message: 'value must be a number for type "number"' }), n.min !== void 0 && typeof n.min != "number" && e.push({ key: r, message: "min must be a number" }), n.max !== void 0 && typeof n.max != "number" && e.push({ key: r, message: "max must be a number" }), n.step !== void 0 && typeof n.step != "number" && e.push({ key: r, message: "step must be a number" });
|
|
157
|
-
else if (a === "boolean")
|
|
158
|
-
typeof n.value != "boolean" && e.push({ key: r, message: 'value must be a boolean for type "boolean"' });
|
|
159
|
-
else if (a === "text")
|
|
160
|
-
typeof n.value != "string" && e.push({ key: r, message: 'value must be a string for type "text"' });
|
|
161
|
-
else if (a === "enum") {
|
|
162
|
-
if (!Array.isArray(n.options))
|
|
163
|
-
e.push({ key: r, message: 'options must be an array for type "enum"' });
|
|
164
|
-
else if (n.options.length === 0)
|
|
165
|
-
e.push({ key: r, message: 'options array cannot be empty for type "enum"' });
|
|
166
|
-
else
|
|
167
|
-
for (let i = 0; i < n.options.length; i++)
|
|
168
|
-
typeof n.options[i] != "string" && e.push({
|
|
169
|
-
key: r,
|
|
170
|
-
message: `options[${i}] must be a string`
|
|
171
|
-
});
|
|
172
|
-
typeof n.value != "string" ? e.push({ key: r, message: 'value must be a string for type "enum"' }) : Array.isArray(n.options) && !n.options.includes(n.value) && e.push({
|
|
173
|
-
key: r,
|
|
174
|
-
message: `value "${n.value}" is not in options: [${n.options.join(", ")}]`
|
|
175
|
-
});
|
|
176
|
-
}
|
|
177
|
-
n.group !== void 0 && typeof n.group != "string" && e.push({ key: r, message: "group must be a string" });
|
|
178
|
-
}
|
|
179
|
-
if (e.length > 0)
|
|
180
|
-
throw new u(
|
|
181
|
-
`AIConfig validation failed with ${e.length} error(s)`,
|
|
182
|
-
e
|
|
183
|
-
);
|
|
184
|
-
}
|
|
185
|
-
function P(t) {
|
|
186
|
-
let e;
|
|
187
|
-
try {
|
|
188
|
-
e = JSON.parse(t);
|
|
189
|
-
} catch (s) {
|
|
190
|
-
throw new u("Invalid JSON", [
|
|
191
|
-
{
|
|
192
|
-
key: "",
|
|
193
|
-
message: `JSON parse error: ${s instanceof Error ? s.message : String(s)}`
|
|
194
|
-
}
|
|
195
|
-
]);
|
|
196
|
-
}
|
|
197
|
-
return g(e), e;
|
|
198
|
-
}
|
|
199
|
-
function R(t) {
|
|
200
|
-
return g(t), t;
|
|
201
|
-
}
|
|
202
|
-
function T(t, e) {
|
|
203
|
-
const s = t[e];
|
|
204
|
-
if (!s)
|
|
205
|
-
throw new Error(`AIConfig key "${e}" not found`);
|
|
206
|
-
return s.value;
|
|
207
|
-
}
|
|
208
|
-
function U(t) {
|
|
209
|
-
if (!(typeof window > "u"))
|
|
210
|
-
try {
|
|
211
|
-
const e = window.webkit?.messageHandlers?.aippyListener;
|
|
212
|
-
if (e)
|
|
213
|
-
try {
|
|
214
|
-
const s = {
|
|
215
|
-
command: "ai.initialize",
|
|
216
|
-
parameters: JSON.stringify(t)
|
|
217
|
-
};
|
|
218
|
-
e.postMessage(s);
|
|
219
|
-
} catch (s) {
|
|
220
|
-
console.warn("❌ [Aippy AI Config] Failed to send config to iOS app:", s);
|
|
221
|
-
}
|
|
222
|
-
if (window.parent && window.parent !== window)
|
|
223
|
-
try {
|
|
224
|
-
const s = {
|
|
225
|
-
type: "ai.initialize",
|
|
226
|
-
config: JSON.stringify(t)
|
|
227
|
-
};
|
|
228
|
-
window.parent.postMessage(s, "*");
|
|
229
|
-
} catch (s) {
|
|
230
|
-
console.warn("❌ [Aippy AI Config] Failed to send config to parent window:", s);
|
|
231
|
-
}
|
|
232
|
-
} catch (e) {
|
|
233
|
-
console.warn("⚠️ [Aippy AI Config] Failed to send config:", e);
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
function z(t) {
|
|
237
|
-
const e = R(t);
|
|
238
|
-
return U(e), new Proxy({}, {
|
|
239
|
-
get(s, r) {
|
|
240
|
-
if (typeof r == "string")
|
|
241
|
-
try {
|
|
242
|
-
return T(e, r);
|
|
243
|
-
} catch {
|
|
244
|
-
return;
|
|
245
|
-
}
|
|
246
|
-
},
|
|
247
|
-
has(s, r) {
|
|
248
|
-
return typeof r != "string" ? !1 : r in e;
|
|
249
|
-
},
|
|
250
|
-
ownKeys(s) {
|
|
251
|
-
return Object.keys(e);
|
|
252
|
-
}
|
|
253
|
-
});
|
|
254
|
-
}
|
|
255
|
-
export {
|
|
256
|
-
u as A,
|
|
257
|
-
h as D,
|
|
258
|
-
C as U,
|
|
259
|
-
B as a,
|
|
260
|
-
J as b,
|
|
261
|
-
A as c,
|
|
262
|
-
b as d,
|
|
263
|
-
w as e,
|
|
264
|
-
L as f,
|
|
265
|
-
k as g,
|
|
266
|
-
P as h,
|
|
267
|
-
T as i,
|
|
268
|
-
z as j,
|
|
269
|
-
R as l,
|
|
270
|
-
F as m,
|
|
271
|
-
v as n,
|
|
272
|
-
D as p,
|
|
273
|
-
U as s,
|
|
274
|
-
g as v
|
|
275
|
-
};
|