Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const grammar_build = @import("zig/build/grammar.zig");
const counters_build = @import("zig/build/metal_counters.zig");
const exl3_build = @import("zig/build/exl3.zig");
const exlr8_build = @import("zig/build/exlr8.zig");
const server_build = @import("zig/build/server.zig");
const golden_build = @import("zig/build/golden.zig");

comptime {
Expand Down Expand Up @@ -204,6 +205,7 @@ fn nativeServer(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.b
.imports = &.{ .{ .name = "engine_api", .module = api }, .{ .name = "tokenizer", .module = tokenizer }, .{ .name = "template", .module = template }, .{ .name = "native_engines", .module = engines }, .{ .name = "checkpoint_cli", .module = b.createModule(.{ .root_source_file = b.path("zig/src/cli/cli.zig"), .target = target, .optimize = .ReleaseSafe, .link_libc = true, .imports = &.{ .{ .name = "native_engines", .module = engines }, exlr8_build.cliImport(b, target, .ReleaseSafe, engine) } }) } },
}) });
exe.root_module.addOptions("build_options", build_options);
_ = server_build.addTo(b, exe.root_module, target, .ReleaseSafe);
if (test_step == null) {
exe.root_module.strip = true;
return exe;
Expand All @@ -221,10 +223,13 @@ fn nativeServer(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.b
.link_libc = true,
.imports = &.{ .{ .name = "engine_api", .module = api }, .{ .name = "tokenizer", .module = tokenizer }, .{ .name = "template", .module = template } },
});
const server_json = server_build.addTo(b, server_tests, target, .Debug);
test_step.?.dependOn(&b.addRunArtifact(b.addTest(.{ .root_module = server_tests })).step);
test_step.?.dependOn(&b.addRunArtifact(b.addTest(.{ .root_module = server_json })).step);
@import("zig/build/cortheon_fuzz.zig").add(b, target, api, tokenizer, template);
// the parse half's tests, as their own test binary (zig/src/server/tool_parse_test.zig)
const tool_parse_tests = b.addTest(.{ .root_module = b.createModule(.{ .root_source_file = b.path("zig/src/server/tool_parse_test.zig"), .target = target, .optimize = .Debug, .link_libc = true, .imports = &.{ .{ .name = "engine_api", .module = api }, .{ .name = "tokenizer", .module = tokenizer }, .{ .name = "template", .module = template } } }) });
_ = server_build.addTo(b, tool_parse_tests.root_module, target, .Debug);
test_step.?.dependOn(&b.addRunArtifact(tool_parse_tests).step);
// the chat-template engine's tests (zig/src/core/template/tests.zig), which no other test binary reaches
test_step.?.dependOn(&b.addRunArtifact(b.addTest(.{ .root_module = b.createModule(.{ .root_source_file = b.path("zig/src/core/template/tests.zig"), .target = target, .optimize = .Debug, .link_libc = true }) })).step);
Expand Down
1 change: 1 addition & 0 deletions zig/build/cortheon_fuzz.zig
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub fn add(b: *std.Build, target: std.Build.ResolvedTarget, api: *Module, tokeni
}),
.filters = &.{"cortheon.fuzz."},
});
_ = @import("server.zig").addTo(b, harness.root_module, target, optimize);
const step = b.step("fuzz-cortheon", "Cortheon's page, link, search and filter readers under the fuzz harness");
step.dependOn(&b.addRunArtifact(harness).step);
}
10 changes: 8 additions & 2 deletions zig/build/cuda.zig
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ fn nativeServer(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.b
.imports = &.{ .{ .name = "engine_api", .module = m.api }, .{ .name = "tokenizer", .module = tokenizer }, .{ .name = "template", .module = template }, .{ .name = "native_engines", .module = m.engines }, .{ .name = "checkpoint_cli", .module = checkpointCli(b, target, .ReleaseSafe, null, m.engines, core) } },
}) });
exe.root_module.addOptions("build_options", build_options);
_ = @import("server.zig").addTo(b, exe.root_module, target, .ReleaseSafe);
if (!install_native) {
exe.root_module.strip = true;
return exe;
Expand Down Expand Up @@ -201,9 +202,14 @@ pub fn hostTests(b: *std.Build, draft_ids: *std.Build.Module, build_options: *st
.link_libc = true,
.imports = &.{ .{ .name = "engine_api", .module = native_modules.api }, .{ .name = "tokenizer", .module = mods.tokenizer }, .{ .name = "template", .module = template } },
});
const server_json = @import("server.zig").addTo(b, server_tests, host, .debug);
const server_test = b.addRunArtifact(b.addTest(.{ .root_module = server_tests }));
step.dependOn(&server_test.step);
b.step("test-server-cpu", "The HTTP server's unit tests (routes, templates, tool parsing) without a GPU").dependOn(&server_test.step);
const json_test = b.addRunArtifact(b.addTest(.{ .root_module = server_json }));
const server_step = b.step("test-server-cpu", "The HTTP server's unit tests (routes, templates, tool parsing) without a GPU");
for ([_]*std.Build.Step.Run{ server_test, json_test }) |run| {
step.dependOn(&run.step);
server_step.dependOn(&run.step);
}
// the server goldens and Cortheon's fuzz step here when the target is not macOS, whose Metal build defines them
if (server_steps) {
golden_build.step(b, host, server_tests, native_modules.api, mods.tokenizer, template);
Expand Down
14 changes: 14 additions & 0 deletions zig/build/server.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//! The server's shared JSON values, available to server and family modules.
const std = @import("std");

/// The server's JSON values as a module (zig/src/server/json.zig), so a family's serving code shares them.
pub fn json(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode) *std.Build.Module {
return b.createModule(.{ .root_source_file = b.path("zig/src/server/json.zig"), .target = target, .optimize = optimize });
}

/// Attach a server's shared JSON module; its tests run separately from the server's root.
pub fn addTo(b: *std.Build, m: *std.Build.Module, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode) *std.Build.Module {
const j = json(b, target, optimize);
m.addImport("json", j);
return j;
}
2 changes: 1 addition & 1 deletion zig/src/server/anthropic.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Anthropic's Messages routes over the chat handler: typed SSE events, tool_use blocks, count_tokens.
const std = @import("std");
const json = @import("json.zig");
const json = @import("json");
const errors = @import("errors.zig");
const http_body = @import("http_body.zig");
const fields = @import("fields.zig");
Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/anthropic_translate.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Anthropic Messages requests as the chat requests that run them (``anthropic_translate.translate``).
const std = @import("std");
const json = @import("json.zig");
const json = @import("json");
const errors = @import("errors.zig");
const fields = @import("fields.zig");
const pyrepr = @import("pyrepr.zig");
Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/chat.zig
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! One reply, as ``ChatApp.chat`` makes it: render, submit to the engine, stream text, reasoning and calls.
const std = @import("std");
const api = @import("engine_api");
const json = @import("json.zig");
const json = @import("json");
const errors = @import("errors.zig");
const fields_mod = @import("fields.zig");
const reply_text = @import("reply_text.zig");
Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/chunk_plan.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Where a prompt's prefill chunks start (Python's PrefillPlan and message_markers): prompts that agree up to a start cut alike up to it.
const std = @import("std");
const json = @import("json.zig");
const json = @import("json");
const errors = @import("errors.zig");
const prompt = @import("prompt.zig");
const Server = @import("server.zig").Server;
Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/compact.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Note and reply are ordinary greedy or keyed generations, so the same request compacts and answers the same way.
const std = @import("std");
const json = @import("json.zig");
const json = @import("json");
const chat = @import("chat.zig");
const stored = @import("compact_mem.zig");
const server_mod = @import("server.zig");
Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/compact_mem.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! The compaction note file and the hash of the messages a note already covers.
const std = @import("std");
const json = @import("json.zig");
const json = @import("json");
const Server = @import("server.zig").Server;
const Value = json.Value;
const Allocator = std.mem.Allocator;
Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/compact_test.zig
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Host checks for opt-in compaction. The fake engine records each prompt and answers OK.
const std = @import("std");
const api = @import("engine_api");
const json = @import("json.zig");
const json = @import("json");
const errors = @import("errors.zig");
const model_text = @import("model_text.zig");
const chat = @import("chat.zig");
Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/completion_prompt_test.zig
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Token ids in a completion prompt, top-level or nested: ids in the vocabulary are served, other values get a 400.
const std = @import("std");
const api = @import("engine_api");
const json = @import("json.zig");
const json = @import("json");
const model_text = @import("model_text.zig");
const openai = @import("openai.zig");
const Server = @import("server.zig").Server;
Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/cortheon/checks.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Cortheon's checks before a reply ends: changed files tested before "done", researched answers naming sources.
const std = @import("std");
const json = @import("../json.zig");
const json = @import("json");
const tools = @import("tools.zig");
const Value = json.Value;

Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/cortheon/cortheon.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Cortheon in the server (--cortheon): its reasoning program, web research before building, server-run web tools.
const std = @import("std");
const json = @import("../json.zig");
const json = @import("json");
const chat = @import("../chat.zig");
const grammar = @import("../grammar.zig");
const prompt_mod = @import("../prompt.zig");
Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/cortheon/cortheon_test.zig
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Cortheon end to end on a scripted engine and a stand-in web: rounds, research, streams, splices and checks.
const std = @import("std");
const api = @import("engine_api");
const json = @import("../json.zig");
const json = @import("json");
const model_text = @import("../model_text.zig");
const openai = @import("../openai.zig");
const server_mod = @import("../server.zig");
Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/cortheon/loop.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Cortheon's reply loop: rounds with the model's server tool calls run between them, checks at the end, one reply.
const std = @import("std");
const json = @import("../json.zig");
const json = @import("json");
const errors = @import("../errors.zig");
const chat = @import("../chat.zig");
const tool_parse = @import("../tool_parse.zig");
Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/cortheon/memory.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! What a reply's client never saw (server tool rounds, Cortheon notes), kept to splice back in front of it next turn.
const std = @import("std");
const json = @import("../json.zig");
const json = @import("json");
const Value = json.Value;
const Allocator = std.mem.Allocator;

Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/cortheon/research.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Research before building: the model names searches, the server runs them and reads the best pages, as hidden rounds.
const std = @import("std");
const json = @import("../json.zig");
const json = @import("json");
const errors = @import("../errors.zig");
const chat = @import("../chat.zig");
const ids = @import("../ids.zig");
Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/cortheon/search.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Web search for Cortheon: DuckDuckGo's keyless HTML results, or Brave's search API when a key is set.
const std = @import("std");
const json = @import("../json.zig");
const json = @import("json");
const html = @import("html.zig");
const Allocator = std.mem.Allocator;

Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/cortheon/tools.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Cortheon's server-run tools: their specs, which calls are theirs, and each call run into the text the model reads.
const std = @import("std");
const json = @import("../json.zig");
const json = @import("json");
const search = @import("search.zig");
const Seen = @import("seen.zig").Seen;
const Value = json.Value;
Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/decisions.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! /v1/decisions checks a body the way 0.6.6 checks it, then scores through the engine hook when a family sets one.
const std = @import("std");
const json = @import("json.zig");
const json = @import("json");
const errors = @import("errors.zig");
const fields = @import("fields.zig");
const pyrepr = @import("pyrepr.zig");
Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/decisions_test.zig
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Request checks for /v1/decisions, and a fake engine hook that scores one choice.
const std = @import("std");
const api = @import("engine_api");
const json = @import("json.zig");
const json = @import("json");
const errors = @import("errors.zig");
const openai = @import("openai.zig");
const model_text = @import("model_text.zig");
Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/fields.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Request field checks shared by every route: numbers, stops, thinking switches, efforts, probabilities.
const std = @import("std");
const json = @import("json.zig");
const json = @import("json");
const errors = @import("errors.zig");
const Value = json.Value;
const Cx = errors.Cx;
Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/grammar.zig
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Structured-output fields checked as ``engine.grammar.request_spec`` checks them; the engine enforces them.
const std = @import("std");
const api = @import("engine_api");
const json = @import("json.zig");
const json = @import("json");
const errors = @import("errors.zig");
const pyrepr = @import("pyrepr.zig");
const tool_specs = @import("tool_specs.zig");
Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/hf_text.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
const std = @import("std");
const tokenizer = @import("tokenizer");
const template = @import("template");
const json = @import("json.zig");
const json = @import("json");
const model_text = @import("model_text.zig");
const Value = json.Value;
const Allocator = std.mem.Allocator;
Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/http_body.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Bounded request bodies, fixed-length or chunked, refused as the Python server refuses them.
const std = @import("std");
const json = @import("json.zig");
const json = @import("json");
const errors = @import("errors.zig");
const Conn = @import("http_conn.zig").Conn;
const Allocator = std.mem.Allocator;
Expand Down
1 change: 1 addition & 0 deletions zig/src/server/json.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const Allocator = std.mem.Allocator;
pub const parse = @import("json_parse.zig").parse;
pub const parseText = @import("json_parse.zig").parseText;
pub const ParseResult = @import("json_parse.zig").Result;
pub const wtf8Encode = @import("json_parse.zig").wtf8Encode;
pub const write = @import("json_write.zig").write;
pub const writeString = @import("json_write.zig").writeString;
pub const Options = @import("json_write.zig").Options;
Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/live.zig
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! The live status line (connections, decode and prefill tok/s), redrawn in a terminal, and /health's copy of it.
const std = @import("std");
const api = @import("engine_api");
const json = @import("json.zig");
const json = @import("json");
const log = @import("log.zig");
const Allocator = std.mem.Allocator;

Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/logprobs.zig
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! OpenAI ``logprobs`` (who may ask, ``choices[0].logprobs`` from the engine's rows) and vLLM's ``prompt_logprobs``.
const std = @import("std");
const api = @import("engine_api");
const json = @import("json.zig");
const json = @import("json");
const errors = @import("errors.zig");
const reply_text = @import("reply_text.zig");
const Server = @import("server.zig").Server;
Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/main.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! ``tensorfold-native``: ``capabilities --json`` for the Python switch, and ``serve MODEL [flags]`` with no Python.
const std = @import("std");
const json = @import("json.zig");
const json = @import("json");
const cli = @import("cli.zig");
const log = @import("log.zig");
const hub = @import("hub.zig");
Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/memory_routes.zig
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Authenticated, read-only sizing diagnostics; unknown counters and plans are omitted rather than guessed.
const std = @import("std");
const api = @import("engine_api");
const json = @import("json.zig");
const json = @import("json");
const process = @import("process_memory.zig");
const routes = @import("routes.zig");
const Server = @import("server.zig").Server;
Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/messages.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Chat messages as the template sees them: leading instructions merged, text parts joined, call arguments as objects.
const std = @import("std");
const json = @import("json.zig");
const json = @import("json");
const errors = @import("errors.zig");
const fields = @import("fields.zig");
const Value = json.Value;
Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/model_text.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! The tokenizer and chat template a server renders prompts and replies with (the tok and jinja branches plug in here).
const std = @import("std");
const json = @import("json.zig");
const json = @import("json");
const Allocator = std.mem.Allocator;

pub const RenderOptions = struct {
Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/openai.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! POST /v1/chat/completions and /v1/completions, JSON or SSE, as ``server.http`` answers them.
const std = @import("std");
const json = @import("json.zig");
const json = @import("json");
const errors = @import("errors.zig");
const fields = @import("fields.zig");
const chat = @import("chat.zig");
Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/prompt.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Prompt ids from a request, as ``prepare_prompt`` and ``render_prompt_ids`` make them.
const std = @import("std");
const json = @import("json.zig");
const json = @import("json");
const errors = @import("errors.zig");
const messages_mod = @import("messages.zig");
const model_text = @import("model_text.zig");
Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/pyrepr.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Python's ``repr`` of decoded JSON, for refusal messages that quote a request's value.
const std = @import("std");
const json = @import("json.zig");
const json = @import("json");
const Value = json.Value;
const Allocator = std.mem.Allocator;

Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/request_log.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! TENSORFOLD_REQUEST_LOG: each chat and completion body appended as one JSON line, images redacted, for replays.
const std = @import("std");
const json = @import("json.zig");
const json = @import("json");
const Value = json.Value;
const Allocator = std.mem.Allocator;

Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/responses.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! OpenAI's Responses API: each request runs as its chat completion, translated item by item and event by event.
const std = @import("std");
const json = @import("json.zig");
const json = @import("json");
const errors = @import("errors.zig");
const http_body = @import("http_body.zig");
const openai = @import("openai.zig");
Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/responses_include_test.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Responses' include: OpenAI's values accepted and ignored, anything else refused by name.
const std = @import("std");
const json = @import("json.zig");
const json = @import("json");
const errors = @import("errors.zig");
const responses_translate = @import("responses_translate.zig");

Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/responses_translate.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! A Responses request as the chat completion that runs it (``responses_translate.translate``).
const std = @import("std");
const json = @import("json.zig");
const json = @import("json");
const errors = @import("errors.zig");
const fields = @import("fields.zig");
const pyrepr = @import("pyrepr.zig");
Expand Down
4 changes: 2 additions & 2 deletions zig/src/server/root.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! The native HTTP server's surface: what main and the test servers build a server from.
pub const json = @import("json.zig");
pub const json = @import("json");
pub const errors = @import("errors.zig");
pub const auth = @import("auth.zig");
pub const cli = @import("cli.zig");
Expand All @@ -17,7 +17,7 @@ pub const Config = server.Config;

test {
@import("std").testing.refAllDecls(@This());
_ = @import("json.zig");
_ = @import("json");
_ = @import("std_options.zig");
_ = @import("fields.zig");
_ = @import("reply_text.zig");
Expand Down
2 changes: 1 addition & 1 deletion zig/src/server/routes.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Method and path dispatch, as ``do_GET``, ``do_POST`` and ``do_DELETE`` route them.
const std = @import("std");
const json = @import("json.zig");
const json = @import("json");
const http_conn = @import("http_conn.zig");
const http_body = @import("http_body.zig");
const auth = @import("auth.zig");
Expand Down
Loading
Loading