@runappsai/sdk 0.0.0-stage → 0.3.0
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/LICENSE +21 -0
- package/README.md +274 -2
- package/dist/activity-tracker.d.ts +113 -0
- package/dist/activity-tracker.d.ts.map +1 -0
- package/dist/activity-tracker.js +176 -0
- package/dist/activity-tracker.js.map +1 -0
- package/dist/audio.d.ts +129 -0
- package/dist/audio.d.ts.map +1 -0
- package/dist/audio.js +267 -0
- package/dist/audio.js.map +1 -0
- package/dist/browser-auth.d.ts +179 -0
- package/dist/browser-auth.d.ts.map +1 -0
- package/dist/browser-auth.js +1361 -0
- package/dist/browser-auth.js.map +1 -0
- package/dist/chat.d.ts +221 -0
- package/dist/chat.d.ts.map +1 -0
- package/dist/chat.js +155 -0
- package/dist/chat.js.map +1 -0
- package/dist/client.d.ts +155 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +157 -0
- package/dist/client.js.map +1 -0
- package/dist/computer.d.ts +57 -0
- package/dist/computer.d.ts.map +1 -0
- package/dist/computer.js +21 -0
- package/dist/computer.js.map +1 -0
- package/dist/embeddings.d.ts +64 -0
- package/dist/embeddings.d.ts.map +1 -0
- package/dist/embeddings.js +30 -0
- package/dist/embeddings.js.map +1 -0
- package/dist/errors.d.ts +24 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +29 -0
- package/dist/errors.js.map +1 -0
- package/dist/event-wrap.d.ts +59 -0
- package/dist/event-wrap.d.ts.map +1 -0
- package/dist/event-wrap.js +142 -0
- package/dist/event-wrap.js.map +1 -0
- package/dist/events.d.ts +119 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +87 -0
- package/dist/events.js.map +1 -0
- package/dist/files.d.ts +218 -0
- package/dist/files.d.ts.map +1 -0
- package/dist/files.js +212 -0
- package/dist/files.js.map +1 -0
- package/dist/image.d.ts +185 -0
- package/dist/image.d.ts.map +1 -0
- package/dist/image.js +148 -0
- package/dist/image.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/media.d.ts +56 -0
- package/dist/media.d.ts.map +1 -0
- package/dist/media.js +133 -0
- package/dist/media.js.map +1 -0
- package/dist/model_options.d.ts +165 -0
- package/dist/model_options.d.ts.map +1 -0
- package/dist/model_options.js +59 -0
- package/dist/model_options.js.map +1 -0
- package/dist/models.d.ts +88 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +55 -0
- package/dist/models.js.map +1 -0
- package/dist/sdk.umd.js +4 -0
- package/dist/sdk.umd.js.map +1 -0
- package/dist/transport.d.ts +120 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +214 -0
- package/dist/transport.js.map +1 -0
- package/dist/types.d.ts +31 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/validate.d.ts +16 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +329 -0
- package/dist/validate.js.map +1 -0
- package/dist/video.d.ts +134 -0
- package/dist/video.d.ts.map +1 -0
- package/dist/video.js +60 -0
- package/dist/video.js.map +1 -0
- package/package.json +54 -4
- package/src/activity-tracker.ts +251 -0
- package/src/audio.ts +440 -0
- package/src/browser-auth.ts +1529 -0
- package/src/chat.ts +368 -0
- package/src/client.ts +250 -0
- package/src/computer.ts +80 -0
- package/src/embeddings.ts +97 -0
- package/src/errors.ts +29 -0
- package/src/event-wrap.ts +168 -0
- package/src/events.ts +172 -0
- package/src/files.ts +347 -0
- package/src/image.ts +339 -0
- package/src/index.ts +151 -0
- package/src/media.ts +147 -0
- package/src/model_options.ts +220 -0
- package/src/models.ts +121 -0
- package/src/transport.ts +292 -0
- package/src/types.ts +31 -0
- package/src/validate.ts +364 -0
- package/src/video.ts +215 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import type { Model } from "./models.js";
|
|
2
|
+
/** Wire-format options shape returned by /v1/models. */
|
|
3
|
+
export interface Schema {
|
|
4
|
+
/**
|
|
5
|
+
* Per-field constraints, keyed by canonical request field name
|
|
6
|
+
* (matching the JSON keys on Image/Video/Speech/Embed/Transcribe
|
|
7
|
+
* params). A field absent from this map is NOT accepted by the
|
|
8
|
+
* model.
|
|
9
|
+
*/
|
|
10
|
+
inputs?: Record<string, FieldSchema>;
|
|
11
|
+
/** Cross-field rules. */
|
|
12
|
+
constraints?: Constraint[];
|
|
13
|
+
/** Rich content (TTS voices, emotions). */
|
|
14
|
+
catalog?: Catalog;
|
|
15
|
+
}
|
|
16
|
+
export interface FieldSchema {
|
|
17
|
+
type: "string" | "int" | "float" | "bool" | "url" | "url[]" | "string[]" | "file";
|
|
18
|
+
/** Default when omitted is "optional". */
|
|
19
|
+
presence?: "required" | "optional" | "forbidden";
|
|
20
|
+
min?: number;
|
|
21
|
+
max?: number;
|
|
22
|
+
default?: unknown;
|
|
23
|
+
enum?: unknown[];
|
|
24
|
+
max_items?: number;
|
|
25
|
+
/** Lower-bound counterpart of max_items. Applies to array types
|
|
26
|
+
* AND `repeatable` object groups. Nil = no minimum. */
|
|
27
|
+
min_items?: number;
|
|
28
|
+
/** Semantic hint for media-input fields. */
|
|
29
|
+
role?: "source" | "reference" | "motion";
|
|
30
|
+
/** When present, this field is a structured sub-object. The wire
|
|
31
|
+
* value is `{<inner-name>: <value>, ...}` matching this inner
|
|
32
|
+
* schema; renderers recurse into it. With `repeatable: true` the
|
|
33
|
+
* wire value becomes an array of such objects (e.g. multi-utterance
|
|
34
|
+
* TTS "+ add another group"). */
|
|
35
|
+
fields?: Record<string, FieldSchema>;
|
|
36
|
+
/** Pairs with `fields`: array-of-objects rather than a single
|
|
37
|
+
* nested object. Ignored when `fields` is absent. */
|
|
38
|
+
repeatable?: boolean;
|
|
39
|
+
/** Human-readable display label. Falls back to the field name. */
|
|
40
|
+
label?: string;
|
|
41
|
+
/** One-sentence tooltip / sub-text explainer. */
|
|
42
|
+
help?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Widget override hint:
|
|
45
|
+
* "textarea" — large multi-line string
|
|
46
|
+
* "slider" — numeric with min/max
|
|
47
|
+
* "radio" — small enum
|
|
48
|
+
* "voice_picker" — string with values from catalog.voices
|
|
49
|
+
* "code" — long string with syntax highlighting
|
|
50
|
+
* "segmented" — pill-shaped row of enum values (compact,
|
|
51
|
+
* horizontal). Best for short ordered enums
|
|
52
|
+
* like the resolution tier (512P / 1K / 2K /
|
|
53
|
+
* 4K) in image generation. Renders as a single
|
|
54
|
+
* line; selected option has solid background.
|
|
55
|
+
* "tile" — grid of square cards, each carrying a small
|
|
56
|
+
* visual proxy for the value (aspect-ratio
|
|
57
|
+
* shape icon, or fit-brackets for the
|
|
58
|
+
* "adaptive" sentinel). Used for aspect_ratio
|
|
59
|
+
* in image generation. When the enum includes
|
|
60
|
+
* "adaptive" or "auto", that entry is
|
|
61
|
+
* promoted to a row-spanning anchor block.
|
|
62
|
+
* "tabs" — horizontal tab strip. Same data contract as
|
|
63
|
+
* "radio" but a different visual. Drives
|
|
64
|
+
* `ui.show_when` on sibling fields.
|
|
65
|
+
* "card_group" — bordered card containing the field's nested
|
|
66
|
+
* `fields`. With `repeatable: true` the card
|
|
67
|
+
* becomes a "+ add another"-able stack.
|
|
68
|
+
* Unknown values fall back to the type default (forward-compat).
|
|
69
|
+
*/
|
|
70
|
+
widget?: string;
|
|
71
|
+
/**
|
|
72
|
+
* Nested presentational hints:
|
|
73
|
+
* "group" (string) — sectional grouping ("main"/"advanced"/"output").
|
|
74
|
+
* "order" (int) — display order within the group; lower first.
|
|
75
|
+
* "card_label" (string) — title above a card_group; "{{i}}" is
|
|
76
|
+
* substituted with the card index for
|
|
77
|
+
* repeatable groups.
|
|
78
|
+
* "show_when" ({field, equals})
|
|
79
|
+
* — purely-visual conditional: hide this
|
|
80
|
+
* field unless a sibling's value matches.
|
|
81
|
+
* Validator ignores it; server still
|
|
82
|
+
* accepts conditionally-hidden fields.
|
|
83
|
+
*/
|
|
84
|
+
ui?: {
|
|
85
|
+
group?: string;
|
|
86
|
+
order?: number;
|
|
87
|
+
card_label?: string;
|
|
88
|
+
show_when?: {
|
|
89
|
+
field: string;
|
|
90
|
+
equals: unknown;
|
|
91
|
+
};
|
|
92
|
+
[k: string]: unknown;
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
export type ConstraintKind = "any_of_required" | "mutually_exclusive" | "group_mutex" | "requires_all" | "pixel_bounds";
|
|
96
|
+
export interface Group {
|
|
97
|
+
/** Stable id; also the value the discriminator field
|
|
98
|
+
* (`Constraint.name`) takes when this group is active. */
|
|
99
|
+
name?: string;
|
|
100
|
+
/** Tab strip display label. Falls back to `name`. */
|
|
101
|
+
label?: string;
|
|
102
|
+
fields: string[];
|
|
103
|
+
}
|
|
104
|
+
export interface Constraint {
|
|
105
|
+
kind: ConstraintKind;
|
|
106
|
+
fields?: string[];
|
|
107
|
+
/**
|
|
108
|
+
* On a `group_mutex` constraint, names the discriminator field
|
|
109
|
+
* selecting which group is active. The renderer auto-injects a
|
|
110
|
+
* `tabs` input with this name (enum = group names) and gives
|
|
111
|
+
* every group member an implicit `show_when` pointing at it.
|
|
112
|
+
* When omitted, the constraint behaves as legacy anonymous-group
|
|
113
|
+
* mutex — all members render flat, mutex enforced at submit.
|
|
114
|
+
*/
|
|
115
|
+
name?: string;
|
|
116
|
+
/**
|
|
117
|
+
* Human-readable title for the synthesized tab widget (e.g.
|
|
118
|
+
* "Animation mode"). Falls back to `name` when omitted.
|
|
119
|
+
*/
|
|
120
|
+
label?: string;
|
|
121
|
+
/**
|
|
122
|
+
* Used by `group_mutex`. Wire shape is either the legacy
|
|
123
|
+
* `string[][]` (each `[a,b,...]` reads as an anonymous
|
|
124
|
+
* `{fields:[a,b,...]}` Group) or the new `Group[]`. Consumers
|
|
125
|
+
* should normalize via `normalizeGroups()` before reading.
|
|
126
|
+
*/
|
|
127
|
+
groups?: Group[] | string[][];
|
|
128
|
+
when?: string;
|
|
129
|
+
then?: string[];
|
|
130
|
+
min?: number;
|
|
131
|
+
max?: number;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Normalize either legacy `string[][]` or new `Group[]` into a
|
|
135
|
+
* uniform `Group[]`. Mirror of sdk-go's `Group.UnmarshalJSON`.
|
|
136
|
+
*/
|
|
137
|
+
export declare function normalizeGroups(g: Constraint["groups"]): Group[];
|
|
138
|
+
export interface Catalog {
|
|
139
|
+
voices?: Array<Record<string, unknown>>;
|
|
140
|
+
emotions?: string[];
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Parse the model's wire-format `options` blob into the typed Schema.
|
|
144
|
+
* Returns null when the model has no options or the blob can't be
|
|
145
|
+
* structurally decoded — callers fall back to whatever default
|
|
146
|
+
* behaviour they had pre-schema.
|
|
147
|
+
*/
|
|
148
|
+
export declare function getOptionsSchema(model: Model): Schema | null;
|
|
149
|
+
/**
|
|
150
|
+
* True iff the model declares an Inputs entry for `name` with
|
|
151
|
+
* presence != "forbidden". Use for "should I show this UI chip"
|
|
152
|
+
* decisions.
|
|
153
|
+
*/
|
|
154
|
+
export declare function acceptsField(model: Model, name: string): boolean;
|
|
155
|
+
/**
|
|
156
|
+
* True iff the schema marks `name` as presence: "required". Use for
|
|
157
|
+
* red-star UI marks and submit-button gating.
|
|
158
|
+
*/
|
|
159
|
+
export declare function requiresField(model: Model, name: string): boolean;
|
|
160
|
+
/**
|
|
161
|
+
* Discrete enum for the named field, or null if no enum constraint.
|
|
162
|
+
* Use to populate dropdown options on the client.
|
|
163
|
+
*/
|
|
164
|
+
export declare function allowedValuesFor(model: Model, name: string): unknown[] | null;
|
|
165
|
+
//# sourceMappingURL=model_options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model_options.d.ts","sourceRoot":"","sources":["../src/model_options.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,wDAAwD;AACxD,MAAM,WAAW,MAAM;IACrB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACrC,yBAAyB;IACzB,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,2CAA2C;IAC3C,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EACA,QAAQ,GACR,KAAK,GACL,OAAO,GACP,MAAM,GACN,KAAK,GACL,OAAO,GACP,UAAU,GACV,MAAM,CAAC;IACX,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,WAAW,CAAC;IACjD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;4DACwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,IAAI,CAAC,EAAE,QAAQ,GAAG,WAAW,GAAG,QAAQ,CAAC;IACzC;;;;sCAIkC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACrC;0DACsD;IACtD,UAAU,CAAC,EAAE,OAAO,CAAC;IAMrB,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;;;;;;OAYG;IACH,EAAE,CAAC,EAAE;QACH,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,OAAO,CAAA;SAAE,CAAC;QAC/C,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;KACtB,CAAC;CACH;AAED,MAAM,MAAM,cAAc,GACtB,iBAAiB,GACjB,oBAAoB,GACpB,aAAa,GACb,cAAc,GACd,cAAc,CAAC;AAEnB,MAAM,WAAW,KAAK;IACpB;+DAC2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,cAAc,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,MAAM,CAAC,EAAE,KAAK,EAAE,GAAG,MAAM,EAAE,EAAE,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC,GAAG,KAAK,EAAE,CAKhE;AAED,MAAM,WAAW,OAAO;IACtB,MAAM,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACxC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,IAAI,CAS5D;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAKhE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAGjE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE,GAAG,IAAI,CAG7E"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// Mirror of internal/api/options_schema/types.go on the JS side.
|
|
2
|
+
// See API.md "Options schema" for the full contract; the gateway
|
|
3
|
+
// materialises this from the legacy options blob at /v1/models
|
|
4
|
+
// response time.
|
|
5
|
+
/**
|
|
6
|
+
* Normalize either legacy `string[][]` or new `Group[]` into a
|
|
7
|
+
* uniform `Group[]`. Mirror of sdk-go's `Group.UnmarshalJSON`.
|
|
8
|
+
*/
|
|
9
|
+
export function normalizeGroups(g) {
|
|
10
|
+
if (!g)
|
|
11
|
+
return [];
|
|
12
|
+
return g.map(item => Array.isArray(item) ? { fields: item } : item);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Parse the model's wire-format `options` blob into the typed Schema.
|
|
16
|
+
* Returns null when the model has no options or the blob can't be
|
|
17
|
+
* structurally decoded — callers fall back to whatever default
|
|
18
|
+
* behaviour they had pre-schema.
|
|
19
|
+
*/
|
|
20
|
+
export function getOptionsSchema(model) {
|
|
21
|
+
const opts = model.options;
|
|
22
|
+
if (!opts || typeof opts !== "object")
|
|
23
|
+
return null;
|
|
24
|
+
// The Model interface types options as Record<string, unknown>;
|
|
25
|
+
// Schema has the same JSON layout, so a structural cast is safe
|
|
26
|
+
// as long as the gateway emits the wire shape we expect. SDK
|
|
27
|
+
// consumers should call validateRequest() to surface errors —
|
|
28
|
+
// this getter is a thin typed view over the same data.
|
|
29
|
+
return opts;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* True iff the model declares an Inputs entry for `name` with
|
|
33
|
+
* presence != "forbidden". Use for "should I show this UI chip"
|
|
34
|
+
* decisions.
|
|
35
|
+
*/
|
|
36
|
+
export function acceptsField(model, name) {
|
|
37
|
+
const schema = getOptionsSchema(model);
|
|
38
|
+
const f = schema?.inputs?.[name];
|
|
39
|
+
if (!f)
|
|
40
|
+
return false;
|
|
41
|
+
return f.presence !== "forbidden";
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* True iff the schema marks `name` as presence: "required". Use for
|
|
45
|
+
* red-star UI marks and submit-button gating.
|
|
46
|
+
*/
|
|
47
|
+
export function requiresField(model, name) {
|
|
48
|
+
const schema = getOptionsSchema(model);
|
|
49
|
+
return schema?.inputs?.[name]?.presence === "required";
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Discrete enum for the named field, or null if no enum constraint.
|
|
53
|
+
* Use to populate dropdown options on the client.
|
|
54
|
+
*/
|
|
55
|
+
export function allowedValuesFor(model, name) {
|
|
56
|
+
const schema = getOptionsSchema(model);
|
|
57
|
+
return schema?.inputs?.[name]?.enum ?? null;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=model_options.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model_options.js","sourceRoot":"","sources":["../src/model_options.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,iEAAiE;AACjE,+DAA+D;AAC/D,iBAAiB;AA2JjB;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,CAAuB;IACrD,IAAI,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IAClB,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAClB,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAgB,EAAE,CAAC,CAAC,CAAE,IAAc,CACrE,CAAC;AACJ,CAAC;AAOD;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAY;IAC3C,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC;IAC3B,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACnD,gEAAgE;IAChE,gEAAgE;IAChE,6DAA6D;IAC7D,8DAA8D;IAC9D,uDAAuD;IACvD,OAAO,IAAyB,CAAC;AACnC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,KAAY,EAAE,IAAY;IACrD,MAAM,MAAM,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACvC,MAAM,CAAC,GAAG,MAAM,EAAE,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACrB,OAAO,CAAC,CAAC,QAAQ,KAAK,WAAW,CAAC;AACpC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAAY,EAAE,IAAY;IACtD,MAAM,MAAM,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACvC,OAAO,MAAM,EAAE,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,QAAQ,KAAK,UAAU,CAAC;AACzD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAY,EAAE,IAAY;IACzD,MAAM,MAAM,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACvC,OAAO,MAAM,EAAE,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,IAAI,CAAC;AAC9C,CAAC"}
|
package/dist/models.d.ts
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { Transport } from "./transport.js";
|
|
2
|
+
/**
|
|
3
|
+
* One model available on the gateway. Pricing is in **pips** (1 USD =
|
|
4
|
+
* 1,000,000 pips), per million tokens — multiply by tokens / 10⁶ for the
|
|
5
|
+
* billed pip cost, or by tokens / 10¹² for USD.
|
|
6
|
+
*/
|
|
7
|
+
export interface Model {
|
|
8
|
+
id: string;
|
|
9
|
+
object: string;
|
|
10
|
+
capability: string;
|
|
11
|
+
provider?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Server-derived "what this model can actually do" tags
|
|
14
|
+
* (e.g. {id:"t2v", label:"Text-to-Video"}, {id:"i2v", label:"Image-to-Video"}).
|
|
15
|
+
* Use `hasCapabilityTag` for stable filter checks; iterate for display.
|
|
16
|
+
* Labels are in English — frontends localise on their side.
|
|
17
|
+
*/
|
|
18
|
+
capability_tags?: Tag[];
|
|
19
|
+
/**
|
|
20
|
+
* Accepted input modalities for chat models. Omitted on capabilities
|
|
21
|
+
* where it doesn't apply (image generation, TTS, etc.). Mirrors
|
|
22
|
+
* Anthropic / Gemini's own `inputModalities` field — operator-set on
|
|
23
|
+
* the gateway, surfaced verbatim here.
|
|
24
|
+
*
|
|
25
|
+
* Canonical values: `"text"`, `"image"`, `"video"`, `"audio"`. The
|
|
26
|
+
* list is open — future modalities ride through without an SDK
|
|
27
|
+
* update. Use `acceptsModality` for the stable filter check.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* const videoCapable = models.filter(m => acceptsModality(m, "video"));
|
|
31
|
+
*/
|
|
32
|
+
input_modalities?: string[];
|
|
33
|
+
options?: Record<string, unknown>;
|
|
34
|
+
input_price_per_mtok: number;
|
|
35
|
+
output_price_per_mtok: number;
|
|
36
|
+
fixed_price: boolean;
|
|
37
|
+
fixed_cost: number;
|
|
38
|
+
max_tokens: number;
|
|
39
|
+
max_input_tokens: number;
|
|
40
|
+
icon_url?: string;
|
|
41
|
+
available_voices?: string[];
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* One capability tag. Mirrors options_schema.Tag on the gateway. IDs
|
|
45
|
+
* are stable across releases; Labels are subject to translation.
|
|
46
|
+
*/
|
|
47
|
+
export interface Tag {
|
|
48
|
+
id: string;
|
|
49
|
+
label: string;
|
|
50
|
+
}
|
|
51
|
+
/** True iff `model.capability_tags` includes a tag with the given stable ID. */
|
|
52
|
+
export declare const hasCapabilityTag: (model: Model, id: string) => boolean;
|
|
53
|
+
/**
|
|
54
|
+
* True iff the chat model accepts the given input modality. Lets you
|
|
55
|
+
* filter by `"image"` / `"video"` / `"audio"` (or `"text"`, always
|
|
56
|
+
* true for chat models that set the field at all) without remembering
|
|
57
|
+
* whether the gateway uses canonical or aliased names.
|
|
58
|
+
*
|
|
59
|
+
* Returns `false` when `input_modalities` is unset — text-only is the
|
|
60
|
+
* conservative default.
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* const videoModels = (await client.models.list())
|
|
64
|
+
* .filter(m => acceptsModality(m, "video"));
|
|
65
|
+
*/
|
|
66
|
+
export declare const acceptsModality: (model: Model, modality: string) => boolean;
|
|
67
|
+
export interface ModelListOptions {
|
|
68
|
+
/** Filter to one capability (e.g. "text", "vision", "image", "tts"). */
|
|
69
|
+
capability?: string;
|
|
70
|
+
}
|
|
71
|
+
/** Convenience: TTS model accepts a reference audio clip as `voice`? */
|
|
72
|
+
export declare const supportsVoiceClone: (model: Model) => boolean;
|
|
73
|
+
/** Convenience: TTS model accepts a free-form `instruct_text` directive? */
|
|
74
|
+
export declare const supportsInstructText: (model: Model) => boolean;
|
|
75
|
+
/** Convenience: admin-set default voice for a TTS model, or null. */
|
|
76
|
+
export declare const defaultVoice: (model: Model) => string | null;
|
|
77
|
+
export declare class ModelsService {
|
|
78
|
+
private readonly transport;
|
|
79
|
+
constructor(transport: Transport);
|
|
80
|
+
/**
|
|
81
|
+
* List models available on the gateway. Pass `{ capability: "..." }` to
|
|
82
|
+
* filter server-side.
|
|
83
|
+
*/
|
|
84
|
+
list(opts?: ModelListOptions, init?: {
|
|
85
|
+
signal?: AbortSignal;
|
|
86
|
+
}): Promise<Model[]>;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=models.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD;;;;GAIG;AACH,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,eAAe,CAAC,EAAE,GAAG,EAAE,CAAC;IACxB;;;;;;;;;;;;OAYG;IACH,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED;;;GAGG;AACH,MAAM,WAAW,GAAG;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf;AAED,gFAAgF;AAChF,eAAO,MAAM,gBAAgB,GAAI,OAAO,KAAK,EAAE,IAAI,MAAM,KAAG,OAEZ,CAAC;AAEjD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,eAAe,GAAI,OAAO,KAAK,EAAE,UAAU,MAAM,KAAG,OAEtB,CAAC;AAE5C,MAAM,WAAW,gBAAgB;IAC/B,wEAAwE;IACxE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAUD,wEAAwE;AACxE,eAAO,MAAM,kBAAkB,GAAI,OAAO,KAAK,KAAG,OACV,CAAC;AAEzC,4EAA4E;AAC5E,eAAO,MAAM,oBAAoB,GAAI,OAAO,KAAK,KAAG,OACV,CAAC;AAE3C,qEAAqE;AACrE,eAAO,MAAM,YAAY,GAAI,OAAO,KAAK,KAAG,MAAM,GAAG,IAGpD,CAAC;AAEF,qBAAa,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,SAAS;IAEjD;;;OAGG;IACG,IAAI,CACR,IAAI,GAAE,gBAAqB,EAC3B,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAC9B,OAAO,CAAC,KAAK,EAAE,CAAC;CAQpB"}
|
package/dist/models.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/** True iff `model.capability_tags` includes a tag with the given stable ID. */
|
|
2
|
+
export const hasCapabilityTag = (model, id) => Array.isArray(model.capability_tags) &&
|
|
3
|
+
model.capability_tags.some((t) => t.id === id);
|
|
4
|
+
/**
|
|
5
|
+
* True iff the chat model accepts the given input modality. Lets you
|
|
6
|
+
* filter by `"image"` / `"video"` / `"audio"` (or `"text"`, always
|
|
7
|
+
* true for chat models that set the field at all) without remembering
|
|
8
|
+
* whether the gateway uses canonical or aliased names.
|
|
9
|
+
*
|
|
10
|
+
* Returns `false` when `input_modalities` is unset — text-only is the
|
|
11
|
+
* conservative default.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* const videoModels = (await client.models.list())
|
|
15
|
+
* .filter(m => acceptsModality(m, "video"));
|
|
16
|
+
*/
|
|
17
|
+
export const acceptsModality = (model, modality) => Array.isArray(model.input_modalities) &&
|
|
18
|
+
model.input_modalities.includes(modality);
|
|
19
|
+
/** True iff the gateway flag in `options[key]` is set. Accepts bool or numeric 1. */
|
|
20
|
+
function optBool(model, key) {
|
|
21
|
+
const v = model.options?.[key];
|
|
22
|
+
if (typeof v === "boolean")
|
|
23
|
+
return v;
|
|
24
|
+
if (typeof v === "number")
|
|
25
|
+
return v !== 0;
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
/** Convenience: TTS model accepts a reference audio clip as `voice`? */
|
|
29
|
+
export const supportsVoiceClone = (model) => optBool(model, "supports_voice_clone");
|
|
30
|
+
/** Convenience: TTS model accepts a free-form `instruct_text` directive? */
|
|
31
|
+
export const supportsInstructText = (model) => optBool(model, "supports_instruct_text");
|
|
32
|
+
/** Convenience: admin-set default voice for a TTS model, or null. */
|
|
33
|
+
export const defaultVoice = (model) => {
|
|
34
|
+
const v = model.options?.["default_voice"];
|
|
35
|
+
return typeof v === "string" ? v : null;
|
|
36
|
+
};
|
|
37
|
+
export class ModelsService {
|
|
38
|
+
transport;
|
|
39
|
+
constructor(transport) {
|
|
40
|
+
this.transport = transport;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* List models available on the gateway. Pass `{ capability: "..." }` to
|
|
44
|
+
* filter server-side.
|
|
45
|
+
*/
|
|
46
|
+
async list(opts = {}, init) {
|
|
47
|
+
let path = "/v1/models";
|
|
48
|
+
if (opts.capability) {
|
|
49
|
+
path += `?capability=${encodeURIComponent(opts.capability)}`;
|
|
50
|
+
}
|
|
51
|
+
const resp = await this.transport.getJSON(path, init);
|
|
52
|
+
return resp.data;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=models.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.js","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAqDA,gFAAgF;AAChF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,KAAY,EAAE,EAAU,EAAW,EAAE,CACpE,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC;IACpC,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;AAEjD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAAY,EAAE,QAAgB,EAAW,EAAE,CACzE,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC;IACrC,KAAK,CAAC,gBAAgB,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAO5C,qFAAqF;AACrF,SAAS,OAAO,CAAC,KAAY,EAAE,GAAW;IACxC,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,OAAO,CAAC,KAAK,SAAS;QAAE,OAAO,CAAC,CAAC;IACrC,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAC1C,OAAO,KAAK,CAAC;AACf,CAAC;AAED,wEAAwE;AACxE,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,KAAY,EAAW,EAAE,CAC1D,OAAO,CAAC,KAAK,EAAE,sBAAsB,CAAC,CAAC;AAEzC,4EAA4E;AAC5E,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,KAAY,EAAW,EAAE,CAC5D,OAAO,CAAC,KAAK,EAAE,wBAAwB,CAAC,CAAC;AAE3C,qEAAqE;AACrE,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,KAAY,EAAiB,EAAE;IAC1D,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,eAAe,CAAC,CAAC;IAC3C,OAAO,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1C,CAAC,CAAC;AAEF,MAAM,OAAO,aAAa;IACK;IAA7B,YAA6B,SAAoB;QAApB,cAAS,GAAT,SAAS,CAAW;IAAG,CAAC;IAErD;;;OAGG;IACH,KAAK,CAAC,IAAI,CACR,OAAyB,EAAE,EAC3B,IAA+B;QAE/B,IAAI,IAAI,GAAG,YAAY,CAAC;QACxB,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,IAAI,IAAI,eAAe,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/D,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAoB,IAAI,EAAE,IAAI,CAAC,CAAC;QACzE,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;CACF"}
|
package/dist/sdk.umd.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
"use strict";var RunApps=(()=>{var J=Object.defineProperty;var at=Object.getOwnPropertyDescriptor;var lt=Object.getOwnPropertyNames;var ct=Object.prototype.hasOwnProperty;var ut=(r,e,t)=>e in r?J(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t;var pt=(r,e)=>{for(var t in e)J(r,t,{get:e[t],enumerable:!0})},dt=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of lt(e))!ct.call(r,s)&&s!==t&&J(r,s,{get:()=>e[s],enumerable:!(n=at(e,s))||n.enumerable});return r};var gt=r=>dt(J({},"__esModule",{value:!0}),r);var l=(r,e,t)=>ut(r,typeof e!="symbol"?e+"":e,t);var Jt={};pt(Jt,{APIError:()=>x,ActivityTracker:()=>C,BrowserAuth:()=>A,Client:()=>T,RunApps:()=>T,RunJobs:()=>T,SDKEvents:()=>k,ServerTools:()=>Ce,acceptsField:()=>Qe,acceptsModality:()=>De,allowedValuesFor:()=>et,assistantMessage:()=>Te,audioPart:()=>Ue,decodeMediaUrl:()=>B,defaultVoice:()=>Le,encodeImageUrl:()=>Ne,getOptionsSchema:()=>$,hasCapabilityTag:()=>Oe,imagePart:()=>Me,newRequestId:()=>D,requiresField:()=>Ze,supportsInstructText:()=>$e,supportsVoiceClone:()=>Fe,systemMessage:()=>Ae,textPart:()=>Ie,toolResultMessage:()=>Re,userMessage:()=>Ee,userMessageParts:()=>Pe,validateRequest:()=>rt,videoPart:()=>je});var x=class extends Error{constructor(t,n,s){super(`runapps: ${t} ${n}: ${s}`);l(this,"statusCode");l(this,"type");this.name="APIError",this.statusCode=t,this.type=n}};var G=class{constructor(e){l(this,"baseURL");l(this,"apiKey");l(this,"apiKeyResolver");l(this,"onUnauthorized");l(this,"fetchImpl");if(!e.apiKey&&!e.apiKeyResolver)throw new Error("RunApps: pass either `apiKey` or `apiKeyResolver` when constructing the client");this.baseURL=e.baseURL.replace(/\/+$/,""),this.apiKey=e.apiKey,this.apiKeyResolver=e.apiKeyResolver,this.onUnauthorized=e.onUnauthorized,this.fetchImpl=e.fetchImpl??fetch.bind(globalThis)}async resolveToken(){return this.apiKeyResolver?await this.apiKeyResolver():this.apiKey??""}async fetchWithAuthRetry(e,t){let n=this.baseURL+e,s=await this.fetchImpl(n,await this.buildInit(t));if(s.status!==401||!this.onUnauthorized)return s;try{await this.onUnauthorized()}catch{return s}return s=await this.fetchImpl(n,await this.buildInit(t)),s}async buildInit(e){let t=await e();return t.cache?t:{...t,cache:"no-store"}}async postJSON(e,t,n){let s=await this.fetchWithAuthRetry(e,async()=>({method:"POST",headers:await this.jsonHeaders(),body:JSON.stringify(t),signal:n?.signal}));if(!s.ok)throw await this.parseError(s);return await s.json()}async getJSON(e,t){let n=await this.fetchWithAuthRetry(e,async()=>({method:"GET",headers:await this.authHeaders(),signal:t?.signal}));if(!n.ok)throw await this.parseError(n);return await n.json()}async getRaw(e,t){let n=await this.fetchWithAuthRetry(e,async()=>({method:"GET",headers:await this.authHeaders(),signal:t?.signal}));if(!n.ok)throw await this.parseError(n);let s=new Uint8Array(await n.arrayBuffer()),i=n.headers.get("content-type")??"",o=(n.headers.get("etag")??"").replace(/"/g,"")||void 0;return{data:s,contentType:i,etag:o}}async postMultipart(e,t,n){let s=await this.fetchWithAuthRetry(e,async()=>({method:"POST",headers:await this.authHeaders(),body:t,signal:n?.signal}));if(!s.ok)throw await this.parseError(s);return await s.json()}async postJSONStream(e,t,n){let s=await this.fetchWithAuthRetry(e,async()=>({method:"POST",headers:{...await this.jsonHeaders(),"Accept-Encoding":"identity"},body:JSON.stringify(t),signal:n?.signal}));if(!s.ok)throw await this.parseError(s);return s}async putBytes(e,t,n){let s=await this.fetchWithAuthRetry(e,async()=>{let i={...await this.authHeaders(),"Content-Type":n?.contentType??"application/octet-stream"};return n?.headers&&Object.assign(i,n.headers),{method:"PUT",headers:i,body:t,signal:n?.signal}});if(!s.ok)throw await this.parseError(s);if(n?.parse!=="none")return await s.json()}async deletePath(e,t){let n=await this.fetchWithAuthRetry(e,async()=>({method:"DELETE",headers:await this.authHeaders(),signal:t?.signal}));if(!n.ok)throw await this.parseError(n);if(t?.parse!=="none")return await n.json()}async head(e,t){let n=await this.fetchWithAuthRetry(e,async()=>({method:"HEAD",headers:await this.authHeaders(),signal:t?.signal}));return{status:n.status,headers:n.headers}}async jsonHeaders(){return{"Content-Type":"application/json",Authorization:`Bearer ${await this.resolveToken()}`}}async authHeaders(){return{Authorization:`Bearer ${await this.resolveToken()}`}}async parseError(e){let t=await e.text(),n="error",s=t||e.statusText;try{let i=JSON.parse(t);i.type&&(n=i.type),i.message&&(s=i.message)}catch{}return new x(e.status,n,s)}};var k=class{constructor(){l(this,"handlers",new Map)}on(e,t){let n=this.handlers.get(e);n||(n=new Set,this.handlers.set(e,n));let s=t;return n.add(s),()=>{this.handlers.get(e)?.delete(s)}}emit(e,t){let n=this.handlers.get(e);if(!(!n||n.size===0))for(let s of n)try{s(t)}catch(i){console.error("[runapps sdk] event listener for",e,"threw:",i)}}clear(){this.handlers.clear()}};function D(){return"req_"+Date.now().toString(36)+"_"+Math.random().toString(36).slice(2,8)}async function h(r,e,t,n){let s=D(),i=Date.now();r.emit("request:start",{id:s,model:e.model,capability:e.capability,startedAt:i,streaming:!1});try{let o=await t(),a=n?n(o):{};return r.emit("request:end",{id:s,model:e.model,capability:e.capability,latencyMs:Date.now()-i,totalTokens:a.totalTokens??0,...a.costUSD!==void 0&&{costUSD:a.costUSD},...a.finishReason!==void 0&&{finishReason:a.finishReason}}),o}catch(o){let a=o;throw r.emit("request:error",{id:s,model:e.model,capability:e.capability,latencyMs:Date.now()-i,error:a,...typeof a.statusCode=="number"&&{statusCode:a.statusCode}}),o}}function mt(r){return r?Math.max(1,Math.round(r.length/4)):0}async function*ke(r,e,t,n){let s=D(),i=Date.now();r.emit("request:start",{id:s,model:e.model,capability:e.capability,startedAt:i,streaming:!0});let o=0,a,u,c;try{for await(let d of t()){let g=n(d);if(g.deltaText){let b=mt(g.deltaText);o+=b,r.emit("request:streamDelta",{id:s,deltaTokens:b,totalTokens:o})}g.completionTokens!==void 0&&(a=g.completionTokens),g.costUSD!==void 0&&(u=g.costUSD),g.finishReason!==void 0&&(c=g.finishReason),yield d}r.emit("request:end",{id:s,model:e.model,capability:e.capability,latencyMs:Date.now()-i,totalTokens:a??o,...u!==void 0&&{costUSD:u},...c!==void 0&&{finishReason:c}})}catch(d){let g=d;throw r.emit("request:error",{id:s,model:e.model,capability:e.capability,latencyMs:Date.now()-i,error:g,...typeof g.statusCode=="number"&&{statusCode:g.statusCode}}),d}}var Ce={WebSearch:"web_search",WebFetch:"web_fetch",TwitterSearch:"twitter_search"},Ee=r=>({role:"user",content:r}),Ae=r=>({role:"system",content:r}),Te=r=>({role:"assistant",content:r}),Re=(r,e)=>({role:"tool",tool_call_id:r,content:e}),Pe=(...r)=>({role:"user",content:r}),Ie=r=>({type:"text",text:r}),Me=(r,e)=>({type:"image_url",image_url:e?{url:r,detail:e}:{url:r}}),je=r=>({type:"video_url",video_url:{url:r}}),Ue=r=>({type:"audio_url",audio_url:{url:r}}),V=class{constructor(e,t){l(this,"transport",e);l(this,"events",t)}async create(e,t){let n={...e,stream:!1};return h(this.events,{model:e.model,capability:"text"},()=>this.transport.postJSON("/v1/chat/completions",n,t),s=>({totalTokens:s.usage?.completion_tokens,costUSD:s.usage?.total_cost,finishReason:s.choices?.[0]?.finish_reason}))}async*stream(e,t){let n={...e,stream:!0,stream_options:e.stream_options??{include_usage:!0}},s=async function*(){let i=await this.transport.postJSONStream("/v1/chat/completions",n,t);if(!i.body)throw new Error("runapps: streaming response had no body");yield*ht(i.body)}.bind(this);yield*ke(this.events,{model:e.model,capability:"text"},s,i=>({deltaText:i.choices?.[0]?.delta?.content??"",completionTokens:i.usage?.completion_tokens,costUSD:i.usage?.total_cost,finishReason:i.choices?.[0]?.finish_reason??void 0}))}};async function*ht(r){let e=new TextDecoder,t=r.getReader(),n="";try{for(;;){let{value:s,done:i}=await t.read();if(i)break;n+=e.decode(s,{stream:!0});let o;for(;(o=n.indexOf(`
|
|
2
|
+
`))!==-1;){let a=n.slice(0,o).replace(/\r$/,"");if(n=n.slice(o+1),!a.startsWith("data: "))continue;let u=a.slice(6).trim();if(u==="[DONE]")return;if(!u)continue;let c;try{c=JSON.parse(u)}catch(g){throw new Error(`runapps: decode stream chunk: ${g.message}`)}let d=c.error;if(d)throw new x(d.code??0,d.type??"upstream_error",d.message??u);yield c}}}finally{t.releaseLock()}}var Oe=(r,e)=>Array.isArray(r.capability_tags)&&r.capability_tags.some(t=>t.id===e),De=(r,e)=>Array.isArray(r.input_modalities)&&r.input_modalities.includes(e);function Be(r,e){let t=r.options?.[e];return typeof t=="boolean"?t:typeof t=="number"?t!==0:!1}var Fe=r=>Be(r,"supports_voice_clone"),$e=r=>Be(r,"supports_instruct_text"),Le=r=>{let e=r.options?.default_voice;return typeof e=="string"?e:null},z=class{constructor(e){l(this,"transport",e)}async list(e={},t){let n="/v1/models";return e.capability&&(n+=`?capability=${encodeURIComponent(e.capability)}`),(await this.transport.getJSON(n,t)).data}};var W=class{constructor(e,t){l(this,"transport",e);l(this,"events",t)}async generate(e,t,n){return h(this.events,{model:e,capability:"image_generation"},()=>this.transport.postJSON("/v1/images/generations",{model:e,...t},n),s=>({costUSD:s.usage?.total_cost}))}async generateAsync(e,t,n){let s=n?.pollIntervalMs??2e3,i=n?.signal;return h(this.events,{model:e,capability:"image_generation"},async()=>{let a=await this.transport.postJSON("/v1/async/images/generations",{model:e,...t},{signal:i});for(;a.status!=="succeeded"&&a.status!=="failed";)await ft(s,i),a=await this.getAsyncStatus(a.id,{signal:i});if(a.status==="failed")throw new Error(a.error??"image generation failed");return{created:a.created_at??Math.floor(Date.now()/1e3),data:a.data??[],usage:a.usage??{total_cost:0}}},o=>({costUSD:o.usage?.total_cost}))}async submitGenerate(e,t,n){return h(this.events,{model:e,capability:"image_generation"},()=>this.transport.postJSON("/v1/async/images/generations",{model:e,...t},n))}async getAsyncStatus(e,t){return this.transport.getJSON(`/v1/async/images/generations/${encodeURIComponent(e)}`,t)}async edit(e,t,n){let s=bt(e,t);return h(this.events,{model:e,capability:"image_edit"},()=>this.transport.postMultipart("/v1/images/edits",s,n),i=>({costUSD:i.usage?.total_cost}))}};function ft(r,e){return new Promise((t,n)=>{if(e?.aborted){n(e.reason??new Error("aborted"));return}let s=setTimeout(()=>{e?.removeEventListener("abort",i),t()},r),i=()=>{clearTimeout(s),n(e.reason??new Error("aborted"))};e?.addEventListener("abort",i,{once:!0})})}function bt(r,e){let t=new FormData;return t.set("model",r),t.set("prompt",e.prompt),e.size&&t.set("size",e.size),e.n!==void 0&&t.set("n",String(e.n)),e.user&&t.set("user",e.user),t.set("image",Ke(e.image),e.image.filename),e.mask&&t.set("mask",Ke(e.mask),e.mask.filename),t}function Ke(r){let e=r.contentType??yt(r.filename);return r.data instanceof Blob?r.data.type===e?r.data:new Blob([r.data],{type:e}):typeof r.data=="string"?new Blob([r.data],{type:e}):new Blob([r.data],{type:e})}function yt(r){switch(r.toLowerCase().split(".").pop()??""){case"png":return"image/png";case"jpg":case"jpeg":return"image/jpeg";case"webp":return"image/webp";case"gif":return"image/gif";default:return"application/octet-stream"}}function Ne(r){if(r instanceof Blob)throw new Error("encodeImageUrl: Blob input requires async; await blob.arrayBuffer() and pass the result instead");let e=r instanceof Uint8Array?r:new Uint8Array(r),t=vt(e),n=32768,s="";for(let o=0;o<e.length;o+=n)s+=String.fromCharCode.apply(null,Array.from(e.subarray(o,o+n)));let i=globalThis.btoa?globalThis.btoa(s):Buffer.from(s,"binary").toString("base64");return`data:${t};base64,${i}`}async function B(r){if(r.startsWith("data:")){let e=r.slice(5),t=e.indexOf(";"),n=e.indexOf(",");if(t===-1||n===-1||n<t)throw new Error("decodeMediaUrl: malformed data URI");let s=e.slice(0,t),i=e.slice(n+1);return{bytes:wt(i),contentType:s}}if(r.startsWith("http://")||r.startsWith("https://")){let e=await fetch(r);if(!e.ok)throw new Error(`decodeMediaUrl: upstream ${e.status}`);let t=await e.arrayBuffer();return{bytes:new Uint8Array(t),contentType:e.headers.get("Content-Type")??""}}throw new Error(`decodeMediaUrl: unsupported url scheme: ${r.slice(0,32)}`)}function wt(r){if(typeof Buffer<"u")return new Uint8Array(Buffer.from(r,"base64"));let e=atob(r),t=new Uint8Array(e.length);for(let n=0;n<e.length;n++)t[n]=e.charCodeAt(n);return t}function vt(r){return r.length>=8&&r[0]===137&&r[1]===80&&r[2]===78&&r[3]===71?"image/png":r.length>=3&&r[0]===255&&r[1]===216&&r[2]===255?"image/jpeg":r.length>=6&&r[0]===71&&r[1]===73&&r[2]===70&&r[3]===56?"image/gif":r.length>=12&&r[0]===82&&r[1]===73&&r[2]===70&&r[3]===70&&r[8]===87&&r[9]===69&&r[10]===66&&r[11]===80?"image/webp":"application/octet-stream"}var X=class{constructor(e,t){l(this,"transport",e);l(this,"events",t)}async speech(e,t,n){return h(this.events,{model:e,capability:"text_to_speech"},async()=>{let s=await this.transport.postJSON("/v1/audio/speech",qe(e,t),n),{bytes:i,contentType:o}=await B(s.audio_url);return{data:i,contentType:o,usage:s.usage}},s=>({costUSD:s.usage?.total_cost}))}async speechAsync(e,t,n){return h(this.events,{model:e,capability:"text_to_speech"},async()=>{let s=await this.transport.postJSON("/v1/async/audio/speech",qe(e,t),n);if(!s.id)throw new Error("runapps: speech submit response missing job id");return xt(this.transport,s.id,n)},s=>({costUSD:s.usage?.total_cost}))}async transcribe(e,t,n){let s=He(e,t);return h(this.events,{model:e,capability:"speech_to_text"},()=>this.transport.postMultipart("/v1/audio/transcriptions",s,n),i=>({costUSD:i.usage?.total_cost}))}async transcribeAsync(e,t,n){return h(this.events,{model:e,capability:"speech_to_text"},async()=>{let s=He(e,t),i=await this.transport.postMultipart("/v1/async/audio/transcriptions",s,n);if(!i.id)throw new Error("runapps: transcribe submit response missing job id");return St(this.transport,i.id,n)},s=>({costUSD:s.usage?.total_cost}))}};async function xt(r,e,t){let n=`/v1/async/audio/speech/${encodeURIComponent(e)}`,s=t?.pollIntervalMs??3e3;await Y(2e3,t?.signal);let o=Date.now()+600*1e3;for(;;){if(t?.signal?.aborted)throw new DOMException("speech poll aborted","AbortError");if(!t?.signal&&Date.now()>o)throw new Error("runapps: speech job timed out (10 min internal cap)");let a=await r.getJSON(n,t);if(a.status==="succeeded"){if(!a.audio_url)throw new Error("runapps: speech job succeeded but no audio_url returned");let{bytes:u,contentType:c}=await B(a.audio_url);return{data:u,contentType:c,usage:a.usage??{total_cost:0}}}if(a.status==="failed")throw new Error(a.error||"runapps: speech job failed");await Y(s,t?.signal)}}async function St(r,e,t){let n=`/v1/async/audio/transcriptions/${encodeURIComponent(e)}`,s=t?.pollIntervalMs??3e3;await Y(2e3,t?.signal);let i=Date.now()+600*1e3;for(;;){if(t?.signal?.aborted)throw new DOMException("transcribe poll aborted","AbortError");if(!t?.signal&&Date.now()>i)throw new Error("runapps: transcribe job timed out (10 min internal cap)");let o=await r.getJSON(n,t);switch(o.status){case"succeeded":return _t(o);case"failed":throw new Error(o.error||"runapps: transcribe job failed");case"queued":case"running":await Y(s,t?.signal);break;default:throw new Error(`runapps: unknown transcribe job status ${JSON.stringify(o.status)}`)}}}function _t(r){let e={text:r.text??"",usage:r.usage??{total_cost:0}},t={};for(let[n,s]of Object.entries(r))n==="text"||n==="usage"||n==="id"||n==="status"||(t[n]=s);return Object.keys(t).length>0&&(e.raw=t),e}function Y(r,e){return new Promise((t,n)=>{if(e?.aborted){n(new DOMException("aborted","AbortError"));return}let s=setTimeout(()=>{e?.removeEventListener("abort",i),t()},r),i=()=>{clearTimeout(s),n(new DOMException("aborted","AbortError"))};e?.addEventListener("abort",i,{once:!0})})}function qe(r,e){let{extra:t,...n}=e,s={model:r,...n};if(t)for(let[i,o]of Object.entries(t))i in s||(s[i]=o);return s}function He(r,e){let t=new FormData;if(t.set("model",r),e.language&&t.set("language",e.language),e.prompt&&t.set("prompt",e.prompt),e.response_format&&t.set("response_format",e.response_format),e.timestamp_granularities)for(let i of e.timestamp_granularities)t.append("timestamp_granularities[]",i);e.user&&t.set("user",e.user);let n=e.file.contentType??kt(e.file.filename),s=e.file.data instanceof Blob?e.file.data:new Blob([e.file.data],{type:n});return t.set("file",s,e.file.filename),t}function kt(r){switch(r.toLowerCase().split(".").pop()??""){case"mp3":return"audio/mpeg";case"wav":return"audio/wav";case"m4a":return"audio/mp4";case"flac":return"audio/flac";case"ogg":return"audio/ogg";case"webm":return"audio/webm";default:return"application/octet-stream"}}var Q=class{constructor(e,t){l(this,"transport",e);l(this,"events",t)}async generate(e,t,n){return h(this.events,{model:e,capability:"video_generation"},()=>this.transport.postJSON("/v1/videos/generations",{model:e,...t},n))}async getStatus(e,t){return this.transport.getJSON(`/v1/videos/generations/${encodeURIComponent(e)}`,t)}async wait(e,t={}){let n=t.pollIntervalMs??5e3;for(;;){let s=await this.getStatus(e,{signal:t.signal});if(s.status==="succeeded"||s.status==="failed")return s;await Ct(n,t.signal)}}async getContent(e,t){return this.transport.getRaw(`/v1/videos/${encodeURIComponent(e)}/content`,t)}};function Ct(r,e){return new Promise((t,n)=>{if(e?.aborted){n(e.reason??new Error("aborted"));return}let s=setTimeout(()=>{e?.removeEventListener("abort",i),t()},r),i=()=>{clearTimeout(s),n(e.reason??new Error("aborted"))};e?.addEventListener("abort",i,{once:!0})})}var Z=class{constructor(e,t){l(this,"transport",e);l(this,"events",t)}async step(e,t,n){return h(this.events,{model:e,capability:"computer_use"},()=>this.transport.postJSON("/v1/computer/step",{model:e,...t},n),s=>({totalTokens:s.usage?.completion_tokens,costUSD:s.usage?.total_cost}))}};function F(r,e){let t=e.replace(/^\/+/,"");return r+"/"+t.split("/").map(encodeURIComponent).join("/")}var ee=class{constructor(e,t){l(this,"transport",e);l(this,"base");this.base=t?"/v1/p/"+encodeURIComponent(t)+"/files":"/v1/files"}async put(e,t,n){let s={};return n?.ifNoneMatch&&(s["If-None-Match"]="*"),n?.ifMatch&&(s["If-Match"]=`"${n.ifMatch.replace(/"/g,"")}"`),this.transport.putBytes(F(this.base,e),t,{contentType:n?.contentType,headers:Object.keys(s).length?s:void 0,signal:n?.signal})}async putString(e,t,n){return this.put(e,t,{...n,contentType:n?.contentType??"text/plain; charset=utf-8"})}async get(e,t){return(await this.read(e,t)).blob}async read(e,t){let{data:n,contentType:s,etag:i}=await this.transport.getRaw(F(this.base,e),t);return{blob:new Blob([new Uint8Array(n)],{type:s||"application/octet-stream"}),contentType:s,etag:i}}async readJSON(e,t){let n;try{n=await this.read(e,t)}catch(s){if(s?.statusCode===404||s?.status===404)return{value:void 0,etag:void 0};throw s}return{value:JSON.parse(await n.blob.text()),etag:n.etag}}async stat(e,t){let{status:n,headers:s}=await this.transport.head(F(this.base,e),t);if(n===404)throw Object.assign(new Error("not found"),{status:404});if(n>=400)throw Object.assign(new Error("stat failed"),{status:n});let i=parseInt(s.get("content-length")??"0",10);return{path:s.get("x-file-path")??e,size:i,content_type:s.get("content-type")??void 0,etag:(s.get("etag")??"").replace(/"/g,"")||void 0,url:s.get("x-file-url")??""}}async exists(e,t){let{status:n}=await this.transport.head(F(this.base,e),t);return n>=200&&n<400}async del(e,t){await this.transport.deletePath(F(this.base,e),t)}async list(e){let t=new URLSearchParams;e?.prefix&&t.set("prefix",e.prefix),e?.cursor&&t.set("cursor",e.cursor),e?.limit&&t.set("limit",String(e.limit)),e?.glob&&t.set("glob",e.glob);let n=t.toString();return this.transport.getJSON(this.base+(n?"?"+n:""),e?.signal?{signal:e.signal}:void 0)}async deleteMany(e,t){return this.transport.postJSON(this.base+"/delete",{prefix:e.prefix??"",glob:e.glob??""},t)}async move(e,t,n){return this.transport.postJSON(this.base+"/move",{from:e,to:t},n)}async copy(e,t,n){return this.transport.postJSON(this.base+"/copy",{from:e,to:t},n)}async putFromURL(e,t,n){return this.transport.postJSON(this.base+"/put-url",{path:e,src_url:t,content_type:n?.contentType,if_none_match:n?.ifNoneMatch,if_match:n?.ifMatch},n?.signal?{signal:n.signal}:void 0)}async batch(e,t){if(e.length===0)return[];let n=30;if(e.length<=n)return(await this.transport.postJSON(this.base+"/batch",{ops:e},t)).results;let s=[];for(let i=0;i<e.length;i+=n){let o=e.slice(i,i+n),a=await this.transport.postJSON(this.base+"/batch",{ops:o},t);s.push(...a.results)}return s}};var te=class{constructor(e,t){l(this,"transport",e);l(this,"events",t)}async create(e,t,n){return h(this.events,{model:e,capability:"embedding"},()=>this.transport.postJSON("/v1/embeddings",{model:e,...t},n),s=>({totalTokens:s.usage?.total_tokens,costUSD:s.usage?.total_cost}))}};var C=class{constructor(){l(this,"active",new Map);l(this,"recent",[]);l(this,"session",{totalCalls:0,totalCostUSD:0,errorCount:0,startedAt:Date.now()});l(this,"lastErrorAt",0);l(this,"changeListeners",new Set)}attach(e){let t=[e.on("request:start",n=>{this.onStart(n),this.notify()}),e.on("request:streamDelta",n=>{this.onDelta(n),this.notify()}),e.on("request:end",n=>{this.onEnd(n),this.notify()}),e.on("request:error",n=>{this.onError(n),this.notify()})];return()=>{for(let n of t)n()}}onChange(e){return this.changeListeners.add(e),()=>this.changeListeners.delete(e)}notify(){for(let e of this.changeListeners)try{e()}catch(t){console.error("[runjobs sdk] ActivityTracker onChange listener threw:",t)}}snapshot(){let e=Date.now();return{active:Array.from(this.active.values()),recent:this.recent.slice(),session:{...this.session},status:e-this.lastErrorAt<3e4?"error":this.active.size>0?"active":"idle"}}onStart(e){this.active.set(e.id,{id:e.id,model:e.model,capability:e.capability,startedAt:e.startedAt,streaming:e.streaming,tokensSoFar:0,tokensPerSec:0,rateSamples:[]})}onDelta(e){let t=this.active.get(e.id);if(!t)return;t.tokensSoFar=e.totalTokens;let n=Date.now();t.rateSamples.push({t:n,tokens:e.deltaTokens});let s=n-1500;for(;t.rateSamples.length>0&&t.rateSamples[0].t<s;)t.rateSamples.shift();if(t.rateSamples.length>=2){let i=t.rateSamples.reduce((a,u)=>a+u.tokens,0),o=n-t.rateSamples[0].t;t.tokensPerSec=o>0?i*1e3/o:0}}onEnd(e){let t=this.active.get(e.id);this.active.delete(e.id),this.pushRecent({id:e.id,model:e.model,capability:e.capability,latencyMs:e.latencyMs,totalTokens:e.totalTokens||t?.tokensSoFar||0,...e.costUSD!==void 0&&{costUSD:e.costUSD},...e.finishReason!==void 0&&{finishReason:e.finishReason},ok:!0,endedAt:Date.now()}),this.session.totalCalls+=1,e.costUSD!==void 0&&(this.session.totalCostUSD+=e.costUSD)}onError(e){let t=this.active.get(e.id);this.active.delete(e.id),this.pushRecent({id:e.id,model:e.model,capability:e.capability,latencyMs:e.latencyMs,totalTokens:t?.tokensSoFar||0,ok:!1,errorMessage:e.error.message,endedAt:Date.now()}),this.session.totalCalls+=1,this.session.errorCount+=1,this.lastErrorAt=Date.now()}pushRecent(e){this.recent.unshift(e),this.recent.length>20&&(this.recent.length=20)}};var Je=60,Ge="__runjobs_auth_v1__",Ve="__runjobs_signed_out_v1__";function ne(r){return r?`${Ge}:${r}`:Ge}function re(r){return r?`${Ve}:${r}`:Ve}var A=class{constructor(e={}){l(this,"origin");l(this,"hideBadge");l(this,"project");l(this,"events");l(this,"tracker");l(this,"badgePosition");l(this,"token",null);l(this,"expiresAt",0);l(this,"userInfo",null);l(this,"listeners",[]);l(this,"parentHandshake",null);l(this,"signingIn",!1);l(this,"getToken",async()=>{if(this.tokenIsFresh())return this.token;if(this.isSignedOut())throw new Error("RunApps: signed out \u2014 call client.signIn() to authenticate");if(this.inIframe()){try{this.parentHandshake&&(await this.parentHandshake,this.parentHandshake=null),this.tokenIsFresh()||await this.requestTokenFromParent()}catch{}if(this.tokenIsFresh())return this.token;throw new Error("RunApps: could not obtain a token from the dashboard")}return this.parentHandshake&&(await this.parentHandshake,this.tokenIsFresh())?this.token:(this.signIn(),new Promise(()=>{}))});this.origin=(e.origin??"https://www.runapps.ai").replace(/\/$/,""),this.hideBadge=!!e.hideBadge,this.project=e.project??null,this.events=e.events??null,this.badgePosition=e.badgePosition??"bottom-right",this.events&&!this.hideBadge?(this.tracker=new C,this.tracker.attach(this.events)):this.tracker=null,!(typeof window>"u")&&(this.loadPersisted(),this.consumeFragment()&&this.clearSignedOut(),this.isSignedOut()||(this.inIframe()&&!this.tokenIsFresh()?this.parentHandshake=this.requestTokenFromParent().catch(()=>{}):this.tokenIsFresh()&&this.userInfo&&!this.hideBadge&&this.renderBadge()))}onTokenChange(e){return this.listeners.push(e),()=>{let t=this.listeners.indexOf(e);t>=0&&this.listeners.splice(t,1)}}get user(){return this.userInfo}hasFreshToken(){return this.tokenIsFresh()}signOut(){this.token=null,this.expiresAt=0,this.userInfo=null,this.parentHandshake=null,this.signingIn=!1,this.clearPersisted(),this.markSignedOut(),this.removeBadge()}invalidate(){this.token=null,this.expiresAt=0,this.userInfo=null,this.parentHandshake=null,this.signingIn=!1,this.clearPersisted()}signIn(){if(typeof window>"u"||this.signingIn)return;this.clearSignedOut(),this.signingIn=!0;let e=location.href.split("#")[0]??location.href,t=window.matchMedia?.("(prefers-color-scheme: dark)").matches?"dark":"light";location.href=this.buildGrantUrl({pageOrigin:location.origin,app:location.host,redirectTo:e,scheme:t})}_buildGrantUrlForTest(e){return this.buildGrantUrl(e)}_storageKeysForTest(){return{auth:ne(this.project),signedOut:re(this.project)}}buildGrantUrl(e){let t=new URLSearchParams;return t.set("origin",e.pageOrigin),t.set("app",e.app),t.set("redirect_to",e.redirectTo),t.set("scheme",e.scheme),this.project&&t.set("project_id",this.project),this.origin+"/api/sdk/grant?"+t.toString()}nowSec(){return Math.floor(Date.now()/1e3)}tokenIsFresh(){return!!this.token&&this.nowSec()<this.expiresAt-Je}inIframe(){try{return window.self!==window.top}catch{return!0}}setToken(e,t,n){this.token=e,this.expiresAt=t||this.nowSec()+3600,n&&(this.userInfo=n,this.hideBadge||this.renderBadge()),this.savePersisted();for(let s of this.listeners)try{s(e)}catch(i){console.warn("[runapps] onTokenChange handler threw",i)}}savePersisted(){if(!(typeof localStorage>"u"||!this.token))try{let e={token:this.token,expiresAt:this.expiresAt,origin:this.origin,...this.userInfo?{user:this.userInfo}:{}};localStorage.setItem(ne(this.project),JSON.stringify(e))}catch{}}loadPersisted(){if(!(typeof localStorage>"u"))try{let e=localStorage.getItem(ne(this.project));if(!e)return;let t=JSON.parse(e);if(!t.token||!t.origin||t.origin!==this.origin)return;if(typeof t.expiresAt=="number"&&t.expiresAt>0&&this.nowSec()>=t.expiresAt-Je){this.clearPersisted();return}this.token=t.token,this.expiresAt=t.expiresAt??0,t.user&&(this.userInfo=t.user)}catch{this.clearPersisted()}}clearPersisted(){if(!(typeof localStorage>"u"))try{localStorage.removeItem(ne(this.project))}catch{}}isSignedOut(){if(typeof localStorage>"u")return!1;try{return localStorage.getItem(re(this.project))==="1"}catch{return!1}}markSignedOut(){if(!(typeof localStorage>"u"))try{localStorage.setItem(re(this.project),"1")}catch{}}clearSignedOut(){if(!(typeof localStorage>"u"))try{localStorage.removeItem(re(this.project))}catch{}}removeBadge(){typeof document>"u"||document.getElementById("__runjobs_identity__")?.remove()}consumeFragment(){if(!location.hash||location.hash.indexOf("runjobs_token=")<0)return!1;let e={};if(location.hash.replace(/^#/,"").split("&").forEach(n=>{let s=n.indexOf("=");s>=0&&(e[decodeURIComponent(n.slice(0,s))]=decodeURIComponent(n.slice(s+1)))}),!e.runjobs_token)return!1;let t;if(e.user)try{t=JSON.parse(e.user)}catch{}this.setToken(e.runjobs_token,parseInt(e.expires_at??"",10)||0,t);try{history.replaceState(null,"",location.pathname+location.search)}catch{}return!0}requestTokenFromParent(){return new Promise((e,t)=>{let n=!1,s=[],i=()=>{n=!0,window.removeEventListener("message",o);for(let u of s)clearTimeout(u)},o=u=>{if(u.origin!==this.origin)return;let c=u.data;c&&c.type==="runjobs:token"&&c.token&&(this.setToken(c.token,c.expires_at??0,c.user),i(),e())};window.addEventListener("message",o);let a=()=>{if(!n)try{window.parent.postMessage({type:"runjobs:request-token"},this.origin)}catch(u){i(),t(u)}};a();for(let u of[250,750,1500,3e3])s.push(setTimeout(a,u));s.push(setTimeout(()=>{n||(i(),t(new Error("runapps: parent handshake timeout")))},5e3))})}renderBadge(){if(typeof document>"u"||!this.userInfo)return;let e="__runjobs_identity__",t=`${this.origin}/dashboard`;(s=>document.body?s():document.addEventListener("DOMContentLoaded",s))(()=>{document.getElementById(e)?.remove();let s=It({id:e,user:this.userInfo,dashboardUrl:t,tracker:this.tracker,position:this.badgePosition,onSignOut:()=>{this.signOut(),typeof window<"u"&&window.location.reload()}});document.body.appendChild(s)})}};function Et(){if(typeof document>"u"||document.getElementById("__runjobs_kf__"))return;let r=document.createElement("style");r.id="__runjobs_kf__",r.textContent="@keyframes __runjobs_led_pulse__ { 0% { box-shadow: 0 0 0 0 rgba(59,130,246,0.7); } 70% { box-shadow: 0 0 0 6px rgba(59,130,246,0); } 100% { box-shadow: 0 0 0 0 rgba(59,130,246,0); }}",(document.head??document.documentElement).appendChild(r)}function At(r){let e=r.startsWith("top")?"top":"bottom",t=r.endsWith("right")?"right":"left",n=e==="bottom"?"bottom:calc(100% + 8px);top:auto":"top:calc(100% + 8px);bottom:auto",s=t==="right"?"right:0;left:auto":"left:0;right:auto";return{badge:`${e}:16px;${t}:16px`,popover:`${n};${s}`}}var de="__runjobs_badge_pos__",ze=5,E=8;function Tt(){if(typeof document>"u")return null;let r=document.cookie.split(";").map(a=>a.trim()).find(a=>a.startsWith(de+"="));if(!r)return null;let t=decodeURIComponent(r.slice(de.length+1)).split(","),n=t[0],s=t[1];if(t.length!==2||n===void 0||s===void 0)return null;let i=Number.parseInt(n,10),o=Number.parseInt(s,10);return!Number.isFinite(i)||!Number.isFinite(o)?null:{x:i,y:o}}function Rt(r,e){if(typeof document>"u")return;let t=3600*24*365,n=typeof window<"u"&&window.location?.protocol==="https:"?";Secure":"";document.cookie=`${de}=${encodeURIComponent(`${Math.round(r)},${Math.round(e)}`)};path=/;max-age=${t};SameSite=Lax${n}`}function We(r,e,t,n){let s=typeof window<"u"?window.innerWidth:1024,i=typeof window<"u"?window.innerHeight:768,o=Math.max(E,s-t-E),a=Math.max(E,i-n-E);return{x:Math.min(Math.max(E,r),o),y:Math.min(Math.max(E,e),a)}}function Pt(r){let e=typeof window<"u"?window.innerWidth:1024,t=typeof window<"u"?window.innerHeight:768,n=r.left+r.width/2,i=r.top+r.height/2<t/2?"top:calc(100% + 8px);bottom:auto":"bottom:calc(100% + 8px);top:auto",o=n<e/2?"left:0;right:auto":"right:0;left:auto";return`${i};${o}`}function It(r){let{id:e,user:t,dashboardUrl:n,tracker:s,position:i,onSignOut:o}=r,a=At(i),u=a.popover;Et();let c=document.createElement("button");c.id=e,c.type="button",c.title="RunApps activity",c.setAttribute("aria-label","RunApps activity status"),c.style.cssText=["position:fixed",a.badge,"z-index:2147483647","display:flex","align-items:center","gap:8px","padding:6px 12px 6px 6px","border-radius:999px","font:500 12px/1 -apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif","color:#fff","background:rgba(15,15,20,0.55)","backdrop-filter:blur(10px) saturate(1.2)","-webkit-backdrop-filter:blur(10px) saturate(1.2)","border:1px solid rgba(255,255,255,0.12)","box-shadow:0 4px 16px rgba(0,0,0,0.15)","user-select:none","max-width:220px","overflow:visible","cursor:pointer","appearance:none","-webkit-appearance:none","transition:background-color 120ms ease-out, box-shadow 120ms ease-out"].join(";"),c.addEventListener("mouseenter",()=>{c.style.backgroundColor="rgba(30,30,40,0.7)",c.style.boxShadow="0 6px 20px rgba(0,0,0,0.22)"}),c.addEventListener("mouseleave",()=>{c.style.backgroundColor="rgba(15,15,20,0.55)",c.style.boxShadow="0 4px 16px rgba(0,0,0,0.15)"});let d=document.createElement("span");d.style.cssText=["position:relative","width:26px;height:26px","flex-shrink:0","display:inline-flex;align-items:center;justify-content:center"].join(";");let g="http://www.w3.org/2000/svg",b=document.createElementNS(g,"svg");b.setAttribute("viewBox","0 0 26 26"),b.setAttribute("width","26"),b.setAttribute("height","26"),b.style.cssText=["position:absolute;inset:0","pointer-events:none","opacity:0","transition:opacity 200ms ease-out"].join(";");let S=document.createElementNS(g,"circle");S.setAttribute("cx","13"),S.setAttribute("cy","13"),S.setAttribute("r","12"),S.setAttribute("fill","none"),S.setAttribute("stroke","rgba(255,255,255,0.08)"),S.setAttribute("stroke-width","1.5");let y=document.createElementNS(g,"circle");y.setAttribute("cx","13"),y.setAttribute("cy","13"),y.setAttribute("r","12"),y.setAttribute("fill","none"),y.setAttribute("stroke","#3b82f6"),y.setAttribute("stroke-width","2"),y.setAttribute("stroke-linecap","round"),y.setAttribute("transform","rotate(-90 13 13)");let ie=2*Math.PI*12;y.setAttribute("stroke-dasharray",String(ie)),y.setAttribute("stroke-dashoffset",String(ie)),b.appendChild(S),b.appendChild(y);let oe=document.createElement("div");oe.textContent=(t.name||"?").charAt(0).toUpperCase(),oe.style.cssText=["width:22px;height:22px;border-radius:50%;flex-shrink:0","display:flex;align-items:center;justify-content:center","background:linear-gradient(135deg,#3b82f6,#8b5cf6)","font-size:11px;font-weight:600;color:#fff","position:relative"].join(";");let L=document.createElement("span");L.style.cssText=["position:absolute","bottom:-2px;right:-2px","width:8px;height:8px;border-radius:50%","background:rgba(255,255,255,0.2)","border:2px solid rgba(15,15,20,1)","box-shadow:0 0 0 0 transparent","transition:background-color 150ms ease-out, box-shadow 200ms ease-out","pointer-events:none"].join(";"),d.appendChild(b),d.appendChild(oe),d.appendChild(L);let ae=document.createElement("span");ae.textContent=t.name||"Signed in",ae.style.cssText="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;pointer-events:none",c.appendChild(d),c.appendChild(ae);let f=null,w=!1,_=null,K=null,N=null,le=()=>{K!==null&&(window.clearTimeout(K),K=null)},R=()=>{N!==null&&(window.clearTimeout(N),N=null)},me=()=>{R(),N=window.setTimeout(()=>{_==="hover"&&P()},300)},he=p=>{if(le(),R(),w){p==="click"&&(_="click");return}f||(f=Ut(n,u,()=>{P(),o()}),f.addEventListener("mouseenter",R),f.addEventListener("mouseleave",()=>{_==="hover"&&me()})),c.appendChild(f),w=!0,_=p,H()},P=()=>{R(),w&&(f?.remove(),w=!1,_=null)};c.addEventListener("click",p=>{p.stopPropagation(),w?P():he("click")}),c.addEventListener("mouseenter",()=>{R(),le(),K=window.setTimeout(()=>{w||he("hover")},400)}),c.addEventListener("mouseleave",()=>{le(),_==="hover"&&me()}),document.addEventListener("click",p=>{w&&!c.contains(p.target)&&P()});let fe=0,be=0,ye=0,we=0,q=!1,I=!1,ce=!1,ue=(p,m)=>{c.style.left=`${p}px`,c.style.top=`${m}px`,c.style.right="auto",c.style.bottom="auto"},ve=()=>{let p=c.getBoundingClientRect();if(u=Pt({left:p.left,top:p.top,width:p.width,height:p.height}),f){f.style.top="",f.style.bottom="",f.style.left="",f.style.right="";for(let m of u.split(";")){let[U,O]=m.split(":");U&&O&&f.style.setProperty(U.trim(),O.trim())}}};c.addEventListener("pointerdown",p=>{if(p.button!==0)return;q=!0,I=!1,fe=p.clientX,be=p.clientY;let m=c.getBoundingClientRect();ye=m.left,we=m.top}),c.addEventListener("pointermove",p=>{if(!q)return;let m=p.clientX-fe,U=p.clientY-be;if(!I){if(Math.abs(m)<ze&&Math.abs(U)<ze)return;I=!0,c.setPointerCapture(p.pointerId),c.style.cursor="grabbing",w&&P()}let O=c.getBoundingClientRect(),_e=We(ye+m,we+U,O.width,O.height);ue(_e.x,_e.y)});let xe=p=>{if(!q||(q=!1,!I))return;I=!1,c.style.cursor="pointer",c.hasPointerCapture(p.pointerId)&&c.releasePointerCapture(p.pointerId);let m=c.getBoundingClientRect();Rt(m.left,m.top),ve(),ce=!0};c.addEventListener("pointerup",xe),c.addEventListener("pointercancel",xe),c.addEventListener("click",p=>{ce&&(ce=!1,p.stopPropagation(),p.preventDefault())},!0);let M=Tt();M&&(ue(M.x,M.y),requestAnimationFrame(()=>{let p=c.getBoundingClientRect(),m=We(M.x,M.y,p.width,p.height);ue(m.x,m.y),ve()}));let pe=!1,j=null,Se=()=>{if(pe=!1,!s){b.style.opacity="0",L.style.background="rgba(255,255,255,0.2)";return}let p=s.snapshot();Mt(b,y,ie,p),jt(L,p),w&&f&&Ot(f,p);let m=p.status!=="idle"||w;m&&j===null?j=window.setInterval(H,160):!m&&j!==null&&(window.clearInterval(j),j=null)};function H(){pe||(pe=!0,typeof requestAnimationFrame=="function"?requestAnimationFrame(Se):setTimeout(Se,0))}return s&&s.onChange(H),H(),c}function Mt(r,e,t,n){if(n.active.length===0){r.style.opacity="0";return}r.style.opacity="1";let s=n.active.reduce((i,o)=>o.tokensPerSec>i.tokensPerSec?o:i,n.active[0]);if(s.streaming&&s.tokensPerSec>0){let i=Math.min(s.tokensPerSec/60,1);e.setAttribute("stroke-dashoffset",String(t*(1-i))),e.setAttribute("stroke","#3b82f6")}else n.status==="error"?(e.setAttribute("stroke-dashoffset","0"),e.setAttribute("stroke","#ef4444")):(e.setAttribute("stroke-dashoffset",String(t*.75)),e.setAttribute("stroke","#a78bfa"))}function jt(r,e){switch(e.status){case"idle":r.style.background="rgba(255,255,255,0.2)",r.style.boxShadow="0 0 0 0 transparent";break;case"active":r.style.background="#3b82f6",r.style.boxShadow="0 0 0 0 rgba(59,130,246,0.7)",r.style.animation="__runjobs_led_pulse__ 1.2s ease-out infinite";break;case"error":r.style.background="#ef4444",r.style.boxShadow="0 0 0 2px rgba(239,68,68,0.3)",r.style.animation="";break}}function Ut(r,e,t){let n=document.createElement("div");n.style.cssText=["position:absolute",e,"min-width:280px;max-width:340px","padding:10px 12px","border-radius:10px","background:rgba(15,15,20,0.92)","backdrop-filter:blur(20px) saturate(1.3)","-webkit-backdrop-filter:blur(20px) saturate(1.3)","border:1px solid rgba(255,255,255,0.12)","box-shadow:0 10px 30px rgba(0,0,0,0.4)","color:#fff","font:400 11px/1.4 -apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif","cursor:default","text-align:left"].join(";"),n.setAttribute("data-runjobs-popover","1"),n.addEventListener("click",u=>u.stopPropagation());let s=document.createElement("div");s.setAttribute("data-runjobs-popover-content","1"),n.appendChild(s);let i=document.createElement("div");i.style.cssText=["margin-top:10px;padding-top:8px","border-top:1px solid rgba(255,255,255,0.08)","display:flex;justify-content:space-between;align-items:center","font-size:10px;color:rgba(255,255,255,0.6)"].join(";");let o=document.createElement("a");o.textContent="Open dashboard \u2192",o.href=r,o.target="_blank",o.rel="noopener noreferrer",o.style.cssText="color:#a78bfa;text-decoration:none",i.appendChild(o);let a=document.createElement("button");return a.type="button",a.textContent="Sign out",a.style.cssText=["background:none;border:0;padding:0;margin:0","font:inherit;cursor:pointer","color:rgba(255,255,255,0.55)","transition:color 120ms ease"].join(";"),a.addEventListener("mouseenter",()=>{a.style.color="#f87171"}),a.addEventListener("mouseleave",()=>{a.style.color="rgba(255,255,255,0.55)"}),a.addEventListener("click",u=>{u.preventDefault(),u.stopPropagation(),t()}),i.appendChild(a),n.appendChild(i),n}function Ot(r,e){let t=r.querySelector("[data-runjobs-popover-content]");if(!t)return;t.innerHTML="";let n=Date.now();t.appendChild(Dt(e,n)),t.appendChild(Bt(e,n)),t.appendChild(Ft(e.session,n))}function Dt(r,e){let t=document.createElement("div");if(t.style.marginBottom="10px",t.appendChild(ge("Active",r.active.length>0?`${r.active.length} in flight`:"\u2014")),r.active.length===0){let n=document.createElement("div");return n.style.cssText="color:rgba(255,255,255,0.4);font-size:10px;padding:2px 0",n.textContent="No calls in flight.",t.appendChild(n),t}for(let n of r.active){let s=document.createElement("div");s.style.cssText="display:flex;justify-content:space-between;gap:8px;padding:3px 0";let i=document.createElement("span");i.style.cssText="color:#fff;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:180px",i.textContent=n.model;let o=document.createElement("span");o.style.cssText="color:rgba(255,255,255,0.7);font-variant-numeric:tabular-nums;font-size:10px";let a=((e-n.startedAt)/1e3).toFixed(1),u=n.tokensPerSec>0?` \xB7 ${Math.round(n.tokensPerSec)} tok/s`:"";o.textContent=`${a}s${u}`,s.appendChild(i),s.appendChild(o),t.appendChild(s)}return t}function Bt(r,e){let t=document.createElement("div");if(t.style.marginBottom="10px",t.appendChild(ge("Recent",r.recent.length>0?`last ${Math.min(r.recent.length,5)}`:"\u2014")),r.recent.length===0){let n=document.createElement("div");return n.style.cssText="color:rgba(255,255,255,0.4);font-size:10px;padding:2px 0",n.textContent="Nothing yet this session.",t.appendChild(n),t}for(let n of r.recent.slice(0,5)){let s=document.createElement("div");s.style.cssText="display:flex;justify-content:space-between;gap:8px;padding:3px 0";let i=document.createElement("span");i.style.cssText="color:#fff;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:180px";let o=document.createElement("span");o.textContent=n.ok?"\u2713 ":"\u2717 ",o.style.color=n.ok?"#10b981":"#ef4444",i.appendChild(o),i.appendChild(document.createTextNode(n.model));let a=document.createElement("span");a.style.cssText="color:rgba(255,255,255,0.7);font-variant-numeric:tabular-nums;font-size:10px";let u=`${(n.latencyMs/1e3).toFixed(1)}s`,c=n.costUSD!==void 0?` \xB7 $${n.costUSD.toFixed(4)}`:"",d=` \xB7 ${Xe(e-n.endedAt)}`;a.textContent=`${u}${c}${d}`,s.appendChild(i),s.appendChild(a),t.appendChild(s)}return t}function Ft(r,e){let t=document.createElement("div");t.appendChild(ge("Session",Xe(e-r.startedAt)));let n=document.createElement("div");n.style.cssText="display:flex;justify-content:space-between;gap:12px;color:rgba(255,255,255,0.85);font-size:10px";let s=document.createElement("span");s.textContent=`${r.totalCalls} call${r.totalCalls===1?"":"s"}`;let i=document.createElement("span");i.textContent=`$${r.totalCostUSD.toFixed(4)}`;let o=document.createElement("span");return o.textContent=r.errorCount>0?`${r.errorCount} error${r.errorCount===1?"":"s"}`:"0 errors",r.errorCount>0&&(o.style.color="#ef4444"),n.appendChild(s),n.appendChild(i),n.appendChild(o),t.appendChild(n),t}function ge(r,e){let t=document.createElement("div");t.style.cssText=["display:flex;justify-content:space-between;align-items:baseline","margin-bottom:4px","color:rgba(255,255,255,0.55)","font-size:10px;text-transform:uppercase;letter-spacing:0.05em"].join(";");let n=document.createElement("span");n.textContent=r;let s=document.createElement("span");return s.textContent=e,s.style.cssText="font-size:9px;letter-spacing:0",t.appendChild(n),t.appendChild(s),t}function Xe(r){return r<1500?"just now":r<6e4?`${Math.round(r/1e3)}s ago`:r<36e5?`${Math.round(r/6e4)}m ago`:`${Math.round(r/36e5)}h ago`}var $t="https://www.runapps.ai",T=class{constructor(e={}){l(this,"chat");l(this,"models");l(this,"image");l(this,"audio");l(this,"video");l(this,"computer");l(this,"files");l(this,"embeddings");l(this,"auth",null);l(this,"events",new k);let t=e.authProvider??"static",n=e.apiKeyResolver,s=e.baseURL,i;if(t==="runapps"||t==="runjobs"){s=s??"https://www.runapps.ai";let a=e.showIdentityBadge!==void 0?e.showIdentityBadge:e.hideIdentityBadge!==void 0?!e.hideIdentityBadge:!0,u=new A({origin:s,hideBadge:!a,events:this.events,...e.badgePosition!==void 0&&{badgePosition:e.badgePosition},...e.project!==void 0&&{project:e.project}});this.auth=u,n=u.getToken,i=()=>u.invalidate()}if(!e.apiKey&&!n)throw new Error('runapps: pass either `apiKey`, `apiKeyResolver`, or `authProvider: "runapps"`');let o=new G({baseURL:s??$t,...e.apiKey!==void 0&&{apiKey:e.apiKey},...n!==void 0&&{apiKeyResolver:n},...i!==void 0&&{onUnauthorized:i},...e.fetch?{fetchImpl:e.fetch}:{}});this.chat=new V(o,this.events),this.models=new z(o),this.image=new W(o,this.events),this.audio=new X(o,this.events),this.video=new Q(o,this.events),this.computer=new Z(o,this.events),this.files=new ee(o,e.project),this.embeddings=new te(o,this.events)}signIn(){this.auth?.signIn()}signOut(){this.auth?.signOut()}get user(){return this.auth?.user??null}};function Ye(r){return r?r.map(e=>Array.isArray(e)?{fields:e}:e):[]}function $(r){let e=r.options;return!e||typeof e!="object"?null:e}function Qe(r,e){let n=$(r)?.inputs?.[e];return n?n.presence!=="forbidden":!1}function Ze(r,e){return $(r)?.inputs?.[e]?.presence==="required"}function et(r,e){return $(r)?.inputs?.[e]?.enum??null}function rt(r,e={}){if(!r)return[];let t=[];if(r.inputs)for(let[n,s]of Object.entries(r.inputs)){let i=n in e,o=e[n];i&&!v(o)?t.push(...st(n,s,o)):i&&s.min_items!==void 0&&Array.isArray(o)&&o.length<s.min_items&&t.push({field:n,reason:`at least ${s.min_items} items`}),t.push(...it(n,s,o,i))}for(let n of r.constraints??[])t.push(...Lt(n,e));return t}function st(r,e,t){let n=[];if(!Kt(e.type,t))return n.push({field:r,reason:`expected type ${e.type}, got ${se(t)}`}),n;if(e.enum&&e.enum.length>0&&!Nt(t,e.enum)&&n.push({field:r,reason:`must be one of ${JSON.stringify(e.enum)}`}),e.type==="int"||e.type==="float"){let s=ot(t);s!==null&&(e.min!==void 0&&s<e.min&&n.push({field:r,reason:`must be >= ${e.min}`}),e.max!==void 0&&s>e.max&&n.push({field:r,reason:`must be <= ${e.max}`}))}return Array.isArray(t)&&(e.max_items!==void 0&&t.length>e.max_items&&n.push({field:r,reason:`at most ${e.max_items} items`}),e.min_items!==void 0&&t.length<e.min_items&&n.push({field:r,reason:`at least ${e.min_items} items`})),e.fields&&(e.repeatable?Array.isArray(t)?t.forEach((s,i)=>{if(typeof s!="object"||s===null||Array.isArray(s)){n.push({field:`${r}[${i}]`,reason:`expected object, got ${se(s)}`});return}n.push(...tt(`${r}[${i}]`,e.fields,s))}):n.push({field:r,reason:`expected array of objects, got ${se(t)}`}):typeof t!="object"||t===null||Array.isArray(t)?n.push({field:r,reason:`expected object, got ${se(t)}`}):n.push(...tt(r,e.fields,t))),n}function tt(r,e,t){let n=[];for(let[s,i]of Object.entries(e)){let o=`${r}.${s}`,a=t[s],u=s in t;u&&!v(a)&&n.push(...st(o,i,a)),n.push(...it(o,i,a,u))}return n}function it(r,e,t,n){let s=e.presence??"optional";return s==="required"&&(!n||v(t))?[{field:r,reason:"required"}]:s==="forbidden"&&n&&!v(t)?[{field:r,reason:"must not be set for this model"}]:[]}function Lt(r,e){switch(r.kind){case"any_of_required":{let t=r.fields??[];return t.some(s=>s in e&&!v(e[s]))?[]:[{field:t.join("/"),reason:`at least one of ${t.join(", ")} is required`}]}case"mutually_exclusive":{let t=r.fields??[],n=t.filter(s=>s in e&&!v(e[s]));return n.length>1?[{field:n.join("/"),reason:`at most one of ${t.join(", ")} may be set (got: ${n.join(", ")})`}]:[]}case"group_mutex":{let t=Ye(r.groups),n=[],s=[];for(let i of t){let o=i.fields.filter(a=>a in e&&!v(e[a]));o.length>0&&(n.push(i),s.push(...o))}if(n.length>1){let i=t.map(o=>`[${o.fields.join("+")}]`).join(" or ");return[{field:s.join("/"),reason:`at most one of ${i} may be used (got: ${s.join(", ")})`}]}return[]}case"requires_all":{let t=r.when;if(!t)return[];if(!(t in e&&!v(e[t])))return[];let s=(r.then??[]).filter(i=>!(i in e)||v(e[i]));return s.length===0?[]:[{field:s.join("/"),reason:`required when ${t} is set`}]}case"pixel_bounds":{let t=r.fields?.[0];if(!t)return[];let n=e[t];if(typeof n!="string"||n==="")return[];let s=Ht(n);if(!s)return[{field:t,reason:`expected WxH dimensions, got "${n}"`}];let[i,o]=s,a=i*o,u=[];return r.min!==void 0&&a<r.min&&u.push({field:t,reason:`image too small: ${i}x${o} = ${a} pixels, minimum ${r.min}`}),r.max!==void 0&&a>r.max&&u.push({field:t,reason:`image too large: ${i}x${o} = ${a} pixels, maximum ${r.max}`}),u}}return[]}function Kt(r,e){switch(r){case"string":return typeof e=="string";case"int":case"float":return ot(e)!==null;case"bool":return typeof e=="boolean";case"url":return typeof e=="string"&&nt(e);case"url[]":return Array.isArray(e)&&e.every(t=>typeof t=="string"&&nt(t));case"string[]":return Array.isArray(e)&&e.every(t=>typeof t=="string");case"file":return!0;default:return!0}}function se(r){return r===null?"null":Array.isArray(r)?"array":typeof r}function ot(r){return typeof r=="number"&&Number.isFinite(r)?r:null}function nt(r){return r.startsWith("http://")||r.startsWith("https://")||r.startsWith("data:")}function v(r){return r==null?!0:typeof r=="string"?r==="":Array.isArray(r)?r.length===0:!1}function Nt(r,e){for(let t of e)if(qt(r,t))return!0;return!1}function qt(r,e){return r===e}function Ht(r){for(let e of["x","X","*","\xD7"]){let t=r.indexOf(e);if(t<=0)continue;let n=parseInt(r.slice(0,t).trim(),10),s=parseInt(r.slice(t+e.length).trim(),10);if(Number.isFinite(n)&&Number.isFinite(s)&&n>0&&s>0)return[n,s]}return null}return gt(Jt);})();
|
|
3
|
+
RunApps = Object.assign(RunApps.Client, RunApps); var RunJobs = RunApps;
|
|
4
|
+
//# sourceMappingURL=sdk.umd.js.map
|