Repository navigation
refactor(orchestration): back SubAgentJobRegistry with DetachedTaskRegistry (D11 phase 3) #346
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+583
−196
Merged
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
fbc5b15
test(tasks): cover cooperative cancellation and token release
senamakel 6f37f83
refactor(tinyagents-tasks): simplify task runtime internals
senamakel f7be8fd
feat(subagent): add invocation registry for subagent tools
senamakel c55a2d6
feat(orchestration): add subagent invocation types
senamakel d7264c8
refactor(subagent): back job registry with detached task registry
senamakel 642c2c0
chore(subagent): gate job registry tasks accessor behind cfg(test)
senamakel 04b8a12
docs(orchestration): add crate README
senamakel e09ab01
refactor(subagent): inline detached task registry import
senamakel a878424
fix(subagent): address review of job registry adapter
senamakel 9e76d28
fix(subagent): explicit id-sorted listings, log registry errors, trus…
senamakel 23ffd2f
fix(subagent): log get_owned registry errors, no panic on registratio…
senamakel File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
397 changes: 230 additions & 167 deletions
397
crates/tinyagents-orchestration/src/subagent/invocation/jobs.rs
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
123 changes: 123 additions & 0 deletions
123
crates/tinyagents-orchestration/src/subagent/invocation/mod_registry_tests.rs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,123 @@ | ||
| //! The job registry is an adapter over `tinyagents_tasks::DetachedTaskRegistry`: | ||
| //! these tests pin the shared-registry view and the lifecycle hand-offs. | ||
|
|
||
| use super::*; | ||
| use tinyagents_harness::error::TinyAgentsError; | ||
| use tinyagents_harness::ids::TaskId; | ||
|
|
||
| #[tokio::test] | ||
| async fn jobs_are_registered_in_the_shared_detached_registry() { | ||
| let jobs = SubAgentJobRegistry::new(); | ||
| let (job_id, _steering) = jobs.create("worker", 7); | ||
| let task_id = TaskId::new(job_id.as_str()); | ||
|
|
||
| let tasks = jobs.tasks(); | ||
| assert_eq!(tasks.len().unwrap(), 1); | ||
| let snapshot = tasks.snapshot(&task_id, "7").unwrap(); | ||
| assert_eq!(snapshot.status.status, SubAgentJobStatus::Queued); | ||
| assert_eq!(snapshot.status.agent, "worker"); | ||
| // Ownership is the detached registry's, so a foreign owner is refused. | ||
| assert!(tasks.snapshot(&task_id, "8").is_err()); | ||
| } | ||
|
|
||
| #[tokio::test] | ||
| async fn steering_is_reachable_while_live_and_released_when_settled() { | ||
| let jobs = SubAgentJobRegistry::new(); | ||
| let (job_id, _steering) = jobs.create("worker", 1); | ||
| let task_id = TaskId::new(job_id.as_str()); | ||
| assert!(jobs.tasks().steering_handle_trusted(&task_id).is_ok()); | ||
|
|
||
| jobs.mark_result(&job_id, Err(TinyAgentsError::Cancelled)); | ||
|
|
||
| assert!(jobs.tasks().steering_handle_trusted(&task_id).is_err()); | ||
| // A settled job stays queryable; the registry never prunes it. | ||
| assert_eq!( | ||
| jobs.get(job_id.as_str()).unwrap().status, | ||
| SubAgentJobStatus::Cancelled | ||
| ); | ||
| assert_eq!(jobs.tasks().len().unwrap(), 1); | ||
| } | ||
|
|
||
| #[tokio::test] | ||
| async fn terminal_jobs_survive_many_registrations() { | ||
| // The detached registry sweeps terminal entries at its soft cap; the job | ||
| // registry must never lose a settled job that way. | ||
| let jobs = SubAgentJobRegistry::new(); | ||
| let mut ids = Vec::new(); | ||
| for _ in 0..2_000 { | ||
| let (id, _s) = jobs.create("worker", 1); | ||
| jobs.mark_result(&id, Err(TinyAgentsError::Cancelled)); | ||
| ids.push(id); | ||
| } | ||
| assert!(ids.iter().all(|id| jobs.get(id.as_str()).is_some())); | ||
| assert_eq!(jobs.list().len(), 2_000); | ||
| } | ||
|
|
||
| #[tokio::test] | ||
| async fn control_errors_keep_their_documented_order() { | ||
| let jobs = SubAgentJobRegistry::new(); | ||
| let (live, _s) = jobs.create("worker", 1); | ||
| let (done, _s2) = jobs.create("worker", 1); | ||
| jobs.mark_result(&done, Err(TinyAgentsError::Cancelled)); | ||
| let not_found = |id: &str| SubAgentJobError::NotFound(id.to_owned()); | ||
|
|
||
| // Unknown id and foreign owner are both NotFound, even for a settled job. | ||
| assert_eq!(jobs.cancel_owned("nope", 1).unwrap_err(), not_found("nope")); | ||
| assert_eq!( | ||
| jobs.cancel_owned(live.as_str(), 2).unwrap_err(), | ||
| not_found(live.as_str()) | ||
| ); | ||
| assert_eq!( | ||
| jobs.cancel_owned(done.as_str(), 2).unwrap_err(), | ||
| not_found(done.as_str()) | ||
| ); | ||
| assert_eq!( | ||
| jobs.send_message_with_request_id(done.as_str(), 2, "m", None) | ||
| .unwrap_err(), | ||
| not_found(done.as_str()) | ||
| ); | ||
| // Own settled job is Terminal. | ||
| let terminal = SubAgentJobError::Terminal { | ||
| job_id: done.as_str().to_owned(), | ||
| status: SubAgentJobStatus::Cancelled, | ||
| }; | ||
| assert_eq!( | ||
| jobs.cancel_owned(done.as_str(), 1).unwrap_err(), | ||
| terminal.clone() | ||
| ); | ||
| assert_eq!( | ||
| jobs.send_message_with_request_id(done.as_str(), 1, "m", None) | ||
| .unwrap_err(), | ||
| terminal | ||
| ); | ||
| // An oversized id on a live job is RequestIdTooLong... | ||
| let long = "x".repeat(10_000); | ||
| assert_eq!( | ||
| jobs.send_message_with_request_id(live.as_str(), 1, "m", Some(&long)) | ||
| .unwrap_err(), | ||
| SubAgentJobError::RequestIdTooLong | ||
| ); | ||
| // ...but a cancelling job reports Cancelling before the id is looked at. | ||
| jobs.cancel_owned(live.as_str(), 1).unwrap(); | ||
| let cancelling = SubAgentJobError::Cancelling(live.as_str().to_owned()); | ||
| assert_eq!( | ||
| jobs.send_message_with_request_id(live.as_str(), 1, "m", Some(&long)) | ||
| .unwrap_err(), | ||
| cancelling | ||
| ); | ||
| // Repeated cancels of a cancelling job stay Ok. | ||
| assert!(jobs.cancel_owned(live.as_str(), 1).is_ok()); | ||
| } | ||
|
|
||
| #[tokio::test] | ||
| async fn listings_are_sorted_by_job_id() { | ||
| let jobs = SubAgentJobRegistry::new(); | ||
| for _ in 0..40 { | ||
| jobs.create("worker", 1); | ||
| } | ||
| let all: Vec<String> = jobs.list().into_iter().map(|j| j.id.0).collect(); | ||
| let mut sorted = all.clone(); | ||
| sorted.sort(); | ||
| assert_eq!(all, sorted); | ||
| assert_eq!(all.len(), 40); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.