mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-17 07:03:25 +00:00
Hook commands: remove string return, use sendMessage() for prompting
- Command handler now returns Promise<void> instead of Promise<string | undefined> - To trigger LLM response, use sendMessage() with triggerTurn: true - Simplify _tryExecuteHookCommand to return boolean Added example hook and slash command in .pi/: - .pi/hooks/test-command.ts - /greet command using sendMessage - .pi/commands/review.md - file-based /review command
This commit is contained in:
parent
c8d9382aaa
commit
30cd723411
5 changed files with 50 additions and 23 deletions
12
.pi/commands/review.md
Normal file
12
.pi/commands/review.md
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
---
|
||||||
|
description: Review a file for issues
|
||||||
|
---
|
||||||
|
Please review the following file for potential issues, bugs, or improvements:
|
||||||
|
|
||||||
|
$1
|
||||||
|
|
||||||
|
Focus on:
|
||||||
|
- Logic errors
|
||||||
|
- Edge cases
|
||||||
|
- Code style
|
||||||
|
- Performance concerns
|
||||||
24
.pi/hooks/test-command.ts
Normal file
24
.pi/hooks/test-command.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
/**
|
||||||
|
* Test hook that registers a /greet command.
|
||||||
|
* Usage: /greet [name]
|
||||||
|
*/
|
||||||
|
import type { HookAPI } from "@mariozechner/pi-coding-agent/hooks";
|
||||||
|
|
||||||
|
export default function (pi: HookAPI) {
|
||||||
|
pi.registerCommand("greet", {
|
||||||
|
description: "Send a greeting message to the LLM",
|
||||||
|
handler: async (ctx) => {
|
||||||
|
const name = ctx.args.trim() || "world";
|
||||||
|
|
||||||
|
// Insert a custom message and trigger LLM response
|
||||||
|
ctx.sendMessage(
|
||||||
|
{
|
||||||
|
customType: "greeting",
|
||||||
|
content: `Hello, ${name}! Please say something nice about them.`,
|
||||||
|
display: true,
|
||||||
|
},
|
||||||
|
true, // triggerTurn - get LLM to respond
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -183,8 +183,7 @@ registerCommand(name: string, options: {
|
||||||
```
|
```
|
||||||
|
|
||||||
Handler return:
|
Handler return:
|
||||||
- `undefined` - command completed
|
- `void` - command completed (use `sendMessage()` with `triggerTurn: true` to prompt LLM)
|
||||||
- `string` - text to send as prompt (like file-based slash commands)
|
|
||||||
|
|
||||||
Wiring (all in AgentSession.prompt()):
|
Wiring (all in AgentSession.prompt()):
|
||||||
- [x] Add hook commands to autocomplete in interactive-mode
|
- [x] Add hook commands to autocomplete in interactive-mode
|
||||||
|
|
|
||||||
|
|
@ -462,15 +462,10 @@ export class AgentSession {
|
||||||
|
|
||||||
// Handle hook commands first (if enabled and text is a slash command)
|
// Handle hook commands first (if enabled and text is a slash command)
|
||||||
if (expandCommands && text.startsWith("/")) {
|
if (expandCommands && text.startsWith("/")) {
|
||||||
const result = await this._tryExecuteHookCommand(text);
|
const handled = await this._tryExecuteHookCommand(text);
|
||||||
if (result.handled) {
|
if (handled) {
|
||||||
if (result.prompt) {
|
// Hook command executed, no prompt to send
|
||||||
// Hook returned text to use as prompt
|
return;
|
||||||
text = result.prompt;
|
|
||||||
} else {
|
|
||||||
// Hook command executed, no prompt to send
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -506,10 +501,10 @@ export class AgentSession {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to execute a hook command. Returns whether it was handled and optional prompt text.
|
* Try to execute a hook command. Returns true if command was found and executed.
|
||||||
*/
|
*/
|
||||||
private async _tryExecuteHookCommand(text: string): Promise<{ handled: boolean; prompt?: string }> {
|
private async _tryExecuteHookCommand(text: string): Promise<boolean> {
|
||||||
if (!this._hookRunner) return { handled: false };
|
if (!this._hookRunner) return false;
|
||||||
|
|
||||||
// Parse command name and args
|
// Parse command name and args
|
||||||
const spaceIndex = text.indexOf(" ");
|
const spaceIndex = text.indexOf(" ");
|
||||||
|
|
@ -517,11 +512,11 @@ export class AgentSession {
|
||||||
const args = spaceIndex === -1 ? "" : text.slice(spaceIndex + 1);
|
const args = spaceIndex === -1 ? "" : text.slice(spaceIndex + 1);
|
||||||
|
|
||||||
const command = this._hookRunner.getCommand(commandName);
|
const command = this._hookRunner.getCommand(commandName);
|
||||||
if (!command) return { handled: false };
|
if (!command) return false;
|
||||||
|
|
||||||
// Get UI context from hook runner (set by mode)
|
// Get UI context from hook runner (set by mode)
|
||||||
const uiContext = this._hookRunner.getUIContext();
|
const uiContext = this._hookRunner.getUIContext();
|
||||||
if (!uiContext) return { handled: false };
|
if (!uiContext) return false;
|
||||||
|
|
||||||
// Build command context
|
// Build command context
|
||||||
const cwd = process.cwd();
|
const cwd = process.cwd();
|
||||||
|
|
@ -541,11 +536,8 @@ export class AgentSession {
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await command.handler(ctx);
|
await command.handler(ctx);
|
||||||
if (typeof result === "string") {
|
return true;
|
||||||
return { handled: true, prompt: result };
|
|
||||||
}
|
|
||||||
return { handled: true };
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// Emit error via hook runner
|
// Emit error via hook runner
|
||||||
this._hookRunner.emitError({
|
this._hookRunner.emitError({
|
||||||
|
|
@ -553,7 +545,7 @@ export class AgentSession {
|
||||||
event: "command",
|
event: "command",
|
||||||
error: err instanceof Error ? err.message : String(err),
|
error: err instanceof Error ? err.message : String(err),
|
||||||
});
|
});
|
||||||
return { handled: true };
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -426,7 +426,7 @@ export interface CommandContext {
|
||||||
export interface RegisteredCommand {
|
export interface RegisteredCommand {
|
||||||
name: string;
|
name: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
handler: (ctx: CommandContext) => Promise<string | undefined>;
|
handler: (ctx: CommandContext) => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue