@lowire/loop 0.0.9 → 0.0.10

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 CHANGED
@@ -14,31 +14,32 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  import type * as types from './types';
17
+ type PromiseOrValue<T> = T | Promise<T>;
17
18
  export type LoopEvents = {
18
19
  onBeforeTurn?: (params: {
19
20
  conversation: types.Conversation;
20
21
  totalUsage: types.Usage;
21
22
  budgetTokens: number;
22
- }) => Promise<'break' | 'continue' | void>;
23
+ }) => PromiseOrValue<'continue' | 'break' | void>;
23
24
  onAfterTurn?: (params: {
24
25
  assistantMessage: types.AssistantMessage;
25
26
  totalUsage: types.Usage;
26
27
  budgetTokens: number;
27
- }) => Promise<'break' | 'continue' | void>;
28
+ }) => PromiseOrValue<'continue' | 'break' | void>;
28
29
  onBeforeToolCall?: (params: {
29
30
  assistantMessage: types.AssistantMessage;
30
31
  toolCall: types.ToolCallContentPart;
31
- }) => Promise<'allowed' | 'disallowed' | void>;
32
+ }) => PromiseOrValue<'continue' | 'break' | 'disallow' | void>;
32
33
  onAfterToolCall?: (params: {
33
34
  assistantMessage: types.AssistantMessage;
34
35
  toolCall: types.ToolCallContentPart;
35
36
  result: types.ToolResult;
36
- }) => Promise<'allowed' | 'disallowed' | void>;
37
+ }) => PromiseOrValue<'continue' | 'break' | 'disallow' | void>;
37
38
  onToolCallError?: (params: {
38
39
  assistantMessage: types.AssistantMessage;
39
40
  toolCall: types.ToolCallContentPart;
40
41
  error: Error;
41
- }) => Promise<void>;
42
+ }) => PromiseOrValue<'continue' | 'break' | void>;
42
43
  };
43
44
  export type LoopOptions = types.CompletionOptions & LoopEvents & {
44
45
  tools?: types.Tool[];
@@ -67,3 +68,4 @@ export declare class Loop {
67
68
  private _summarizeConversation;
68
69
  cache(): types.ReplayCache;
69
70
  }
71
+ export {};
package/lib/loop.js CHANGED
@@ -86,7 +86,9 @@ class Loop {
86
86
  if (name === 'report_result')
87
87
  return { result: args, status: 'ok', usage: totalUsage, turns };
88
88
  const status = await options.onBeforeToolCall?.({ assistantMessage, toolCall });
89
- if (status === 'disallowed') {
89
+ if (status === 'break')
90
+ return { status: 'break', usage: totalUsage, turns };
91
+ if (status === 'disallow') {
90
92
  toolCall.result = {
91
93
  content: [{ type: 'text', text: 'Tool call is disallowed.' }],
92
94
  isError: true,
@@ -108,7 +110,9 @@ class Loop {
108
110
  const text = result.content.filter(part => part.type === 'text').map(part => part.text).join('\n');
109
111
  debug?.('lowire:loop')('Tool result', text, JSON.stringify(result, null, 2));
110
112
  const status = await options.onAfterToolCall?.({ assistantMessage, toolCall, result });
111
- if (status === 'disallowed') {
113
+ if (status === 'break')
114
+ return { status: 'break', usage: totalUsage, turns };
115
+ if (status === 'disallow') {
112
116
  toolCall.result = {
113
117
  content: [{ type: 'text', text: 'Tool result is disallowed to be reported.' }],
114
118
  isError: true,
@@ -119,7 +123,9 @@ class Loop {
119
123
  }
120
124
  catch (error) {
121
125
  const errorMessage = `Error while executing tool "${name}": ${error instanceof Error ? error.message : String(error)}\n\nPlease try to recover and complete the task.`;
122
- await options.onToolCallError?.({ assistantMessage, toolCall, error });
126
+ const status = await options.onToolCallError?.({ assistantMessage, toolCall, error });
127
+ if (status === 'break')
128
+ return { status: 'break', usage: totalUsage, turns };
123
129
  toolCall.result = {
124
130
  content: [{ type: 'text', text: errorMessage }],
125
131
  isError: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lowire/loop",
3
- "version": "0.0.9",
3
+ "version": "0.0.10",
4
4
  "description": "Small agentic loop",
5
5
  "repository": {
6
6
  "type": "git",