mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-11-08 08:07:29 +00:00
fabro(01KQRF918YQT8T17RHTE6DYCTE): simplify_opus (succeeded)
Fabro-Run: 01KQRF918YQT8T17RHTE6DYCTE
Fabro-Completed: 6
Fabro-Checkpoint: 44ae06d75c
⚒️ Generated with [Fabro](https://fabro.sh)
This commit is contained in:
parent
b3bda8467a
commit
9250bf90e1
38 changed files with 75 additions and 87 deletions
|
|
@ -172,4 +172,4 @@ export function useLoginDevToken() {
|
|||
return response.json() as Promise<{ ok: boolean }>;
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,4 +76,4 @@ export const queryKeys = {
|
|||
settings: {
|
||||
server: () => "/api/v1/settings",
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -41,8 +41,11 @@ const INTERVIEW_EVENTS = new Set([
|
|||
"interview.interrupted",
|
||||
]);
|
||||
const STEERING_EVENTS = new Set([
|
||||
"steering.received",
|
||||
"steering.applied",
|
||||
"agent.steering.injected",
|
||||
"agent.steering.attached",
|
||||
"agent.steering.detached",
|
||||
"agent.steer.buffered",
|
||||
"agent.steer.dropped",
|
||||
]);
|
||||
|
||||
export function queryKeysForRunEvent(
|
||||
|
|
@ -153,4 +156,4 @@ export function useRunEvents(runId: string | undefined) {
|
|||
if (!runId) return;
|
||||
return subscribeToRunEvents(runId, mutate as MutateFn);
|
||||
}, [mutate, runId]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -794,7 +794,7 @@ export default function Runs() {
|
|||
<div className="flex gap-5 overflow-x-auto pb-4">
|
||||
{filteredColumns.map((col) => (
|
||||
<div key={col.id} className="w-72 shrink-0">
|
||||
<BoardColumn column={col} />
|
||||
<BoardColumn column={col} onSteer={setSteerRunId} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
|
@ -869,6 +869,9 @@ export default function Runs() {
|
|||
</>
|
||||
)}
|
||||
</div>
|
||||
{steerRunId && (
|
||||
<SteerComposer runId={steerRunId} onClose={() => setSteerRunId(null)} />
|
||||
)}
|
||||
</DndContext>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8395,4 +8395,4 @@ components:
|
|||
login:
|
||||
type: string
|
||||
description: User's login identifier (e.g. GitHub username).
|
||||
example: octocat
|
||||
example: octocat
|
||||
|
|
|
|||
|
|
@ -62,4 +62,4 @@ pub use types::{AgentEvent, CompletionCoordinator, SessionEvent, SessionState, T
|
|||
unreachable_pub,
|
||||
reason = "Test support stays crate-visible for cross-module unit tests."
|
||||
)]
|
||||
pub(crate) mod test_support;
|
||||
pub(crate) mod test_support;
|
||||
|
|
|
|||
|
|
@ -422,22 +422,12 @@ impl Session {
|
|||
}
|
||||
|
||||
pub fn steer(&self, message: String) {
|
||||
self.steering_queue
|
||||
.lock()
|
||||
.expect("steering queue lock poisoned")
|
||||
.push_back((message, SteerKind::Append, None));
|
||||
self.control_handle().steer(message, None);
|
||||
}
|
||||
|
||||
/// Push an interrupt steer and cancel the current round token.
|
||||
pub fn interrupt_with(&self, text: String, actor: Option<Principal>) {
|
||||
self.steering_queue
|
||||
.lock()
|
||||
.expect("steering queue lock poisoned")
|
||||
.push_back((text, SteerKind::Interrupt, actor));
|
||||
self.round_token
|
||||
.read()
|
||||
.expect("round token lock poisoned")
|
||||
.cancel();
|
||||
self.control_handle().interrupt_with(text, actor);
|
||||
}
|
||||
|
||||
/// Returns a lightweight handle for external steering control.
|
||||
|
|
@ -734,16 +724,11 @@ impl Session {
|
|||
|
||||
// Reset round token if it was cancelled (steer interrupt)
|
||||
{
|
||||
let needs_reset = self
|
||||
let mut guard = self
|
||||
.round_token
|
||||
.read()
|
||||
.expect("round token lock poisoned")
|
||||
.is_cancelled();
|
||||
if needs_reset {
|
||||
let mut guard = self
|
||||
.round_token
|
||||
.write()
|
||||
.expect("round token lock poisoned");
|
||||
.write()
|
||||
.expect("round token lock poisoned");
|
||||
if guard.is_cancelled() {
|
||||
*guard = CancellationToken::new();
|
||||
}
|
||||
}
|
||||
|
|
@ -1079,10 +1064,9 @@ impl Session {
|
|||
.expect("steering queue lock poisoned")
|
||||
.drain(..)
|
||||
.collect();
|
||||
for (msg, kind, actor) in messages {
|
||||
let text = msg.clone();
|
||||
for (text, kind, actor) in messages {
|
||||
self.history.push(Turn::Steering {
|
||||
content: msg,
|
||||
content: text.clone(),
|
||||
timestamp: SystemTime::now(),
|
||||
});
|
||||
self.event_emitter
|
||||
|
|
|
|||
|
|
@ -803,4 +803,4 @@ mod tests {
|
|||
_ => panic!("expected McpServerFailed variant"),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1024,4 +1024,4 @@ async fn scenario_provider_specific_editing(session: &mut Session, dir: &Path) {
|
|||
content.contains("goodbye"),
|
||||
"Expected 'goodbye' in target.rs, got: {content}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1556,4 +1556,4 @@ pub(crate) enum ProviderCommand {
|
|||
pub(crate) struct CompletionArgs {
|
||||
/// Shell to generate completions for
|
||||
pub shell: clap_complete::Shell,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,4 +24,4 @@ pub(crate) mod uninstall;
|
|||
pub(crate) mod upgrade;
|
||||
pub(crate) mod validate;
|
||||
pub(crate) mod version;
|
||||
pub(crate) mod workflow;
|
||||
pub(crate) mod workflow;
|
||||
|
|
|
|||
|
|
@ -975,4 +975,4 @@ mod tests {
|
|||
|
||||
assert!(credential.contains("vault-key"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,4 +34,4 @@ pub(crate) async fn execute(args: SteerArgs) -> Result<()> {
|
|||
|
||||
println!("Steer delivered.");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1324,4 +1324,4 @@ destination = "{destination}"
|
|||
"should fail when both --quiet and --verbose"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1950,4 +1950,4 @@ mod tests {
|
|||
"hint should only fire on unstructured 404s, got: {message}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -175,4 +175,4 @@ mod tests {
|
|||
assert!(json.contains(r#""type":"run.steer""#));
|
||||
assert!(json.contains(r#""kind":"interrupt""#));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -415,4 +415,4 @@ mod tests {
|
|||
let answer = ask.await.unwrap().answer;
|
||||
assert_eq!(answer.value, AnswerValue::Yes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3241,4 +3241,4 @@ async fn reject_if_archived(state: &AppState, run_id: &RunId) -> Option<Response
|
|||
clippy::disallowed_methods,
|
||||
reason = "server unit tests stage fixtures with sync std::fs writes"
|
||||
)]
|
||||
mod tests;
|
||||
mod tests;
|
||||
|
|
|
|||
|
|
@ -87,4 +87,4 @@ pub use self::steering::SteerKind;
|
|||
pub use status::{
|
||||
BlockedReason, FailureReason, InvalidTransition, ParseFailureReasonError,
|
||||
ParseSuccessReasonError, RunControlAction, RunStatus, SuccessReason, TerminalStatus,
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -177,4 +177,4 @@ pub struct AgentSteerBufferedProps {
|
|||
pub struct AgentSteerDroppedProps {
|
||||
pub count: usize,
|
||||
pub reason: String,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1447,4 +1447,4 @@ mod tests {
|
|||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Whether a steer appends to the queue or interrupts the current round.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, strum::Display)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
#[strum(serialize_all = "lowercase")]
|
||||
pub enum SteerKind {
|
||||
Append,
|
||||
Interrupt,
|
||||
|
|
|
|||
|
|
@ -608,10 +608,7 @@ fn event_body_from_event(event: &Event) -> EventBody {
|
|||
AgentEvent::SteeringInjected { text, kind, .. } => {
|
||||
EventBody::AgentSteeringInjected(fabro_types::AgentSteeringInjectedProps {
|
||||
text: text.clone(),
|
||||
kind: match kind {
|
||||
::fabro_types::SteerKind::Append => "append".to_string(),
|
||||
::fabro_types::SteerKind::Interrupt => "interrupt".to_string(),
|
||||
},
|
||||
kind: kind.to_string(),
|
||||
visit: *visit,
|
||||
})
|
||||
}
|
||||
|
|
@ -720,10 +717,7 @@ fn event_body_from_event(event: &Event) -> EventBody {
|
|||
}
|
||||
Event::SteerBuffered { kind, .. } => {
|
||||
EventBody::AgentSteerBuffered(fabro_types::AgentSteerBufferedProps {
|
||||
kind: match kind {
|
||||
::fabro_types::SteerKind::Append => "append".to_string(),
|
||||
::fabro_types::SteerKind::Interrupt => "interrupt".to_string(),
|
||||
},
|
||||
kind: kind.to_string(),
|
||||
})
|
||||
}
|
||||
Event::SteerDropped { count, reason, .. } => {
|
||||
|
|
@ -1881,4 +1875,4 @@ mod tests {
|
|||
let actor = stored.actor.as_ref().expect("actor set");
|
||||
assert_eq!(actor, &user_principal("alice"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1397,4 +1397,4 @@ impl Event {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -192,4 +192,4 @@ mod tests {
|
|||
"run.unarchived"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -225,4 +225,4 @@ fn agent_actor_for_event(
|
|||
AgentEvent::SteeringInjected { actor, .. } => actor.clone(),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -504,14 +504,7 @@ impl CodergenBackend for AgentApiBackend {
|
|||
// Register with steering hub for steer delivery
|
||||
let stage_id = stage_scope.stage_id();
|
||||
let _steering_guard = if let Some(ref hub) = self.steering_hub {
|
||||
let control_handle = session.control_handle();
|
||||
hub.register(&stage_id, &control_handle);
|
||||
let coordinator = SteeringCompletionCoordinator {
|
||||
hub: Arc::clone(hub),
|
||||
stage_id: stage_id.clone(),
|
||||
handle: control_handle,
|
||||
};
|
||||
session.set_completion_coordinator(Arc::new(coordinator));
|
||||
register_session_steering(hub, &stage_id, &mut session);
|
||||
Some(SteeringGuard {
|
||||
hub: Arc::clone(hub),
|
||||
stage_id: stage_id.clone(),
|
||||
|
|
@ -575,14 +568,7 @@ impl CodergenBackend for AgentApiBackend {
|
|||
|
||||
// Re-register with steering hub for the new session
|
||||
if let Some(ref hub) = self.steering_hub {
|
||||
let control_handle = session.control_handle();
|
||||
hub.register(&stage_id, &control_handle);
|
||||
let coordinator = SteeringCompletionCoordinator {
|
||||
hub: Arc::clone(hub),
|
||||
stage_id: stage_id.clone(),
|
||||
handle: control_handle,
|
||||
};
|
||||
session.set_completion_coordinator(Arc::new(coordinator));
|
||||
register_session_steering(hub, &stage_id, &mut session);
|
||||
}
|
||||
|
||||
// Re-subscribe to forward events + track files from the new session
|
||||
|
|
@ -677,6 +663,23 @@ impl CodergenBackend for AgentApiBackend {
|
|||
}
|
||||
}
|
||||
|
||||
/// Register a session with the steering hub, setting up the completion
|
||||
/// coordinator so the close-the-door protocol works.
|
||||
fn register_session_steering(
|
||||
hub: &Arc<SteeringHub>,
|
||||
stage_id: &StageId,
|
||||
session: &mut Session,
|
||||
) {
|
||||
let control_handle = session.control_handle();
|
||||
hub.register(stage_id, &control_handle);
|
||||
let coordinator = SteeringCompletionCoordinator {
|
||||
hub: Arc::clone(hub),
|
||||
stage_id: stage_id.clone(),
|
||||
handle: control_handle,
|
||||
};
|
||||
session.set_completion_coordinator(Arc::new(coordinator));
|
||||
}
|
||||
|
||||
/// RAII guard that unregisters a session from the steering hub on drop.
|
||||
struct SteeringGuard {
|
||||
hub: Arc<SteeringHub>,
|
||||
|
|
|
|||
|
|
@ -158,4 +158,4 @@ pub mod steering_hub;
|
|||
pub mod test_support;
|
||||
#[doc(hidden)]
|
||||
pub mod transforms;
|
||||
pub mod workflow_bundle;
|
||||
pub mod workflow_bundle;
|
||||
|
|
|
|||
|
|
@ -1063,4 +1063,4 @@ mod tests {
|
|||
Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1498,4 +1498,4 @@ mod tests {
|
|||
result = result.as_ref().map(|_| "Ok"),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1163,4 +1163,4 @@ async fn run_with_lifecycle_emits_initialize_and_setup_events() {
|
|||
assert!(sandbox_idx < setup_idx);
|
||||
assert!(setup_idx < run_started_idx);
|
||||
assert!(run_started_idx < run_running_idx);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1089,4 +1089,4 @@ mod tests {
|
|||
Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1388,4 +1388,4 @@ mod tests {
|
|||
|
||||
assert!(matches!(result, Err(Error::Cancelled)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -444,4 +444,4 @@ mod tests {
|
|||
assert!(retro_completed_properties.get("retro").is_some());
|
||||
assert_eq!(retro_completed_properties["retro"]["smoothness"], "smooth");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -352,4 +352,4 @@ pub struct PullRequestOptions {
|
|||
pub github_app: Option<fabro_github::GitHubCredentials>,
|
||||
pub origin_url: Option<String>,
|
||||
pub model: String,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -277,4 +277,4 @@ mod tests {
|
|||
.is_empty()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -259,4 +259,4 @@ mod tests {
|
|||
assert_eq!(q.len(), 1);
|
||||
assert_eq!(q[0].1, SteerKind::Interrupt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -523,4 +523,4 @@ impl WorkflowRunner {
|
|||
))
|
||||
.await
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue