summaryrefslogtreecommitdiff
path: root/src/extension_loader.zig
diff options
context:
space:
mode:
authort <t@tjp.lol>2026-07-02 10:29:53 -0600
committert <t@tjp.lol>2026-07-03 12:10:09 -0600
commitc4d7f70ff831cfcdad0f2a6224f9a14f86905de6 (patch)
tree89dac8fb213dc6dcd2612a5ff6974d5013dcdb63 /src/extension_loader.zig
parent800b2c4b6115845f6bf15d90484b3e80e81a606f (diff)
Stage and apply event-field overrides at tool lifecycle boundaries
Stage writable event-field overrides by tool call id so they can be applied at the correct point in the turn lifecycle. Capture input overrides from tool_call_complete, capture output overrides from tool_result, and clear staged overrides defensively at turn start and shutdown. Also honor user_message text overrides when starting a turn, add the helper that applies staged overrides to the agent at dispatch boundaries, and cover the behavior with tests for staged input/output overrides.
Diffstat (limited to 'src/extension_loader.zig')
-rw-r--r--src/extension_loader.zig14
1 files changed, 10 insertions, 4 deletions
diff --git a/src/extension_loader.zig b/src/extension_loader.zig
index 4620a2e..1c29ceb 100644
--- a/src/extension_loader.zig
+++ b/src/extension_loader.zig
@@ -220,7 +220,11 @@ pub fn loadFromDirs(
for (found.items) |f| {
var entries: std.array_list.Managed(Entry) = .init(allocator);
defer entries.deinit();
- try runtime.evalEntries(f.script_path, f.package_root, &entries);
+ runtime.evalEntries(f.script_path, f.package_root, &entries) catch |err| {
+ // Entries collected before the failure hold Lua refs + names.
+ for (entries.items) |e| runtime.dropEntry(e);
+ return err;
+ };
for (entries.items) |e| {
try cands.append(.{ .entry = e, .source = f.source, .script_path = f.script_path });
}
@@ -254,10 +258,13 @@ pub fn loadFromDirs(
runtime.dropEntry(cnd.entry);
continue;
}
+ // Log before activating: `activateEntry` consumes the entry
+ // (frees its name), so `cnd.entry.name` is dangling afterwards.
+ std.log.debug("extension: activating '{s}' ({s})", .{ cnd.entry.name, cnd.source.label() });
runtime.activateEntry(cnd.entry) catch |err| {
logConflict(
- "extension '{s}' ({s}: {s}) failed to activate: {t}",
- .{ cnd.entry.name, cnd.source.label(), cnd.script_path, err },
+ "extension ({s}: {s}) failed to activate: {t}",
+ .{ cnd.source.label(), cnd.script_path, err },
);
// activateEntry consumed the entry already. Drop the rest.
var j = i + 1;
@@ -265,7 +272,6 @@ pub fn loadFromDirs(
cands.clearRetainingCapacity();
return err;
};
- std.log.debug("extension: activated '{s}' ({s})", .{ cnd.entry.name, cnd.source.label() });
}
cands.clearRetainingCapacity();