quantum-ai-sdk 0.2.0 → 0.2.2

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 (49) hide show
  1. package/dist/account.d.ts +22 -0
  2. package/dist/account.js +47 -0
  3. package/dist/agent.d.ts +12 -0
  4. package/dist/agent.js +114 -0
  5. package/dist/audio.d.ts +82 -0
  6. package/dist/audio.js +140 -0
  7. package/dist/auth.d.ts +7 -0
  8. package/dist/auth.js +8 -0
  9. package/dist/batch.d.ts +22 -0
  10. package/dist/batch.js +32 -0
  11. package/dist/chat.d.ts +27 -0
  12. package/dist/chat.js +122 -0
  13. package/dist/client.d.ts +264 -0
  14. package/dist/client.js +498 -0
  15. package/dist/compute.d.ts +37 -0
  16. package/dist/compute.js +56 -0
  17. package/dist/contact.d.ts +12 -0
  18. package/dist/contact.js +26 -0
  19. package/dist/credits.d.ts +27 -0
  20. package/dist/credits.js +40 -0
  21. package/dist/documents.d.ts +17 -0
  22. package/dist/documents.js +42 -0
  23. package/dist/embeddings.d.ts +7 -0
  24. package/dist/embeddings.js +14 -0
  25. package/dist/errors.d.ts +29 -0
  26. package/dist/errors.js +70 -0
  27. package/dist/image.d.ts +12 -0
  28. package/dist/image.js +28 -0
  29. package/dist/index.d.ts +17 -0
  30. package/dist/index.js +33 -0
  31. package/dist/jobs.d.ts +46 -0
  32. package/dist/jobs.js +128 -0
  33. package/dist/keys.d.ts +17 -0
  34. package/dist/keys.js +24 -0
  35. package/dist/models.d.ts +12 -0
  36. package/dist/models.js +16 -0
  37. package/dist/rag.d.ts +22 -0
  38. package/dist/rag.js +44 -0
  39. package/dist/realtime.d.ts +121 -0
  40. package/dist/realtime.js +259 -0
  41. package/dist/session.d.ts +7 -0
  42. package/dist/session.js +17 -0
  43. package/dist/types.d.ts +1018 -0
  44. package/dist/types.js +5 -0
  45. package/dist/video.d.ts +46 -0
  46. package/dist/video.js +74 -0
  47. package/dist/voices.d.ts +27 -0
  48. package/dist/voices.js +55 -0
  49. package/package.json +3 -3
