totalum-sdk 0.1.0-dev.10

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 (53) hide show
  1. package/README.md +18 -0
  2. package/dist/_types/billing.d-BbSZh1wY.d.ts +38 -0
  3. package/dist/_types/coerce.d-C0KIW76L.d.ts +6 -0
  4. package/dist/_types/errors.d-Cu3q_E_r.d.ts +3093 -0
  5. package/dist/_types/integrations.d-BNGV70e3.d.ts +793 -0
  6. package/dist/_types/ops.d-C9375KIG.d.ts +117 -0
  7. package/dist/ai/index.d.ts +424 -0
  8. package/dist/ai/index.js +185 -0
  9. package/dist/analytics/index.d.ts +35 -0
  10. package/dist/analytics/index.js +15 -0
  11. package/dist/browser/index.d.ts +1595 -0
  12. package/dist/browser/index.js +168 -0
  13. package/dist/cron/index.d.ts +180 -0
  14. package/dist/cron/index.js +61 -0
  15. package/dist/d1/errors.js +31 -0
  16. package/dist/d1/https.js +103 -0
  17. package/dist/d1/index.d.ts +107 -0
  18. package/dist/d1/index.js +73 -0
  19. package/dist/d1/lazy.js +112 -0
  20. package/dist/d1/libsql.js +125 -0
  21. package/dist/d1/session.js +38 -0
  22. package/dist/d1/sql.js +87 -0
  23. package/dist/d1/types.js +1 -0
  24. package/dist/email/index.d.ts +31 -0
  25. package/dist/email/index.js +30 -0
  26. package/dist/errors.js +35 -0
  27. package/dist/files/index.d.ts +119 -0
  28. package/dist/files/index.js +63 -0
  29. package/dist/http.js +85 -0
  30. package/dist/index.d.ts +73 -0
  31. package/dist/index.js +68 -0
  32. package/dist/logs/index.d.ts +51 -0
  33. package/dist/logs/index.js +18 -0
  34. package/dist/payments/index.d.ts +47 -0
  35. package/dist/payments/index.js +20 -0
  36. package/dist/pdf/index.d.ts +42 -0
  37. package/dist/pdf/index.js +17 -0
  38. package/dist/react/index.d.ts +91 -0
  39. package/dist/react/index.js +178 -0
  40. package/dist/realtime/index.d.ts +103 -0
  41. package/dist/realtime/index.js +30 -0
  42. package/dist/scan/index.d.ts +46 -0
  43. package/dist/scan/index.js +12 -0
  44. package/dist/seo/index.d.ts +23 -0
  45. package/dist/seo/index.js +12 -0
  46. package/dist/speech/index.d.ts +41 -0
  47. package/dist/speech/index.js +22 -0
  48. package/dist/web/index.d.ts +170 -0
  49. package/dist/web/index.js +31 -0
  50. package/dist/webhooks/index.d.ts +48 -0
  51. package/dist/webhooks/index.js +61 -0
  52. package/package.json +146 -0
  53. package/totalum-sdk.md +1088 -0
