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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ jobs:
uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2

- name: Build the Engine crates at the floor
run: cargo build --locked -p runvil -p runvil-engine -p runvil-lua -p runvil-parser -p runvil-types -p runvil-vfs -p runvil-model-client
run: cargo build --locked -p runvil -p runvil-engine -p runvil-lua -p runvil-prompt -p runvil-types -p runvil-vfs -p runvil-model-client

# Single required status check for branch protection: it fails when any
# job fails or is cancelled, so a cancelled job cannot read as green.
Expand Down
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Seven terms have exactly one meaning each, everywhere in this repository: code c

## Principles

- Design for human review. A reviewer reads one crate at a time: its code, its surface (every item another crate can name, methods, fields, and variants included), and the items it names from other crates. Keep all three small, and prefer more, smaller crates to fewer, larger ones.
- Do more with less. Prefer simple, foundational primitives over specific solutions: a primitive that naturally enables today's functionality and also generalizes beats a custom mechanism specified as a laundry list of requirements. Generality is the payoff, not a goal.
- When evaluating how to implement a feature, check whether the existing facilities subsume the work before building new machinery. Prioritize in this order:
1. Reuse an existing facility
Expand Down
22 changes: 11 additions & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[workspace]
resolver = "3"
members = ["crates/*", "crates/runvil-internal/types", "crates/runvil-internal/engine", "crates/runvil-internal/lua", "crates/runvil-internal/parser", "crates/runvil-internal/vfs", "crates/runvil-internal/model-client", "crates/workshop/desktop", "crates/workshop/server", "crates/workshop/server-api", "crates/workshop/gateway", "crates/workshop/gateway-discovery", "crates/workshop/menu", "crates/workshop/protocol", "crates/workshop/registry", "crates/workshop/status", "crates/workshop/support", "crates/workshop/user-state", "crates/workshop/workspace", "crates/workshop/run-log", "crates/workshop/agents", "crates/harness-internal/runner", "crates/harness-internal/plugin-loader", "crates/harness-internal/test-plugin"]
members = ["crates/*", "crates/runvil-internal/types", "crates/runvil-internal/engine", "crates/runvil-internal/lua", "crates/runvil-internal/prompt", "crates/runvil-internal/vfs", "crates/runvil-internal/model-client", "crates/workshop/desktop", "crates/workshop/server", "crates/workshop/server-api", "crates/workshop/gateway", "crates/workshop/gateway-discovery", "crates/workshop/menu", "crates/workshop/protocol", "crates/workshop/registry", "crates/workshop/status", "crates/workshop/support", "crates/workshop/user-state", "crates/workshop/workspace", "crates/workshop/run-log", "crates/workshop/agents", "crates/harness-internal/runner", "crates/harness-internal/plugin-loader", "crates/harness-internal/test-plugin"]
# crates/runvil-internal, crates/workshop, and crates/harness-internal
# are manifestless containers holding their families' private crates.
# Cargo prunes excluded subtrees from member globs, so a "crates/workshop/*"
Expand Down Expand Up @@ -41,7 +41,7 @@ plugin-std = { path = "crates/plugin-std" }
plugin-mcp = { path = "crates/plugin-mcp" }
runvil-lua = { path = "crates/runvil-internal/lua" }
runvil-model-client = { path = "crates/runvil-internal/model-client" }
runvil-parser = { path = "crates/runvil-internal/parser" }
runvil-prompt = { path = "crates/runvil-internal/prompt" }
runvil-vfs = { path = "crates/runvil-internal/vfs" }
workshop-server = { path = "crates/workshop/server" }
workshop-server-api = { path = "crates/workshop/server-api" }
Expand Down
4 changes: 2 additions & 2 deletions crates/build-xtask/src/product/container_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ fn a_container_crate_depending_on_a_container_sibling_passes() {
let root = tempfile::TempDir::new().expect("tempdir");
write_crate(
root.path(),
"runvil-internal/parser",
"runvil-parser",
"runvil-internal/prompt",
"runvil-prompt",
"[dependencies]\nrunvil-lua = { path = \"../lua\" }\n",
);
write_crate(root.path(), "runvil-internal/lua", "runvil-lua", "");
Expand Down
4 changes: 2 additions & 2 deletions crates/build-xtask/src/product/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,10 +230,10 @@ fn dev_build_and_target_dependencies_are_checked() {
root.path(),
"workshop-server",
"workshop-server",
"[dev-dependencies]\nrunvil-parser = { path = \"../runvil-parser\" }\n\
"[dev-dependencies]\nrunvil-prompt = { path = \"../runvil-prompt\" }\n\
[target.'cfg(windows)'.dependencies]\nharness-runner = { path = \"../harness-runner\" }\n",
);
write_crate(root.path(), "runvil-parser", "runvil-parser", "");
write_crate(root.path(), "runvil-prompt", "runvil-prompt", "");
write_crate(root.path(), "harness-runner", "harness-runner", "");
let violations = product_boundary_violations(root.path());
assert_eq!(
Expand Down
2 changes: 1 addition & 1 deletion crates/build-xtask/src/tidy-wiring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ mod tests {
fn a_crate_with_no_package_root_build_script_fails_even_with_a_src_build_module() {
let root = tempfile::TempDir::new().expect("tempdir");
write_wired(root.path());
let name = "runvil-parser";
let name = "runvil-prompt";
let parser = write_built(root.path(), "parser", name, BUILD_DEPENDENCY, None);
let module = parser.join("src").join("build.rs");
std::fs::write(module, CALLS_CHECK).expect("the module writes");
Expand Down
4 changes: 2 additions & 2 deletions crates/runvil-internal/engine/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ publish = false
[dependencies]
runvil-lua.workspace = true
runvil-model-client.workspace = true
runvil-parser.workspace = true
runvil-prompt.workspace = true
runvil-types.workspace = true
runvil-vfs.workspace = true
regex.workspace = true
Expand All @@ -31,7 +31,7 @@ test-support = []
[dev-dependencies]
criterion.workspace = true
runvil-lua = { workspace = true, features = ["test-support"] }
runvil-parser = { workspace = true, features = ["test-support"] }
runvil-prompt = { workspace = true, features = ["test-support"] }

# The bench drives runs on the serial test driver and answers their rounds
# from the scripted model, so it needs the feature that provides both.
Expand Down
2 changes: 1 addition & 1 deletion crates/runvil-internal/engine/benches/models_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use criterion::{Criterion, criterion_group, criterion_main};
use runvil_engine::test_support::scripted_chat::{ScriptedChat, ScriptedReply};
use runvil_engine::test_support::{drive, perform_locally};
use runvil_engine::{Effect, EffectAnswer, Run, RunConfig, RunOutcome};
use runvil_parser::Prompt;
use runvil_prompt::Prompt;
use runvil_types::models::{ModelCatalog, ModelId, ModelInfo, ModelRole, ThinkingMode};
use runvil_types::seed::RunSeed;
use runvil_types::timestamp::Timestamp;
Expand Down
8 changes: 4 additions & 4 deletions crates/runvil-internal/engine/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! [`Error`] is a `pub(crate)` internal error type, never part of the public API.
//! A run it ends reports its kind and message in
//! [`RunOutcome::Failed`](crate::RunOutcome::Failed), and
//! [`ParseError`](crate::parser::ParseError),
//! [`ParseError`](crate::prompt::ParseError),
//! [`CompletionError`](crate::model::CompletionError), and
//! [`runvil_types::tools::ToolError`] each reach that outcome through this
//! type, which classifies them and keeps their causes.
Expand All @@ -18,7 +18,7 @@
//! of their own: `Parse`, `Completion`, and `Substitution` hand their whole
//! `Display` and `source` to the error they hold. That is the exception to
//! the field rule above, and it is why `Error::originating_error` answers
//! `None` for `Completion` and `Substitution` and the parser's own cause for
//! `None` for `Completion` and `Substitution` and the loader's own cause for
//! `Parse`.

use runvil_types::ids::TaskId;
Expand Down Expand Up @@ -115,12 +115,12 @@ pub(crate) enum Error {
/// The prompt failed to parse: invalid frontmatter YAML or a
/// structurally-classified failure.
///
/// Holds the parser's [`ParseError`](crate::parser::ParseError) whole, so
/// Holds the loader's [`ParseError`](crate::prompt::ParseError) whole, so
/// its stable kind, its location fields, and the YAML decode failure a
/// frontmatter failure keeps as its cause survive until the run's
/// failure message is built from them.
#[error(transparent)]
Parse(crate::parser::ParseError),
Parse(crate::prompt::ParseError),

/// A model round or a catalog fetch failed, as the broker that performed
/// it reported.
Expand Down
16 changes: 8 additions & 8 deletions crates/runvil-internal/engine/src/error/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@
use std::borrow::Cow;

use runvil_lua::Error as LuaError;
use runvil_parser::Error as ParserError;
use runvil_prompt::Error as ParserError;
use runvil_types::ids::TaskId;
use runvil_vfs::VfsError;

use super::{BoxedSource, Error};

impl Error {
/// Builds a parse failure with a stable classification and no source span.
pub(crate) fn parse(kind: crate::parser::ParseErrorKind, message: impl Into<String>) -> Error {
Error::Parse(crate::parser::detail::parse_error(kind, message))
pub(crate) fn parse(kind: crate::prompt::ParseErrorKind, message: impl Into<String>) -> Error {
Error::Parse(crate::prompt::detail::parse_error(kind, message))
}

/// Stamps the prompt's frontmatter name onto a parse failure raised by
Expand All @@ -25,7 +25,7 @@ impl Error {
pub(crate) fn with_prompt_name(self, name: &str) -> Error {
match self {
Error::Parse(error) => {
Error::Parse(crate::parser::detail::with_prompt_name(error, name))
Error::Parse(crate::prompt::detail::with_prompt_name(error, name))
}
other => other,
}
Expand Down Expand Up @@ -134,12 +134,12 @@ impl From<crate::model::CompletionError> for Error {
/// internal failure maps onto its own variant. The parser crate's error
/// type is not `#[non_exhaustive]` (the two crates version together), so
/// this match is total.
impl From<crate::parser::ParseError> for Error {
fn from(error: crate::parser::ParseError) -> Self {
match crate::parser::detail::parse_error_into_inner(error) {
impl From<crate::prompt::ParseError> for Error {
fn from(error: crate::prompt::ParseError) -> Self {
match crate::prompt::detail::parse_error_into_inner(error) {
inner
@ (ParserError::ParseFrontmatter { .. } | ParserError::ParseStructured { .. }) => {
Error::Parse(crate::parser::detail::parse_error_from_inner(inner))
Error::Parse(crate::prompt::detail::parse_error_from_inner(inner))
}
ParserError::Lua(lua) => Error::from(lua),
ParserError::Internal(message) => Error::internal(message),
Expand Down
2 changes: 1 addition & 1 deletion crates/runvil-internal/engine/src/error/tests-chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use runvil_types::tools::{ToolError, ToolErrorKind};
use runvil_vfs::VfsError;

use super::*;
use crate::parser::Prompt;
use crate::prompt::Prompt;

/// The display text of each segment of `error`'s source chain, the error
/// itself first.
Expand Down
2 changes: 1 addition & 1 deletion crates/runvil-internal/engine/src/error/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use runvil_lua::Error as LuaError;

use super::*;
use crate::parser::Prompt;
use crate::prompt::Prompt;

#[path = "tests-chain.rs"]
mod chain;
Expand Down
2 changes: 1 addition & 1 deletion crates/runvil-internal/engine/src/execute/context-bound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use runvil_types::packs::PackId;
use runvil_types::tools::ToolCatalog;

use crate::lua::{RosterEntry, ToolSet};
use crate::parser::Prompt;
use crate::prompt::Prompt;

/// Builds the run's shared tool set: the frontmatter's declared Packs,
/// and the run catalog and roster, all moved out of the config. Nothing
Expand Down
2 changes: 1 addition & 1 deletion crates/runvil-internal/engine/src/execute/context-tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ fn derived_values_come_from_the_prompt_and_limits() {
let ctx = test_state(&prompt);
assert_eq!(
ctx.section_count(),
runvil_parser::detail::sections(&prompt).len()
runvil_prompt::detail::sections(&prompt).len()
);
assert_eq!(ctx.max_tool_iterations(), 24);
}
Expand Down
14 changes: 10 additions & 4 deletions crates/runvil-internal/engine/src/execute/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use runvil_vfs::{Access, VfsRef};

use crate::lua::{Argv, ToolSet};
use crate::model::{ModelBinding, ModelRole, ModelSet};
use crate::parser::Prompt;
use crate::prompt::Prompt;

use super::config::{RunConfig, RunLimits};
use super::fill;
Expand Down Expand Up @@ -333,13 +333,19 @@ impl ChainState {
/// call: the frontmatter's `max_tool_iterations` over the limits
/// default.
fn max_tool_iterations(&self) -> usize {
crate::parser::detail::max_tool_iterations(self.shared.prompt.frontmatter())
.resolve(self.shared.limits.max_tool_iterations.get() as usize)
self.shared
.prompt
.frontmatter()
.max_tool_iterations()
.map_or(
self.shared.limits.max_tool_iterations.get() as usize,
|cap| cap.get() as usize,
)
}

/// The run's top-level section count, reported as `sys.section_count`.
fn section_count(&self) -> usize {
crate::parser::detail::sections(&self.shared.prompt).len()
crate::prompt::detail::sections(&self.shared.prompt).len()
}

/// The H1-to-walk handoff: the `argv` H1 left behind at the freeze,
Expand Down
2 changes: 1 addition & 1 deletion crates/runvil-internal/engine/src/execute/fill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use std::collections::BTreeMap;

use crate::model::{ModelBinding, ModelInfo, ModelInvocation, ModelRole, ModelSet, ThinkingMode};
use crate::parser::{Prompt, RoleRequirements};
use crate::prompt::{Prompt, RoleRequirements};

use super::requirements::{RequirementCheck, Requirements, UnmetRequirement};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use serde_json::json;

use crate::execute::{Run, RunConfig, RunErrorKind, RunOutcome, Step};
use crate::lua::RosterEntry;
use crate::parser::Prompt;
use crate::prompt::Prompt;
use crate::test_support::scenario::{TEST_SEED, test_model_with};

/// The notice line of a run whose catalog or roster names the reserved
Expand Down
2 changes: 1 addition & 1 deletion crates/runvil-internal/engine/src/execute/requirements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use runvil_types::packs::PackId;
use runvil_types::tools::ToolCatalog;

use crate::lua::RosterEntry;
use crate::parser::Prompt;
use crate::prompt::Prompt;

#[cfg(test)]
#[path = "requirements-tests.rs"]
Expand Down
2 changes: 1 addition & 1 deletion crates/runvil-internal/engine/src/execute/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ mod effect;
pub(crate) use effect::{AnswerRecord, ChatAnswerRecord, EffectRecord};
pub use effect::{Effect, EffectAnswer, EffectId, PackToolSets, Round, ToolCallOrigin, ToolCaller};

use crate::parser::Prompt;
use crate::prompt::Prompt;

use super::RunOutcome;
use super::config::RunConfig;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::execute::run::{
AnswerRecord, Effect, EffectAnswer, EffectId, EffectRecord, Round, Run, Step,
};
use crate::model::{Completion, CompletionResult};
use crate::parser::Prompt;
use crate::prompt::Prompt;
use crate::test_support::scenario::{chat_answer, only_effect, test_model_with};
use crate::test_support::scripted_chat::text;

Expand Down
2 changes: 1 addition & 1 deletion crates/runvil-internal/engine/src/execute/scheduler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ use runvil_vfs::Origin;
use runvil_vfs::detail::ScopeHandle;

use crate::lua::Answer;
use crate::parser::{Block, Prompt};
use crate::prompt::{Block, Prompt};
use crate::{Error, Result};

use super::context::ChainState;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use runvil_types::event::ReplyOrigin;

use crate::execute::run::{Effect, EffectId, Round};
use crate::lua::Answer;
use crate::parser::Prompt;
use crate::prompt::Prompt;
use crate::{Error, Result};

use super::{Chain, ChainIndex, Continuation, EffectTable, Scheduler};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::execute::section_context::{SectionContext, TaskSeed};
use crate::execute::walk_target::JumpTarget;
use crate::heading_address::SectionPos;
use crate::lua::{Answer, Blocked};
use crate::parser::{Block, BodyText, Prompt, Section};
use crate::prompt::{Block, BodyText, Prompt, Section};
use crate::{Error, Result};

mod anchor;
Expand Down Expand Up @@ -474,7 +474,7 @@ impl Chain {
/// result outlives a mutable borrow of the chain.
pub(super) fn blocks<'p>(&self, prompt: &'p Prompt) -> &'p [Block] {
if self.kind.is_h1() {
crate::parser::detail::h1_blocks(prompt)
crate::prompt::detail::h1_blocks(prompt)
} else {
self.walk
.current()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ impl Chain {
use crate::execute::context::ChainState;
use crate::execute::section_context::TaskSeed;
use crate::heading_address::{SectionIndex, SectionPos};
use crate::parser::Prompt;
use crate::prompt::Prompt;
use crate::test_support::scenario::{TEST_SEED, TEST_STARTED_AT};

let source = concat!(
Expand Down
Loading
Loading