PranitInitial commit439f83c3 months agoHistory
254 lines · 9.1 KB · Zig
RawDownload
const std = @import("std"); pub const emergency_ceiling_bytes: usize = 64 * 1024 * 1024; pub const Name = enum {    skill_description_bytes,    skill_catalog_bytes,    skill_chunk_bytes,    skill_file_bytes,    mcp_description_bytes,    mcp_search_result_bytes,    mcp_server_instructions_bytes,    mcp_selected_schema_bytes,    project_instruction_file_bytes,    project_instructions_total_bytes,    image_adapter_output_bytes,     pub fn defaultBytes(self: Name) usize {        return switch (self) {            .skill_description_bytes => 1024,            .skill_catalog_bytes => 16 * 1024,            .skill_chunk_bytes => 20 * 1024,            .skill_file_bytes => 1024 * 1024,            .mcp_description_bytes => 1024,            .mcp_search_result_bytes => 16 * 1024,            .mcp_server_instructions_bytes => 2 * 1024,            .mcp_selected_schema_bytes => 64 * 1024,            .project_instruction_file_bytes => 64 * 1024,            .project_instructions_total_bytes => 128 * 1024,            .image_adapter_output_bytes => 20 * 1024,        };    }     pub fn parse(raw: []const u8) ?Name {        inline for (std.meta.fields(Name)) |field| {            if (std.mem.eql(u8, raw, field.name)) return @enumFromInt(field.value);        }        return null;    }}; pub const Source = enum {    compiled_default,    user_global,    user_workspace,    command_line,     pub fn label(self: Source) []const u8 {        return switch (self) {            .compiled_default => "compiled default",            .user_global => "global settings",            .user_workspace => "workspace settings",            .command_line => "command line",        };    }}; pub const Value = union(enum) {    bytes: usize,    off,     pub fn normalBytes(self: Value) ?usize {        return switch (self) {            .bytes => |bytes| bytes,            .off => null,        };    }     pub fn effectiveBytes(self: Value) usize {        return @min(self.normalBytes() orelse emergency_ceiling_bytes, emergency_ceiling_bytes);    }}; pub const Resolved = struct {    value: Value,    source: Source,     pub fn effectiveBytes(self: Resolved) usize {        return self.value.effectiveBytes();    }}; pub const Override = struct {    name: Name,    value: Value,}; pub const Values = struct {    skill_description_bytes: Resolved = defaultResolved(.skill_description_bytes),    skill_catalog_bytes: Resolved = defaultResolved(.skill_catalog_bytes),    skill_chunk_bytes: Resolved = defaultResolved(.skill_chunk_bytes),    skill_file_bytes: Resolved = defaultResolved(.skill_file_bytes),    mcp_description_bytes: Resolved = defaultResolved(.mcp_description_bytes),    mcp_search_result_bytes: Resolved = defaultResolved(.mcp_search_result_bytes),    mcp_server_instructions_bytes: Resolved = defaultResolved(.mcp_server_instructions_bytes),    mcp_selected_schema_bytes: Resolved = defaultResolved(.mcp_selected_schema_bytes),    project_instruction_file_bytes: Resolved = defaultResolved(.project_instruction_file_bytes),    project_instructions_total_bytes: Resolved = defaultResolved(.project_instructions_total_bytes),    image_adapter_output_bytes: Resolved = defaultResolved(.image_adapter_output_bytes),     pub fn get(self: Values, name: Name) Resolved {        return switch (name) {            inline else => |tag| @field(self, @tagName(tag)),        };    }     pub fn apply(self: *Values, overrides: Overrides) void {        inline for (std.meta.fields(Name)) |field| {            const name: Name = @enumFromInt(field.value);            if (overrides.get(name)) |value| @field(self, field.name) = value;        }    }     pub fn applyCommandLine(self: *Values, overrides: []const Override) void {        for (overrides) |override| {            self.set(override.name, .{ .value = override.value, .source = .command_line });        }    }     pub fn set(self: *Values, name: Name, value: Resolved) void {        switch (name) {            inline else => |tag| @field(self, @tagName(tag)) = value,        }    }}; pub const Overrides = struct {    skill_description_bytes: ?Resolved = null,    skill_catalog_bytes: ?Resolved = null,    skill_chunk_bytes: ?Resolved = null,    skill_file_bytes: ?Resolved = null,    mcp_description_bytes: ?Resolved = null,    mcp_search_result_bytes: ?Resolved = null,    mcp_server_instructions_bytes: ?Resolved = null,    mcp_selected_schema_bytes: ?Resolved = null,    project_instruction_file_bytes: ?Resolved = null,    project_instructions_total_bytes: ?Resolved = null,    image_adapter_output_bytes: ?Resolved = null,     pub fn get(self: Overrides, name: Name) ?Resolved {        return switch (name) {            inline else => |tag| @field(self, @tagName(tag)),        };    }     pub fn set(self: *Overrides, name: Name, value: Resolved) void {        switch (name) {            inline else => |tag| @field(self, @tagName(tag)) = value,        }    }     pub fn retag(self: *Overrides, source: Source) void {        inline for (std.meta.fields(Name)) |field| {            if (@field(self, field.name)) |*value| value.source = source;        }    }     pub fn merge(self: *Overrides, incoming: Overrides) void {        inline for (std.meta.fields(Name)) |field| {            if (@field(incoming, field.name)) |value| @field(self, field.name) = value;        }    }}; pub fn parseOverride(raw: []const u8) !Override {    const separator = std.mem.indexOfScalar(u8, raw, '=') orelse return error.InvalidContextLimitOverride;    const raw_name = std.mem.trim(u8, raw[0..separator], " \t\r\n");    const raw_value = std.mem.trim(u8, raw[separator + 1 ..], " \t\r\n");    if (raw_name.len == 0 or raw_value.len == 0) return error.InvalidContextLimitOverride;    return .{        .name = Name.parse(raw_name) orelse return error.UnknownContextLimit,        .value = try parseValueString(raw_value),    };} pub fn parseJsonObject(value: std.json.Value) !Overrides {    if (value != .object) return error.InvalidContextLimitsType;     var result = Overrides{};    var iterator = value.object.iterator();    while (iterator.next()) |entry| {        const name = Name.parse(entry.key_ptr.*) orelse return error.UnknownContextLimit;        result.set(name, .{            .value = try parseJsonValue(entry.value_ptr.*),            .source = .compiled_default,        });    }    return result;} fn parseJsonValue(value: std.json.Value) !Value {    return switch (value) {        .integer => |integer| .{ .bytes = std.math.cast(usize, integer) orelse return error.InvalidContextLimitValue },        .string => |string| parseValueString(string),        else => error.InvalidContextLimitValue,    };} fn parseValueString(raw: []const u8) !Value {    if (std.ascii.eqlIgnoreCase(raw, "off")) return .off;    return .{ .bytes = std.fmt.parseUnsigned(usize, raw, 10) catch return error.InvalidContextLimitValue };} fn defaultResolved(comptime name: Name) Resolved {    return .{        .value = .{ .bytes = name.defaultBytes() },        .source = .compiled_default,    };} pub fn utf8PrefixLength(bytes: []const u8, max_bytes: usize) usize {    var end = @min(max_bytes, bytes.len);    while (end > 0 and !std.unicode.utf8ValidateSlice(bytes[0..end])) : (end -= 1) {}    return end;} pub fn lineSafePrefixLength(bytes: []const u8, max_bytes: usize) usize {    const utf8_end = utf8PrefixLength(bytes, max_bytes);    if (utf8_end == bytes.len) return utf8_end;    if (std.mem.lastIndexOfScalar(u8, bytes[0..utf8_end], '\n')) |newline| return newline + 1;    return utf8_end;} test "defaults match the public context limit contract" {    const values = Values{};    inline for (std.meta.fields(Name)) |field| {        const name: Name = @enumFromInt(field.value);        try std.testing.expectEqual(name.defaultBytes(), values.get(name).effectiveBytes());        try std.testing.expectEqual(Source.compiled_default, values.get(name).source);    }} test "context limit overrides accept bytes and off" {    const bytes = try parseOverride("skill_chunk_bytes=4096");    try std.testing.expectEqual(Name.skill_chunk_bytes, bytes.name);    try std.testing.expectEqual(@as(usize, 4096), bytes.value.bytes);     const off = try parseOverride("mcp_description_bytes=off");    try std.testing.expectEqual(Name.mcp_description_bytes, off.name);    try std.testing.expectEqual(emergency_ceiling_bytes, off.value.effectiveBytes());} test "context limit overrides reject unknown names and malformed values" {    try std.testing.expectError(error.UnknownContextLimit, parseOverride("wat=1"));    try std.testing.expectError(error.InvalidContextLimitValue, parseOverride("skill_chunk_bytes=-1"));    try std.testing.expectError(error.InvalidContextLimitOverride, parseOverride("skill_chunk_bytes"));} test "line safe prefix preserves utf8 and complete lines when possible" {    try std.testing.expectEqual(@as(usize, 4), lineSafePrefixLength("one\ntwo\n", 7));    try std.testing.expectEqual(@as(usize, 0), lineSafePrefixLength("éclair", 1));    try std.testing.expectEqual(@as(usize, 2), lineSafePrefixLength("éclair", 2));    try std.testing.expectEqual(@as(usize, 3), lineSafePrefixLength(&.{ 'a', 'b', 'c', 0xe4 }, 4));}