@spicyapi/sdk 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Official TypeScript SDK for the SpicyAPI public API. It contains the typed client, webhook
4
4
  verification helpers, documentation index, and generated OpenAPI types. It does not install the CLI,
5
- MCP server, or Codex Skill.
5
+ MCP server, or Agent Skill.
6
6
 
7
7
  ```bash
8
8
  npm install @spicyapi/sdk
@@ -16,6 +16,83 @@ const models = await client.listModels({ includeSchema: true });
16
16
  ```
17
17
 
18
18
  Set `SPICY_API_KEY` with your process secret manager. Task creation and retry may reserve funds; use
19
- stable idempotency keys and explicit user confirmation.
19
+ stable idempotency keys and explicit user confirmation. Call `quoteTask` with the exact request
20
+ first, display its `estimatedCost`, `maxCharge` and `expiresAt`, then call `createTask` with the
21
+ unchanged input, `quoteId` and `expectedCost`.
20
22
 
21
23
  Documentation: <https://spicyapi.ai/en/docs>
24
+
25
+ ## Chat and LLM streaming
26
+
27
+ Use the official `openai` client for `/v1/chat/completions`; install it separately with
28
+ `npm install openai`. The native SDK intentionally keeps tasks, quotes and uploads in one small
29
+ client. It does not reimplement the OpenAI streaming protocol.
30
+
31
+ ```js
32
+ import OpenAI from "openai";
33
+
34
+ const client = new OpenAI({
35
+ apiKey: process.env.SPICY_API_KEY,
36
+ baseURL: "https://api.spicyapi.ai/v1",
37
+ maxRetries: 0,
38
+ });
39
+ const signal = AbortSignal.timeout(120_000);
40
+ const stream = await client.chat.completions.create(
41
+ {
42
+ model: process.env.SPICY_MODEL,
43
+ messages: [{ role: "user", content: "Explain a rainbow in one sentence." }],
44
+ stream: true,
45
+ stream_options: { include_usage: true },
46
+ },
47
+ {
48
+ signal,
49
+ headers: { "Idempotency-Key": process.env.SPICY_IDEMPOTENCY_KEY },
50
+ },
51
+ );
52
+ try {
53
+ for await (const chunk of stream) {
54
+ process.stdout.write(chunk.choices[0]?.delta.content ?? "");
55
+ if (chunk.usage) process.stderr.write(JSON.stringify(chunk.usage) + "\n");
56
+ }
57
+ } finally {
58
+ stream.controller.abort();
59
+ }
60
+ ```
61
+
62
+ The abort signal covers stream consumption as well as connection setup. Aborting stops the local
63
+ stream; it does not cancel an accepted task or promise a refund. With `stream: false`, read
64
+ `choices[0].message.content`. In a tool conversation, accumulate tool-call fragments by index and
65
+ preserve the complete assistant message before adding matching `tool_call_id` results. Only enable
66
+ tools or reasoning fields when the model schema supports them.
67
+
68
+ CLI and MCP currently submit and track native tasks; they do not expose live chat token streaming.
69
+ Use this client path for a token-by-token interface, or native `jobs/stream` when you need quote
70
+ confirmation and the platform event envelope.
71
+
72
+ Select `SPICY_MODEL` from the live model schema. Keep API keys on your server and persist
73
+ `SPICY_IDEMPOTENCY_KEY` for the same logical action; disable automatic retries to avoid silently
74
+ repeating a billable operation. Compatibility requests use the price at acceptance. Use native
75
+ `quoteTask` and `createTask` when confirming `expectedCost` is required.
76
+
77
+ Reasoning-capable models may return `delta.reasoning_content`; it is optional and may need an
78
+ explicit type extension in the official client. Reasoning tokens are already included in
79
+ `completion_tokens`. Stream completion is not proof of financial settlement.
80
+
81
+ [Complete compatibility guide](https://spicyapi.ai/en/docs/quotes-and-compatibility) ·
82
+ [Official JavaScript client](https://github.com/openai/openai-node)
83
+
84
+ ## Media inputs and results
85
+
86
+ Pass a publicly accessible HTTPS image, video, or audio URL directly in the field specified by the
87
+ model schema. Uploading is optional: local files use `createUploadUrl` → PUT → `commitUploadedFile`,
88
+ then the returned account-bound `spicy://` URI (valid for one day).
89
+
90
+ `getTask` and `waitForTask` return ready media in `output.assets`, including `url`, `expiresAt`,
91
+ MIME, and available dimensions, duration, and byte count. Download `asset.url` directly without
92
+ forwarding `SPICY_API_KEY`; no separate `createDownloadUrl` call is required. `pending` assets need
93
+ another poll. URLs normally last 20 minutes, within the 14-day result retention window. Poll again
94
+ to refresh a URL; `createDownloadUrl` remains available for older integrations.
95
+
96
+ V2 webhooks use the same result fields. A retry keeps the business event and `request_id`, but
97
+ refreshes `url` and `expiresAt`. Verify the signature against the exact received body and
98
+ deduplicate using `request_id`, not a full-body hash. V1 payloads remain unchanged.