@@ -0,0 +1,185 @@
1
+ import { assertNode, TotalumError } from '../errors.js';
2
+ import { jsonClient, projectKey, rawClient, readEnv } from '../http.js';
3
+ import { totalumSpeech } from '../speech/index.js';
4
+ export { TotalumError, isTotalumError } from '../errors.js';
5
+ const resultOf = (c) => ({
6
+ id: c.id ?? '',
7
+ model: c.model ?? '',
8
+ text: c.choices?.[0]?.message?.content ?? '',
9
+ toolCalls: c.choices?.[0]?.message?.tool_calls ?? [],
10
+ finishReason: c.choices?.[0]?.finish_reason ?? null,
11
+ usage: {
12
+ inputTokens: c.usage?.prompt_tokens ?? 0,
13
+ outputTokens: c.usage?.completion_tokens ?? 0,
14
+ costUsd: c.usage?.costUsd ?? 0,
15
+ credits: c.usage?.credits ?? 0,
16
+ },
17
+ raw: c,
18
+ });
19
+ /** SSE `data:` payloads of a stream, in order (`[DONE]` ends it). */
20
+ async function* events(body) {
21
+ const reader = body.getReader();
22
+ const decoder = new TextDecoder();
23
+ let pending = '';
24
+ for (;;) {
25
+ const { done, value } = await reader.read();
26
+ if (!done)
27
+ pending += decoder.decode(value, { stream: true });
28
+ let end = pending.indexOf('\n\n');
29
+ while (end !== -1) {
30
+ const data = /^data:\s*(.*)$/m.exec(pending.slice(0, end))?.[1]?.trim() ?? '';
31
+ pending = pending.slice(end + 2);
32
+ end = pending.indexOf('\n\n');
33
+ if (data === '[DONE]')
34
+ return;
35
+ if (data.startsWith('{'))
36
+ yield JSON.parse(data);
37
+ }
38
+ if (done)
39
+ return;
40
+ }
41
+ }
42
+ function chatStream(body) {
43
+ const [raw, parsed] = body.tee();
44
+ const acc = { text: '', choices: [{ message: {} }] };
45
+ let credits = 0;
46
+ const source = (async function* () {
47
+ for await (const e of events(parsed)) {
48
+ const totalum = e.totalum;
49
+ if (totalum) {
50
+ credits = totalum.credits ?? 0;
51
+ continue;
52
+ }
53
+ const chunk = e;
54
+ if (!acc.id && chunk.id)
55
+ acc.id = chunk.id;
56
+ if (!acc.model && chunk.model)
57
+ acc.model = chunk.model;
58
+ if (chunk.usage)
59
+ acc.usage = chunk.usage;
60
+ const choice = chunk.choices?.[0];
61
+ if (choice?.finish_reason && acc.choices?.[0])
62
+ acc.choices[0].finish_reason = choice.finish_reason;
63
+ const delta = choice?.delta?.content;
64
+ if (delta) {
65
+ acc.text += delta;
66
+ yield delta;
67
+ }
68
+ }
69
+ })();
70
+ const drain = async () => {
71
+ while (!(await source.next()).done) {
72
+ /* read to the end: the usage and credits chunks come last */
73
+ }
74
+ };
75
+ return {
76
+ raw,
77
+ /** The text deltas as they arrive (one pass; `result()` afterwards reads the rest). */
78
+ text: () => source,
79
+ async result() {
80
+ await drain();
81
+ const r = resultOf({
82
+ ...acc,
83
+ choices: [{ message: { content: acc.text }, finish_reason: acc.choices?.[0]?.finish_reason ?? null }],
84
+ });
85
+ return { ...r, usage: { ...r.usage, costUsd: acc.usage?.costUsd ?? 0, credits } };
86
+ },
87
+ };
88
+ }
89
+ /**
90
+ * `totalum.ai` (plan 05 §6.1, plan 04 §5.1) over SDK-API `/v1/ai/*` (scope `ai`): aliases `cheap|normal|best` or any
91
+ * OpenRouter slug, every call priced `usage.cost × 28` and returned with its credits. No `ai.agent()` (A5.27) — the
92
+ * agent loop is the template's `src/agents/` on the Vercel AI SDK, pointed at `gatewayConfig()`.
93
+ */
94
+ export function totalumAi(options = {}) {
95
+ const call = jsonClient(options);
96
+ const raw = rawClient(options);
97
+ const speech = totalumSpeech(options);
98
+ /**
99
+ * A chat completion; `model` is an alias (`cheap`, `normal`, `best`) or any OpenRouter slug.
100
+ *
101
+ * @example
102
+ * const { text } = await ai.chat({ model: 'cheap', messages: [{ role: 'user', content: 'Hi' }] });
103
+ */
104
+ const chat = Object.assign(async (req) => resultOf(await call('POST', '/v1/ai/chat', { ...req, stream: false })), {
105
+ /**
106
+ * The same request streamed: `raw` is the OpenAI-format SSE (return it from a route), `text()` its deltas,
107
+ * `result()` the final result with its credits.
108
+ */
109
+ stream: async (req) => {
110
+ const res = await raw('/v1/ai/chat', { ...req, stream: true });
111
+ if (!res.body)
112
+ throw new TotalumError('RESPONSE_PARSE_ERROR', 'The chat stream has no body', res.status);
113
+ return chatStream(res.body);
114
+ },
115
+ });
116
+ const videoJob = (jobId) => call('GET', `/v1/ai/video/${encodeURIComponent(jobId)}`);
117
+ /** A JSON object matching `schema` (JSON Schema). */
118
+ const generateObject = (req) => call('POST', '/v1/ai/object', req);
119
+ return {
120
+ chat,
121
+ generateObject,
122
+ /** Sugar over `generateObject`: one of `options`, chosen by the model. */
123
+ async classify(req) {
124
+ const { object } = await generateObject({
125
+ ...(req.model ? { model: req.model } : {}),
126
+ prompt: `${req.instructions ?? 'Classify the input into exactly one label.'}\n\nInput:\n${req.input}`,
127
+ schema: {
128
+ type: 'object',
129
+ properties: { label: { type: 'string', enum: [...req.options] } },
130
+ required: ['label'],
131
+ additionalProperties: false,
132
+ },
133
+ });
134
+ const label = object?.label;
135
+ return { label: typeof label === 'string' ? label : '' };
136
+ },
137
+ /** Embedding vectors for one or more texts. */
138
+ embed: (req) => call('POST', '/v1/ai/embed', req),
139
+ image: {
140
+ /** Images from a prompt; `store: true` keeps them as project files. */
141
+ generate: (req) => call('POST', '/v1/ai/image', req),
142
+ /** An image edited by a prompt. */
143
+ edit: (req) => call('POST', '/v1/ai/image/edit', req),
144
+ },
145
+ video: {
146
+ /** `202`: the job and the credits reserved for it; poll `get(jobId)` (the clip is stored when it completes). */
147
+ generate: (req) => call('POST', '/v1/ai/video', req),
148
+ /** The video job: `status`, and the stored clip once completed. */
149
+ get: videoJob,
150
+ /**
151
+ * ⚠ NODE-ONLY: polls `get(jobId)` until the job leaves `queued`/`running` (default every 5 s, at most 10 min).
152
+ * In a Worker it throws `NODE_ONLY` — store the `jobId` and read `get(jobId)` later instead.
153
+ */
154
+ async wait(jobId, opts = {}) {
155
+ assertNode('totalum.ai.video.wait()', 'Start the job with ai.video.generate(), store the jobId, and read ai.video.get(jobId) when the page is refreshed.', 'https://totalum.app/docs/sdk/ai#node-only');
156
+ const until = Date.now() + (opts.timeoutMs ?? 600_000);
157
+ for (;;) {
158
+ const job = await videoJob(jobId);
159
+ if ((job.status !== 'queued' && job.status !== 'running') || Date.now() > until)
160
+ return job;
161
+ await new Promise((r) => setTimeout(r, opts.intervalMs ?? 5000));
162
+ }
163
+ },
164
+ },
165
+ vision: {
166
+ /** A text description of an image (URL, data URL or project file key). */
167
+ describe: (req) => call('POST', '/v1/ai/vision/describe', req),
168
+ },
169
+ speech: {
170
+ /** Same as `speech.synthesize`. */
171
+ speak: speech.synthesize,
172
+ /** Same as `speech.transcribe`. */
173
+ transcribe: speech.transcribe,
174
+ },
175
+ models: {
176
+ /** The model aliases and the models a project may call, with their prices. */
177
+ list: () => call('GET', '/v1/ai/models'),
178
+ },
179
+ /** The exact OpenRouter API for any OpenRouter/OpenAI client (A6.19): `new OpenAI(ai.gatewayConfig())`. Server-side only. */
180
+ gatewayConfig: () => ({
181
+ baseURL: options.aiBaseUrl ?? readEnv('TOTALUM_AI_BASE_URL') ?? 'https://ai.totalum.app/api/v1',
182
+ apiKey: projectKey(options),
183
+ }),
184
+ };
185
+ }
@@ -0,0 +1,35 @@
1
+ import { b as SiteMetric, a as SiteDimension, S as SiteAnalyticsOutput } from '../_types/ops.d-C9375KIG.js';
2
+ import { T as TotalumClientOptions } from '../_types/errors.d-Cu3q_E_r.js';
3
+ export { a as TotalumError, i as isTotalumError } from '../_types/errors.d-Cu3q_E_r.js';
4
+ import '../_types/coerce.d-C0KIW76L.js';
5
+
6
+ interface SiteAnalyticsQuery {
7
+ /** ISO; default the last 7 days. */
8
+ from?: string;
9
+ to?: string;
10
+ /** `minute` only within the last 30 minutes. */
11
+ granularity?: 'minute' | 'hour' | 'day';
12
+ /** Up to 4. */
13
+ metric?: SiteMetric | SiteMetric[];
14
+ /** Omit for a time series (`series`); set for a top-N (`top`). */
15
+ dimension?: SiteDimension;
16
+ /** Top-N, ≤ 100. */
17
+ limit?: number;
18
+ bots?: 'exclude' | 'include' | 'only';
19
+ /** `dev` = the preview host, `live` = the published and custom hosts; omitted = both. */
20
+ env?: 'dev' | 'live';
21
+ }
22
+ /** `totalum.analytics` (plan 05 §6.13) over SDK-API `/v1/analytics/site` (scope `analytics:read`): the site's own traffic. Free. */
23
+ declare function totalumAnalytics(options?: TotalumClientOptions): {
24
+ /**
25
+ * Page views, visits, uniques, errors, bytes or TTFB as a series or a top-N.
26
+ *
27
+ * @example
28
+ * const { top } = await analytics.site({ dimension: 'path', metric: 'page_views', limit: 10 });
29
+ */
30
+ site: (q?: SiteAnalyticsQuery) => Promise<SiteAnalyticsOutput>;
31
+ };
32
+ type TotalumAnalytics = ReturnType<typeof totalumAnalytics>;
33
+
34
+ export { SiteAnalyticsOutput, SiteDimension, SiteMetric, TotalumClientOptions, totalumAnalytics };
35
+ export type { SiteAnalyticsQuery, TotalumAnalytics };
@@ -0,0 +1,15 @@
1
+ import { jsonClient, query } from '../http.js';
2
+ export { TotalumError, isTotalumError } from '../errors.js';
3
+ /** `totalum.analytics` (plan 05 §6.13) over SDK-API `/v1/analytics/site` (scope `analytics:read`): the site's own traffic. Free. */
4
+ export function totalumAnalytics(options = {}) {
5
+ const call = jsonClient(options);
6
+ return {
7
+ /**
8
+ * Page views, visits, uniques, errors, bytes or TTFB as a series or a top-N.
9
+ *
10
+ * @example
11
+ * const { top } = await analytics.site({ dimension: 'path', metric: 'page_views', limit: 10 });
12
+ */
13
+ site: (q = {}) => call('GET', `/v1/analytics/site${query({ ...q, metric: typeof q.metric === 'string' ? [q.metric] : q.metric })}`),
14
+ };
15
+ }