mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-11-15 09:11:22 +00:00
Merge pull request #1100 from fabro-sh/codex/adopt-stage-files
Some checks failed
Rust / Format (push) Waiting to run
Rust / Clippy (push) Waiting to run
Rust / Rustdoc (push) Waiting to run
Rust / Generated Docs (push) Waiting to run
Rust / Test (Linux) (push) Waiting to run
Rust / Sandbox providers (Docker) (push) Waiting to run
Rust / Test (macOS) (push) Waiting to run
Rust / Process titles (musl) (push) Waiting to run
Installer / Homebrew push retries (push) Has been cancelled
Some checks failed
Rust / Format (push) Waiting to run
Rust / Clippy (push) Waiting to run
Rust / Rustdoc (push) Waiting to run
Rust / Generated Docs (push) Waiting to run
Rust / Test (Linux) (push) Waiting to run
Rust / Sandbox providers (Docker) (push) Waiting to run
Rust / Test (macOS) (push) Waiting to run
Rust / Process titles (musl) (push) Waiting to run
Installer / Homebrew push retries (push) Has been cancelled
Adopt Petri fix for tracked files in successor prompts
This commit is contained in:
commit
1f5da01b47
3 changed files with 151 additions and 16 deletions
30
Cargo.lock
generated
30
Cargo.lock
generated
|
|
@ -5181,7 +5181,7 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
|
|||
[[package]]
|
||||
name = "petri-attractor-steps"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#165c6ba4b6e928ec10a01688bf85de4bc5418233"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#f30a12df140fb60f55a7c6cff3d7f45673c7a7c5"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"globset",
|
||||
|
|
@ -5212,7 +5212,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "petri-driver"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#165c6ba4b6e928ec10a01688bf85de4bc5418233"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#f30a12df140fb60f55a7c6cff3d7f45673c7a7c5"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"getrandom 0.3.4",
|
||||
|
|
@ -5232,7 +5232,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "petri-engine"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#165c6ba4b6e928ec10a01688bf85de4bc5418233"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#f30a12df140fb60f55a7c6cff3d7f45673c7a7c5"
|
||||
dependencies = [
|
||||
"petri-ir",
|
||||
"serde",
|
||||
|
|
@ -5244,7 +5244,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "petri-execution"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#165c6ba4b6e928ec10a01688bf85de4bc5418233"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#f30a12df140fb60f55a7c6cff3d7f45673c7a7c5"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"petri-driver",
|
||||
|
|
@ -5268,7 +5268,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "petri-executor"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#165c6ba4b6e928ec10a01688bf85de4bc5418233"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#f30a12df140fb60f55a7c6cff3d7f45673c7a7c5"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"libc",
|
||||
|
|
@ -5283,7 +5283,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "petri-executor-sandbox"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#165c6ba4b6e928ec10a01688bf85de4bc5418233"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#f30a12df140fb60f55a7c6cff3d7f45673c7a7c5"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"petri-executor",
|
||||
|
|
@ -5305,7 +5305,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "petri-frontend"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#165c6ba4b6e928ec10a01688bf85de4bc5418233"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#f30a12df140fb60f55a7c6cff3d7f45673c7a7c5"
|
||||
dependencies = [
|
||||
"marked-yaml",
|
||||
"petri-ir",
|
||||
|
|
@ -5319,7 +5319,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "petri-frontend-attractor"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#165c6ba4b6e928ec10a01688bf85de4bc5418233"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#f30a12df140fb60f55a7c6cff3d7f45673c7a7c5"
|
||||
dependencies = [
|
||||
"minijinja",
|
||||
"petri-frontend",
|
||||
|
|
@ -5336,7 +5336,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "petri-frontend-fabro"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#165c6ba4b6e928ec10a01688bf85de4bc5418233"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#f30a12df140fb60f55a7c6cff3d7f45673c7a7c5"
|
||||
dependencies = [
|
||||
"petri-frontend",
|
||||
"petri-frontend-attractor",
|
||||
|
|
@ -5351,7 +5351,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "petri-frontend-native"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#165c6ba4b6e928ec10a01688bf85de4bc5418233"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#f30a12df140fb60f55a7c6cff3d7f45673c7a7c5"
|
||||
dependencies = [
|
||||
"petri-frontend",
|
||||
"petri-ir",
|
||||
|
|
@ -5362,7 +5362,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "petri-ir"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#165c6ba4b6e928ec10a01688bf85de4bc5418233"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#f30a12df140fb60f55a7c6cff3d7f45673c7a7c5"
|
||||
dependencies = [
|
||||
"regex",
|
||||
"serde",
|
||||
|
|
@ -5375,7 +5375,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "petri-runtime"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#165c6ba4b6e928ec10a01688bf85de4bc5418233"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#f30a12df140fb60f55a7c6cff3d7f45673c7a7c5"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"petri-driver",
|
||||
|
|
@ -5396,7 +5396,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "petri-steps"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#165c6ba4b6e928ec10a01688bf85de4bc5418233"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#f30a12df140fb60f55a7c6cff3d7f45673c7a7c5"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"petri-executor",
|
||||
|
|
@ -5412,7 +5412,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "petri-store"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#165c6ba4b6e928ec10a01688bf85de4bc5418233"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#f30a12df140fb60f55a7c6cff3d7f45673c7a7c5"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"getrandom 0.3.4",
|
||||
|
|
@ -5427,7 +5427,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "petri-testkit"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#165c6ba4b6e928ec10a01688bf85de4bc5418233"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#f30a12df140fb60f55a7c6cff3d7f45673c7a7c5"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"petri-driver",
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ Goal: Add a /health endpoint to the API server
|
|||
## Completed stages
|
||||
- **plan**: success
|
||||
- Model: claude-sonnet-4-5, 12.4k tokens in / 3.2k out
|
||||
- Files: docs/plan.md
|
||||
- Files: ["docs/plan.md"]
|
||||
- **test**: success
|
||||
- Script: `cargo test 2>&1 || true`
|
||||
- Output:
|
||||
|
|
@ -230,6 +230,18 @@ The preamble includes:
|
|||
|
||||
Internal keys (prefixed with `internal.`, `current`, `graph.`, `thread.`, `response.`) are excluded from preambles to avoid noise.
|
||||
|
||||
Native agent stages include their tracked file paths in `compact`,
|
||||
`summary:medium`, and `summary:high` preambles. The list includes successful
|
||||
native write, edit, and patch calls across the stage's turns, including repair
|
||||
turns and child-agent writes. Paths are sorted and listed once. A moved file
|
||||
uses its destination; deletions and changes made only through shell commands
|
||||
are not tracked. ACP agents and prompt-only stages do not produce this list.
|
||||
|
||||
The file list follows the preamble size limit below; the complete list remains
|
||||
in the recorded stage output. `full`, `truncate`, and `summary:low` do not add a
|
||||
file-list detail. Continuing a shared conversation does not attribute an
|
||||
earlier stage's edits to the next stage.
|
||||
|
||||
### Large preamble values
|
||||
|
||||
In fidelity modes that render context or completed-stage output, one value can contribute at most 8 KiB of serialized JSON inline. Fabro stores larger values as content-addressed blobs, materializes them as readable files, and puts the size, file path, and a 300-character preview in the preamble. The agent can read the file when it needs the full value.
|
||||
|
|
|
|||
123
lib/components/fabro-petri/tests/stage_files.rs
Normal file
123
lib/components/fabro-petri/tests/stage_files.rs
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
//! A tracked native edit reaches both Fabro's public stage view and the next
|
||||
//! prompt.
|
||||
|
||||
mod support;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use fabro_petri::check::Launch;
|
||||
use fabro_petri::engine::{self, RunStatus};
|
||||
use fabro_petri::projection::{Item, RunView};
|
||||
use fabro_petri::runtime::RuntimeSpec;
|
||||
use fabro_store::platform_records::{PlatformRecord, RunCreatedRecord, StoredPlatformRecord};
|
||||
use fabro_types::{RunId, StageId, test_support as types_support};
|
||||
use pebble_coding_agent::test_support::{
|
||||
ScriptedCall, message_text, scripted_client, text_response, tool_call_response,
|
||||
};
|
||||
use petri_execution::events::replay_run;
|
||||
use petri_store::{Access, MemoryRunStore, RunKey, RunStore};
|
||||
use serde_json::json;
|
||||
use support::{Silent, no_questions, run_request};
|
||||
|
||||
#[tokio::test]
|
||||
async fn compact_successor_receives_tracked_native_files() {
|
||||
let root = tempfile::tempdir().expect("runtime directory");
|
||||
let (client, provider) = scripted_client(vec![
|
||||
ScriptedCall::response(tool_call_response(
|
||||
"write_file",
|
||||
"write",
|
||||
json!({"file_path":"direct-edit.txt", "content":"changed"}),
|
||||
)),
|
||||
ScriptedCall::response(text_response("Done.")),
|
||||
ScriptedCall::response(text_response("Reviewed.")),
|
||||
]);
|
||||
let runtime = RuntimeSpec {
|
||||
model_client: Some(client),
|
||||
..RuntimeSpec::default()
|
||||
};
|
||||
let workflow = r#"digraph Files {
|
||||
graph [backend="api", default_max_retries=0]
|
||||
start [shape=Mdiamond]
|
||||
edit [prompt="Write the file"]
|
||||
review [prompt="Review the edit", fidelity="compact"]
|
||||
exit [shape=Msquare]
|
||||
start -> edit -> review -> exit
|
||||
}"#;
|
||||
let graphs = support::admit(
|
||||
&[
|
||||
("workflow.fabro", workflow),
|
||||
("workflow.toml", support::SETTINGS),
|
||||
],
|
||||
Launch {
|
||||
default_model: Some("test/model".into()),
|
||||
..Launch::default()
|
||||
},
|
||||
&runtime,
|
||||
);
|
||||
let store = Arc::new(MemoryRunStore::new());
|
||||
let run_id = RunId::new();
|
||||
let outcome = engine::run(run_request(
|
||||
&run_id.to_string(),
|
||||
&root.path().join("run"),
|
||||
graphs,
|
||||
store.clone(),
|
||||
runtime,
|
||||
no_questions(Arc::new(Silent)),
|
||||
))
|
||||
.await
|
||||
.expect("workflow run settles");
|
||||
assert_eq!(outcome.status, RunStatus::Success, "{outcome:?}");
|
||||
let logs = store
|
||||
.open(&RunKey::new(run_id.to_string()), Access::Read)
|
||||
.await
|
||||
.expect("stored run");
|
||||
let events = replay_run(&*logs).await.expect("replayed run");
|
||||
let mut spec = types_support::test_run_spec();
|
||||
spec.run_id = run_id;
|
||||
let created = StoredPlatformRecord {
|
||||
seq: 1,
|
||||
recorded_at: 0,
|
||||
position: None,
|
||||
record: PlatformRecord::RunCreated(RunCreatedRecord {
|
||||
spec,
|
||||
title: Some("Tracked files".into()),
|
||||
parent_id: None,
|
||||
retried_from: None,
|
||||
web_url: None,
|
||||
}),
|
||||
};
|
||||
let mut view = RunView::new();
|
||||
view.fold(&Item::Platform(&created), 1);
|
||||
for (index, event) in events.iter().enumerate() {
|
||||
view.fold(&Item::Petri(event), index as u64 + 2);
|
||||
}
|
||||
let projection = view.projection().expect("public run projection");
|
||||
let edit = projection
|
||||
.stage(&StageId::new("edit", 1))
|
||||
.expect("edit stage");
|
||||
assert_eq!(
|
||||
edit.agent
|
||||
.as_ref()
|
||||
.expect("native agent")
|
||||
.totals
|
||||
.files_touched,
|
||||
["direct-edit.txt"]
|
||||
);
|
||||
let review = projection
|
||||
.stage(&StageId::new("review", 1))
|
||||
.expect("review stage");
|
||||
assert!(
|
||||
review
|
||||
.agent
|
||||
.as_ref()
|
||||
.expect("native agent")
|
||||
.totals
|
||||
.files_touched
|
||||
.is_empty()
|
||||
);
|
||||
let requests = provider.requests();
|
||||
assert_eq!(requests.len(), 3);
|
||||
let sent = message_text(requests[2].messages().last().expect("review input"));
|
||||
assert!(sent.contains("- **edit**: succeeded"), "{sent}");
|
||||
assert!(sent.contains("Files: [\"direct-edit.txt\"]"), "{sent}");
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue