Skip to content

Commit e03abb4

Browse files
hyperpolymathclaude
andcommitted
Agent-mode API: the machine-facing interface for LLM consumers
agent_api.rs — complete agent-facing API: - AST-as-JSON bridge: parse_to_json(), json_to_program(), validate_json_ast() Agents can produce AST directly as JSON, skip text parsing entirely - Structured errors: AgentError with error code, Kategoria level, context, and Remediation suggestions with confidence scores and AstPatch fixes - TypeError→AgentError conversion for all 14 error kinds with tailored remediations (e.g., LinearUsedTwice → "remove second use" or "clone") - Valid moves API: variables in scope, callable functions, spawnable agents, linear obligations, budget remaining, protocol state - Grammar summary card: 10 top-level forms, 14 statements, 12 expressions, 10 types, 54 keywords, 14 operators, 10 cost entries, 11 Harvard rules - Full validation pipeline: parse→typecheck→summarize in single JSON call CLI commands: agent-parse, agent-validate, agent-moves, agent-card, agent-from-json Design rationale: the text syntax is the human interface. The AST-JSON + structured errors + valid-next-moves API is the agent interface. 007 needs both. This implements the second. 169 tests (160 + 9 new). Zero clippy warnings. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent d2a009b commit e03abb4

4 files changed

Lines changed: 2320 additions & 6 deletions

File tree

crates/oo7-cli/src/main.rs

