my harness for niri
1import OpenAI from "openai"
2import type { LoopHooks, LoopState } from "./types.js"
3
4export type FunctionToolCall = OpenAI.Chat.ChatCompletionMessageToolCall & { type: "function" }
5
6export type ToolArgs = {
7 command?: string
8 query?: string
9 max_lines?: number
10 timeout_ms?: number
11 path?: string
12 start_line?: number
13 end_line?: number
14 old_text?: string
15 new_text?: string
16 note?: string
17 detail?: string
18 limit?: number
19 status?: string
20 item_id?: string
21 action?: string
22 channel_id?: string
23 channel_ids?: string[]
24 before_message_id?: string
25 content?: string
26 source_item_id?: string
27 reference_message?: string
28 reply_mode?: string
29 [key: string]: unknown
30}
31
32export type ToolExecutionOutcome = { shouldRest?: boolean; isWait?: boolean }
33
34export type CompletionTurnResult = {
35 message: OpenAI.Chat.ChatCompletionMessage
36 usage?: OpenAI.Completions.CompletionUsage
37 emittedText: boolean
38 emittedThinking: boolean
39 bufferedThinking: string
40}
41
42export type CompletionRequest = {
43 model: string
44 messages: OpenAI.Chat.ChatCompletionMessageParam[]
45 tools: OpenAI.Chat.ChatCompletionTool[]
46 tool_choice: "required" | "auto" | "none"
47 include_reasoning?: boolean
48 reasoning?: { enabled?: boolean; exclude?: boolean; effort?: "none" | "minimal" | "low" | "medium" | "high" | "xhigh" }
49 provider?: { require_parameters?: boolean }
50 enable_thinking?: boolean
51 chat_template_kwargs?: { enable_thinking?: boolean }
52}
53
54export type ToolCallAssembly = {
55 id: string
56 type: "function"
57 function: {
58 name: string
59 arguments: string
60 }
61}
62
63export type ToolArgKey = keyof ToolArgs
64export type ArgTuple<K extends readonly ToolArgKey[]> = { [I in keyof K]: ToolArgs[K[I]] }
65
66export type ToolExecutionContext = {
67 convId: number
68 state: LoopState
69 hooks: LoopHooks
70 call: FunctionToolCall
71 args: ToolArgs
72}
73
74export type ToolHandler = (ctx: ToolExecutionContext) => Promise<ToolExecutionOutcome>