@lowire/loop 0.0.24 → 0.0.25
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/lib/loop.d.ts +0 -1
- package/lib/loop.js +6 -7
- package/package.json +1 -1
package/lib/loop.d.ts
CHANGED
|
@@ -59,7 +59,6 @@ export declare class Loop {
|
|
|
59
59
|
constructor(options: LoopOptions);
|
|
60
60
|
run(task: string, runOptions?: Omit<LoopOptions, 'model' | 'api' | 'apiKey'> & {
|
|
61
61
|
model?: string;
|
|
62
|
-
abortController?: AbortController;
|
|
63
62
|
}): Promise<{
|
|
64
63
|
result?: types.ToolResult;
|
|
65
64
|
status: 'ok' | 'break' | 'error';
|
package/lib/loop.js
CHANGED
|
@@ -29,7 +29,6 @@ class Loop {
|
|
|
29
29
|
}
|
|
30
30
|
async run(task, runOptions = {}) {
|
|
31
31
|
const options = { ...this._loopOptions, ...runOptions };
|
|
32
|
-
const abortController = runOptions.abortController;
|
|
33
32
|
const allTools = [...(options.tools || []).map(wrapToolWithIsDone)];
|
|
34
33
|
const conversation = {
|
|
35
34
|
systemPrompt,
|
|
@@ -57,7 +56,7 @@ class Loop {
|
|
|
57
56
|
} : undefined;
|
|
58
57
|
const summarizedConversation = options.summarize ? this._summarizeConversation(task, conversation, options) : conversation;
|
|
59
58
|
await options.onBeforeTurn?.({ conversation: summarizedConversation, totalUsage, budgetTokens: budget.tokens });
|
|
60
|
-
if (
|
|
59
|
+
if (options.signal?.aborted)
|
|
61
60
|
return { status: 'break', usage: totalUsage, turns };
|
|
62
61
|
debug?.('lowire:loop')(`Request`, JSON.stringify({ ...summarizedConversation, tools: `${summarizedConversation.tools.length} tools` }, null, 2));
|
|
63
62
|
const tokenEstimate = Math.floor(JSON.stringify(summarizedConversation).length / 4);
|
|
@@ -66,7 +65,7 @@ class Loop {
|
|
|
66
65
|
const { result: assistantMessage, usage } = await (0, cache_1.cachedComplete)(this._provider, summarizedConversation, caches, {
|
|
67
66
|
...options,
|
|
68
67
|
maxTokens: budget.tokens !== undefined ? budget.tokens - tokenEstimate : undefined,
|
|
69
|
-
signal:
|
|
68
|
+
signal: options.signal,
|
|
70
69
|
});
|
|
71
70
|
if (assistantMessage.stopReason.code === 'error')
|
|
72
71
|
return { status: 'error', error: assistantMessage.stopReason.message, usage: totalUsage, turns };
|
|
@@ -80,7 +79,7 @@ class Loop {
|
|
|
80
79
|
debug?.('lowire:loop')('Usage', `input: ${usage.input}, output: ${usage.output}`);
|
|
81
80
|
debug?.('lowire:loop')('Assistant', intent, JSON.stringify(assistantMessage.content, null, 2));
|
|
82
81
|
await options.onAfterTurn?.({ assistantMessage, totalUsage, budgetTokens: budget.tokens });
|
|
83
|
-
if (
|
|
82
|
+
if (options.signal?.aborted)
|
|
84
83
|
return { status: 'break', usage: totalUsage, turns };
|
|
85
84
|
conversation.messages.push(assistantMessage);
|
|
86
85
|
const toolCalls = assistantMessage.content.filter(part => part.type === 'tool_call');
|
|
@@ -94,7 +93,7 @@ class Loop {
|
|
|
94
93
|
const { name, arguments: args } = toolCall;
|
|
95
94
|
debug?.('lowire:loop')('Call tool', name, JSON.stringify(args, null, 2));
|
|
96
95
|
const status = await options.onBeforeToolCall?.({ assistantMessage, toolCall });
|
|
97
|
-
if (
|
|
96
|
+
if (options.signal?.aborted)
|
|
98
97
|
return { status: 'break', usage: totalUsage, turns };
|
|
99
98
|
if (status === 'disallow') {
|
|
100
99
|
toolCall.result = {
|
|
@@ -118,7 +117,7 @@ class Loop {
|
|
|
118
117
|
const text = result.content.filter(part => part.type === 'text').map(part => part.text).join('\n');
|
|
119
118
|
debug?.('lowire:loop')('Tool result', text, JSON.stringify(result, null, 2));
|
|
120
119
|
const status = await options.onAfterToolCall?.({ assistantMessage, toolCall, result });
|
|
121
|
-
if (
|
|
120
|
+
if (options.signal?.aborted)
|
|
122
121
|
return { status: 'break', usage: totalUsage, turns };
|
|
123
122
|
if (status === 'disallow') {
|
|
124
123
|
toolCall.result = {
|
|
@@ -134,7 +133,7 @@ class Loop {
|
|
|
134
133
|
catch (error) {
|
|
135
134
|
const errorMessage = `Error while executing tool "${name}": ${error instanceof Error ? error.message : String(error)}\n\nPlease try to recover and complete the task.`;
|
|
136
135
|
await options.onToolCallError?.({ assistantMessage, toolCall, error });
|
|
137
|
-
if (
|
|
136
|
+
if (options.signal?.aborted)
|
|
138
137
|
return { status: 'break', usage: totalUsage, turns };
|
|
139
138
|
toolCall.result = {
|
|
140
139
|
content: [{ type: 'text', text: errorMessage }],
|