@sinas/sdk 0.5.0 → 0.8.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/{chunk-IABVF56L.js → chunk-RHQVV5O6.js} +344 -99
- package/dist/chunk-RHQVV5O6.js.map +1 -0
- package/dist/client.cjs +356 -98
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +330 -5
- package/dist/client.d.ts +330 -5
- package/dist/client.js +29 -1
- package/dist/index.cjs +624 -244
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +62 -4
- package/dist/index.d.ts +62 -4
- package/dist/index.js +298 -147
- package/dist/index.js.map +1 -1
- package/dist/sinas-sdk.umd.js +610 -244
- package/dist/sinas-sdk.umd.js.map +1 -1
- package/package.json +6 -3
- package/dist/chunk-IABVF56L.js.map +0 -1
|
@@ -307,6 +307,124 @@ async function executeFunction(client, ref, input = {}, timeout) {
|
|
|
307
307
|
error: data.error
|
|
308
308
|
};
|
|
309
309
|
}
|
|
310
|
+
async function enqueueFunction(client, ref, input = {}, options = {}) {
|
|
311
|
+
const [ns, name] = parseRef2(ref);
|
|
312
|
+
const baseUrl = client.requireBaseUrl();
|
|
313
|
+
const body = { input };
|
|
314
|
+
if (options.triggerId !== void 0) body.trigger_id = options.triggerId;
|
|
315
|
+
if (options.delaySeconds !== void 0) body.delay_seconds = options.delaySeconds;
|
|
316
|
+
if (options.callbackUrl !== void 0) body.callback_url = options.callbackUrl;
|
|
317
|
+
const res = await client.fetch(`${baseUrl}/functions/${ns}/${name}/execute/async`, {
|
|
318
|
+
method: "POST",
|
|
319
|
+
body: JSON.stringify(body)
|
|
320
|
+
});
|
|
321
|
+
const data = await res.json();
|
|
322
|
+
return {
|
|
323
|
+
executionId: data.execution_id,
|
|
324
|
+
status: data.status
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
async function submitFunctionBatch(client, ref, inputs, options = {}) {
|
|
328
|
+
const [ns, name] = parseRef2(ref);
|
|
329
|
+
const baseUrl = client.requireBaseUrl();
|
|
330
|
+
const body = { inputs };
|
|
331
|
+
if (options.triggerIdPrefix !== void 0) body.trigger_id_prefix = options.triggerIdPrefix;
|
|
332
|
+
if (options.delaySeconds !== void 0) body.delay_seconds = options.delaySeconds;
|
|
333
|
+
if (options.callbackUrl !== void 0) body.callback_url = options.callbackUrl;
|
|
334
|
+
if (options.batchCallbackUrl !== void 0) body.batch_callback_url = options.batchCallbackUrl;
|
|
335
|
+
const res = await client.fetch(`${baseUrl}/functions/${ns}/${name}/execute/batch`, {
|
|
336
|
+
method: "POST",
|
|
337
|
+
body: JSON.stringify(body)
|
|
338
|
+
});
|
|
339
|
+
const data = await res.json();
|
|
340
|
+
return {
|
|
341
|
+
batchId: data.batch_id,
|
|
342
|
+
executionIds: data.execution_ids,
|
|
343
|
+
total: data.total,
|
|
344
|
+
status: data.status
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
async function submitAgentBatch(client, ref, inputs, options = {}) {
|
|
348
|
+
const [ns, name] = parseRef2(ref);
|
|
349
|
+
const baseUrl = client.requireBaseUrl();
|
|
350
|
+
const body = {
|
|
351
|
+
inputs: inputs.map((item) => ({
|
|
352
|
+
input_variables: item.inputVariables || {},
|
|
353
|
+
message: item.message
|
|
354
|
+
}))
|
|
355
|
+
};
|
|
356
|
+
if (options.triggerIdPrefix !== void 0) body.trigger_id_prefix = options.triggerIdPrefix;
|
|
357
|
+
if (options.callbackUrl !== void 0) body.callback_url = options.callbackUrl;
|
|
358
|
+
if (options.batchCallbackUrl !== void 0) body.batch_callback_url = options.batchCallbackUrl;
|
|
359
|
+
const res = await client.fetch(`${baseUrl}/agents/${ns}/${name}/chats/batch`, {
|
|
360
|
+
method: "POST",
|
|
361
|
+
body: JSON.stringify(body)
|
|
362
|
+
});
|
|
363
|
+
const data = await res.json();
|
|
364
|
+
return {
|
|
365
|
+
batchId: data.batch_id,
|
|
366
|
+
executionIds: data.execution_ids,
|
|
367
|
+
chatIds: data.chat_ids,
|
|
368
|
+
total: data.total,
|
|
369
|
+
status: data.status
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
async function getBatch(client, batchId) {
|
|
373
|
+
const baseUrl = client.requireBaseUrl();
|
|
374
|
+
const res = await client.fetch(`${baseUrl}/batches/${batchId}`);
|
|
375
|
+
const data = await res.json();
|
|
376
|
+
return {
|
|
377
|
+
batchId: data.batch_id,
|
|
378
|
+
kind: data.kind,
|
|
379
|
+
target: data.target,
|
|
380
|
+
userId: data.user_id,
|
|
381
|
+
total: data.total,
|
|
382
|
+
completed: data.completed,
|
|
383
|
+
failed: data.failed,
|
|
384
|
+
cancelled: data.cancelled,
|
|
385
|
+
running: data.running,
|
|
386
|
+
queued: data.queued,
|
|
387
|
+
status: data.status,
|
|
388
|
+
startedAt: data.started_at,
|
|
389
|
+
finishedAt: data.finished_at,
|
|
390
|
+
triggerIdPrefix: data.trigger_id_prefix
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
async function listBatchExecutions(client, batchId, options = {}) {
|
|
394
|
+
const baseUrl = client.requireBaseUrl();
|
|
395
|
+
const params = new URLSearchParams();
|
|
396
|
+
if (options.status) params.set("status", options.status);
|
|
397
|
+
if (options.limit !== void 0) params.set("limit", String(options.limit));
|
|
398
|
+
if (options.offset !== void 0) params.set("offset", String(options.offset));
|
|
399
|
+
const q = params.toString();
|
|
400
|
+
const res = await client.fetch(
|
|
401
|
+
`${baseUrl}/batches/${batchId}/executions${q ? "?" + q : ""}`
|
|
402
|
+
);
|
|
403
|
+
const data = await res.json();
|
|
404
|
+
return (data.executions || []).map((row) => ({
|
|
405
|
+
executionId: row.execution_id,
|
|
406
|
+
status: row.status,
|
|
407
|
+
functionName: row.function_name,
|
|
408
|
+
chatId: row.chat_id ?? null,
|
|
409
|
+
triggerId: row.trigger_id,
|
|
410
|
+
startedAt: row.started_at ?? null,
|
|
411
|
+
completedAt: row.completed_at ?? null,
|
|
412
|
+
durationMs: row.duration_ms ?? null,
|
|
413
|
+
error: row.error ?? null
|
|
414
|
+
}));
|
|
415
|
+
}
|
|
416
|
+
async function cancelBatch(client, batchId) {
|
|
417
|
+
const baseUrl = client.requireBaseUrl();
|
|
418
|
+
const res = await client.fetch(`${baseUrl}/batches/${batchId}/cancel`, {
|
|
419
|
+
method: "POST"
|
|
420
|
+
});
|
|
421
|
+
const data = await res.json();
|
|
422
|
+
return {
|
|
423
|
+
batchId: data.batch_id,
|
|
424
|
+
status: data.status,
|
|
425
|
+
cancelledChildren: data.cancelled_children
|
|
426
|
+
};
|
|
427
|
+
}
|
|
310
428
|
|
|
311
429
|
// src/client/states.ts
|
|
312
430
|
async function stateGet(client, ns, key) {
|
|
@@ -340,12 +458,111 @@ async function stateList(client, ns) {
|
|
|
340
458
|
return res.json();
|
|
341
459
|
}
|
|
342
460
|
|
|
461
|
+
// src/client/chatEvents.ts
|
|
462
|
+
var isObject = (v) => !!v && typeof v === "object" && !Array.isArray(v);
|
|
463
|
+
var str = (v) => typeof v === "string" ? v : null;
|
|
464
|
+
var num = (v) => typeof v === "number" && Number.isFinite(v) ? v : 0;
|
|
465
|
+
var optionsOf = (v) => Array.isArray(v) && v.length > 0 && v.every((o) => typeof o === "string") ? v : null;
|
|
466
|
+
function parsePendingInput(raw) {
|
|
467
|
+
if (!isObject(raw)) return null;
|
|
468
|
+
if (typeof raw.tool_call_id !== "string" || !raw.tool_call_id) return null;
|
|
469
|
+
return {
|
|
470
|
+
toolCallId: raw.tool_call_id,
|
|
471
|
+
question: str(raw.question) ?? "",
|
|
472
|
+
options: optionsOf(raw.options),
|
|
473
|
+
expiresAt: str(raw.expires_at),
|
|
474
|
+
createdAt: str(raw.created_at)
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
function parsePendingInputs(raw) {
|
|
478
|
+
return Array.isArray(raw) ? raw.map(parsePendingInput).filter((p) => p !== null) : [];
|
|
479
|
+
}
|
|
480
|
+
function pendingInputFromChunk(chunk) {
|
|
481
|
+
if (chunk.event !== "input_required" && chunk.event !== "message") return null;
|
|
482
|
+
let parsed;
|
|
483
|
+
try {
|
|
484
|
+
parsed = JSON.parse(chunk.data);
|
|
485
|
+
} catch {
|
|
486
|
+
return null;
|
|
487
|
+
}
|
|
488
|
+
if (chunk.event === "message" && (!isObject(parsed) || parsed.type !== "input_required")) return null;
|
|
489
|
+
return parsePendingInput(parsed);
|
|
490
|
+
}
|
|
491
|
+
function parseApproval(raw) {
|
|
492
|
+
if (!isObject(raw) || typeof raw.tool_call_id !== "string") return null;
|
|
493
|
+
return {
|
|
494
|
+
type: str(raw.type) ?? "approval_required",
|
|
495
|
+
toolCallId: raw.tool_call_id,
|
|
496
|
+
functionNamespace: str(raw.function_namespace) ?? "",
|
|
497
|
+
functionName: str(raw.function_name) ?? "",
|
|
498
|
+
arguments: isObject(raw.arguments) ? raw.arguments : {}
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
function parseUsage(raw) {
|
|
502
|
+
if (!isObject(raw)) return null;
|
|
503
|
+
return {
|
|
504
|
+
calls: num(raw.calls),
|
|
505
|
+
promptTokens: num(raw.prompt_tokens),
|
|
506
|
+
completionTokens: num(raw.completion_tokens),
|
|
507
|
+
totalTokens: num(raw.total_tokens),
|
|
508
|
+
cacheReadTokens: num(raw.cache_read_tokens),
|
|
509
|
+
cacheWriteTokens: num(raw.cache_write_tokens),
|
|
510
|
+
costUsd: typeof raw.cost_usd === "number" ? raw.cost_usd : null,
|
|
511
|
+
unpricedCalls: num(raw.unpriced_calls),
|
|
512
|
+
errors: num(raw.errors)
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
var TURN_STATUSES = ["completed", "input_required", "in_progress", "injected"];
|
|
516
|
+
function parseTurnState(raw) {
|
|
517
|
+
const status = TURN_STATUSES.includes(raw.status) ? raw.status : "completed";
|
|
518
|
+
return {
|
|
519
|
+
status,
|
|
520
|
+
pendingInputs: parsePendingInputs(raw.pending_inputs),
|
|
521
|
+
channelId: str(raw.channel_id),
|
|
522
|
+
usage: parseUsage(raw.usage)
|
|
523
|
+
};
|
|
524
|
+
}
|
|
525
|
+
function parseMessage(data) {
|
|
526
|
+
const toolCalls = data.tool_calls;
|
|
527
|
+
return {
|
|
528
|
+
id: data.id,
|
|
529
|
+
chatId: data.chat_id,
|
|
530
|
+
role: data.role,
|
|
531
|
+
content: data.content ?? null,
|
|
532
|
+
toolCalls: toolCalls ?? null,
|
|
533
|
+
toolCallId: data.tool_call_id ?? null,
|
|
534
|
+
name: data.name ?? null,
|
|
535
|
+
createdAt: data.created_at
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
function parseDone(data) {
|
|
539
|
+
try {
|
|
540
|
+
const parsed = JSON.parse(data);
|
|
541
|
+
if (isObject(parsed) && typeof parsed.status === "string") return { status: parsed.status };
|
|
542
|
+
} catch {
|
|
543
|
+
}
|
|
544
|
+
return { status: "completed" };
|
|
545
|
+
}
|
|
546
|
+
function approvalResumeChannel(result, approved = true) {
|
|
547
|
+
if (result.resume === "waiting") return null;
|
|
548
|
+
if (result.resume === void 0 && !approved) return null;
|
|
549
|
+
return result.channelId || null;
|
|
550
|
+
}
|
|
551
|
+
function answerResumeChannel(result) {
|
|
552
|
+
if (!result.resumed && !result.resumePending) return null;
|
|
553
|
+
return result.channelId || null;
|
|
554
|
+
}
|
|
555
|
+
|
|
343
556
|
// src/client/chat.ts
|
|
344
|
-
|
|
557
|
+
function splitAgentRef(agentRef) {
|
|
345
558
|
const [ns, name] = agentRef.split("/");
|
|
346
559
|
if (!ns || !name) {
|
|
347
560
|
throw new Error(`Invalid agent ref "${agentRef}": expected "namespace/name"`);
|
|
348
561
|
}
|
|
562
|
+
return [ns, name];
|
|
563
|
+
}
|
|
564
|
+
async function createChat(client, agentRef, input) {
|
|
565
|
+
const [ns, name] = splitAgentRef(agentRef);
|
|
349
566
|
const config = client.getConfig();
|
|
350
567
|
const res = await client.fetch(`${config.apiBase}/agents/${ns}/${name}/chats`, {
|
|
351
568
|
method: "POST",
|
|
@@ -371,66 +588,117 @@ async function sendMessage(client, chatId, content) {
|
|
|
371
588
|
chatId: data.chat_id,
|
|
372
589
|
role: data.role,
|
|
373
590
|
content: data.content,
|
|
374
|
-
createdAt: data.created_at
|
|
591
|
+
createdAt: data.created_at,
|
|
592
|
+
...parseTurnState(data)
|
|
375
593
|
};
|
|
376
594
|
}
|
|
377
|
-
function
|
|
378
|
-
const
|
|
595
|
+
async function invokeAgent(client, agentRef, message, options = {}) {
|
|
596
|
+
const [ns, name] = splitAgentRef(agentRef);
|
|
597
|
+
const config = client.getConfig();
|
|
598
|
+
const body = { message };
|
|
599
|
+
if (options.sessionKey !== void 0) body.session_key = options.sessionKey;
|
|
600
|
+
if (options.reset !== void 0) body.reset = options.reset;
|
|
601
|
+
if (options.input !== void 0) body.input = options.input;
|
|
602
|
+
const res = await client.fetch(`${config.apiBase}/agents/${ns}/${name}/invoke`, {
|
|
603
|
+
method: "POST",
|
|
604
|
+
body: JSON.stringify(body)
|
|
605
|
+
});
|
|
606
|
+
const data = await res.json();
|
|
379
607
|
return {
|
|
380
|
-
|
|
608
|
+
reply: typeof data.reply === "string" ? data.reply : "",
|
|
381
609
|
chatId: data.chat_id,
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
toolCalls: toolCalls ?? null,
|
|
385
|
-
toolCallId: data.tool_call_id ?? null,
|
|
386
|
-
name: data.name ?? null,
|
|
387
|
-
createdAt: data.created_at
|
|
610
|
+
sessionKey: data.session_key ?? null,
|
|
611
|
+
...parseTurnState(data)
|
|
388
612
|
};
|
|
389
613
|
}
|
|
390
614
|
async function getChat(client, chatId) {
|
|
391
615
|
const config = client.getConfig();
|
|
392
616
|
const res = await client.fetch(`${config.apiBase}/chats/${chatId}`);
|
|
393
617
|
const data = await res.json();
|
|
394
|
-
|
|
618
|
+
const detail = {
|
|
395
619
|
id: data.id,
|
|
396
620
|
agentNamespace: data.agent_namespace,
|
|
397
621
|
agentName: data.agent_name,
|
|
398
622
|
title: data.title,
|
|
399
|
-
messages: (data.messages || []).map(
|
|
400
|
-
pendingApprovals: (data.pending_approvals || []).map((
|
|
401
|
-
type: "approval_required",
|
|
402
|
-
toolCallId: pa.tool_call_id,
|
|
403
|
-
functionNamespace: pa.function_namespace,
|
|
404
|
-
functionName: pa.function_name,
|
|
405
|
-
arguments: pa.arguments || {}
|
|
406
|
-
}))
|
|
623
|
+
messages: (data.messages || []).map(parseMessage),
|
|
624
|
+
pendingApprovals: (data.pending_approvals || []).map(parseApproval).filter((a) => a !== null)
|
|
407
625
|
};
|
|
626
|
+
if (Array.isArray(data.pending_inputs)) {
|
|
627
|
+
detail.pendingInputs = parsePendingInputs(data.pending_inputs);
|
|
628
|
+
}
|
|
629
|
+
return detail;
|
|
408
630
|
}
|
|
409
|
-
async function approveToolCall(client, chatId, toolCallId, approved) {
|
|
631
|
+
async function approveToolCall(client, chatId, toolCallId, approved, options = {}) {
|
|
410
632
|
const config = client.getConfig();
|
|
633
|
+
const body = { approved };
|
|
634
|
+
if (approved && options.alwaysAllow) body.always_allow = true;
|
|
411
635
|
const res = await client.fetch(
|
|
412
|
-
`${config.apiBase}/chats/${chatId}/approve-tool/${toolCallId}`,
|
|
413
|
-
{ method: "POST", body: JSON.stringify(
|
|
636
|
+
`${config.apiBase}/chats/${chatId}/approve-tool/${encodeURIComponent(toolCallId)}`,
|
|
637
|
+
{ method: "POST", body: JSON.stringify(body) }
|
|
414
638
|
);
|
|
415
639
|
const data = await res.json();
|
|
416
|
-
|
|
640
|
+
const result = {
|
|
417
641
|
status: data.status,
|
|
418
642
|
toolCallId: data.tool_call_id,
|
|
419
643
|
channelId: data.channel_id
|
|
420
644
|
};
|
|
645
|
+
if (data.resume === "waiting" || data.resume === "queued") result.resume = data.resume;
|
|
646
|
+
if (typeof data.message === "string") result.message = data.message;
|
|
647
|
+
return result;
|
|
421
648
|
}
|
|
422
|
-
function
|
|
423
|
-
const
|
|
649
|
+
async function listPendingInputs(client, chatId) {
|
|
650
|
+
const config = client.getConfig();
|
|
651
|
+
const res = await client.fetch(`${config.apiBase}/chats/${chatId}/pending-input`);
|
|
652
|
+
return parsePendingInputs(await res.json());
|
|
653
|
+
}
|
|
654
|
+
async function answerPendingInput(client, chatId, toolCallId, answer, options = {}) {
|
|
655
|
+
const config = client.getConfig();
|
|
656
|
+
const body = { answer };
|
|
657
|
+
if (options.wait) body.wait = true;
|
|
658
|
+
const res = await client.fetch(
|
|
659
|
+
`${config.apiBase}/chats/${chatId}/pending-input/${encodeURIComponent(toolCallId)}`,
|
|
660
|
+
{ method: "POST", body: JSON.stringify(body) }
|
|
661
|
+
);
|
|
662
|
+
const data = await res.json();
|
|
663
|
+
if (options.wait) {
|
|
664
|
+
return {
|
|
665
|
+
toolCallId: data.tool_call_id,
|
|
666
|
+
chatId: data.chat_id,
|
|
667
|
+
reply: typeof data.reply === "string" ? data.reply : "",
|
|
668
|
+
message: data.message && typeof data.message === "object" ? parseMessage(data.message) : null,
|
|
669
|
+
...parseTurnState(data)
|
|
670
|
+
};
|
|
671
|
+
}
|
|
672
|
+
return {
|
|
673
|
+
status: "answered",
|
|
674
|
+
toolCallId: data.tool_call_id,
|
|
675
|
+
resumed: !!data.resumed,
|
|
676
|
+
resumePending: !!data.resume_pending,
|
|
677
|
+
channelId: data.channel_id ?? null,
|
|
678
|
+
message: typeof data.message === "string" ? data.message : ""
|
|
679
|
+
};
|
|
680
|
+
}
|
|
681
|
+
function streamFromChannel(client, chatId, channelId, onChunk, onDone, onError, options = {}) {
|
|
424
682
|
const config = client.getConfig();
|
|
683
|
+
const params = new URLSearchParams({ last_id: options.lastId ?? "0" });
|
|
684
|
+
if (options.includeThinking) params.set("include_thinking", "true");
|
|
685
|
+
return runSSE(
|
|
686
|
+
`${config.apiBase}/chats/${chatId}/stream/${encodeURIComponent(channelId)}?${params}`,
|
|
687
|
+
(signal) => ({ headers: client.getAuthHeaders(), signal }),
|
|
688
|
+
"Stream reconnect failed",
|
|
689
|
+
onChunk,
|
|
690
|
+
onDone,
|
|
691
|
+
onError
|
|
692
|
+
);
|
|
693
|
+
}
|
|
694
|
+
function runSSE(url, init, failure, onChunk, onDone, onError) {
|
|
695
|
+
const controller = new AbortController();
|
|
425
696
|
(async () => {
|
|
426
697
|
try {
|
|
427
|
-
const res = await fetch(
|
|
428
|
-
`${config.apiBase}/chats/${chatId}/stream/${channelId}?last_id=0`,
|
|
429
|
-
{ headers: client.getAuthHeaders(), signal: controller.signal }
|
|
430
|
-
);
|
|
698
|
+
const res = await fetch(url, init(controller.signal));
|
|
431
699
|
if (!res.ok) {
|
|
432
700
|
const body = await res.json().catch(() => ({ detail: res.statusText }));
|
|
433
|
-
throw new Error(body.detail ||
|
|
701
|
+
throw new Error(body.detail || failure);
|
|
434
702
|
}
|
|
435
703
|
const reader = res.body.getReader();
|
|
436
704
|
const decoder = new TextDecoder();
|
|
@@ -444,7 +712,7 @@ function streamFromChannel(client, chatId, channelId, onChunk, onDone, onError)
|
|
|
444
712
|
for (const chunk of chunks) {
|
|
445
713
|
onChunk(chunk);
|
|
446
714
|
if (chunk.event === "done") {
|
|
447
|
-
onDone?.();
|
|
715
|
+
onDone?.(parseDone(chunk.data));
|
|
448
716
|
return;
|
|
449
717
|
}
|
|
450
718
|
}
|
|
@@ -453,9 +721,13 @@ function streamFromChannel(client, chatId, channelId, onChunk, onDone, onError)
|
|
|
453
721
|
const { chunks } = parseSSE(buffer + "\n\n");
|
|
454
722
|
for (const chunk of chunks) {
|
|
455
723
|
onChunk(chunk);
|
|
724
|
+
if (chunk.event === "done") {
|
|
725
|
+
onDone?.(parseDone(chunk.data));
|
|
726
|
+
return;
|
|
727
|
+
}
|
|
456
728
|
}
|
|
457
729
|
}
|
|
458
|
-
onDone?.();
|
|
730
|
+
onDone?.({ status: "closed" });
|
|
459
731
|
} catch (err) {
|
|
460
732
|
if (err.name === "AbortError") return;
|
|
461
733
|
onError?.(err);
|
|
@@ -466,75 +738,33 @@ function streamFromChannel(client, chatId, channelId, onChunk, onDone, onError)
|
|
|
466
738
|
function parseSSE(buffer) {
|
|
467
739
|
const chunks = [];
|
|
468
740
|
const normalized = buffer.replace(/\r\n/g, "\n");
|
|
469
|
-
|
|
470
|
-
let
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
if (line.startsWith("event:")) {
|
|
480
|
-
event = line.slice(6).trim();
|
|
481
|
-
} else if (line.startsWith("data:")) {
|
|
482
|
-
data = line.slice(5).trim();
|
|
483
|
-
} else if (line === "") {
|
|
484
|
-
if (event || data) {
|
|
485
|
-
chunks.push({ event: event || "message", data });
|
|
486
|
-
event = "";
|
|
487
|
-
data = "";
|
|
488
|
-
}
|
|
741
|
+
let start = 0;
|
|
742
|
+
let end;
|
|
743
|
+
while ((end = normalized.indexOf("\n\n", start)) !== -1) {
|
|
744
|
+
const block = normalized.slice(start, end);
|
|
745
|
+
start = end + 2;
|
|
746
|
+
let event = "";
|
|
747
|
+
const data = [];
|
|
748
|
+
for (const line of block.split("\n")) {
|
|
749
|
+
if (line.startsWith("event:")) event = line.slice(6).trim();
|
|
750
|
+
else if (line.startsWith("data:")) data.push(line.slice(5).trim());
|
|
489
751
|
}
|
|
752
|
+
if (event || data.length) chunks.push({ event: event || "message", data: data.join("\n") });
|
|
490
753
|
}
|
|
491
|
-
return { chunks, remaining };
|
|
754
|
+
return { chunks, remaining: normalized.slice(start) };
|
|
492
755
|
}
|
|
493
|
-
function streamMessage(client, chatId, content, onChunk, onDone, onError) {
|
|
494
|
-
const controller = new AbortController();
|
|
756
|
+
function streamMessage(client, chatId, content, onChunk, onDone, onError, options = {}) {
|
|
495
757
|
const config = client.getConfig();
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
throw new Error(body.detail || "Stream request failed");
|
|
507
|
-
}
|
|
508
|
-
const reader = res.body.getReader();
|
|
509
|
-
const decoder = new TextDecoder();
|
|
510
|
-
let buffer = "";
|
|
511
|
-
while (true) {
|
|
512
|
-
const { done, value } = await reader.read();
|
|
513
|
-
if (done) break;
|
|
514
|
-
buffer += decoder.decode(value, { stream: true });
|
|
515
|
-
const { chunks, remaining } = parseSSE(buffer);
|
|
516
|
-
buffer = remaining;
|
|
517
|
-
for (const chunk of chunks) {
|
|
518
|
-
onChunk(chunk);
|
|
519
|
-
if (chunk.event === "done") {
|
|
520
|
-
onDone?.();
|
|
521
|
-
return;
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
if (buffer.trim()) {
|
|
526
|
-
const { chunks } = parseSSE(buffer + "\n\n");
|
|
527
|
-
for (const chunk of chunks) {
|
|
528
|
-
onChunk(chunk);
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
onDone?.();
|
|
532
|
-
} catch (err) {
|
|
533
|
-
if (err.name === "AbortError") return;
|
|
534
|
-
onError?.(err);
|
|
535
|
-
}
|
|
536
|
-
})();
|
|
537
|
-
return controller;
|
|
758
|
+
const body = { content };
|
|
759
|
+
if (options.includeThinking) body.include_thinking = true;
|
|
760
|
+
return runSSE(
|
|
761
|
+
`${config.apiBase}/chats/${chatId}/messages/stream`,
|
|
762
|
+
(signal) => ({ method: "POST", headers: client.getAuthHeaders(), body: JSON.stringify(body), signal }),
|
|
763
|
+
"Stream request failed",
|
|
764
|
+
onChunk,
|
|
765
|
+
onDone,
|
|
766
|
+
onError
|
|
767
|
+
);
|
|
538
768
|
}
|
|
539
769
|
|
|
540
770
|
// src/client/collections.ts
|
|
@@ -585,14 +815,29 @@ export {
|
|
|
585
815
|
SinasClient,
|
|
586
816
|
executeQuery,
|
|
587
817
|
executeFunction,
|
|
818
|
+
enqueueFunction,
|
|
819
|
+
submitFunctionBatch,
|
|
820
|
+
submitAgentBatch,
|
|
821
|
+
getBatch,
|
|
822
|
+
listBatchExecutions,
|
|
823
|
+
cancelBatch,
|
|
588
824
|
stateGet,
|
|
589
825
|
stateSet,
|
|
590
826
|
stateDelete,
|
|
591
827
|
stateList,
|
|
828
|
+
parsePendingInput,
|
|
829
|
+
parsePendingInputs,
|
|
830
|
+
pendingInputFromChunk,
|
|
831
|
+
parseApproval,
|
|
832
|
+
approvalResumeChannel,
|
|
833
|
+
answerResumeChannel,
|
|
592
834
|
createChat,
|
|
593
835
|
sendMessage,
|
|
836
|
+
invokeAgent,
|
|
594
837
|
getChat,
|
|
595
838
|
approveToolCall,
|
|
839
|
+
listPendingInputs,
|
|
840
|
+
answerPendingInput,
|
|
596
841
|
streamFromChannel,
|
|
597
842
|
streamMessage,
|
|
598
843
|
listCollections,
|
|
@@ -600,4 +845,4 @@ export {
|
|
|
600
845
|
uploadFile,
|
|
601
846
|
generateFileUrl
|
|
602
847
|
};
|
|
603
|
-
//# sourceMappingURL=chunk-
|
|
848
|
+
//# sourceMappingURL=chunk-RHQVV5O6.js.map
|