my harness for niri
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 65 lines 2.1 kB view raw
1import { emit } from "../stream.js" 2import { buildToolHandlers } from "./loop-tool-registry.js" 3import { executeToolCall, pushToolMessage } from "./loop-tool-runtime.js" 4import type { FunctionToolCall } from "./loop-shared.js" 5import type { LoopHooks, LoopState } from "./types.js" 6 7function skipRemainingToolCalls( 8 convId: number, 9 state: LoopState, 10 calls: readonly FunctionToolCall[], 11 startIndex: number, 12 source: string, 13): void { 14 calls.slice(startIndex).forEach((pendingCall) => { 15 const skippedContent = `skipped: interrupted by incoming ${source} event.` 16 const result = pushToolMessage(convId, state, pendingCall, skippedContent) 17 emit({ type: "tool", name: pendingCall.function.name, args: { _skipped: true }, result }) 18 }) 19} 20 21function maybeInterruptAfterTool( 22 convId: number, 23 state: LoopState, 24 hooks: LoopHooks, 25 calls: readonly FunctionToolCall[], 26 nextIndex: number, 27): boolean { 28 if (state.pendingInputs.length === 0) return false 29 30 const incoming = state.pendingInputs.shift()! 31 hooks.injectIncomingEvent(convId, incoming) 32 skipRemainingToolCalls(convId, state, calls, nextIndex, incoming.source) 33 return true 34} 35 36/** 37 * Processes all function tool calls requested in one assistant turn. 38 * 39 * @param convId - Active conversation id. 40 * @param state - Mutable loop state. 41 * @param hooks - Loop hooks for side effects and event flow. 42 * @param calls - Function tool calls to execute in order. 43 * @returns `true` when a `rest` tool call ended the loop, otherwise `false`. 44 */ 45export async function processToolCalls( 46 convId: number, 47 state: LoopState, 48 hooks: LoopHooks, 49 calls: readonly FunctionToolCall[], 50): Promise<boolean> { 51 const handlers = buildToolHandlers() 52 53 for (let i = 0; i < calls.length; i++) { 54 const call = calls[i]! 55 const outcome = await executeToolCall(convId, state, hooks, handlers, call) 56 57 if (outcome.shouldRest) return true 58 if (outcome.isWait) continue 59 60 const interrupted = maybeInterruptAfterTool(convId, state, hooks, calls, i + 1) 61 if (interrupted) return false 62 } 63 64 return false 65}