@astralform/js 7.2.0 → 7.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/dist/index.cjs +179 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +150 -2
- package/dist/index.d.ts +150 -2
- package/dist/index.js +175 -46
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -35,10 +35,14 @@ __export(index_exports, {
|
|
|
35
35
|
StreamAbortedError: () => StreamAbortedError,
|
|
36
36
|
StreamManager: () => StreamManager,
|
|
37
37
|
ToolRegistry: () => ToolRegistry,
|
|
38
|
+
VOICE_POLISH_MODES: () => VOICE_POLISH_MODES,
|
|
38
39
|
generateId: () => generateId,
|
|
39
40
|
isEmbeddedResource: () => isEmbeddedResource,
|
|
41
|
+
isVoiceLLMMode: () => isVoiceLLMMode,
|
|
42
|
+
isVoicePolishMode: () => isVoicePolishMode,
|
|
40
43
|
mapSseToChat: () => mapSseToChat,
|
|
41
44
|
parseEmbeddedResource: () => parseEmbeddedResource,
|
|
45
|
+
parseVoicePolishFrame: () => parseVoicePolishFrame,
|
|
42
46
|
replayEvents: () => replayEvents,
|
|
43
47
|
streamJobSSE: () => streamJobSSE,
|
|
44
48
|
translateDelta: () => translateDelta
|
|
@@ -241,12 +245,13 @@ function createRateLimitErrorFromHttp(response, rawText) {
|
|
|
241
245
|
|
|
242
246
|
// src/streaming.ts
|
|
243
247
|
async function* streamJobSSE(options) {
|
|
244
|
-
const { url, headers, signal, fetchFn } = options;
|
|
248
|
+
const { url, headers, signal, fetchFn, method = "GET", body } = options;
|
|
245
249
|
let response;
|
|
246
250
|
try {
|
|
247
251
|
response = await fetchFn(url, {
|
|
248
|
-
method
|
|
252
|
+
method,
|
|
249
253
|
headers,
|
|
254
|
+
body,
|
|
250
255
|
signal
|
|
251
256
|
});
|
|
252
257
|
} catch (err) {
|
|
@@ -308,6 +313,57 @@ async function* streamJobSSE(options) {
|
|
|
308
313
|
}
|
|
309
314
|
}
|
|
310
315
|
|
|
316
|
+
// src/types.ts
|
|
317
|
+
var ChatEventType = {
|
|
318
|
+
// Connection lifecycle (SDK-local, not wire)
|
|
319
|
+
Connected: "connected",
|
|
320
|
+
Disconnected: "disconnected",
|
|
321
|
+
// Turn lifecycle
|
|
322
|
+
MessageStart: "message_start",
|
|
323
|
+
MessageStop: "message_stop",
|
|
324
|
+
// Block lifecycle
|
|
325
|
+
BlockStart: "block_start",
|
|
326
|
+
BlockDelta: "block_delta",
|
|
327
|
+
BlockStop: "block_stop",
|
|
328
|
+
// Reliability
|
|
329
|
+
Stall: "stall",
|
|
330
|
+
Retry: "retry",
|
|
331
|
+
Error: "error",
|
|
332
|
+
Keepalive: "keepalive",
|
|
333
|
+
// Conversation-level (typed custom events)
|
|
334
|
+
UserMessage: "user_message",
|
|
335
|
+
TitleGenerated: "title_generated",
|
|
336
|
+
TodoUpdate: "todo_update",
|
|
337
|
+
PlanUpdate: "plan_update",
|
|
338
|
+
NoteUpdate: "note_update",
|
|
339
|
+
ContextUpdate: "context_update",
|
|
340
|
+
SubagentStart: "subagent_start",
|
|
341
|
+
SubagentStop: "subagent_stop",
|
|
342
|
+
ContextWarning: "context_warning",
|
|
343
|
+
MemoryRecall: "memory_recall",
|
|
344
|
+
MemoryUpdate: "memory_update",
|
|
345
|
+
DesktopStream: "desktop_stream",
|
|
346
|
+
AttachmentStaged: "attachment_staged",
|
|
347
|
+
WorkspaceReady: "workspace_ready",
|
|
348
|
+
AssetCreated: "asset_created",
|
|
349
|
+
ToolApprovalRequested: "tool_approval_requested",
|
|
350
|
+
ToolApprovalGranted: "tool_approval_granted",
|
|
351
|
+
ToolPermissionDenied: "tool_permission_denied",
|
|
352
|
+
ToolHarnessWarning: "tool_harness_warning",
|
|
353
|
+
UserUnavailable: "user_unavailable",
|
|
354
|
+
PromptSuggestion: "prompt_suggestion",
|
|
355
|
+
StateChanged: "state_changed",
|
|
356
|
+
// Generic fallthrough for unknown custom events
|
|
357
|
+
Custom: "custom"
|
|
358
|
+
};
|
|
359
|
+
var VOICE_POLISH_MODES = ["raw", "light", "structured", "formal"];
|
|
360
|
+
function isVoicePolishMode(value) {
|
|
361
|
+
return typeof value === "string" && VOICE_POLISH_MODES.includes(value);
|
|
362
|
+
}
|
|
363
|
+
function isVoiceLLMMode(mode) {
|
|
364
|
+
return mode !== "raw";
|
|
365
|
+
}
|
|
366
|
+
|
|
311
367
|
// src/client.ts
|
|
312
368
|
var DEFAULT_BASE_URL = "https://api.astralform.ai";
|
|
313
369
|
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
@@ -736,6 +792,94 @@ var AstralformClient = class {
|
|
|
736
792
|
const raw = await response.json();
|
|
737
793
|
return this.mapAsset(raw);
|
|
738
794
|
}
|
|
795
|
+
// --- Voice input ---
|
|
796
|
+
/** The agent's voice-input defaults (`GET /v1/voice/config`). */
|
|
797
|
+
async getVoiceConfig() {
|
|
798
|
+
const raw = await this.get("/v1/voice/config");
|
|
799
|
+
return {
|
|
800
|
+
enabled: Boolean(raw.enabled),
|
|
801
|
+
modes: raw.modes ?? [...VOICE_POLISH_MODES],
|
|
802
|
+
// A mode this SDK does not know must not reach a `switch` typed as
|
|
803
|
+
// `VoicePolishMode`; `structured` is the server's own default.
|
|
804
|
+
defaultMode: isVoicePolishMode(raw.default_mode) ? raw.default_mode : "structured",
|
|
805
|
+
silenceAutoStopSeconds: raw.silence_auto_stop_seconds ?? 2,
|
|
806
|
+
autoSend: raw.auto_send ?? true,
|
|
807
|
+
maxRecordingSeconds: raw.max_recording_seconds ?? 300,
|
|
808
|
+
supportsStreaming: Boolean(raw.supports_streaming),
|
|
809
|
+
hotwords: raw.hotwords ?? []
|
|
810
|
+
};
|
|
811
|
+
}
|
|
812
|
+
/**
|
|
813
|
+
* Transcribe one recording with the agent's configured speech-to-text
|
|
814
|
+
* provider (`POST /v1/voice/transcriptions`). 16 kHz mono 16-bit WAV is the
|
|
815
|
+
* reference format; anything the provider accepts works.
|
|
816
|
+
*
|
|
817
|
+
* Deliberately outside `withDeadline`: a recording can run to
|
|
818
|
+
* `VoiceConfig.maxRecordingSeconds`, so the 30 s default would cut real
|
|
819
|
+
* uploads off. Pass `options.signal` to give up on a stalled one; the
|
|
820
|
+
* promise then rejects with the abort reason — the runtime's `AbortError`,
|
|
821
|
+
* or whatever was passed to `abort(reason)`.
|
|
822
|
+
*/
|
|
823
|
+
async transcribeVoice(audio, options = {}) {
|
|
824
|
+
const formData = new FormData();
|
|
825
|
+
formData.append("file", audio, options.filename ?? "recording.wav");
|
|
826
|
+
if (options.hotwords?.length) {
|
|
827
|
+
formData.append("hotwords", options.hotwords.join(", "));
|
|
828
|
+
}
|
|
829
|
+
if (options.language) {
|
|
830
|
+
formData.append("language", options.language);
|
|
831
|
+
}
|
|
832
|
+
const response = await this.fetchFn(`${this.baseURL}/v1/voice/transcriptions`, {
|
|
833
|
+
method: "POST",
|
|
834
|
+
headers: this.authHeaders,
|
|
835
|
+
body: formData,
|
|
836
|
+
signal: options.signal
|
|
837
|
+
}).catch((err) => {
|
|
838
|
+
if (options.signal?.aborted) {
|
|
839
|
+
throw err;
|
|
840
|
+
}
|
|
841
|
+
throw new ConnectionError(
|
|
842
|
+
err instanceof Error ? err.message : "Failed to connect"
|
|
843
|
+
);
|
|
844
|
+
});
|
|
845
|
+
await this.handleError(response);
|
|
846
|
+
const raw = await response.json();
|
|
847
|
+
return {
|
|
848
|
+
text: raw.text ?? "",
|
|
849
|
+
language: raw.language ?? null,
|
|
850
|
+
durationMs: raw.duration_ms ?? null,
|
|
851
|
+
asrMs: raw.asr_ms ?? 0
|
|
852
|
+
};
|
|
853
|
+
}
|
|
854
|
+
/**
|
|
855
|
+
* Stream the LLM rewrite of a transcript (`POST /v1/voice/polish`) as typed
|
|
856
|
+
* frames.
|
|
857
|
+
*
|
|
858
|
+
* Failures the server reports mid-stream arrive as an `error` frame, but
|
|
859
|
+
* the iteration itself can reject: aborting `signal` closes the connection
|
|
860
|
+
* (which cancels the model call upstream) and rejects with
|
|
861
|
+
* `StreamAbortedError`; a non-2xx open rejects with `AuthenticationError`,
|
|
862
|
+
* `RateLimitError` or `ServerError`; a network failure with
|
|
863
|
+
* `ConnectionError`. Wrap the `for await` accordingly.
|
|
864
|
+
*/
|
|
865
|
+
async *streamVoicePolish(request, options = {}) {
|
|
866
|
+
const frames = streamJobSSE({
|
|
867
|
+
url: `${this.baseURL}/v1/voice/polish`,
|
|
868
|
+
headers: { ...this.headers, Accept: "text/event-stream" },
|
|
869
|
+
method: "POST",
|
|
870
|
+
body: JSON.stringify({
|
|
871
|
+
text: request.text,
|
|
872
|
+
mode: request.mode,
|
|
873
|
+
hotwords: request.hotwords ?? []
|
|
874
|
+
}),
|
|
875
|
+
signal: options.signal,
|
|
876
|
+
fetchFn: this.fetchFn
|
|
877
|
+
});
|
|
878
|
+
for await (const frame of frames) {
|
|
879
|
+
const event = parseVoicePolishFrame(frame);
|
|
880
|
+
if (event) yield event;
|
|
881
|
+
}
|
|
882
|
+
}
|
|
739
883
|
async listUploads(conversationId) {
|
|
740
884
|
const raw = await this.get(
|
|
741
885
|
`/v1/conversations/${encodeURIComponent(conversationId)}/uploads`
|
|
@@ -822,6 +966,35 @@ var AstralformClient = class {
|
|
|
822
966
|
}));
|
|
823
967
|
}
|
|
824
968
|
};
|
|
969
|
+
function parseVoicePolishFrame(frame) {
|
|
970
|
+
let payload;
|
|
971
|
+
try {
|
|
972
|
+
const parsed = JSON.parse(frame.data);
|
|
973
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return null;
|
|
974
|
+
payload = parsed;
|
|
975
|
+
} catch {
|
|
976
|
+
return null;
|
|
977
|
+
}
|
|
978
|
+
switch (frame.event) {
|
|
979
|
+
case "delta":
|
|
980
|
+
return typeof payload.text === "string" ? { type: "delta", text: payload.text } : null;
|
|
981
|
+
case "done":
|
|
982
|
+
return typeof payload.text === "string" ? {
|
|
983
|
+
type: "done",
|
|
984
|
+
text: payload.text,
|
|
985
|
+
polishMs: payload.polish_ms ?? 0
|
|
986
|
+
} : null;
|
|
987
|
+
case "error":
|
|
988
|
+
return {
|
|
989
|
+
type: "error",
|
|
990
|
+
reason: payload.reason ?? "unknown",
|
|
991
|
+
partial: payload.partial ?? "",
|
|
992
|
+
...typeof payload.detail === "string" ? { detail: payload.detail } : {}
|
|
993
|
+
};
|
|
994
|
+
default:
|
|
995
|
+
return null;
|
|
996
|
+
}
|
|
997
|
+
}
|
|
825
998
|
|
|
826
999
|
// src/storage.ts
|
|
827
1000
|
var InMemoryStorage = class {
|
|
@@ -2306,50 +2479,6 @@ function planRestore(args) {
|
|
|
2306
2479
|
return steps;
|
|
2307
2480
|
}
|
|
2308
2481
|
|
|
2309
|
-
// src/types.ts
|
|
2310
|
-
var ChatEventType = {
|
|
2311
|
-
// Connection lifecycle (SDK-local, not wire)
|
|
2312
|
-
Connected: "connected",
|
|
2313
|
-
Disconnected: "disconnected",
|
|
2314
|
-
// Turn lifecycle
|
|
2315
|
-
MessageStart: "message_start",
|
|
2316
|
-
MessageStop: "message_stop",
|
|
2317
|
-
// Block lifecycle
|
|
2318
|
-
BlockStart: "block_start",
|
|
2319
|
-
BlockDelta: "block_delta",
|
|
2320
|
-
BlockStop: "block_stop",
|
|
2321
|
-
// Reliability
|
|
2322
|
-
Stall: "stall",
|
|
2323
|
-
Retry: "retry",
|
|
2324
|
-
Error: "error",
|
|
2325
|
-
Keepalive: "keepalive",
|
|
2326
|
-
// Conversation-level (typed custom events)
|
|
2327
|
-
UserMessage: "user_message",
|
|
2328
|
-
TitleGenerated: "title_generated",
|
|
2329
|
-
TodoUpdate: "todo_update",
|
|
2330
|
-
PlanUpdate: "plan_update",
|
|
2331
|
-
NoteUpdate: "note_update",
|
|
2332
|
-
ContextUpdate: "context_update",
|
|
2333
|
-
SubagentStart: "subagent_start",
|
|
2334
|
-
SubagentStop: "subagent_stop",
|
|
2335
|
-
ContextWarning: "context_warning",
|
|
2336
|
-
MemoryRecall: "memory_recall",
|
|
2337
|
-
MemoryUpdate: "memory_update",
|
|
2338
|
-
DesktopStream: "desktop_stream",
|
|
2339
|
-
AttachmentStaged: "attachment_staged",
|
|
2340
|
-
WorkspaceReady: "workspace_ready",
|
|
2341
|
-
AssetCreated: "asset_created",
|
|
2342
|
-
ToolApprovalRequested: "tool_approval_requested",
|
|
2343
|
-
ToolApprovalGranted: "tool_approval_granted",
|
|
2344
|
-
ToolPermissionDenied: "tool_permission_denied",
|
|
2345
|
-
ToolHarnessWarning: "tool_harness_warning",
|
|
2346
|
-
UserUnavailable: "user_unavailable",
|
|
2347
|
-
PromptSuggestion: "prompt_suggestion",
|
|
2348
|
-
StateChanged: "state_changed",
|
|
2349
|
-
// Generic fallthrough for unknown custom events
|
|
2350
|
-
Custom: "custom"
|
|
2351
|
-
};
|
|
2352
|
-
|
|
2353
2482
|
// src/stream-manager.ts
|
|
2354
2483
|
var StreamManager = class {
|
|
2355
2484
|
constructor(session) {
|
|
@@ -3004,10 +3133,14 @@ function parseEmbeddedResource(value) {
|
|
|
3004
3133
|
StreamAbortedError,
|
|
3005
3134
|
StreamManager,
|
|
3006
3135
|
ToolRegistry,
|
|
3136
|
+
VOICE_POLISH_MODES,
|
|
3007
3137
|
generateId,
|
|
3008
3138
|
isEmbeddedResource,
|
|
3139
|
+
isVoiceLLMMode,
|
|
3140
|
+
isVoicePolishMode,
|
|
3009
3141
|
mapSseToChat,
|
|
3010
3142
|
parseEmbeddedResource,
|
|
3143
|
+
parseVoicePolishFrame,
|
|
3011
3144
|
replayEvents,
|
|
3012
3145
|
streamJobSSE,
|
|
3013
3146
|
translateDelta
|