Skip to content

Conversation

@zikajk
Copy link
Member

@zikajk zikajk commented Nov 29, 2025

Implement advanced lifecycle hooks

Key changes:

  • New Hook Types: sessionStart, sessionEnd, chatStart, chatEnd for better lifecycle management.

  • Enhanced preRequest: Supports prompt rewriting, context injection, and request blocking.

  • Enhanced preToolCall: Allows argument modification, approval overrides (allow/ask/deny), and tool blocking via exit codes or JSON.

  • New postToolCall: Provides access to tool responses and errors, allowing for post-execution context injection.

  • JSON Protocol: Hooks now communicate via structured JSON on stdin/stdout for robust data exchange.

  • Integration: Updates chat loop and tool state machine to respect hook decisions.

  • I added a entry in changelog under unreleased section.

@zikajk zikajk requested a review from ericdallo November 29, 2025 15:37
Moves cache directory resolution and workspace hashing from `eca.db` to a new `eca.cache` namespace.
Centralizes file path management and allows other components (hooks) to acess cache paths.
Avoids circular dependencies on the database namespace.
@zikajk zikajk force-pushed the advanced-hooks branch 2 times, most recently from e177621 to af57b0a Compare November 29, 2025 16:05
@zikajk
Copy link
Member Author

zikajk commented Nov 29, 2025

@ericdallo I am not sure about the failing Windows test. Maybe you have an idea?

["## Contexts"
""
(contexts-str refined-contexts repo-map*)])
(contexts-str refined-contexts repo-map* (get-in db [:chats chat-id :startup-context]))])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should go indeed to a refined-context, following others

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does, right?

Comment on lines +40 to +42
(logger/debug logger-tag "Hook JSON output must result in map")))
(catch Exception e
(logger/debug logger-tag "Hook output is not valid JSON, treating as plain text"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe these should be at least a logger/warn?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure. It is still valid to not return JSON. The question would be if this should be logged at all :-).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah maybe the first one? I don't know too

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think both are valid.
The first one will tell the user that his output is a valid json but not the one compatible with advanced hooks.
The second one might be useful to catch if the JSON is invalid but it will probably throw even with a string.
If i am not wrong, they will fire too often to have them on any other level than debug, no?

(if (and @approved?* (not hook-rejected?))
(when-not (#{:stopping :cleanup} (:status (get-tool-call-state @db* chat-id id)))
(assert-chat-not-stopped! chat-ctx)
(let [delayed-future (delay (future (let [result (f.tools/call-tool! name
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few enters + remove vertical alignment would make this way better to read

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the vertical alignment, but where do you see newlines would help?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think one after delay and other after future maybe?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, i see, i did that :). Good.

Copy link
Member

@ericdallo ericdallo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a first review looks good! I will start test manually
The changes were all good and nice besides chat.clj which scared me a little bit the amount of unrelated changes TBH :)

Key changes:
- New Hook Types: `sessionStart`, `sessionEnd`, `chatStart`, `chatEnd` for better lifecycle management.
- Enhanced `preRequest`: Supports prompt rewriting, context injection, and request blocking.
- Enhanced `preToolCall`: Allows argument modification, approval overrides (allow/ask/deny), and tool blocking via exit codes or JSON.
- New `postToolCall`: Provides access to tool responses and errors, allowing for post-execution context injection.
- JSON Protocol: Hooks now communicate via structured JSON on stdin/stdout for robust data exchange.
- Integration: Updates chat loop and tool state machine to respect hook decisions.
- `docs/configuration.md`: Detailed reference for new hook types, JSON icnput/output schema, and execution options (timeout, runOnError).
- `docs/examples.md`: Added practical examples for prompt rewriting, tool guarding, and context injection.
@zikajk zikajk force-pushed the advanced-hooks branch 2 times, most recently from 922eb19 to 408ffd6 Compare November 30, 2025 17:40
Copy link
Member

@ericdallo ericdallo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me! I didn't test all new hooks features, but the most important ones, feel free to merge

@ericdallo ericdallo merged commit abd127e into master Dec 1, 2025
9 checks passed
@ericdallo ericdallo mentioned this pull request Dec 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants