feat: inject LETTA_AGENT_ID into hook environment context (#731)

Co-authored-by: letta-code <248085862+letta-code@users.noreply.github.com>
Co-authored-by: Cameron <cpfiffer@users.noreply.github.com>
This commit is contained in:
github-actions[bot]
2026-01-28 16:24:17 -08:00
committed by GitHub
parent 79d02ffbdc
commit 4c702057e0
2 changed files with 49 additions and 1 deletions

View File

@@ -29,13 +29,21 @@ function trySpawnWithLauncher(
throw new Error("Empty launcher");
}
// Extract agent_id if present (available on many hook input types)
const agentId = "agent_id" in input ? input.agent_id : undefined;
// Build environment: start with parent env but exclude LETTA_AGENT_ID to prevent inheritance
// We only want to pass the agent ID that's explicitly provided in the hook input
const { LETTA_AGENT_ID: _, ...parentEnv } = process.env;
return spawn(executable, args, {
cwd: workingDirectory,
env: {
...process.env,
...parentEnv,
// Add hook-specific environment variables
LETTA_HOOK_EVENT: input.event_type,
LETTA_WORKING_DIR: workingDirectory,
...(agentId && { LETTA_AGENT_ID: agentId }),
},
stdio: ["pipe", "pipe", "pipe"],
});

View File

@@ -160,6 +160,46 @@ describe.skipIf(isWindows)("Hooks Executor", () => {
expect(result.exitCode).toBe(HookExitCode.ALLOW);
expect(result.stdout).toBe("PreToolUse");
});
test("receives LETTA_AGENT_ID environment variable when agent_id is provided", async () => {
const hook: HookCommand = {
type: "command",
command: "echo $LETTA_AGENT_ID",
};
const input: PreToolUseHookInput = {
event_type: "PreToolUse",
working_directory: tempDir,
tool_name: "Bash",
tool_input: {},
agent_id: "agent-test-12345",
};
const result = await executeHookCommand(hook, input, tempDir);
expect(result.exitCode).toBe(HookExitCode.ALLOW);
expect(result.stdout).toBe("agent-test-12345");
});
test("LETTA_AGENT_ID is not set when agent_id is not provided", async () => {
const hook: HookCommand = {
type: "command",
command: "echo \"agent_id:${LETTA_AGENT_ID:-empty}\"",
};
const input: PreToolUseHookInput = {
event_type: "PreToolUse",
working_directory: tempDir,
tool_name: "Bash",
tool_input: {},
// Note: agent_id is not provided
};
const result = await executeHookCommand(hook, input, tempDir);
expect(result.exitCode).toBe(HookExitCode.ALLOW);
expect(result.stdout).toBe("agent_id:empty");
});
});
describe("executeHooks", () => {