@@ -0,0 +1,22 @@
1
+ import type { QuantumClient } from "./client.js";
2
+ import type { BalanceResponse, UsageQuery, UsageResponse, UsageSummaryResponse, AccountPricingResponse } from "./types.js";
3
+ /**
4
+ * Get account credit balance.
5
+ * @internal — called by QuantumClient.accountBalance()
6
+ */
7
+ export declare function accountBalance(client: QuantumClient): Promise<BalanceResponse>;
8
+ /**
9
+ * Get paginated usage history.
10
+ * @internal — called by QuantumClient.accountUsage()
11
+ */
12
+ export declare function accountUsage(client: QuantumClient, query?: UsageQuery): Promise<UsageResponse>;
13
+ /**
14
+ * Get monthly usage summary.
15
+ * @internal — called by QuantumClient.accountUsageSummary()
16
+ */
17
+ export declare function accountUsageSummary(client: QuantumClient, months?: number): Promise<UsageSummaryResponse>;
18
+ /**
19
+ * Get the full pricing table (model ID → pricing entry map).
20
+ * @internal — called by QuantumClient.accountPricing()
21
+ */
22
+ export declare function accountPricing(client: QuantumClient): Promise<AccountPricingResponse>;
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Get account credit balance.
3
+ * @internal — called by QuantumClient.accountBalance()
4
+ */
5
+ export async function accountBalance(client) {
6
+ const { data } = await client._doJSON("GET", "/qai/v1/account/balance", undefined);
7
+ return data;
8
+ }
9
+ /**
10
+ * Get paginated usage history.
11
+ * @internal — called by QuantumClient.accountUsage()
12
+ */
13
+ export async function accountUsage(client, query) {
14
+ let path = "/qai/v1/account/usage";
15
+ const params = [];
16
+ if (query?.limit !== undefined) {
17
+ params.push(`limit=${query.limit}`);
18
+ }
19
+ if (query?.start_after !== undefined) {
20
+ params.push(`start_after=${query.start_after}`);
21
+ }
22
+ if (params.length > 0) {
23
+ path += `?${params.join("&")}`;
24
+ }
25
+ const { data } = await client._doJSON("GET", path, undefined);
26
+ return data;
27
+ }
28
+ /**
29
+ * Get monthly usage summary.
30
+ * @internal — called by QuantumClient.accountUsageSummary()
31
+ */
32
+ export async function accountUsageSummary(client, months) {
33
+ let path = "/qai/v1/account/usage/summary";
34
+ if (months !== undefined) {
35
+ path += `?months=${months}`;
36
+ }
37
+ const { data } = await client._doJSON("GET", path, undefined);
38
+ return data;
39
+ }
40
+ /**
41
+ * Get the full pricing table (model ID → pricing entry map).
42
+ * @internal — called by QuantumClient.accountPricing()
43
+ */
44
+ export async function accountPricing(client) {
45
+ const { data } = await client._doJSON("GET", "/qai/v1/pricing", undefined);
46
+ return data;
47
+ }
@@ -0,0 +1,12 @@
1
+ import type { QuantumClient } from "./client.js";
2
+ import type { AgentEvent, AgentRequest, MissionEvent, MissionRequest } from "./types.js";
3
+ /**
4
+ * Run a server-side agent orchestration. Streams SSE events.
5
+ * @internal — called by QuantumClient.agentRun()
6
+ */
7
+ export declare function agentRun(client: QuantumClient, req: AgentRequest, signal?: AbortSignal): AsyncIterableIterator<AgentEvent>;
8
+ /**
9
+ * Run a full mission orchestration. Streams SSE events.
10
+ * @internal — called by QuantumClient.missionRun()
11
+ */
12
+ export declare function missionRun(client: QuantumClient, req: MissionRequest, signal?: AbortSignal): AsyncIterableIterator<MissionEvent>;
package/dist/agent.js ADDED
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Parse a raw SSE JSON event into a typed agent/mission event.
3
+ */
4
+ function parseSSEEvent(raw) {
5
+ const event = { ...raw, done: false };
6
+ if (raw.type === "done") {
7
+ event.done = true;
8
+ }
9
+ // Parse usage if present
10
+ if (raw.input_tokens !== undefined ||
11
+ raw.output_tokens !== undefined ||
12
+ raw.cost_ticks !== undefined) {
13
+ event.usage = {
14
+ input_tokens: raw.input_tokens ?? 0,
15
+ output_tokens: raw.output_tokens ?? 0,
16
+ cost_ticks: raw.cost_ticks ?? 0,
17
+ };
18
+ }
19
+ return event;
20
+ }
21
+ /**
22
+ * Run a server-side agent orchestration. Streams SSE events.
23
+ * @internal — called by QuantumClient.agentRun()
24
+ */
25
+ export async function* agentRun(client, req, signal) {
26
+ const response = await client._doStreamRaw("/qai/v1/agent", req, signal);
27
+ const reader = response.body;
28
+ if (!reader) {
29
+ throw new Error("qai: response body is null");
30
+ }
31
+ const decoder = new TextDecoder();
32
+ const streamReader = reader.getReader();
33
+ let buffer = "";
34
+ try {
35
+ while (true) {
36
+ const { done, value } = await streamReader.read();
37
+ if (done) {
38
+ break;
39
+ }
40
+ buffer += decoder.decode(value, { stream: true });
41
+ const lines = buffer.split("\n");
42
+ buffer = lines.pop() ?? "";
43
+ for (const line of lines) {
44
+ if (!line.startsWith("data: ")) {
45
+ continue;
46
+ }
47
+ const payload = line.slice(6);
48
+ if (payload === "[DONE]") {
49
+ yield { type: "done", done: true };
50
+ return;
51
+ }
52
+ let raw;
53
+ try {
54
+ raw = JSON.parse(payload);
55
+ }
56
+ catch {
57
+ yield { type: "error", message: "parse SSE: invalid JSON", done: false };
58
+ return;
59
+ }
60
+ yield parseSSEEvent(raw);
61
+ }
62
+ }
63
+ }
64
+ finally {
65
+ streamReader.releaseLock();
66
+ }
67
+ }
68
+ /**
69
+ * Run a full mission orchestration. Streams SSE events.
70
+ * @internal — called by QuantumClient.missionRun()
71
+ */
72
+ export async function* missionRun(client, req, signal) {
73
+ const response = await client._doStreamRaw("/qai/v1/missions", req, signal);
74
+ const reader = response.body;
75
+ if (!reader) {
76
+ throw new Error("qai: response body is null");
77
+ }
78
+ const decoder = new TextDecoder();
79
+ const streamReader = reader.getReader();
80
+ let buffer = "";
81
+ try {
82
+ while (true) {
83
+ const { done, value } = await streamReader.read();
84
+ if (done) {
85
+ break;
86
+ }
87
+ buffer += decoder.decode(value, { stream: true });
88
+ const lines = buffer.split("\n");
89
+ buffer = lines.pop() ?? "";
90
+ for (const line of lines) {
91
+ if (!line.startsWith("data: ")) {
92
+ continue;
93
+ }
94
+ const payload = line.slice(6);
95
+ if (payload === "[DONE]") {
96
+ yield { type: "done", done: true };
97
+ return;
98
+ }
99
+ let raw;
100
+ try {
101
+ raw = JSON.parse(payload);
102
+ }
103
+ catch {
104
+ yield { type: "error", message: "parse SSE: invalid JSON", done: false };
105
+ return;
106
+ }
107
+ yield parseSSEEvent(raw);
108
+ }
109
+ }
110
+ }
111
+ finally {
112
+ streamReader.releaseLock();
113
+ }
114
+ }
@@ -0,0 +1,82 @@
1
+ import type { QuantumClient } from "./client.js";
2
+ import type { AlignRequest, AlignResponse, DialogueRequest, DialogueResponse, DubRequest, DubResponse, IsolateVoiceRequest, IsolateVoiceResponse, MusicAdvancedRequest, MusicAdvancedResponse, MusicFinetuneCreateRequest, MusicFinetuneInfo, MusicFinetuneListResponse, MusicRequest, MusicResponse, RemixVoiceRequest, RemixVoiceResponse, SoundEffectRequest, SoundEffectResponse, SpeechToSpeechRequest, SpeechToSpeechResponse, StarfishTTSRequest, StarfishTTSResponse, StatusResponse, STTRequest, STTResponse, TTSRequest, TTSResponse, VoiceDesignRequest, VoiceDesignResponse } from "./types.js";
3
+ /**
4
+ * Generate speech from text.
5
+ * @internal
6
+ */
7
+ export declare function speak(client: QuantumClient, req: TTSRequest): Promise<TTSResponse>;
8
+ /**
9
+ * Convert speech to text.
10
+ * @internal
11
+ */
12
+ export declare function transcribe(client: QuantumClient, req: STTRequest): Promise<STTResponse>;
13
+ /**
14
+ * Generate sound effects from a text prompt (ElevenLabs).
15
+ * @internal
16
+ */
17
+ export declare function soundEffects(client: QuantumClient, req: SoundEffectRequest): Promise<SoundEffectResponse>;
18
+ /**
19
+ * Generate music from a text prompt.
20
+ * @internal
21
+ */
22
+ export declare function generateMusic(client: QuantumClient, req: MusicRequest): Promise<MusicResponse>;
23
+ /**
24
+ * Generate multi-speaker dialogue audio (ElevenLabs).
25
+ * @internal
26
+ */
27
+ export declare function dialogue(client: QuantumClient, req: DialogueRequest): Promise<DialogueResponse>;
28
+ /**
29
+ * Convert speech audio to a different voice (ElevenLabs).
30
+ * @internal
31
+ */
32
+ export declare function speechToSpeech(client: QuantumClient, req: SpeechToSpeechRequest): Promise<SpeechToSpeechResponse>;
33
+ /**
34
+ * Remove background noise and isolate speech (ElevenLabs).
35
+ * @internal
36
+ */
37
+ export declare function isolateVoice(client: QuantumClient, req: IsolateVoiceRequest): Promise<IsolateVoiceResponse>;
38
+ /**
39
+ * Transform a voice by modifying attributes (ElevenLabs).
40
+ * @internal
41
+ */
42
+ export declare function remixVoice(client: QuantumClient, req: RemixVoiceRequest): Promise<RemixVoiceResponse>;
43
+ /**
44
+ * Dub audio/video into a target language (ElevenLabs).
45
+ * @internal
46
+ */
47
+ export declare function dub(client: QuantumClient, req: DubRequest): Promise<DubResponse>;
48
+ /**
49
+ * Get word-level timestamps for audio+text alignment (ElevenLabs).
50
+ * @internal
51
+ */
52
+ export declare function align(client: QuantumClient, req: AlignRequest): Promise<AlignResponse>;
53
+ /**
54
+ * Generate voice previews from a text description (ElevenLabs).
55
+ * @internal
56
+ */
57
+ export declare function voiceDesign(client: QuantumClient, req: VoiceDesignRequest): Promise<VoiceDesignResponse>;
58
+ /**
59
+ * Generate speech using HeyGen's Starfish TTS model.
60
+ * @internal
61
+ */
62
+ export declare function starfishTTS(client: QuantumClient, req: StarfishTTSRequest): Promise<StarfishTTSResponse>;
63
+ /**
64
+ * Generate music via ElevenLabs Eleven Music (advanced: finetunes, etc).
65
+ * @internal
66
+ */
67
+ export declare function generateMusicAdvanced(client: QuantumClient, req: MusicAdvancedRequest): Promise<MusicAdvancedResponse>;
68
+ /**
69
+ * List all music finetunes for the authenticated user.
70
+ * @internal
71
+ */
72
+ export declare function listFinetunes(client: QuantumClient): Promise<MusicFinetuneListResponse>;
73
+ /**
74
+ * Create a new music finetune from audio samples (base64-encoded).
75
+ * @internal
76
+ */
77
+ export declare function createFinetune(client: QuantumClient, req: MusicFinetuneCreateRequest): Promise<MusicFinetuneInfo>;
78
+ /**
79
+ * Delete a music finetune by ID.
80
+ * @internal
81
+ */
82
+ export declare function deleteFinetune(client: QuantumClient, id: string): Promise<StatusResponse>;
package/dist/audio.js ADDED
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Helper to backfill cost/request metadata from response headers.
3
+ */
4
+ function backfillMeta(data, meta) {
5
+ if (!data.cost_ticks) {
6
+ data.cost_ticks = meta.costTicks;
7
+ }
8
+ if (!data.request_id) {
9
+ data.request_id = meta.requestId;
10
+ }
11
+ return data;
12
+ }
13
+ /**
14
+ * Generate speech from text.
15
+ * @internal
16
+ */
17
+ export async function speak(client, req) {
18
+ const { data, meta } = await client._doJSON("POST", "/qai/v1/audio/tts", req);
19
+ return backfillMeta(data, meta);
20
+ }
21
+ /**
22
+ * Convert speech to text.
23
+ * @internal
24
+ */
25
+ export async function transcribe(client, req) {
26
+ const { data, meta } = await client._doJSON("POST", "/qai/v1/audio/stt", req);
27
+ return backfillMeta(data, meta);
28
+ }
29
+ /**
30
+ * Generate sound effects from a text prompt (ElevenLabs).
31
+ * @internal
32
+ */
33
+ export async function soundEffects(client, req) {
34
+ const { data, meta } = await client._doJSON("POST", "/qai/v1/audio/sound-effects", req);
35
+ return backfillMeta(data, meta);
36
+ }
37
+ /**
38
+ * Generate music from a text prompt.
39
+ * @internal
40
+ */
41
+ export async function generateMusic(client, req) {
42
+ const { data, meta } = await client._doJSON("POST", "/qai/v1/audio/music", req);
43
+ return backfillMeta(data, meta);
44
+ }
45
+ /**
46
+ * Generate multi-speaker dialogue audio (ElevenLabs).
47
+ * @internal
48
+ */
49
+ export async function dialogue(client, req) {
50
+ const { data, meta } = await client._doJSON("POST", "/qai/v1/audio/dialogue", req);
51
+ return backfillMeta(data, meta);
52
+ }
53
+ /**
54
+ * Convert speech audio to a different voice (ElevenLabs).
55
+ * @internal
56
+ */
57
+ export async function speechToSpeech(client, req) {
58
+ const { data, meta } = await client._doJSON("POST", "/qai/v1/audio/speech-to-speech", req);
59
+ return backfillMeta(data, meta);
60
+ }
61
+ /**
62
+ * Remove background noise and isolate speech (ElevenLabs).
63
+ * @internal
64
+ */
65
+ export async function isolateVoice(client, req) {
66
+ const { data, meta } = await client._doJSON("POST", "/qai/v1/audio/isolate", req);
67
+ return backfillMeta(data, meta);
68
+ }
69
+ /**
70
+ * Transform a voice by modifying attributes (ElevenLabs).
71
+ * @internal
72
+ */
73
+ export async function remixVoice(client, req) {
74
+ const { data, meta } = await client._doJSON("POST", "/qai/v1/audio/remix", req);
75
+ return backfillMeta(data, meta);
76
+ }
77
+ /**
78
+ * Dub audio/video into a target language (ElevenLabs).
79
+ * @internal
80
+ */
81
+ export async function dub(client, req) {
82
+ const { data, meta } = await client._doJSON("POST", "/qai/v1/audio/dub", req);
83
+ return backfillMeta(data, meta);
84
+ }
85
+ /**
86
+ * Get word-level timestamps for audio+text alignment (ElevenLabs).
87
+ * @internal
88
+ */
89
+ export async function align(client, req) {
90
+ const { data, meta } = await client._doJSON("POST", "/qai/v1/audio/align", req);
91
+ return backfillMeta(data, meta);
92
+ }
93
+ /**
94
+ * Generate voice previews from a text description (ElevenLabs).
95
+ * @internal
96
+ */
97
+ export async function voiceDesign(client, req) {
98
+ const { data, meta } = await client._doJSON("POST", "/qai/v1/audio/voice-design", req);
99
+ return backfillMeta(data, meta);
100
+ }
101
+ /**
102
+ * Generate speech using HeyGen's Starfish TTS model.
103
+ * @internal
104
+ */
105
+ export async function starfishTTS(client, req) {
106
+ const { data, meta } = await client._doJSON("POST", "/qai/v1/audio/starfish-tts", req);
107
+ return backfillMeta(data, meta);
108
+ }
109
+ /**
110
+ * Generate music via ElevenLabs Eleven Music (advanced: finetunes, etc).
111
+ * @internal
112
+ */
113
+ export async function generateMusicAdvanced(client, req) {
114
+ const { data, meta } = await client._doJSON("POST", "/qai/v1/audio/music/advanced", req);
115
+ return backfillMeta(data, meta);
116
+ }
117
+ /**
118
+ * List all music finetunes for the authenticated user.
119
+ * @internal
120
+ */
121
+ export async function listFinetunes(client) {
122
+ const { data } = await client._doJSON("GET", "/qai/v1/audio/finetunes", undefined);
123
+ return data;
124
+ }
125
+ /**
126
+ * Create a new music finetune from audio samples (base64-encoded).
127
+ * @internal
128
+ */
129
+ export async function createFinetune(client, req) {
130
+ const { data } = await client._doJSON("POST", "/qai/v1/audio/finetunes", req);
131
+ return data;
132
+ }
133
+ /**
134
+ * Delete a music finetune by ID.
135
+ * @internal
136
+ */
137
+ export async function deleteFinetune(client, id) {
138
+ const { data } = await client._doJSON("DELETE", `/qai/v1/audio/finetunes/${id}`, undefined);
139
+ return data;
140
+ }
package/dist/auth.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ import type { QuantumClient } from "./client.js";
2
+ import type { AuthAppleRequest, AuthResponse } from "./types.js";
3
+ /**
4
+ * Authenticate with Apple Sign-In.
5
+ * @internal — called by QuantumClient.authApple()
6
+ */
7
+ export declare function authApple(client: QuantumClient, req: AuthAppleRequest): Promise<AuthResponse>;
package/dist/auth.js ADDED
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Authenticate with Apple Sign-In.
3
+ * @internal — called by QuantumClient.authApple()
4
+ */
5
+ export async function authApple(client, req) {
6
+ const { data } = await client._doJSON("POST", "/qai/v1/auth/apple", req);
7
+ return data;
8
+ }
@@ -0,0 +1,22 @@
1
+ import type { QuantumClient } from "./client.js";
2
+ import type { BatchSubmitRequest, BatchSubmitResponse, BatchJsonlResponse, BatchJobsResponse, BatchJobInfo } from "./types.js";
3
+ /**
4
+ * Submit a batch of jobs for processing.
5
+ * @internal — called by QuantumClient.batchSubmit()
6
+ */
7
+ export declare function batchSubmit(client: QuantumClient, req: BatchSubmitRequest): Promise<BatchSubmitResponse>;
8
+ /**
9
+ * Submit a batch of jobs using JSONL format.
10
+ * @internal — called by QuantumClient.batchSubmitJsonl()
11
+ */
12
+ export declare function batchSubmitJsonl(client: QuantumClient, jsonl: string): Promise<BatchJsonlResponse>;
13
+ /**
14
+ * List all batch jobs for the account.
15
+ * @internal — called by QuantumClient.batchJobs()
16
+ */
17
+ export declare function batchJobs(client: QuantumClient): Promise<BatchJobsResponse>;
18
+ /**
19
+ * Get the status and result of a single batch job.
20
+ * @internal — called by QuantumClient.batchJob()
21
+ */
22
+ export declare function batchJob(client: QuantumClient, id: string): Promise<BatchJobInfo>;
package/dist/batch.js ADDED
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Submit a batch of jobs for processing.
3
+ * @internal — called by QuantumClient.batchSubmit()
4
+ */
5
+ export async function batchSubmit(client, req) {
6
+ const { data } = await client._doJSON("POST", "/qai/v1/batch", req);
7
+ return data;
8
+ }
9
+ /**
10
+ * Submit a batch of jobs using JSONL format.
11
+ * @internal — called by QuantumClient.batchSubmitJsonl()
12
+ */
13
+ export async function batchSubmitJsonl(client, jsonl) {
14
+ const { data } = await client._doJSON("POST", "/qai/v1/batch/jsonl", { jsonl });
15
+ return data;
16
+ }
17
+ /**
18
+ * List all batch jobs for the account.
19
+ * @internal — called by QuantumClient.batchJobs()
20
+ */
21
+ export async function batchJobs(client) {
22
+ const { data } = await client._doJSON("GET", "/qai/v1/batch/jobs", undefined);
23
+ return { ...data, jobs: data.jobs ?? [] };
24
+ }
25
+ /**
26
+ * Get the status and result of a single batch job.
27
+ * @internal — called by QuantumClient.batchJob()
28
+ */
29
+ export async function batchJob(client, id) {
30
+ const { data } = await client._doJSON("GET", `/qai/v1/batch/jobs/${id}`, undefined);
31
+ return data;
32
+ }
package/dist/chat.d.ts ADDED
@@ -0,0 +1,27 @@
1
+ import type { QuantumClient } from "./client.js";
2
+ import type { ChatRequest, ChatResponse, ContentBlock, StreamEvent } from "./types.js";
3
+ /**
4
+ * Returns concatenated text content from a ChatResponse, ignoring thinking and tool_use blocks.
5
+ */
6
+ export declare function responseText(response: ChatResponse): string;
7
+ /**
8
+ * Returns concatenated thinking content from a ChatResponse.
9
+ */
10
+ export declare function responseThinking(response: ChatResponse): string;
11
+ /**
12
+ * Returns all tool_use blocks from a ChatResponse.
13
+ */
14
+ export declare function responseToolCalls(response: ChatResponse): ContentBlock[];
15
+ /**
16
+ * Send a non-streaming chat request.
17
+ * @internal — called by QuantumClient.chat()
18
+ */
19
+ export declare function chat(client: QuantumClient, req: ChatRequest): Promise<ChatResponse>;
20
+ /**
21
+ * Send a streaming chat request. Returns an AsyncIterableIterator of StreamEvents.
22
+ *
23
+ * The last event will have done=true. Cancel the AbortSignal to abort early.
24
+ *
25
+ * @internal — called by QuantumClient.chatStream()
26
+ */
27
+ export declare function chatStream(client: QuantumClient, req: ChatRequest, signal?: AbortSignal): AsyncIterableIterator<StreamEvent>;
package/dist/chat.js ADDED
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Returns concatenated text content from a ChatResponse, ignoring thinking and tool_use blocks.
3
+ */
4
+ export function responseText(response) {
5
+ return response.content
6
+ .filter((b) => b.type === "text")
7
+ .map((b) => b.text ?? "")
8
+ .join("");
9
+ }
10
+ /**
11
+ * Returns concatenated thinking content from a ChatResponse.
12
+ */
13
+ export function responseThinking(response) {
14
+ return response.content
15
+ .filter((b) => b.type === "thinking")
16
+ .map((b) => b.text ?? "")
17
+ .join("");
18
+ }
19
+ /**
20
+ * Returns all tool_use blocks from a ChatResponse.
21
+ */
22
+ export function responseToolCalls(response) {
23
+ return response.content.filter((b) => b.type === "tool_use");
24
+ }
25
+ /**
26
+ * Send a non-streaming chat request.
27
+ * @internal — called by QuantumClient.chat()
28
+ */
29
+ export async function chat(client, req) {
30
+ const body = { ...req, stream: false };
31
+ const { data, meta } = await client._doJSON("POST", "/qai/v1/chat", body);
32
+ data.cost_ticks = data.cost_ticks || meta.costTicks;
33
+ data.request_id = data.request_id || meta.requestId;
34
+ if (!data.model) {
35
+ data.model = meta.model;
36
+ }
37
+ return data;
38
+ }
39
+ /**
40
+ * Send a streaming chat request. Returns an AsyncIterableIterator of StreamEvents.
41
+ *
42
+ * The last event will have done=true. Cancel the AbortSignal to abort early.
43
+ *
44
+ * @internal — called by QuantumClient.chatStream()
45
+ */
46
+ export async function* chatStream(client, req, signal) {
47
+ const body = { ...req, stream: true };
48
+ const response = await client._doStreamRaw("/qai/v1/chat", body, signal);
49
+ const reader = response.body;
50
+ if (!reader) {
51
+ throw new Error("qai: response body is null");
52
+ }
53
+ const decoder = new TextDecoder();
54
+ const streamReader = reader.getReader();
55
+ let buffer = "";
56
+ try {
57
+ while (true) {
58
+ const { done, value } = await streamReader.read();
59
+ if (done) {
60
+ break;
61
+ }
62
+ buffer += decoder.decode(value, { stream: true });
63
+ // Process complete lines from the buffer.
64
+ const lines = buffer.split("\n");
65
+ // Keep the last (possibly incomplete) line in the buffer.
66
+ buffer = lines.pop() ?? "";
67
+ for (const line of lines) {
68
+ if (!line.startsWith("data: ")) {
69
+ continue;
70
+ }
71
+ const payload = line.slice(6); // "data: ".length
72
+ if (payload === "[DONE]") {
73
+ yield { type: "done", done: true };
74
+ return;
75
+ }
76
+ let raw;
77
+ try {
78
+ raw = JSON.parse(payload);
79
+ }
80
+ catch {
81
+ yield {
82
+ type: "error",
83
+ error: `parse SSE: invalid JSON`,
84
+ done: false,
85
+ };
86
+ return;
87
+ }
88
+ const event = { type: raw.type || "unknown", done: false };
89
+ switch (raw.type) {
90
+ case "content_delta":
91
+ case "thinking_delta":
92
+ event.delta = raw.delta;
93
+ break;
94
+ case "tool_use":
95
+ event.tool_use = {
96
+ id: String(raw.id ?? ""),
97
+ name: String(raw.name ?? ""),
98
+ input: raw.input ?? {},
99
+ };
100
+ break;
101
+ case "usage":
102
+ event.usage = {
103
+ input_tokens: raw.input_tokens ?? 0,
104
+ output_tokens: raw.output_tokens ?? 0,
105
+ cost_ticks: raw.cost_ticks ?? 0,
106
+ };
107
+ break;
108
+ case "error":
109
+ event.error = raw.message;
110
+ break;
111
+ case "heartbeat":
112
+ // pass through
113
+ break;
114
+ }
115
+ yield event;
116
+ }
117
+ }
118
+ }
119
+ finally {
120
+ streamReader.releaseLock();
121
+ }
122
+ }