summaryrefslogtreecommitdiff
path: root/libpanto/src/openai_responses_json.zig
diff options
context:
space:
mode:
Diffstat (limited to 'libpanto/src/openai_responses_json.zig')
-rw-r--r--libpanto/src/openai_responses_json.zig30
1 files changed, 3 insertions, 27 deletions
diff --git a/libpanto/src/openai_responses_json.zig b/libpanto/src/openai_responses_json.zig
index fb98fe1..cb58c2c 100644
--- a/libpanto/src/openai_responses_json.zig
+++ b/libpanto/src/openai_responses_json.zig
@@ -25,6 +25,7 @@ const Writer = std.Io.Writer;
const conversation = @import("conversation.zig");
const config_mod = @import("config.zig");
const tool_registry_mod = @import("tool_registry.zig");
+const writeRawJson = @import("provider.zig").writeRawJson;
// ===========================================================================
// Request serialization
@@ -288,17 +289,6 @@ fn concatTextBlocks(
}
}
-fn writeRawJson(s: *std.json.Stringify, raw: []const u8) !void {
- var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
- defer arena.deinit();
- const parsed = std.json.parseFromSlice(std.json.Value, arena.allocator(), raw, .{}) catch {
- try s.beginObject();
- try s.endObject();
- return;
- };
- try s.write(parsed.value);
-}
-
// ===========================================================================
// Streaming event parsing
// ===========================================================================
@@ -325,11 +315,8 @@ pub const StreamEvent = struct {
/// `output_text`/`reasoning_summary` delta, or function-call argument
/// fragment.
delta: ?[]const u8 = null,
- /// Item id (`response.output_item.added/done`, function-call argument
- /// deltas reference `item_id`).
- item_id: ?[]const u8 = null,
- /// Output array index. Some function-call argument events identify the
- /// item by this instead of repeating `item_id`.
+ /// Output array index. The stable key for a tool call across all of its
+ /// events (`item_id` is unreliable on the Copilot proxy, so unused).
output_index: ?usize = null,
/// Item type on add/done: "message" | "function_call" | "reasoning".
item_type: ?[]const u8 = null,
@@ -359,8 +346,6 @@ pub const StreamEvent = struct {
pub const OutputItem = struct {
output_index: usize,
- item_id: ?[]const u8 = null,
- item_type: ?[]const u8 = null,
call_id: ?[]const u8 = null,
name: ?[]const u8 = null,
arguments: ?[]const u8 = null,
@@ -390,24 +375,20 @@ pub fn parseStreamEvent(allocator: Allocator, payload: []const u8) !StreamEvent
if (std.mem.eql(u8, type_str, "response.output_text.delta")) {
ev.kind = .output_text_delta;
ev.delta = strField(obj, "delta");
- ev.item_id = strField(obj, "item_id");
ev.output_index = usizeField(obj, "output_index");
} else if (std.mem.eql(u8, type_str, "response.reasoning_summary_text.delta")) {
ev.kind = .reasoning_summary_delta;
ev.delta = strField(obj, "delta");
- ev.item_id = strField(obj, "item_id");
ev.output_index = usizeField(obj, "output_index");
} else if (std.mem.eql(u8, type_str, "response.function_call_arguments.delta")) {
ev.kind = .function_call_arguments_delta;
ev.delta = strField(obj, "delta") orelse
strField(obj, "arguments_delta") orelse
strField(obj, "arguments");
- ev.item_id = strField(obj, "item_id");
ev.output_index = usizeField(obj, "output_index");
} else if (std.mem.eql(u8, type_str, "response.function_call_arguments.done")) {
ev.kind = .function_call_arguments_done;
ev.arguments = strField(obj, "arguments");
- ev.item_id = strField(obj, "item_id");
ev.output_index = usizeField(obj, "output_index");
} else if (std.mem.eql(u8, type_str, "response.output_item.added")) {
ev.kind = .output_item_added;
@@ -437,7 +418,6 @@ fn readItem(allocator: Allocator, obj: std.json.ObjectMap, ev: *StreamEvent) !vo
const item = obj.get("item") orelse return;
if (item != .object) return;
const io = item.object;
- ev.item_id = strField(io, "id");
ev.item_type = strField(io, "type");
ev.item_phase = strField(io, "phase");
ev.call_id = strField(io, "call_id");
@@ -495,8 +475,6 @@ fn readCompletedOutput(allocator: Allocator, obj: std.json.ObjectMap, ev: *Strea
if (!std.mem.eql(u8, item_type, "function_call")) continue;
try items.append(allocator, .{
.output_index = i,
- .item_id = strField(v.object, "id"),
- .item_type = item_type,
.call_id = strField(v.object, "call_id"),
.name = strField(v.object, "name"),
.arguments = strField(v.object, "arguments"),
@@ -762,7 +740,6 @@ test "responses parseStreamEvent - function_call item added/done + args delta" {
);
defer d.deinit();
try testing.expectEqual(EventKind.function_call_arguments_delta, d.kind);
- try testing.expectEqualStrings("fc_1", d.item_id.?);
try testing.expectEqualStrings("{\"x\":1}", d.delta.?);
var alt = try parseStreamEvent(allocator,
@@ -835,7 +812,6 @@ test "responses parseStreamEvent - completed output function calls" {
try testing.expectEqual(EventKind.completed, ev.kind);
try testing.expectEqual(@as(usize, 1), ev.completed_items.len);
try testing.expectEqual(@as(usize, 0), ev.completed_items[0].output_index);
- try testing.expectEqualStrings("fc_1", ev.completed_items[0].item_id.?);
try testing.expectEqualStrings("call_9", ev.completed_items[0].call_id.?);
try testing.expectEqualStrings("std__read", ev.completed_items[0].name.?);
try testing.expectEqualStrings("{\"path\":\"a\"}", ev.completed_items[0].arguments.?);