@absolutejs/ai 0.0.29 → 0.0.30

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/ai/index.js CHANGED
@@ -3501,6 +3501,158 @@ var generateObjectAI = async (options) => {
3501
3501
  }
3502
3502
  throw lastError instanceof Error ? lastError : new Error(`generateObjectAI: failed to produce valid output`);
3503
3503
  };
3504
+
3505
+ // src/ai/streamAIWithTools.ts
3506
+ var DEFAULT_STREAM_TOOL_MAX_TURNS = 8;
3507
+ var toolCallKey = (call) => `${call.name}:${JSON.stringify(call.input)}`;
3508
+ var pushText = (blocks, content) => {
3509
+ const last = blocks[blocks.length - 1];
3510
+ if (last && last.type === "text") {
3511
+ last.content += content;
3512
+ return;
3513
+ }
3514
+ blocks.push({ content, type: "text" });
3515
+ };
3516
+ var flushThinking3 = (blocks, thinking) => {
3517
+ if (!thinking)
3518
+ return null;
3519
+ blocks.push({
3520
+ signature: thinking.signature || undefined,
3521
+ thinking: thinking.text,
3522
+ type: "thinking"
3523
+ });
3524
+ return null;
3525
+ };
3526
+ var executeToolHandler = async (tools, call) => {
3527
+ const definition = tools[call.name];
3528
+ if (!definition) {
3529
+ return { ok: false, result: `Error: unknown tool "${call.name}"` };
3530
+ }
3531
+ try {
3532
+ return { ok: true, result: await definition.handler(call.input) };
3533
+ } catch (err) {
3534
+ return {
3535
+ ok: false,
3536
+ result: `Error: ${err instanceof Error ? err.message : String(err)}`
3537
+ };
3538
+ }
3539
+ };
3540
+ var streamAIWithTools = async function* (options) {
3541
+ const {
3542
+ maxTurns = DEFAULT_STREAM_TOOL_MAX_TURNS,
3543
+ provider,
3544
+ toolChoice,
3545
+ tools,
3546
+ ...base
3547
+ } = options;
3548
+ const providerTools = toProviderTools(tools);
3549
+ const allToolCalls = [];
3550
+ const executedKeys = new Set;
3551
+ const messages = [...options.messages];
3552
+ let usage;
3553
+ let fullText = "";
3554
+ let turn = 0;
3555
+ const streamOneTurn = async function* () {
3556
+ const stream = provider.stream({
3557
+ cacheSystemPrompt: base.cacheSystemPrompt,
3558
+ maxTokens: base.maxTokens,
3559
+ messages,
3560
+ model: base.model,
3561
+ promptCaching: base.promptCaching,
3562
+ reasoning: base.reasoning,
3563
+ signal: base.signal,
3564
+ stopSequences: base.stopSequences,
3565
+ systemPrompt: base.systemPrompt,
3566
+ temperature: base.temperature,
3567
+ toolChoice: toolChoice ?? "auto",
3568
+ tools: providerTools,
3569
+ topP: base.topP
3570
+ });
3571
+ const blocks = [];
3572
+ const pending = [];
3573
+ let thinking = null;
3574
+ let turnUsage;
3575
+ for await (const chunk of stream) {
3576
+ if (base.signal?.aborted)
3577
+ break;
3578
+ if (chunk.type === "thinking") {
3579
+ if (chunk.content)
3580
+ yield { content: chunk.content, type: "thinking" };
3581
+ thinking = thinking ?? { signature: "", text: "" };
3582
+ thinking.text += chunk.content;
3583
+ if (chunk.signature)
3584
+ thinking.signature = chunk.signature;
3585
+ } else if (chunk.type === "text") {
3586
+ thinking = flushThinking3(blocks, thinking);
3587
+ fullText += chunk.content;
3588
+ pushText(blocks, chunk.content);
3589
+ yield { content: chunk.content, type: "text" };
3590
+ } else if (chunk.type === "tool_use") {
3591
+ thinking = flushThinking3(blocks, thinking);
3592
+ pending.push({ id: chunk.id, input: chunk.input, name: chunk.name });
3593
+ blocks.push({
3594
+ id: chunk.id,
3595
+ input: chunk.input && typeof chunk.input === "object" ? chunk.input : {},
3596
+ name: chunk.name,
3597
+ type: "tool_use"
3598
+ });
3599
+ } else if (chunk.type === "done") {
3600
+ thinking = flushThinking3(blocks, thinking);
3601
+ turnUsage = chunk.usage;
3602
+ }
3603
+ }
3604
+ thinking = flushThinking3(blocks, thinking);
3605
+ return { blocks, pending, usage: turnUsage };
3606
+ };
3607
+ while (turn < maxTurns) {
3608
+ turn += 1;
3609
+ const outcome = yield* streamOneTurn();
3610
+ usage = mergeUsage(usage, outcome.usage);
3611
+ yield { type: "turn", usage: outcome.usage };
3612
+ const { blocks, pending } = outcome;
3613
+ allToolCalls.push(...pending);
3614
+ const allRepeats = pending.length > 0 && pending.every((call) => executedKeys.has(toolCallKey(call)));
3615
+ const finished = pending.length === 0 || turn >= maxTurns || allRepeats || base.signal?.aborted === true;
3616
+ if (finished)
3617
+ break;
3618
+ messages.push({ content: blocks, role: "assistant" });
3619
+ const resultBlocks = [];
3620
+ for (const call of pending) {
3621
+ yield {
3622
+ id: call.id,
3623
+ input: call.input,
3624
+ name: call.name,
3625
+ type: "tool_start"
3626
+ };
3627
+ const startedAt = Date.now();
3628
+ const { ok, result } = await executeToolHandler(tools, call);
3629
+ executedKeys.add(toolCallKey(call));
3630
+ yield {
3631
+ id: call.id,
3632
+ input: call.input,
3633
+ ms: Date.now() - startedAt,
3634
+ name: call.name,
3635
+ ok,
3636
+ result,
3637
+ type: "tool_result"
3638
+ };
3639
+ resultBlocks.push({
3640
+ content: result,
3641
+ tool_use_id: call.id,
3642
+ type: "tool_result"
3643
+ });
3644
+ }
3645
+ messages.push({ content: resultBlocks, role: "user" });
3646
+ }
3647
+ const summary = {
3648
+ text: fullText,
3649
+ toolCalls: allToolCalls,
3650
+ turns: turn,
3651
+ usage
3652
+ };
3653
+ yield { ...summary, type: "done" };
3654
+ return summary;
3655
+ };
3504
3656
  // src/ai/conversationManager.ts
3505
3657
  var NOT_FOUND3 = -1;
3506
3658
  var TITLE_MAX_LENGTH2 = 80;
@@ -4422,6 +4574,7 @@ var startProviderStatusMonitor = (options) => {
4422
4574
  export {
4423
4575
  xai,
4424
4576
  withResilience,
4577
+ streamAIWithTools,
4425
4578
  streamAIToSSE,
4426
4579
  streamAI,
4427
4580
  startProviderStatusMonitor,
@@ -4461,5 +4614,5 @@ export {
4461
4614
  PROVIDER_STATUS_PAGES
4462
4615
  };
4463
4616
 
4464
- //# debugId=AAB25EB53BF9BE9064756E2164756E21
4617
+ //# debugId=488D46E6DE9AC4E164756E2164756E21
4465
4618
  //# sourceMappingURL=index.js.map