Skip to content

Enable writable hooks (v3) #12

@zastrowm

Description

@zastrowm

Overview

Enable writable hooks in TypeScript SDK to allow hook callbacks to modify event properties and change agent behavior, achieving parity with the Python SDK.

From strands-agents#294:

Right now, TypeScript hooks only supports reading properties, but not modifying properties to change behavior - like BeforeToolCallEvent modifying the tool to be called.

For parity of the Python SDK and to enable additional use cases, allow [some] TS hooks to modify events to change behavior of the running agent.

Implementation Requirements

Based on clarification discussion and repository analysis:

Current State

  • TypeScript: All event properties are readonly except for AfterModelCallEvent.retryModelCall
  • Python SDK: Uses _can_write() method to control which properties can be modified
  • Pattern Already Established: The agent already checks retryModelCall after invoking hooks and acts on modified values

Writable Properties to Implement

Match the Python SDK's writable properties exactly:

1. BeforeToolCallEvent

  • tool: Allow changing which tool gets executed
  • toolUse: Allow modifying tool parameters (name, toolUseId, input)

2. AfterToolCallEvent

  • result: Allow modifying the tool result before it's sent back to the model

3. AfterModelCallEvent

  • retryModelCall: Already writable (no changes needed)

Implementation Approach

Simple Pattern: Remove readonly modifiers from the properties listed above.

Do NOT implement:

  • cancel_tool property (deferred to future issue)
  • Property validation (no additional validation beyond what exists)
  • Formal _can_write() mechanism (use simple non-readonly approach)

Agent Integration

The agent must read the potentially modified properties after invoking hooks:

  1. BeforeToolCallEvent: After yielding the event, check if tool or toolUse were modified and use the updated values
  2. AfterToolCallEvent: After yielding the event, check if result was modified and use the updated value

Files to Modify

  1. src/hooks/events.ts

    • Remove readonly from: BeforeToolCallEvent.tool, BeforeToolCallEvent.toolUse, AfterToolCallEvent.result
  2. src/agent/agent.ts

    • After yielding BeforeToolCallEvent, use the potentially modified tool and toolUse properties
    • After yielding AfterToolCallEvent, use the potentially modified result property
  3. src/agent/__tests__/agent.hook.test.ts

    • Add test cases for modifying tool property in BeforeToolCallEvent
    • Add test cases for modifying toolUse property in BeforeToolCallEvent
    • Add test cases for modifying result property in AfterToolCallEvent
    • Follow existing test conventions in this file
  4. src/hooks/__tests__/events.test.ts

    • Update existing readonly verification tests (currently using @ts-expect-error)
    • Add tests confirming writable properties can be modified

Testing Requirements

All tests should be added to src/agent/__tests__/agent.hook.test.ts following existing patterns in that file:

  • Test writable property modifications: Verify hooks can modify tool, toolUse, and result
  • Test agent behavior changes: Verify agent uses the modified values
  • Test edge cases:
    • Setting tool to undefined
    • Modifying toolUse parameters
    • Changing result status/content
  • Maintain 80%+ test coverage

Acceptance Criteria

  • BeforeToolCallEvent.tool is writable (no readonly modifier)
  • BeforeToolCallEvent.toolUse is writable (no readonly modifier)
  • AfterToolCallEvent.result is writable (no readonly modifier)
  • Agent reads and uses modified tool from BeforeToolCallEvent
  • Agent reads and uses modified toolUse from BeforeToolCallEvent
  • Agent reads and uses modified result from AfterToolCallEvent
  • Tests in agent.hook.test.ts verify writable property behavior
  • Tests follow existing conventions in agent.hook.test.ts
  • All existing tests pass
  • Test coverage remains at 80%+

Out of Scope

  • cancel_tool property (deferred to future issue)
  • Documentation updates (maintained in separate repository)
  • Property validation beyond what Python SDK has
  • Writable properties on other events

Additional Notes

  • Type signature changes are acceptable (not considered breaking changes)
  • No additional validation required - match Python SDK behavior
  • Implementation should be straightforward following the retryModelCall pattern

Related Task

Create a follow-up task to add guidelines to the testing documentation about hook test conventions and the requirement to add hook tests to agent.hook.test.ts.

Estimated Scope

  • Complexity: Medium
  • Files Modified: ~4 files
  • New Test Cases: 5-8 test cases
  • Implementation Time: 3-5 days

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions