@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.
Files changed (105) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +274 -2
  3. package/dist/activity-tracker.d.ts +113 -0
  4. package/dist/activity-tracker.d.ts.map +1 -0
  5. package/dist/activity-tracker.js +176 -0
  6. package/dist/activity-tracker.js.map +1 -0
  7. package/dist/audio.d.ts +129 -0
  8. package/dist/audio.d.ts.map +1 -0
  9. package/dist/audio.js +267 -0
  10. package/dist/audio.js.map +1 -0
  11. package/dist/browser-auth.d.ts +179 -0
  12. package/dist/browser-auth.d.ts.map +1 -0
  13. package/dist/browser-auth.js +1361 -0
  14. package/dist/browser-auth.js.map +1 -0
  15. package/dist/chat.d.ts +221 -0
  16. package/dist/chat.d.ts.map +1 -0
  17. package/dist/chat.js +155 -0
  18. package/dist/chat.js.map +1 -0
  19. package/dist/client.d.ts +155 -0
  20. package/dist/client.d.ts.map +1 -0
  21. package/dist/client.js +157 -0
  22. package/dist/client.js.map +1 -0
  23. package/dist/computer.d.ts +57 -0
  24. package/dist/computer.d.ts.map +1 -0
  25. package/dist/computer.js +21 -0
  26. package/dist/computer.js.map +1 -0
  27. package/dist/embeddings.d.ts +64 -0
  28. package/dist/embeddings.d.ts.map +1 -0
  29. package/dist/embeddings.js +30 -0
  30. package/dist/embeddings.js.map +1 -0
  31. package/dist/errors.d.ts +24 -0
  32. package/dist/errors.d.ts.map +1 -0
  33. package/dist/errors.js +29 -0
  34. package/dist/errors.js.map +1 -0
  35. package/dist/event-wrap.d.ts +59 -0
  36. package/dist/event-wrap.d.ts.map +1 -0
  37. package/dist/event-wrap.js +142 -0
  38. package/dist/event-wrap.js.map +1 -0
  39. package/dist/events.d.ts +119 -0
  40. package/dist/events.d.ts.map +1 -0
  41. package/dist/events.js +87 -0
  42. package/dist/events.js.map +1 -0
  43. package/dist/files.d.ts +218 -0
  44. package/dist/files.d.ts.map +1 -0
  45. package/dist/files.js +212 -0
  46. package/dist/files.js.map +1 -0
  47. package/dist/image.d.ts +185 -0
  48. package/dist/image.d.ts.map +1 -0
  49. package/dist/image.js +148 -0
  50. package/dist/image.js.map +1 -0
  51. package/dist/index.d.ts +30 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +26 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/media.d.ts +56 -0
  56. package/dist/media.d.ts.map +1 -0
  57. package/dist/media.js +133 -0
  58. package/dist/media.js.map +1 -0
  59. package/dist/model_options.d.ts +165 -0
  60. package/dist/model_options.d.ts.map +1 -0
  61. package/dist/model_options.js +59 -0
  62. package/dist/model_options.js.map +1 -0
  63. package/dist/models.d.ts +88 -0
  64. package/dist/models.d.ts.map +1 -0
  65. package/dist/models.js +55 -0
  66. package/dist/models.js.map +1 -0
  67. package/dist/sdk.umd.js +4 -0
  68. package/dist/sdk.umd.js.map +1 -0
  69. package/dist/transport.d.ts +120 -0
  70. package/dist/transport.d.ts.map +1 -0
  71. package/dist/transport.js +214 -0
  72. package/dist/transport.js.map +1 -0
  73. package/dist/types.d.ts +31 -0
  74. package/dist/types.d.ts.map +1 -0
  75. package/dist/types.js +2 -0
  76. package/dist/types.js.map +1 -0
  77. package/dist/validate.d.ts +16 -0
  78. package/dist/validate.d.ts.map +1 -0
  79. package/dist/validate.js +329 -0
  80. package/dist/validate.js.map +1 -0
  81. package/dist/video.d.ts +134 -0
  82. package/dist/video.d.ts.map +1 -0
  83. package/dist/video.js +60 -0
  84. package/dist/video.js.map +1 -0
  85. package/package.json +54 -4
  86. package/src/activity-tracker.ts +251 -0
  87. package/src/audio.ts +440 -0
  88. package/src/browser-auth.ts +1529 -0
  89. package/src/chat.ts +368 -0
  90. package/src/client.ts +250 -0
  91. package/src/computer.ts +80 -0
  92. package/src/embeddings.ts +97 -0
  93. package/src/errors.ts +29 -0
  94. package/src/event-wrap.ts +168 -0
  95. package/src/events.ts +172 -0
  96. package/src/files.ts +347 -0
  97. package/src/image.ts +339 -0
  98. package/src/index.ts +151 -0
  99. package/src/media.ts +147 -0
  100. package/src/model_options.ts +220 -0
  101. package/src/models.ts +121 -0
  102. package/src/transport.ts +292 -0
  103. package/src/types.ts +31 -0
  104. package/src/validate.ts +364 -0
  105. package/src/video.ts +215 -0
package/dist/client.js ADDED
@@ -0,0 +1,157 @@
1
+ import { Transport } from "./transport.js";
2
+ import { ChatService } from "./chat.js";
3
+ import { ModelsService } from "./models.js";
4
+ import { ImageService } from "./image.js";
5
+ import { AudioService } from "./audio.js";
6
+ import { VideoService } from "./video.js";
7
+ import { ComputerService } from "./computer.js";
8
+ import { FilesService } from "./files.js";
9
+ import { EmbeddingsService } from "./embeddings.js";
10
+ import { BrowserAuth } from "./browser-auth.js";
11
+ import { SDKEvents } from "./events.js";
12
+ // The platform, not the bare gateway: personal rk_ keys are checked and
13
+ // billed by www.runapps.ai, which forwards to the gateway. api.runapps.ai
14
+ // only knows the gateway's own keys.
15
+ const DEFAULT_BASE_URL = "https://www.runapps.ai";
16
+ /**
17
+ * Top-level RunApps SDK client. Construct once, share across services.
18
+ *
19
+ * Browser bundle (resource projects on runapps.ai):
20
+ *
21
+ * ```html
22
+ * <script src="https://cdn.jsdelivr.net/npm/@runappsai/sdk/dist/sdk.umd.js"></script>
23
+ * <script>
24
+ * const client = new RunApps.Client({ authProvider: "runapps" });
25
+ * const res = await client.chat.create({
26
+ * model: "gpt-4o-mini",
27
+ * messages: [{ role: "user", content: "hello" }],
28
+ * });
29
+ * </script>
30
+ * ```
31
+ *
32
+ * Node / server-side:
33
+ *
34
+ * ```ts
35
+ * import { RunApps } from "@runappsai/sdk";
36
+ * const client = new RunApps({ apiKey: process.env.RUNJOBS_API_KEY! });
37
+ * ```
38
+ */
39
+ export class RunApps {
40
+ chat;
41
+ models;
42
+ image;
43
+ audio;
44
+ video;
45
+ computer;
46
+ files;
47
+ embeddings;
48
+ /**
49
+ * Browser auth helper, populated only when `authProvider: "runapps"`.
50
+ * Use `client.signIn()` and `client.user` for the common cases; the
51
+ * full instance is exposed for advanced flows (manual `onTokenChange`
52
+ * subscription, etc.).
53
+ */
54
+ auth = null;
55
+ /**
56
+ * Runtime event bus for SDK-call telemetry. Every LLM-ish service
57
+ * (chat / embeddings / image / audio / video / computer) fires
58
+ * `request:start`, `request:streamDelta`, `request:end`, and
59
+ * `request:error` events here so UI overlays — like the bottom-right
60
+ * identity badge's activity ring — can render real-time state
61
+ * without business code threading anything through.
62
+ *
63
+ * Zero-cost when nobody subscribes (emit is a few property reads).
64
+ * Subscribe via `client.events.on("request:start", handler)` — the
65
+ * returned closure is the unsubscribe.
66
+ */
67
+ events = new SDKEvents();
68
+ constructor(options = {}) {
69
+ const provider = options.authProvider ?? "static";
70
+ let apiKeyResolver = options.apiKeyResolver;
71
+ let baseURL = options.baseURL;
72
+ let onUnauthorized;
73
+ if (provider === "runapps" || provider === "runjobs") {
74
+ // The grant page (/api/sdk/grant) and the gateway both live on
75
+ // www.runapps.ai. An explicit baseURL keeps control.
76
+ baseURL = baseURL ?? "https://www.runapps.ai";
77
+ // Badge default: SHOWN. The badge is now a real-time activity
78
+ // indicator (LED + ring + popover) — useful enough that we'd
79
+ // rather have the rare "I already have my own UI" bundle opt
80
+ // OUT with `showIdentityBadge: false` than have every bundle
81
+ // miss the live feedback by default. The legacy
82
+ // `hideIdentityBadge` flag still wins when set, for callers
83
+ // that explicitly suppressed the badge under the old default.
84
+ const showBadge = options.showIdentityBadge !== undefined
85
+ ? options.showIdentityBadge
86
+ : options.hideIdentityBadge !== undefined
87
+ ? !options.hideIdentityBadge
88
+ : true;
89
+ const auth = new BrowserAuth({
90
+ origin: baseURL,
91
+ hideBadge: !showBadge,
92
+ // Pipe the shared event bus into BrowserAuth so the badge can
93
+ // render its real-time activity ring / LED / popover. Safe to
94
+ // pass even when the caller never subscribes — emit is a few
95
+ // property reads when nobody's listening.
96
+ events: this.events,
97
+ ...(options.badgePosition !== undefined && { badgePosition: options.badgePosition }),
98
+ ...(options.project !== undefined && { project: options.project }),
99
+ });
100
+ this.auth = auth;
101
+ // The browser auth resolver wins over any caller-supplied one
102
+ // because the auth flow owns token issuance + refresh from now on.
103
+ apiKeyResolver = auth.getToken;
104
+ // 401 from the gateway → token was revoked server-side (typically
105
+ // because the user unsubscribed in another tab). Drop the cached
106
+ // token so the transport's auto-retry hits a fresh signIn() flow.
107
+ onUnauthorized = () => auth.invalidate();
108
+ }
109
+ if (!options.apiKey && !apiKeyResolver) {
110
+ throw new Error("runapps: pass either `apiKey`, `apiKeyResolver`, or `authProvider: \"runapps\"`");
111
+ }
112
+ const transport = new Transport({
113
+ baseURL: baseURL ?? DEFAULT_BASE_URL,
114
+ ...(options.apiKey !== undefined && { apiKey: options.apiKey }),
115
+ ...(apiKeyResolver !== undefined && { apiKeyResolver }),
116
+ ...(onUnauthorized !== undefined && { onUnauthorized }),
117
+ ...(options.fetch ? { fetchImpl: options.fetch } : {}),
118
+ });
119
+ // Service constructors receive the shared event bus so each call
120
+ // path (chat/embeddings/image/audio/video/computer) can emit
121
+ // start/end/error around its network operations. Files and Models
122
+ // intentionally don't take it — they're infrastructure, not
123
+ // user-facing LLM calls, and surfacing them would clutter the
124
+ // badge with /v1/models polls.
125
+ this.chat = new ChatService(transport, this.events);
126
+ this.models = new ModelsService(transport);
127
+ this.image = new ImageService(transport, this.events);
128
+ this.audio = new AudioService(transport, this.events);
129
+ this.video = new VideoService(transport, this.events);
130
+ this.computer = new ComputerService(transport, this.events);
131
+ // `project` also scopes the file URLs (/v1/p/<project>/files/...),
132
+ // so two apps never issue byte-identical file requests. Omitted →
133
+ // legacy unscoped /v1/files/... paths.
134
+ this.files = new FilesService(transport, options.project);
135
+ this.embeddings = new EmbeddingsService(transport, this.events);
136
+ }
137
+ /** Force a redirect to the runapps.ai grant page. No-op in static
138
+ * auth mode or in Node. */
139
+ signIn() {
140
+ this.auth?.signIn();
141
+ }
142
+ /**
143
+ * Clear the cached token + identity from memory and localStorage.
144
+ * The next API call will trigger sign-in again (redirect to grant
145
+ * page). Wire this to a "Sign out" button in your settings UI.
146
+ *
147
+ * No-op in static auth mode or in Node.
148
+ */
149
+ signOut() {
150
+ this.auth?.signOut();
151
+ }
152
+ /** Currently-authenticated user (runapps auth mode), or null. */
153
+ get user() {
154
+ return this.auth?.user ?? null;
155
+ }
156
+ }
157
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ import type { Transport } from "./transport.js";
2
+ import type { Usage } from "./types.js";
3
+ import type { SDKEvents } from "./events.js";
4
+ /** Single-step computer-use request — a screenshot + history → next action(s). */
5
+ export interface ComputerStepParams {
6
+ /**
7
+ * Conversation history including screenshots and tool results. Each
8
+ * entry has `role` + `content` (string or array of blocks). Format is
9
+ * intentionally opaque to support both Anthropic and OpenAI computer-use
10
+ * protocols — the gateway adapts.
11
+ */
12
+ messages: Record<string, unknown>[];
13
+ /** Screen resolution. Defaults to 1920×1080 if omitted. */
14
+ display_width?: number;
15
+ display_height?: number;
16
+ max_tokens?: number;
17
+ enable_zoom?: boolean;
18
+ /** OpenAI Responses-API state chaining. */
19
+ previous_response_id?: string;
20
+ /** Follow-up `computer_call_output` for OpenAI's Responses API. */
21
+ openai_input?: unknown;
22
+ user?: string;
23
+ }
24
+ /** One block of a computer-use response: text, tool_use (Anthropic), or computer_call (OpenAI). */
25
+ export interface ComputerContentBlock {
26
+ type: string;
27
+ text?: string;
28
+ id?: string;
29
+ name?: string;
30
+ /** Anthropic tool input (raw JSON). */
31
+ input?: unknown;
32
+ call_id?: string;
33
+ /** OpenAI computer-call action. */
34
+ action?: Record<string, unknown>;
35
+ }
36
+ export interface ComputerResponse {
37
+ content: ComputerContentBlock[];
38
+ stop_reason?: string;
39
+ usage: Usage;
40
+ response_id?: string;
41
+ /** "anthropic" | "openai" — which protocol the upstream returned. */
42
+ protocol?: string;
43
+ }
44
+ export declare class ComputerService {
45
+ private readonly transport;
46
+ private readonly events;
47
+ constructor(transport: Transport, events: SDKEvents);
48
+ /**
49
+ * Execute one step of a computer-use agent loop. Given a screenshot
50
+ * and conversation history, returns the next action(s) the model
51
+ * wants the caller to execute.
52
+ */
53
+ step(model: string, params: ComputerStepParams, init?: {
54
+ signal?: AbortSignal;
55
+ }): Promise<ComputerResponse>;
56
+ }
57
+ //# sourceMappingURL=computer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"computer.d.ts","sourceRoot":"","sources":["../src/computer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAG7C,kFAAkF;AAClF,MAAM,WAAW,kBAAkB;IACjC;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IACpC,2DAA2D;IAC3D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,2CAA2C;IAC3C,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,mEAAmE;IACnE,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,mGAAmG;AACnG,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,oBAAoB,EAAE,CAAC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,KAAK,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,eAAe;IAExB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,SAAS;IAGpC;;;;OAIG;IACG,IAAI,CACR,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,kBAAkB,EAC1B,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAC9B,OAAO,CAAC,gBAAgB,CAAC;CAgB7B"}
@@ -0,0 +1,21 @@
1
+ import { wrapEvents } from "./event-wrap.js";
2
+ export class ComputerService {
3
+ transport;
4
+ events;
5
+ constructor(transport, events) {
6
+ this.transport = transport;
7
+ this.events = events;
8
+ }
9
+ /**
10
+ * Execute one step of a computer-use agent loop. Given a screenshot
11
+ * and conversation history, returns the next action(s) the model
12
+ * wants the caller to execute.
13
+ */
14
+ async step(model, params, init) {
15
+ return wrapEvents(this.events, { model, capability: "computer_use" }, () => this.transport.postJSON("/v1/computer/step", { model, ...params }, init), (r) => ({
16
+ totalTokens: r.usage?.completion_tokens,
17
+ costUSD: r.usage?.total_cost,
18
+ }));
19
+ }
20
+ }
21
+ //# sourceMappingURL=computer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"computer.js","sourceRoot":"","sources":["../src/computer.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AA6C7C,MAAM,OAAO,eAAe;IAEP;IACA;IAFnB,YACmB,SAAoB,EACpB,MAAiB;QADjB,cAAS,GAAT,SAAS,CAAW;QACpB,WAAM,GAAN,MAAM,CAAW;IACjC,CAAC;IAEJ;;;;OAIG;IACH,KAAK,CAAC,IAAI,CACR,KAAa,EACb,MAA0B,EAC1B,IAA+B;QAE/B,OAAO,UAAU,CACf,IAAI,CAAC,MAAM,EACX,EAAE,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,EACrC,GAAG,EAAE,CACH,IAAI,CAAC,SAAS,CAAC,QAAQ,CACrB,mBAAmB,EACnB,EAAE,KAAK,EAAE,GAAG,MAAM,EAAE,EACpB,IAAI,CACL,EACH,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACN,WAAW,EAAE,CAAC,CAAC,KAAK,EAAE,iBAAiB;YACvC,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,UAAU;SAC7B,CAAC,CACH,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,64 @@
1
+ import type { Transport } from "./transport.js";
2
+ import type { Usage } from "./types.js";
3
+ import type { SDKEvents } from "./events.js";
4
+ export interface EmbeddingsParams {
5
+ /** Single string OR array of strings — gateway forwards either
6
+ * shape verbatim. Passing a string returns `data: [{...}]` (1
7
+ * element), passing an array returns one element per input. */
8
+ input: string | string[];
9
+ /** OpenAI per-end-user observability tag. */
10
+ user?: string;
11
+ /** "float" (default) or "base64". `base64` packs vectors as
12
+ * little-endian float32 + base64-encoded — saves bandwidth for
13
+ * high-D embeddings (3072-D × 1000 docs is ~3× smaller than the
14
+ * JSON float-array form). */
15
+ encoding_format?: "float" | "base64";
16
+ /** Truncate the output vector. text-embedding-3-* only — other
17
+ * models reject. */
18
+ dimensions?: number;
19
+ }
20
+ export interface Embedding {
21
+ object: "embedding";
22
+ /** Vector. When `encoding_format` was "float" (default), this is
23
+ * `number[]`. When "base64", this is the encoded `string`. */
24
+ embedding: number[] | string;
25
+ index: number;
26
+ }
27
+ /** OpenAI's usage block plus the gateway's billing extension
28
+ * (`total_cost` in USD).
29
+ *
30
+ * Shape parallels the `Usage` type used by chat / image / video so
31
+ * callers can read `.total_cost` on every response uniformly. */
32
+ export interface EmbeddingsUsage extends Usage {
33
+ prompt_tokens: number;
34
+ total_tokens: number;
35
+ }
36
+ export interface EmbeddingsResponse {
37
+ object: "list";
38
+ data: Embedding[];
39
+ model: string;
40
+ usage: EmbeddingsUsage;
41
+ }
42
+ export declare class EmbeddingsService {
43
+ private readonly transport;
44
+ private readonly events;
45
+ constructor(transport: Transport, events: SDKEvents);
46
+ /**
47
+ * Create one or more embeddings.
48
+ *
49
+ * ```ts
50
+ * const r = await client.embeddings.create("text-embedding-3-small", {
51
+ * input: ["alpha", "beta"],
52
+ * dimensions: 1536,
53
+ * });
54
+ * for (const e of r.data) {
55
+ * console.log(e.index, (e.embedding as number[]).slice(0, 4));
56
+ * }
57
+ * console.log(`Cost: $${r.usage.total_cost.toFixed(6)}`);
58
+ * ```
59
+ */
60
+ create(model: string, params: EmbeddingsParams, init?: {
61
+ signal?: AbortSignal;
62
+ }): Promise<EmbeddingsResponse>;
63
+ }
64
+ //# sourceMappingURL=embeddings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embeddings.d.ts","sourceRoot":"","sources":["../src/embeddings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAY7C,MAAM,WAAW,gBAAgB;IAC/B;;oEAEgE;IAChE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzB,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;kCAG8B;IAC9B,eAAe,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IACrC;yBACqB;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,WAAW,CAAC;IACpB;mEAC+D;IAC/D,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;kEAIkE;AAClE,MAAM,WAAW,eAAgB,SAAQ,KAAK;IAC5C,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,eAAe,CAAC;CACxB;AAED,qBAAa,iBAAiB;IAE1B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,SAAS;IAGpC;;;;;;;;;;;;;OAaG;IACG,MAAM,CACV,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,gBAAgB,EACxB,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAC9B,OAAO,CAAC,kBAAkB,CAAC;CAgB/B"}
@@ -0,0 +1,30 @@
1
+ import { wrapEvents } from "./event-wrap.js";
2
+ export class EmbeddingsService {
3
+ transport;
4
+ events;
5
+ constructor(transport, events) {
6
+ this.transport = transport;
7
+ this.events = events;
8
+ }
9
+ /**
10
+ * Create one or more embeddings.
11
+ *
12
+ * ```ts
13
+ * const r = await client.embeddings.create("text-embedding-3-small", {
14
+ * input: ["alpha", "beta"],
15
+ * dimensions: 1536,
16
+ * });
17
+ * for (const e of r.data) {
18
+ * console.log(e.index, (e.embedding as number[]).slice(0, 4));
19
+ * }
20
+ * console.log(`Cost: $${r.usage.total_cost.toFixed(6)}`);
21
+ * ```
22
+ */
23
+ async create(model, params, init) {
24
+ return wrapEvents(this.events, { model, capability: "embedding" }, () => this.transport.postJSON("/v1/embeddings", { model, ...params }, init), (r) => ({
25
+ totalTokens: r.usage?.total_tokens,
26
+ costUSD: r.usage?.total_cost,
27
+ }));
28
+ }
29
+ }
30
+ //# sourceMappingURL=embeddings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embeddings.js","sourceRoot":"","sources":["../src/embeddings.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAqD7C,MAAM,OAAO,iBAAiB;IAET;IACA;IAFnB,YACmB,SAAoB,EACpB,MAAiB;QADjB,cAAS,GAAT,SAAS,CAAW;QACpB,WAAM,GAAN,MAAM,CAAW;IACjC,CAAC;IAEJ;;;;;;;;;;;;;OAaG;IACH,KAAK,CAAC,MAAM,CACV,KAAa,EACb,MAAwB,EACxB,IAA+B;QAE/B,OAAO,UAAU,CACf,IAAI,CAAC,MAAM,EACX,EAAE,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,EAClC,GAAG,EAAE,CACH,IAAI,CAAC,SAAS,CAAC,QAAQ,CACrB,gBAAgB,EAChB,EAAE,KAAK,EAAE,GAAG,MAAM,EAAE,EACpB,IAAI,CACL,EACH,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACN,WAAW,EAAE,CAAC,CAAC,KAAK,EAAE,YAAY;YAClC,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,UAAU;SAC7B,CAAC,CACH,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * APIError represents an error returned by the RunApps gateway.
3
+ *
4
+ * Use `instanceof APIError` (or check `name === "APIError"`) to distinguish
5
+ * gateway errors from network / runtime errors:
6
+ *
7
+ * ```ts
8
+ * try {
9
+ * await client.chat.create({ model: "...", messages: [...] });
10
+ * } catch (e) {
11
+ * if (e instanceof APIError) {
12
+ * console.error(`API ${e.statusCode}: ${e.message}`);
13
+ * } else {
14
+ * throw e;
15
+ * }
16
+ * }
17
+ * ```
18
+ */
19
+ export declare class APIError extends Error {
20
+ readonly statusCode: number;
21
+ readonly type: string;
22
+ constructor(statusCode: number, type: string, message: string);
23
+ }
24
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,QAAS,SAAQ,KAAK;IACjC,SAAgB,UAAU,EAAE,MAAM,CAAC;IACnC,SAAgB,IAAI,EAAE,MAAM,CAAC;gBAEjB,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAM9D"}
package/dist/errors.js ADDED
@@ -0,0 +1,29 @@
1
+ /**
2
+ * APIError represents an error returned by the RunApps gateway.
3
+ *
4
+ * Use `instanceof APIError` (or check `name === "APIError"`) to distinguish
5
+ * gateway errors from network / runtime errors:
6
+ *
7
+ * ```ts
8
+ * try {
9
+ * await client.chat.create({ model: "...", messages: [...] });
10
+ * } catch (e) {
11
+ * if (e instanceof APIError) {
12
+ * console.error(`API ${e.statusCode}: ${e.message}`);
13
+ * } else {
14
+ * throw e;
15
+ * }
16
+ * }
17
+ * ```
18
+ */
19
+ export class APIError extends Error {
20
+ statusCode;
21
+ type;
22
+ constructor(statusCode, type, message) {
23
+ super(`runapps: ${statusCode} ${type}: ${message}`);
24
+ this.name = "APIError";
25
+ this.statusCode = statusCode;
26
+ this.type = type;
27
+ }
28
+ }
29
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAO,QAAS,SAAQ,KAAK;IACjB,UAAU,CAAS;IACnB,IAAI,CAAS;IAE7B,YAAY,UAAkB,EAAE,IAAY,EAAE,OAAe;QAC3D,KAAK,CAAC,YAAY,UAAU,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC,CAAC;QACpD,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Tiny wrapper used by every LLM-ish service to fire
3
+ * `request:start` → `request:end` / `request:error` events around a
4
+ * single network call. Centralised here so the service files don't
5
+ * duplicate the try/catch + latency-stopwatch pattern N times.
6
+ *
7
+ * Streaming chat has its own logic (it must yield deltas mid-flight)
8
+ * — see `wrapStream` below.
9
+ */
10
+ import { type SDKCapability, type SDKEvents } from "./events.js";
11
+ interface CallMeta {
12
+ model: string;
13
+ capability: SDKCapability;
14
+ }
15
+ interface EndInfo {
16
+ totalTokens?: number;
17
+ costUSD?: number;
18
+ finishReason?: string;
19
+ }
20
+ /**
21
+ * Run `fn` while emitting start/end/error events around it.
22
+ * `extractEnd` plucks token / cost / finish_reason off the response
23
+ * shape so each service can map its own response type without the
24
+ * helper knowing about it.
25
+ *
26
+ * Re-throws on error so the caller still sees the rejection — the
27
+ * helper only inserts telemetry, it doesn't swallow.
28
+ */
29
+ export declare function wrapEvents<T>(events: SDKEvents, meta: CallMeta, fn: () => Promise<T>, extractEnd?: (r: T) => EndInfo): Promise<T>;
30
+ /**
31
+ * Token-count estimator for stream deltas. Stream chunks carry text,
32
+ * not tokens — getting an exact count would mean shipping a
33
+ * tokenizer in the SDK (huge), so we use the standard ~4-chars =
34
+ * 1-token English heuristic. Off by 10-30% for code or non-English,
35
+ * but the badge UI shows tokens/sec as a vibe indicator, not for
36
+ * billing, so the imprecision is fine.
37
+ */
38
+ export declare function estimateTokens(text: string): number;
39
+ /**
40
+ * Stream wrapper — same start/end/error envelope as wrapEvents but
41
+ * also fires `request:streamDelta` for each yielded chunk so the
42
+ * badge's tokens/sec sliding window has samples.
43
+ *
44
+ * Generic over the chunk type because each service's stream
45
+ * (chat / video / etc.) carries its own shape. The caller passes a
46
+ * `extractDelta` that pulls text + cumulative usage off the chunk.
47
+ *
48
+ * Usage:
49
+ * yield* wrapStream(events, {model, capability}, () => transport.postJSONStream(...),
50
+ * (chunk) => ({ deltaText: chunk.choices[0]?.delta?.content, usage: chunk.usage }));
51
+ */
52
+ export declare function wrapStream<TChunk>(events: SDKEvents, meta: CallMeta, source: () => AsyncIterable<TChunk>, extractDelta: (chunk: TChunk) => {
53
+ deltaText?: string;
54
+ completionTokens?: number;
55
+ costUSD?: number;
56
+ finishReason?: string;
57
+ }): AsyncGenerator<TChunk, void, unknown>;
58
+ export {};
59
+ //# sourceMappingURL=event-wrap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-wrap.d.ts","sourceRoot":"","sources":["../src/event-wrap.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAgB,KAAK,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAE/E,UAAU,QAAQ;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,aAAa,CAAC;CAC3B;AAED,UAAU,OAAO;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,wBAAsB,UAAU,CAAC,CAAC,EAChC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,QAAQ,EACd,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,OAAO,GAC7B,OAAO,CAAC,CAAC,CAAC,CAmCZ;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGnD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAuB,UAAU,CAAC,MAAM,EACtC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,MAAM,aAAa,CAAC,MAAM,CAAC,EACnC,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IAInB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GACA,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAsDvC"}
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Tiny wrapper used by every LLM-ish service to fire
3
+ * `request:start` → `request:end` / `request:error` events around a
4
+ * single network call. Centralised here so the service files don't
5
+ * duplicate the try/catch + latency-stopwatch pattern N times.
6
+ *
7
+ * Streaming chat has its own logic (it must yield deltas mid-flight)
8
+ * — see `wrapStream` below.
9
+ */
10
+ import { newRequestId } from "./events.js";
11
+ /**
12
+ * Run `fn` while emitting start/end/error events around it.
13
+ * `extractEnd` plucks token / cost / finish_reason off the response
14
+ * shape so each service can map its own response type without the
15
+ * helper knowing about it.
16
+ *
17
+ * Re-throws on error so the caller still sees the rejection — the
18
+ * helper only inserts telemetry, it doesn't swallow.
19
+ */
20
+ export async function wrapEvents(events, meta, fn, extractEnd) {
21
+ const id = newRequestId();
22
+ const startedAt = Date.now();
23
+ events.emit("request:start", {
24
+ id,
25
+ model: meta.model,
26
+ capability: meta.capability,
27
+ startedAt,
28
+ streaming: false,
29
+ });
30
+ try {
31
+ const result = await fn();
32
+ const info = extractEnd ? extractEnd(result) : {};
33
+ events.emit("request:end", {
34
+ id,
35
+ model: meta.model,
36
+ capability: meta.capability,
37
+ latencyMs: Date.now() - startedAt,
38
+ totalTokens: info.totalTokens ?? 0,
39
+ ...(info.costUSD !== undefined && { costUSD: info.costUSD }),
40
+ ...(info.finishReason !== undefined && { finishReason: info.finishReason }),
41
+ });
42
+ return result;
43
+ }
44
+ catch (err) {
45
+ const e = err;
46
+ events.emit("request:error", {
47
+ id,
48
+ model: meta.model,
49
+ capability: meta.capability,
50
+ latencyMs: Date.now() - startedAt,
51
+ error: e,
52
+ ...(typeof e.statusCode === "number" && { statusCode: e.statusCode }),
53
+ });
54
+ throw err;
55
+ }
56
+ }
57
+ /**
58
+ * Token-count estimator for stream deltas. Stream chunks carry text,
59
+ * not tokens — getting an exact count would mean shipping a
60
+ * tokenizer in the SDK (huge), so we use the standard ~4-chars =
61
+ * 1-token English heuristic. Off by 10-30% for code or non-English,
62
+ * but the badge UI shows tokens/sec as a vibe indicator, not for
63
+ * billing, so the imprecision is fine.
64
+ */
65
+ export function estimateTokens(text) {
66
+ if (!text)
67
+ return 0;
68
+ return Math.max(1, Math.round(text.length / 4));
69
+ }
70
+ /**
71
+ * Stream wrapper — same start/end/error envelope as wrapEvents but
72
+ * also fires `request:streamDelta` for each yielded chunk so the
73
+ * badge's tokens/sec sliding window has samples.
74
+ *
75
+ * Generic over the chunk type because each service's stream
76
+ * (chat / video / etc.) carries its own shape. The caller passes a
77
+ * `extractDelta` that pulls text + cumulative usage off the chunk.
78
+ *
79
+ * Usage:
80
+ * yield* wrapStream(events, {model, capability}, () => transport.postJSONStream(...),
81
+ * (chunk) => ({ deltaText: chunk.choices[0]?.delta?.content, usage: chunk.usage }));
82
+ */
83
+ export async function* wrapStream(events, meta, source, extractDelta) {
84
+ const id = newRequestId();
85
+ const startedAt = Date.now();
86
+ events.emit("request:start", {
87
+ id,
88
+ model: meta.model,
89
+ capability: meta.capability,
90
+ startedAt,
91
+ streaming: true,
92
+ });
93
+ let totalTokens = 0;
94
+ let lastUsageTokens;
95
+ let costUSD;
96
+ let finishReason;
97
+ try {
98
+ for await (const chunk of source()) {
99
+ const info = extractDelta(chunk);
100
+ if (info.deltaText) {
101
+ const delta = estimateTokens(info.deltaText);
102
+ totalTokens += delta;
103
+ events.emit("request:streamDelta", {
104
+ id,
105
+ deltaTokens: delta,
106
+ totalTokens,
107
+ });
108
+ }
109
+ if (info.completionTokens !== undefined)
110
+ lastUsageTokens = info.completionTokens;
111
+ if (info.costUSD !== undefined)
112
+ costUSD = info.costUSD;
113
+ if (info.finishReason !== undefined)
114
+ finishReason = info.finishReason;
115
+ yield chunk;
116
+ }
117
+ events.emit("request:end", {
118
+ id,
119
+ model: meta.model,
120
+ capability: meta.capability,
121
+ latencyMs: Date.now() - startedAt,
122
+ // Prefer the exact upstream count over our heuristic when it
123
+ // arrived in the final chunk.
124
+ totalTokens: lastUsageTokens ?? totalTokens,
125
+ ...(costUSD !== undefined && { costUSD }),
126
+ ...(finishReason !== undefined && { finishReason }),
127
+ });
128
+ }
129
+ catch (err) {
130
+ const e = err;
131
+ events.emit("request:error", {
132
+ id,
133
+ model: meta.model,
134
+ capability: meta.capability,
135
+ latencyMs: Date.now() - startedAt,
136
+ error: e,
137
+ ...(typeof e.statusCode === "number" && { statusCode: e.statusCode }),
138
+ });
139
+ throw err;
140
+ }
141
+ }
142
+ //# sourceMappingURL=event-wrap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-wrap.js","sourceRoot":"","sources":["../src/event-wrap.ts"],"names":[],"mappings":"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"}