Lines changed: 128 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ fn main() {
2323
Some("typecheck") => cmd_typecheck(&args),
2424
Some("eval") => cmd_eval(&args),
2525
Some("demo") => run_demo(),
26+
Some("agent-parse") => cmd_agent_parse(&args),
27+
Some("agent-validate") => cmd_agent_validate(&args),
28+
Some("agent-moves") => cmd_agent_moves(&args),
29+
Some("agent-card") => cmd_agent_card(),
30+
Some("agent-from-json") => cmd_agent_from_json(),
2631
Some("--help") | Some("-h") | None => print_usage(),
2732
Some(cmd) => {
2833
eprintln!("Unknown command: {}", cmd);
@@ -36,12 +41,20 @@ fn print_usage() {
3641
println!("007 Agent Meta-Language — Reference Evaluator");
3742
println!();
3843
println!("Usage:");
39-
println!(" oo7 parse <file.007> Parse a .007 file and print AST as JSON");
40-
println!(" oo7 check <file.007> Validate syntax (no output on success)");
41-
println!(" oo7 typecheck <file.007> Type-check a .007 file (L1-3, L7)");
42-
println!(" oo7 eval <file.007> Parse and evaluate (parse-only for now)");
43-
println!(" oo7 demo Run built-in demo producing decision traces");
44-
println!(" oo7 --help Show this help message");
44+
println!(" oo7 parse <file.007> Parse a .007 file and print AST as JSON");
45+
println!(" oo7 check <file.007> Validate syntax (no output on success)");
46+
println!(" oo7 typecheck <file.007> Type-check a .007 file (L1-3, L7)");
47+
println!(" oo7 eval <file.007> Parse and evaluate (parse-only for now)");
48+
println!(" oo7 demo Run built-in demo producing decision traces");
49+
println!();
50+
println!("Agent-Mode API (machine-facing, JSON output):");
51+
println!(" oo7 agent-parse <file.007> Parse and return JSON AST");
52+
println!(" oo7 agent-validate <file.007> Full pipeline: parse + typecheck, return AgentResult");
53+
println!(" oo7 agent-moves <file.007> <name> Valid moves for agent <name> as JSON");
54+
println!(" oo7 agent-card Print grammar reference card as JSON");
55+
println!(" oo7 agent-from-json Read JSON AST from stdin, validate, return AgentResult");
56+
println!();
57+
println!(" oo7 --help Show this help message");
4558
println!();
4659
println!("The telescope is on. We're looking.");
4760
}
@@ -187,6 +200,115 @@ fn cmd_eval(args: &[String]) {
187200
}
188201
}
189202

203+
// ============================================================
204+
// Agent-Mode CLI Commands
205+
// ============================================================
206+
207+
/// `oo7 agent-parse <file.007>` — parse and return JSON AST.
208+
///
209+
/// Equivalent to `oo7 parse` but uses the agent_api bridge for
210+
/// consistency with the agent-mode interface.
211+
fn cmd_agent_parse(args: &[String]) {
212+
let source = read_source_file(args);
213+
214+
match oo7_core::agent_api::parse_to_json(&source) {
215+
Ok(json) => println!("{}", json),
216+
Err(e) => {
217+
let err_json = serde_json::to_string_pretty(&e).unwrap_or_else(|_| e.message.clone());
218+
eprintln!("{}", err_json);
219+
std::process::exit(1);
220+
}
221+
}
222+
}
223+
224+
/// `oo7 agent-validate <file.007>` — full pipeline, return AgentResult as JSON.
225+
///
226+
/// Runs parse -> typecheck -> declaration summary -> valid moves.
227+
/// Always outputs JSON, even on error.
228+
fn cmd_agent_validate(args: &[String]) {
229+
let source = read_source_file(args);
230+
let result = oo7_core::agent_api::validate_source(&source);
231+
let json = serde_json::to_string_pretty(&result).expect("AgentResult serialization failed");
232+
println!("{}", json);
233+
234+
if !result.success {
235+
std::process::exit(1);
236+
}
237+
}
238+
239+
/// `oo7 agent-moves <file.007> <agent-name>` — valid moves for an agent.
240+
///
241+
/// Parses and type-checks the file, then returns the ValidMoves for
242+
/// the named agent as JSON.
243+
fn cmd_agent_moves(args: &[String]) {
244+
let source = read_source_file(args);
245+
let agent_name = match args.get(3) {
246+
Some(name) => name,
247+
None => {
248+
eprintln!("Error: missing agent name argument.");
249+
eprintln!("Usage: oo7 agent-moves <file.007> <agent-name>");
250+
std::process::exit(1);
251+
}
252+
};
253+
254+
let program = match parser::parse_program(&source) {
255+
Ok(p) => p,
256+
Err(e) => {
257+
let err = oo7_core::agent_api::AgentResult::error(vec![
258+
oo7_core::AgentError {
259+
code: "PARSE_ERROR".to_string(),
260+
level: 0,
261+
message: e.to_string(),
262+
location: None,
263+
context: serde_json::Value::Null,
264+
remediations: vec![],
265+
},
266+
]);
267+
let json = serde_json::to_string_pretty(&err).unwrap();
268+
eprintln!("{}", json);
269+
std::process::exit(1);
270+
}
271+
};
272+
273+
let moves = oo7_core::agent_api::valid_moves(&program, agent_name);
274+
let json = serde_json::to_string_pretty(&moves).expect("ValidMoves serialization failed");
275+
println!("{}", json);
276+
}
277+
278+
/// `oo7 agent-card` — print grammar reference card as JSON.
279+
fn cmd_agent_card() {
280+
println!("{}", oo7_core::agent_api::grammar_card());
281+
}
282+
283+
/// `oo7 agent-from-json` — read JSON AST from stdin, validate, return AgentResult.
284+
///
285+
/// Reads the entire stdin as a JSON AST, deserializes to Program,
286+
/// type-checks, and returns the AgentResult.
287+
fn cmd_agent_from_json() {
288+
let mut input = String::new();
289+
if let Err(e) = std::io::Read::read_to_string(&mut std::io::stdin(), &mut input) {
290+
let result = oo7_core::agent_api::AgentResult::error(vec![oo7_core::AgentError {
291+
code: "IO_ERROR".to_string(),
292+
level: 0,
293+
message: format!("Failed to read stdin: {}", e),
294+
location: None,
295+
context: serde_json::Value::Null,
296+
remediations: vec![],
297+
}]);
298+
let json = serde_json::to_string_pretty(&result).unwrap();
299+
println!("{}", json);
300+
std::process::exit(1);
301+
}
302+
303+
let result = oo7_core::agent_api::validate_json_ast(&input);
304+
let json = serde_json::to_string_pretty(&result).expect("AgentResult serialization failed");
305+
println!("{}", json);
306+
307+
if !result.success {
308+
std::process::exit(1);
309+
}
310+
}
311+
190312
/// Run a built-in demo that exercises the branch/given/traced system
191313
/// and produces decision trace output.
192314
fn run_demo() {

0 commit comments

Comments
 (0)