@letta-ai/letta-code 0.26.3 → 0.26.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@letta-ai/letta-code",
3
- "version": "0.26.3",
3
+ "version": "0.26.4",
4
4
  "description": "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
5
5
  "type": "module",
6
6
  "packageManager": "bun@1.3.0",
@@ -72,6 +72,7 @@ Use `letta.capabilities` for optional behavior:
72
72
  letta.capabilities.tools
73
73
  letta.capabilities.commands
74
74
  letta.capabilities.events.lifecycle
75
+ letta.capabilities.events.tools
75
76
  letta.capabilities.events.turns
76
77
  letta.capabilities.ui.panels
77
78
  letta.capabilities.ui.statusValues
@@ -8,6 +8,7 @@ This is the first slice of the hooks-v2 direction. The long-term goal is for typ
8
8
 
9
9
  ```ts
10
10
  letta.capabilities.events.lifecycle
11
+ letta.capabilities.events.tools
11
12
  letta.capabilities.events.turns
12
13
  ```
13
14
 
@@ -33,26 +34,27 @@ letta.events.on("event_name", (event, ctx) => {
33
34
  });
34
35
  ```
35
36
 
36
- Future hook-replacement events should use this same API. For example, a future tool gate should look like:
37
+ Tool events use this same API. Existing settings-based hooks still own blocking decisions and model feedback injection until those contracts are explicitly added to extension events.
37
38
 
38
39
  ```ts
39
- letta.events.on("tool_call", (event, ctx) => {
40
+ letta.events.on("tool_start", (event, ctx) => {
40
41
  if (event.toolName !== "Bash") return;
41
- if (String(event.input.command).includes("rm -rf")) {
42
- return { block: true, reason: "Dangerous command" };
42
+ if (String(event.args.command).startsWith("npm test")) {
43
+ return { args: { ...event.args, command: "bun test" } };
43
44
  }
44
45
  });
45
46
  ```
46
47
 
47
- Lifecycle and turn-start events are wired today, and existing settings-based hooks still own blocking behavior.
48
+ Lifecycle, turn-start, and tool-start events are wired today.
48
49
 
49
- Lifecycle handlers are notification-only and should not return values. `turn_start` handlers can transform the outbound input for the next model turn.
50
+ Lifecycle handlers are notification-only and should not return values. `turn_start` handlers can transform the outbound input for the next model turn. `tool_start` handlers can transform the tool arguments before execution.
50
51
 
51
52
  ## Supported events
52
53
 
53
54
  ```ts
54
55
  "conversation_open"
55
56
  "conversation_close"
57
+ "tool_start"
56
58
  "turn_start"
57
59
  ```
58
60
 
@@ -91,6 +93,41 @@ Lifecycle handlers are notification-only and should not return values. `turn_sta
91
93
  }
92
94
  ```
93
95
 
96
+ `tool_start` event:
97
+
98
+ ```ts
99
+ {
100
+ agentId: string | null;
101
+ conversationId: string | null;
102
+ toolCallId: string | null;
103
+ toolName: string;
104
+ args: Record<string, unknown>;
105
+ }
106
+ ```
107
+
108
+ `tool_start` fires immediately before a client-side tool executes. This includes built-in tools, extension tools, and external tools executed through the local tool manager. It runs after permission/approval classification and before `PreToolUse` hooks, so trusted local extensions can change the actual executed arguments after the approval UI has already classified the original request.
109
+
110
+ Handlers can inspect `event.args`, mutate it directly, or return replacement args:
111
+
112
+ ```ts
113
+ letta.events.on("tool_start", (event) => {
114
+ if (event.toolName !== "Bash") return;
115
+ event.args = {
116
+ ...event.args,
117
+ command: String(event.args.command).replaceAll("npm test", "bun test"),
118
+ };
119
+ });
120
+
121
+ letta.events.on("tool_start", (event) => {
122
+ if (event.toolName !== "Read") return;
123
+ return { args: { ...event.args, limit: 200 } };
124
+ });
125
+ ```
126
+
127
+ Handlers run in registration order. Later handlers see the current args after earlier mutations/returns. If a handler throws, its partial `event.args` mutation is rolled back and the error is recorded as an extension diagnostic.
128
+
129
+ `tool_start` is intentionally a trusted local extension point: it can rewrite commands, file paths, and other tool inputs before execution. Keep transforms focused and unsurprising. It does not support blocking; use existing hooks for blocking safety decisions.
130
+
94
131
  `turn_start` fires before outbound turns that include a user message. In the TUI this includes normal submits and prompt-style command turns. In headless it includes one-shot prompts and bidirectional user turns.
95
132
 
96
133
  Handlers can mutate `event.input` directly or return replacement input: