@absolutejs/ai 0.0.28 → 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
|
@@ -3432,6 +3432,7 @@ var generateAIWithTools = async (options) => {
|
|
|
3432
3432
|
};
|
|
3433
3433
|
return runTurn(options.messages, maxTurns);
|
|
3434
3434
|
};
|
|
3435
|
+
var DEFAULT_OBJECT_REPAIR_ATTEMPTS = 1;
|
|
3435
3436
|
var generateObjectAI = async (options) => {
|
|
3436
3437
|
const toolName = options.toolName ?? DEFAULT_OBJECT_TOOL_NAME;
|
|
3437
3438
|
const tool = {
|
|
@@ -3439,26 +3440,218 @@ var generateObjectAI = async (options) => {
|
|
|
3439
3440
|
input_schema: options.schema,
|
|
3440
3441
|
name: toolName
|
|
3441
3442
|
};
|
|
3442
|
-
const
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3443
|
+
const maxRepairAttempts = Math.max(0, options.maxRepairAttempts ?? DEFAULT_OBJECT_REPAIR_ATTEMPTS);
|
|
3444
|
+
const messages = [...options.messages];
|
|
3445
|
+
let usage;
|
|
3446
|
+
let lastError;
|
|
3447
|
+
for (let attempt = 0;attempt <= maxRepairAttempts; attempt += 1) {
|
|
3448
|
+
const result = await generateAI({
|
|
3449
|
+
cacheSystemPrompt: options.cacheSystemPrompt,
|
|
3450
|
+
maxTokens: options.maxTokens,
|
|
3451
|
+
messages,
|
|
3452
|
+
model: options.model,
|
|
3453
|
+
promptCaching: options.promptCaching,
|
|
3454
|
+
provider: options.provider,
|
|
3455
|
+
reasoning: options.reasoning,
|
|
3456
|
+
signal: options.signal,
|
|
3457
|
+
systemPrompt: options.systemPrompt,
|
|
3458
|
+
temperature: options.temperature,
|
|
3459
|
+
toolChoice: { name: toolName },
|
|
3460
|
+
tools: [tool]
|
|
3461
|
+
});
|
|
3462
|
+
usage = mergeUsage(usage, result.usage);
|
|
3463
|
+
const call = result.toolCalls.find((toolCall) => toolCall.name === toolName);
|
|
3464
|
+
let failure;
|
|
3465
|
+
let object;
|
|
3466
|
+
if (!call) {
|
|
3467
|
+
lastError = new Error(`generateObjectAI: model did not call the "${toolName}" tool`);
|
|
3468
|
+
failure = `You did not call the "${toolName}" tool. Call it exactly once with the structured result.`;
|
|
3469
|
+
} else {
|
|
3470
|
+
try {
|
|
3471
|
+
object = options.validate ? options.validate(call.input) : call.input;
|
|
3472
|
+
} catch (error) {
|
|
3473
|
+
lastError = error;
|
|
3474
|
+
failure = `Your "${toolName}" output failed validation: ${error instanceof Error ? error.message : String(error)}. Call "${toolName}" again with corrected output that satisfies the schema.`;
|
|
3475
|
+
}
|
|
3476
|
+
}
|
|
3477
|
+
if (failure === undefined)
|
|
3478
|
+
return { object, usage };
|
|
3479
|
+
if (attempt >= maxRepairAttempts)
|
|
3480
|
+
break;
|
|
3481
|
+
if (call) {
|
|
3482
|
+
messages.push({
|
|
3483
|
+
content: [
|
|
3484
|
+
{
|
|
3485
|
+
id: call.id,
|
|
3486
|
+
input: call.input && typeof call.input === "object" ? call.input : {},
|
|
3487
|
+
name: toolName,
|
|
3488
|
+
type: "tool_use"
|
|
3489
|
+
}
|
|
3490
|
+
],
|
|
3491
|
+
role: "assistant"
|
|
3492
|
+
}, {
|
|
3493
|
+
content: [
|
|
3494
|
+
{ content: failure, tool_use_id: call.id, type: "tool_result" }
|
|
3495
|
+
],
|
|
3496
|
+
role: "user"
|
|
3497
|
+
});
|
|
3498
|
+
} else {
|
|
3499
|
+
messages.push({ content: failure, role: "user" });
|
|
3500
|
+
}
|
|
3501
|
+
}
|
|
3502
|
+
throw lastError instanceof Error ? lastError : new Error(`generateObjectAI: failed to produce valid output`);
|
|
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"
|
|
3455
3523
|
});
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
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
|
+
};
|
|
3459
3538
|
}
|
|
3460
|
-
|
|
3461
|
-
|
|
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;
|
|
3462
3655
|
};
|
|
3463
3656
|
// src/ai/conversationManager.ts
|
|
3464
3657
|
var NOT_FOUND3 = -1;
|
|
@@ -4381,6 +4574,7 @@ var startProviderStatusMonitor = (options) => {
|
|
|
4381
4574
|
export {
|
|
4382
4575
|
xai,
|
|
4383
4576
|
withResilience,
|
|
4577
|
+
streamAIWithTools,
|
|
4384
4578
|
streamAIToSSE,
|
|
4385
4579
|
streamAI,
|
|
4386
4580
|
startProviderStatusMonitor,
|
|
@@ -4420,5 +4614,5 @@ export {
|
|
|
4420
4614
|
PROVIDER_STATUS_PAGES
|
|
4421
4615
|
};
|
|
4422
4616
|
|
|
4423
|
-
//# debugId=
|
|
4617
|
+
//# debugId=488D46E6DE9AC4E164756E2164756E21
|
|
4424
4618
|
//# sourceMappingURL=index.js.map
|