mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-16 06:02:42 +00:00
Merge main, resolve CHANGELOG conflict
This commit is contained in:
commit
c15efdbcd9
41 changed files with 515 additions and 184 deletions
|
|
@ -90,7 +90,9 @@ function createNoOpUIContext(): HookUIContext {
|
|||
confirm: async () => false,
|
||||
input: async () => undefined,
|
||||
notify: () => {},
|
||||
custom: () => ({ close: () => {}, requestRender: () => {} }),
|
||||
custom: async () => undefined as never,
|
||||
setEditorText: () => {},
|
||||
getEditorText: () => "",
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,9 @@ const noOpUIContext: HookUIContext = {
|
|||
confirm: async () => false,
|
||||
input: async () => undefined,
|
||||
notify: () => {},
|
||||
custom: () => ({ close: () => {}, requestRender: () => {} }),
|
||||
custom: async () => undefined as never,
|
||||
setEditorText: () => {},
|
||||
getEditorText: () => "",
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -46,30 +46,46 @@ export function wrapToolWithHooks<T>(tool: AgentTool<any, T>, hookRunner: HookRu
|
|||
}
|
||||
|
||||
// Execute the actual tool, forwarding onUpdate for progress streaming
|
||||
const result = await tool.execute(toolCallId, params, signal, onUpdate);
|
||||
try {
|
||||
const result = await tool.execute(toolCallId, params, signal, onUpdate);
|
||||
|
||||
// Emit tool_result event - hooks can modify the result
|
||||
if (hookRunner.hasHandlers("tool_result")) {
|
||||
const resultResult = (await hookRunner.emit({
|
||||
type: "tool_result",
|
||||
toolName: tool.name,
|
||||
toolCallId,
|
||||
input: params,
|
||||
content: result.content,
|
||||
details: result.details,
|
||||
isError: false,
|
||||
})) as ToolResultEventResult | undefined;
|
||||
// Emit tool_result event - hooks can modify the result
|
||||
if (hookRunner.hasHandlers("tool_result")) {
|
||||
const resultResult = (await hookRunner.emit({
|
||||
type: "tool_result",
|
||||
toolName: tool.name,
|
||||
toolCallId,
|
||||
input: params,
|
||||
content: result.content,
|
||||
details: result.details,
|
||||
isError: false,
|
||||
})) as ToolResultEventResult | undefined;
|
||||
|
||||
// Apply modifications if any
|
||||
if (resultResult) {
|
||||
return {
|
||||
content: resultResult.content ?? result.content,
|
||||
details: (resultResult.details ?? result.details) as T,
|
||||
};
|
||||
// Apply modifications if any
|
||||
if (resultResult) {
|
||||
return {
|
||||
content: resultResult.content ?? result.content,
|
||||
details: (resultResult.details ?? result.details) as T,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return result;
|
||||
} catch (err) {
|
||||
// Emit tool_result event for errors so hooks can observe failures
|
||||
if (hookRunner.hasHandlers("tool_result")) {
|
||||
await hookRunner.emit({
|
||||
type: "tool_result",
|
||||
toolName: tool.name,
|
||||
toolCallId,
|
||||
input: params,
|
||||
content: [{ type: "text", text: err instanceof Error ? err.message : String(err) }],
|
||||
details: undefined,
|
||||
isError: true,
|
||||
});
|
||||
}
|
||||
throw err; // Re-throw original error for agent-loop
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import type { AgentMessage } from "@mariozechner/pi-agent-core";
|
||||
import type { ImageContent, Message, Model, TextContent, ToolResultMessage } from "@mariozechner/pi-ai";
|
||||
import type { Component } from "@mariozechner/pi-tui";
|
||||
import type { Component, TUI } from "@mariozechner/pi-tui";
|
||||
import type { Theme } from "../../modes/interactive/theme/theme.js";
|
||||
import type { CompactionPreparation, CompactionResult } from "../compaction/index.js";
|
||||
import type { ExecOptions, ExecResult } from "../exec.js";
|
||||
|
|
@ -59,12 +59,48 @@ export interface HookUIContext {
|
|||
|
||||
/**
|
||||
* Show a custom component with keyboard focus.
|
||||
* The component receives keyboard input via handleInput() if implemented.
|
||||
* The factory receives TUI, theme, and a done() callback to close the component.
|
||||
* Can be async for fire-and-forget work (don't await the work, just start it).
|
||||
*
|
||||
* @param component - Component to display (implement handleInput for keyboard, dispose for cleanup)
|
||||
* @returns Object with close() to restore normal UI and requestRender() to trigger redraw
|
||||
* @param factory - Function that creates the component. Call done() when finished.
|
||||
* @returns Promise that resolves with the value passed to done()
|
||||
*
|
||||
* @example
|
||||
* // Sync factory
|
||||
* const result = await ctx.ui.custom((tui, theme, done) => {
|
||||
* const component = new MyComponent(tui, theme);
|
||||
* component.onFinish = (value) => done(value);
|
||||
* return component;
|
||||
* });
|
||||
*
|
||||
* // Async factory with fire-and-forget work
|
||||
* const result = await ctx.ui.custom(async (tui, theme, done) => {
|
||||
* const loader = new CancellableLoader(tui, theme.fg("accent"), theme.fg("muted"), "Working...");
|
||||
* loader.onAbort = () => done(null);
|
||||
* doWork(loader.signal).then(done); // Don't await - fire and forget
|
||||
* return loader;
|
||||
* });
|
||||
*/
|
||||
custom(component: Component & { dispose?(): void }): { close: () => void; requestRender: () => void };
|
||||
custom<T>(
|
||||
factory: (
|
||||
tui: TUI,
|
||||
theme: Theme,
|
||||
done: (result: T) => void,
|
||||
) => (Component & { dispose?(): void }) | Promise<Component & { dispose?(): void }>,
|
||||
): Promise<T>;
|
||||
|
||||
/**
|
||||
* Set the text in the core input editor.
|
||||
* Use this to pre-fill the input box with generated content (e.g., prompt templates, extracted questions).
|
||||
* @param text - Text to set in the editor
|
||||
*/
|
||||
setEditorText(text: string): void;
|
||||
|
||||
/**
|
||||
* Get the current text from the core input editor.
|
||||
* @returns Current editor text
|
||||
*/
|
||||
getEditorText(): string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ export interface CreateAgentSessionResult {
|
|||
// Re-exports
|
||||
|
||||
export type { CustomTool } from "./custom-tools/types.js";
|
||||
export type { HookAPI, HookFactory } from "./hooks/types.js";
|
||||
export type { HookAPI, HookContext, HookFactory } from "./hooks/types.js";
|
||||
export type { Settings, SkillsSettings } from "./settings-manager.js";
|
||||
export type { Skill } from "./skills.js";
|
||||
export type { FileSlashCommand } from "./slash-commands.js";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue