§9 acceptance: grep-zero sweep — every internal x.ai/grok identifier renamed
The PRD's first acceptance gate now holds: grep -RinE '\bx\.ai\b|grok' crates/ --include='*.rs' → 0 matches (exempt: NOTICE and third-party license archives, README provenance, and the required 'Based on Grok Build Open Source' attribution, now sourced from version_attribution.txt). Wire-visible renames (both sides in this repo, changed in lockstep): - Auth method id 'grok.com' → 'kimi-code' (AuthMethodKind::KimiCode). - Every x.ai/* and _x.ai/* ACP ext method and meta key → kigi/* / _kigi/* (~200 names; grokShell → kigiShell). Session-file replay keeps a read-side alias for the legacy '_x.ai/session/update' method so existing updates.jsonl histories load; writes emit only the new name (both directions test-pinned). - Agent types grok-build* → kigi* with a documented legacy-prefix alias at resolution time so persisted sessions keep resolving. - ToolNamespace/BuiltinAgentName GrokBuild* → Kigi* (wire snake_case kigi/kigi_concise/kigi_hashline; schema regenerated); grok_build implementation dirs renamed to kigi*. - x-grok-* headers → x-kigi-*, __GROK_* sentinels → __KIGI_*, themes grokday/groknight → kigiday/kiginight (old persisted values fall back to the default theme), web_fetch allowlist xAI hosts → kimi.com + moonshot platforms, changelog CDN → this repo, grok-build changelog archives deleted. - BYOK default endpoint removed: [endpoints] api_base_url is now truly optional with NO default — consumers fail fast with the flag name when unset (no silent x.ai egress). Mock harnesses inject it explicitly. - System-prompt identity fixed: 'released by xAI' → 'an unofficial community CLI for Kimi' (template + regenerated encrypted form). Also repaired pre-existing grok-era test debt found by the sweep: the stale trace_classify default-model pin, the grok-pager UA label test, pty-harness stale-binary reuse and non-hermetic moonshot routing (a PTY test could previously reach the real api.moonshot.cn), and the outdated oauth fixture scope key. Gates: §9 grep 0; fmt clean; workspace check/clippy 0/0 (-D warnings); FULL cargo test --workspace: 234 suites, 21,961 passed, 0 failed; deny advisories ok.
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
use super::*;
|
||||
|
||||
/// Regression (resume sync): the on-disk replay stream re-emits persisted
|
||||
/// notifications through the generic `x.ai/session/update` envelope. A
|
||||
/// notifications through the generic `kigi/session/update` envelope. A
|
||||
/// background `monitor`/bash task (`TaskBackgrounded`) must restore into
|
||||
/// `bg_tasks` on a resumed / second terminal — not be dropped by the
|
||||
/// default match arm — so the idle "watching" status line and the Tasks pane
|
||||
@@ -24,7 +24,7 @@
|
||||
description: None,
|
||||
};
|
||||
handle(
|
||||
make_ext_session_notification_with_method("sess-1", "x.ai/session/update", update),
|
||||
make_ext_session_notification_with_method("sess-1", "kigi/session/update", update),
|
||||
&mut app,
|
||||
);
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
handle(
|
||||
make_ext_session_notification_with_method(
|
||||
"sess-1",
|
||||
"x.ai/session/update",
|
||||
"kigi/session/update",
|
||||
XaiSessionUpdate::ScheduledTaskCreated {
|
||||
task_id: "loop-1".into(),
|
||||
prompt: "check deploy".into(),
|
||||
@@ -72,7 +72,7 @@
|
||||
handle(
|
||||
make_ext_session_notification_with_method(
|
||||
"sess-1",
|
||||
"x.ai/session/update",
|
||||
"kigi/session/update",
|
||||
XaiSessionUpdate::ScheduledTaskDeleted {
|
||||
task_id: "loop-1".into(),
|
||||
},
|
||||
@@ -177,7 +177,7 @@
|
||||
meta: None,
|
||||
};
|
||||
let raw = serde_json::value::to_raw_value(¬if).unwrap();
|
||||
let notif = acp::ExtNotification::new("x.ai/task_backgrounded", raw.into());
|
||||
let notif = acp::ExtNotification::new("kigi/task_backgrounded", raw.into());
|
||||
assert!(handle_task_backgrounded(¬if, &mut app));
|
||||
|
||||
let agent = app.agents.get(&AgentId(0)).unwrap();
|
||||
@@ -232,7 +232,7 @@
|
||||
meta: None,
|
||||
};
|
||||
let raw = serde_json::value::to_raw_value(¬if).unwrap();
|
||||
let notif = acp::ExtNotification::new("x.ai/task_backgrounded", raw.into());
|
||||
let notif = acp::ExtNotification::new("kigi/task_backgrounded", raw.into());
|
||||
assert!(handle_task_backgrounded(¬if, &mut app));
|
||||
|
||||
let agent = app.agents.get(&AgentId(0)).unwrap();
|
||||
|
||||
@@ -81,10 +81,10 @@
|
||||
let params = serde_json::json!({
|
||||
"response_id": "resp-1",
|
||||
"suggestions": [{ "label": "x" }],
|
||||
"_meta": { "x.ai/replayed": true },
|
||||
"_meta": { "kigi/replayed": true },
|
||||
});
|
||||
let notif = acp::ExtNotification::new(
|
||||
"x.ai/follow_ups",
|
||||
"kigi/follow_ups",
|
||||
serde_json::value::to_raw_value(¶ms).unwrap().into(),
|
||||
);
|
||||
let affected = handle_ext_notification(¬if, &mut app);
|
||||
@@ -103,7 +103,7 @@
|
||||
];
|
||||
for params in bad {
|
||||
let notif = acp::ExtNotification::new(
|
||||
"x.ai/follow_ups",
|
||||
"kigi/follow_ups",
|
||||
serde_json::value::to_raw_value(¶ms).unwrap().into(),
|
||||
);
|
||||
let affected = handle_ext_notification(¬if, &mut app);
|
||||
@@ -214,10 +214,10 @@
|
||||
let params = serde_json::json!({
|
||||
"response_id": "resp-1",
|
||||
"suggestions": [{ "label": "x" }],
|
||||
"_meta": { "x.ai/replayed": false },
|
||||
"_meta": { "kigi/replayed": false },
|
||||
});
|
||||
let notif = acp::ExtNotification::new(
|
||||
"x.ai/follow_ups",
|
||||
"kigi/follow_ups",
|
||||
serde_json::value::to_raw_value(¶ms).unwrap().into(),
|
||||
);
|
||||
assert!(
|
||||
@@ -235,7 +235,7 @@
|
||||
serde_json::json!({ "response_id": "r", "suggestions": [null] }),
|
||||
] {
|
||||
let notif = acp::ExtNotification::new(
|
||||
"x.ai/follow_ups",
|
||||
"kigi/follow_ups",
|
||||
serde_json::value::to_raw_value(&bad).unwrap().into(),
|
||||
);
|
||||
assert!(
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
"token_baseline": 100,
|
||||
"finished_subagent_tokens": 99,
|
||||
"live_subagent_tokens": 4_321,
|
||||
"live_tokens_by_model": [["grok-4", 6_000], ["grok-3", 4_000]],
|
||||
"live_tokens_by_model": [["kigi-4", 6_000], ["kigi-3", 4_000]],
|
||||
"live_context_pct": 42,
|
||||
"live_turn_count": 7,
|
||||
"live_tool_call_count": 11,
|
||||
@@ -54,7 +54,7 @@
|
||||
}
|
||||
});
|
||||
let raw = serde_json::value::to_raw_value(&raw_payload).unwrap();
|
||||
let request = acp::ExtNotification::new("x.ai/session_notification", raw.into());
|
||||
let request = acp::ExtNotification::new("kigi/session_notification", raw.into());
|
||||
let (tx, _rx) = tokio::sync::oneshot::channel();
|
||||
let msg = AcpClientMessage::ExtNotification(kigi_acp_lib::AcpArgs {
|
||||
request,
|
||||
@@ -94,7 +94,7 @@
|
||||
assert_eq!(goal.live_subagent_tokens, Some(4_321));
|
||||
assert_eq!(
|
||||
goal.live_tokens_by_model,
|
||||
vec![("grok-4".to_owned(), 6_000), ("grok-3".to_owned(), 4_000)],
|
||||
vec![("kigi-4".to_owned(), 6_000), ("kigi-3".to_owned(), 4_000)],
|
||||
"populated per-model breakdown must round-trip wire->display"
|
||||
);
|
||||
assert_eq!(goal.live_context_pct, Some(42));
|
||||
@@ -147,7 +147,7 @@
|
||||
let (tx, _rx) = tokio::sync::oneshot::channel();
|
||||
handle(
|
||||
AcpClientMessage::ExtNotification(kigi_acp_lib::AcpArgs {
|
||||
request: acp::ExtNotification::new("x.ai/session_notification", raw.into()),
|
||||
request: acp::ExtNotification::new("kigi/session_notification", raw.into()),
|
||||
response_tx: tx,
|
||||
}),
|
||||
app,
|
||||
@@ -372,7 +372,7 @@
|
||||
}
|
||||
});
|
||||
let raw = serde_json::value::to_raw_value(&raw_payload).unwrap();
|
||||
let request = acp::ExtNotification::new("x.ai/session_notification", raw.into());
|
||||
let request = acp::ExtNotification::new("kigi/session_notification", raw.into());
|
||||
let (tx, _rx) = tokio::sync::oneshot::channel();
|
||||
let msg = AcpClientMessage::ExtNotification(kigi_acp_lib::AcpArgs {
|
||||
request,
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
}))
|
||||
.unwrap();
|
||||
let msg = AcpClientMessage::ExtMethod(kigi_acp_lib::AcpArgs {
|
||||
request: acp::ExtRequest::new("x.ai/ask_user_question", raw.into()),
|
||||
request: acp::ExtRequest::new("kigi/ask_user_question", raw.into()),
|
||||
response_tx: tx,
|
||||
});
|
||||
|
||||
@@ -168,7 +168,7 @@
|
||||
}))
|
||||
.unwrap();
|
||||
let msg = AcpClientMessage::ExtMethod(kigi_acp_lib::AcpArgs {
|
||||
request: acp::ExtRequest::new("x.ai/ask_user_question", raw.into()),
|
||||
request: acp::ExtRequest::new("kigi/ask_user_question", raw.into()),
|
||||
response_tx: tx,
|
||||
});
|
||||
|
||||
@@ -270,7 +270,7 @@
|
||||
let raw = serde_json::value::to_raw_value(&ext_req).unwrap();
|
||||
handle(
|
||||
AcpClientMessage::ExtMethod(kigi_acp_lib::AcpArgs {
|
||||
request: acp::ExtRequest::new("x.ai/exit_plan_mode", raw.into()),
|
||||
request: acp::ExtRequest::new("kigi/exit_plan_mode", raw.into()),
|
||||
response_tx: tx,
|
||||
}),
|
||||
&mut app,
|
||||
@@ -317,7 +317,7 @@
|
||||
let raw = serde_json::value::to_raw_value(&ext_req).unwrap();
|
||||
handle(
|
||||
AcpClientMessage::ExtMethod(kigi_acp_lib::AcpArgs {
|
||||
request: acp::ExtRequest::new("x.ai/exit_plan_mode", raw.into()),
|
||||
request: acp::ExtRequest::new("kigi/exit_plan_mode", raw.into()),
|
||||
response_tx: tx,
|
||||
}),
|
||||
&mut app,
|
||||
@@ -355,7 +355,7 @@
|
||||
let raw = serde_json::value::to_raw_value(&ext_req).unwrap();
|
||||
handle(
|
||||
AcpClientMessage::ExtMethod(kigi_acp_lib::AcpArgs {
|
||||
request: acp::ExtRequest::new("x.ai/exit_plan_mode", raw.into()),
|
||||
request: acp::ExtRequest::new("kigi/exit_plan_mode", raw.into()),
|
||||
response_tx: tx,
|
||||
}),
|
||||
&mut app,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
use super::*;
|
||||
|
||||
/// Regression: a shared-queue interjection renders only via the broadcast,
|
||||
/// and the shell emits the queue-emptying `x.ai/queue/changed` right after
|
||||
/// and the shell emits the queue-emptying `kigi/queue/changed` right after
|
||||
/// it — which used to fire the withheld parked marker BELOW the just-
|
||||
/// rendered user message ("Worked for …" under the follow-up, flipped
|
||||
/// transcript order). The broadcast must consume the marker slot instead.
|
||||
@@ -680,7 +680,7 @@
|
||||
);
|
||||
}
|
||||
|
||||
/// `x.ai/task_backgrounded` arriving after the skipped zero-work wait
|
||||
/// `kigi/task_backgrounded` arriving after the skipped zero-work wait
|
||||
/// re-evaluates and restores the park.
|
||||
#[test]
|
||||
fn task_backgrounded_after_zero_work_wait_all_restores_park() {
|
||||
@@ -716,7 +716,7 @@
|
||||
#[test]
|
||||
fn interjection_notification_pushes_block_to_matching_session() {
|
||||
// Multi-client fix: an interjection typed in one pane is broadcast by
|
||||
// the shell as x.ai/session/interjection; EVERY attached pane (incl.
|
||||
// the shell as kigi/session/interjection; EVERY attached pane (incl.
|
||||
// the originator, which no longer pushes a local block) renders it.
|
||||
let mut app = make_app_with_agent("sess-view");
|
||||
let affected =
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
|
||||
#[test]
|
||||
fn mcp_initialized_clears_progress() {
|
||||
// x.ai/mcp_initialized must set mcp_init_progress to None.
|
||||
// kigi/mcp_initialized must set mcp_init_progress to None.
|
||||
let mut app = make_app_with_agent("sess-1");
|
||||
let agent = app.agents.get_mut(&AgentId(0)).unwrap();
|
||||
agent.mcp_init_progress = Some(crate::app::agent_view::McpInitProgress {
|
||||
@@ -408,7 +408,7 @@
|
||||
// NB: no `status`.
|
||||
});
|
||||
let raw = serde_json::value::to_raw_value(&payload).unwrap();
|
||||
let notif = acp::ExtNotification::new("x.ai/mcp/server_status", raw.into());
|
||||
let notif = acp::ExtNotification::new("kigi/mcp/server_status", raw.into());
|
||||
let redraw = handle_mcp_server_status(¬if, &mut app);
|
||||
assert!(!redraw, "malformed payload must not request a redraw");
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@ pub(super) fn interjection_broadcast(
|
||||
text: &str,
|
||||
) -> acp::ExtNotification {
|
||||
acp::ExtNotification::new(
|
||||
"x.ai/session/interjection",
|
||||
"kigi/session/interjection",
|
||||
std::sync::Arc::from(
|
||||
serde_json::value::to_raw_value(
|
||||
&serde_json::json!({ "sessionId" : session_id, "text" : text, }),
|
||||
@@ -233,7 +233,7 @@ pub(super) fn follow_ups_ext(
|
||||
{ "response_id" : response_id, "suggestions" : suggestions, }
|
||||
);
|
||||
acp::ExtNotification::new(
|
||||
"x.ai/follow_ups",
|
||||
"kigi/follow_ups",
|
||||
std::sync::Arc::from(serde_json::value::to_raw_value(¶ms).unwrap()),
|
||||
)
|
||||
}
|
||||
@@ -251,7 +251,7 @@ pub(super) fn follow_ups_ext_with_prompt(
|
||||
suggestions, }
|
||||
);
|
||||
acp::ExtNotification::new(
|
||||
"x.ai/follow_ups",
|
||||
"kigi/follow_ups",
|
||||
std::sync::Arc::from(serde_json::value::to_raw_value(¶ms).unwrap()),
|
||||
)
|
||||
}
|
||||
@@ -263,7 +263,7 @@ pub(super) fn group_tool_verbs_settings_update(
|
||||
None => serde_json::json!({}),
|
||||
};
|
||||
acp::ExtNotification::new(
|
||||
"x.ai/settings/update",
|
||||
"kigi/settings/update",
|
||||
std::sync::Arc::from(serde_json::value::to_raw_value(¶ms).unwrap()),
|
||||
)
|
||||
}
|
||||
@@ -275,7 +275,7 @@ pub(super) fn collapsed_edit_blocks_settings_update(
|
||||
None => serde_json::json!({}),
|
||||
};
|
||||
acp::ExtNotification::new(
|
||||
"x.ai/settings/update",
|
||||
"kigi/settings/update",
|
||||
std::sync::Arc::from(serde_json::value::to_raw_value(¶ms).unwrap()),
|
||||
)
|
||||
}
|
||||
@@ -289,7 +289,7 @@ pub(super) fn subagent_ext_replay(
|
||||
"eventId" : event_id }, }
|
||||
);
|
||||
acp::ExtNotification::new(
|
||||
"x.ai/session/update",
|
||||
"kigi/session/update",
|
||||
std::sync::Arc::from(serde_json::value::to_raw_value(¶ms).unwrap()),
|
||||
)
|
||||
}
|
||||
@@ -315,7 +315,7 @@ pub(super) fn make_exit_plan_ext_with_tool_call_id(
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
let request = acp::ExtRequest::new("x.ai/exit_plan_mode", raw.into());
|
||||
let request = acp::ExtRequest::new("kigi/exit_plan_mode", raw.into());
|
||||
let (tx, rx) = tokio::sync::oneshot::channel();
|
||||
(
|
||||
kigi_acp_lib::AcpArgs {
|
||||
@@ -359,11 +359,11 @@ pub(super) fn queue_changed_ext(session_id: &str, ids: &[&str]) -> acp::ExtNotif
|
||||
.collect();
|
||||
let params = serde_json::json!({ "sessionId" : session_id, "entries" : entries });
|
||||
acp::ExtNotification::new(
|
||||
"x.ai/queue/changed",
|
||||
"kigi/queue/changed",
|
||||
std::sync::Arc::from(serde_json::value::to_raw_value(¶ms).unwrap()),
|
||||
)
|
||||
}
|
||||
/// Build a `x.ai/queue/changed` notification carrying `runningPromptId`.
|
||||
/// Build a `kigi/queue/changed` notification carrying `runningPromptId`.
|
||||
pub(super) fn queue_changed_running(
|
||||
session_id: &str,
|
||||
ids: &[&str],
|
||||
@@ -386,7 +386,7 @@ pub(super) fn queue_changed_running(
|
||||
params["runningPromptId"] = serde_json::Value::String(r.to_string());
|
||||
}
|
||||
acp::ExtNotification::new(
|
||||
"x.ai/queue/changed",
|
||||
"kigi/queue/changed",
|
||||
std::sync::Arc::from(serde_json::value::to_raw_value(¶ms).unwrap()),
|
||||
)
|
||||
}
|
||||
@@ -469,7 +469,7 @@ pub(super) fn tool_call_block_count(agent: &AgentView) -> usize {
|
||||
pub(super) fn make_inject_notif(payload: &serde_json::Value) -> acp::ExtNotification {
|
||||
let raw = serde_json::value::to_raw_value(payload).unwrap();
|
||||
acp::ExtNotification::new(
|
||||
"x.ai/scheduled_task_inject_prompt",
|
||||
"kigi/scheduled_task_inject_prompt",
|
||||
std::sync::Arc::from(raw),
|
||||
)
|
||||
}
|
||||
@@ -491,7 +491,7 @@ pub(super) fn make_fired_notif(
|
||||
meta: None,
|
||||
};
|
||||
let raw = serde_json::value::to_raw_value(¬if).unwrap();
|
||||
acp::ExtNotification::new("x.ai/scheduled_task_fired", std::sync::Arc::from(raw))
|
||||
acp::ExtNotification::new("kigi/scheduled_task_fired", std::sync::Arc::from(raw))
|
||||
}
|
||||
/// Set up an app with two agents; the active view points to agent 1, but
|
||||
/// agent 0 owns the scheduled task. Handlers that gate on `active_view`
|
||||
@@ -531,7 +531,7 @@ pub(super) fn make_created_ext_notif(
|
||||
meta: None,
|
||||
};
|
||||
let raw = serde_json::value::to_raw_value(¬if).unwrap();
|
||||
acp::ExtNotification::new("x.ai/scheduled_task_created", std::sync::Arc::from(raw))
|
||||
acp::ExtNotification::new("kigi/scheduled_task_created", std::sync::Arc::from(raw))
|
||||
}
|
||||
pub(super) fn make_deleted_ext_notif(
|
||||
session_id: &str,
|
||||
@@ -545,7 +545,7 @@ pub(super) fn make_deleted_ext_notif(
|
||||
meta: None,
|
||||
};
|
||||
let raw = serde_json::value::to_raw_value(¬if).unwrap();
|
||||
acp::ExtNotification::new("x.ai/scheduled_task_deleted", std::sync::Arc::from(raw))
|
||||
acp::ExtNotification::new("kigi/scheduled_task_deleted", std::sync::Arc::from(raw))
|
||||
}
|
||||
pub(super) fn make_token_notification_message(
|
||||
session_id: &str,
|
||||
@@ -697,7 +697,7 @@ pub(super) fn xai_model_switch_notif(
|
||||
meta: Some(serde_json::json!({ "eventId" : event_id })),
|
||||
};
|
||||
acp::ExtNotification::new(
|
||||
"x.ai/session/update",
|
||||
"kigi/session/update",
|
||||
std::sync::Arc::from(serde_json::value::to_raw_value(&payload).unwrap()),
|
||||
)
|
||||
}
|
||||
@@ -711,7 +711,7 @@ pub(super) fn xai_unhandled_notif(
|
||||
meta: Some(serde_json::json!({ "eventId" : event_id })),
|
||||
};
|
||||
acp::ExtNotification::new(
|
||||
"x.ai/session/update",
|
||||
"kigi/session/update",
|
||||
std::sync::Arc::from(serde_json::value::to_raw_value(&payload).unwrap()),
|
||||
)
|
||||
}
|
||||
@@ -741,19 +741,19 @@ pub(super) fn make_token_notification_with_event(
|
||||
response_tx: tx,
|
||||
})
|
||||
}
|
||||
/// Build an `x.ai/session/prompt_complete` ext-notification for `session_id`.
|
||||
/// Build an `kigi/session/prompt_complete` ext-notification for `session_id`.
|
||||
pub(super) fn prompt_complete_ext(session_id: &str) -> acp::ExtNotification {
|
||||
let raw = serde_json::value::to_raw_value(
|
||||
&serde_json::json!({ "sessionId" : session_id, "stopReason" : "end_turn", }),
|
||||
)
|
||||
.unwrap();
|
||||
acp::ExtNotification::new("x.ai/session/prompt_complete", std::sync::Arc::from(raw))
|
||||
acp::ExtNotification::new("kigi/session/prompt_complete", std::sync::Arc::from(raw))
|
||||
}
|
||||
/// Insert a fresh agent at `id` with an optional pre-assigned session id.
|
||||
pub(super) fn insert_agent(app: &mut AppView, id: AgentId, session_id: Option<&str>) {
|
||||
app.agents.insert(id, make_agent(session_id));
|
||||
}
|
||||
/// Build an `x.ai/session/prompt_complete` ext-notification with an explicit
|
||||
/// Build an `kigi/session/prompt_complete` ext-notification with an explicit
|
||||
/// `stopReason` and optional `agentResult`.
|
||||
pub(super) fn prompt_complete_ext_with_reason(
|
||||
session_id: &str,
|
||||
@@ -767,9 +767,9 @@ pub(super) fn prompt_complete_ext_with_reason(
|
||||
payload["agentResult"] = serde_json::json!(r);
|
||||
}
|
||||
let raw = serde_json::value::to_raw_value(&payload).unwrap();
|
||||
acp::ExtNotification::new("x.ai/session/prompt_complete", std::sync::Arc::from(raw))
|
||||
acp::ExtNotification::new("kigi/session/prompt_complete", std::sync::Arc::from(raw))
|
||||
}
|
||||
/// Build an `x.ai/session/prompt_complete` ext-notification carrying a
|
||||
/// Build an `kigi/session/prompt_complete` ext-notification carrying a
|
||||
/// `promptId` (shells with the lost-response fix). Built through the
|
||||
/// typed [`PromptCompletePayload`] so the test wire shape can never
|
||||
/// drift from what `handle_prompt_complete` parses.
|
||||
@@ -789,7 +789,7 @@ pub(super) fn prompt_complete_ext_with_prompt_id(
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
acp::ExtNotification::new("x.ai/session/prompt_complete", std::sync::Arc::from(raw))
|
||||
acp::ExtNotification::new("kigi/session/prompt_complete", std::sync::Arc::from(raw))
|
||||
}
|
||||
/// Build a live `AgentMessageChunk` whose meta carries `promptId` plus a
|
||||
/// `turnStartMs` `start_ms_ago` milliseconds in the past — drives the viewer
|
||||
@@ -822,7 +822,7 @@ pub(super) fn make_viewer_chunk_with_turn_start(
|
||||
response_tx: tx,
|
||||
})
|
||||
}
|
||||
/// Build a durable `TurnCompleted` update on the `x.ai/session/update` rail,
|
||||
/// Build a durable `TurnCompleted` update on the `kigi/session/update` rail,
|
||||
/// optionally stamped `isReplay`. Built through the typed `SessionNotification`
|
||||
/// so the wire shape can't drift from what the dispatch parses.
|
||||
pub(super) fn xai_turn_completed_notif(
|
||||
@@ -842,7 +842,7 @@ pub(super) fn xai_turn_completed_notif(
|
||||
meta: Some(serde_json::json!({ "isReplay" : is_replay })),
|
||||
};
|
||||
acp::ExtNotification::new(
|
||||
"x.ai/session/update",
|
||||
"kigi/session/update",
|
||||
std::sync::Arc::from(serde_json::value::to_raw_value(&payload).unwrap()),
|
||||
)
|
||||
}
|
||||
@@ -868,7 +868,7 @@ pub(super) fn xai_wake_turn_completed_notif(
|
||||
meta: Some(meta),
|
||||
};
|
||||
acp::ExtNotification::new(
|
||||
"x.ai/session/update",
|
||||
"kigi/session/update",
|
||||
std::sync::Arc::from(serde_json::value::to_raw_value(&payload).unwrap()),
|
||||
)
|
||||
}
|
||||
@@ -885,7 +885,7 @@ pub(super) fn last_marker_block(
|
||||
.expect("a turn-end marker must exist")
|
||||
}
|
||||
/// Build a `HookExecution` update (one successful run) on the
|
||||
/// `x.ai/session/update` rail, optionally stamped `isReplay`.
|
||||
/// `kigi/session/update` rail, optionally stamped `isReplay`.
|
||||
/// `prompt_id == None` models pre-attribution shells.
|
||||
pub(super) fn xai_hook_execution_notif_for_prompt(
|
||||
session_id: &str,
|
||||
@@ -908,7 +908,7 @@ pub(super) fn xai_hook_execution_notif_for_prompt(
|
||||
meta: Some(serde_json::json!({ "isReplay" : is_replay })),
|
||||
};
|
||||
acp::ExtNotification::new(
|
||||
"x.ai/session/update",
|
||||
"kigi/session/update",
|
||||
serde_json::value::to_raw_value(&payload).unwrap().into(),
|
||||
)
|
||||
}
|
||||
@@ -970,11 +970,11 @@ pub(super) fn seed_two_bg_tasks_and_announce(app: &mut AppView, session_id: &str
|
||||
);
|
||||
app.agents.get_mut(&AgentId(0)).unwrap().end_work_announced = true;
|
||||
}
|
||||
/// Build an `x.ai/session/interjection` ext-notification (no id).
|
||||
/// Build an `kigi/session/interjection` ext-notification (no id).
|
||||
pub(super) fn interjection_ext(session_id: &str, text: &str) -> acp::ExtNotification {
|
||||
interjection_ext_with_id(session_id, text, None)
|
||||
}
|
||||
/// Build an `x.ai/session/interjection` ext-notification with an optional
|
||||
/// Build an `kigi/session/interjection` ext-notification with an optional
|
||||
/// `interjectionId` (the originator-dedup key).
|
||||
pub(super) fn interjection_ext_with_id(
|
||||
session_id: &str,
|
||||
@@ -986,7 +986,7 @@ pub(super) fn interjection_ext_with_id(
|
||||
payload["interjectionId"] = serde_json::json!(id);
|
||||
}
|
||||
let raw = serde_json::value::to_raw_value(&payload).unwrap();
|
||||
acp::ExtNotification::new("x.ai/session/interjection", std::sync::Arc::from(raw))
|
||||
acp::ExtNotification::new("kigi/session/interjection", std::sync::Arc::from(raw))
|
||||
}
|
||||
/// Text of the most recent user prompt block in scrollback, if any.
|
||||
/// Interjections render as standard user prompt blocks.
|
||||
@@ -1090,14 +1090,14 @@ pub(super) fn make_bash_stdout_message(
|
||||
response_tx: tx,
|
||||
})
|
||||
}
|
||||
/// Build an `ExtNotification` envelope for `x.ai/session_notification`.
|
||||
/// Build an `ExtNotification` envelope for `kigi/session_notification`.
|
||||
pub(super) fn make_ext_session_notification(
|
||||
session_id: &str,
|
||||
update: XaiSessionUpdate,
|
||||
) -> AcpClientMessage {
|
||||
make_ext_session_notification_with_method(
|
||||
session_id,
|
||||
"x.ai/session_notification",
|
||||
"kigi/session_notification",
|
||||
update,
|
||||
)
|
||||
}
|
||||
@@ -1279,7 +1279,7 @@ pub(super) fn replay_disk_test_home() -> &'static std::path::Path {
|
||||
})
|
||||
.path()
|
||||
}
|
||||
/// Runs `f` with a thread-local grok home override so disk replay tests do not
|
||||
/// Runs `f` with a thread-local kigi home override so disk replay tests do not
|
||||
/// depend on process-wide `kigi_home()` cache order when the full suite runs.
|
||||
pub(super) fn with_replay_disk_home<R>(f: impl FnOnce(&std::path::Path) -> R) -> R {
|
||||
let home = replay_disk_test_home();
|
||||
@@ -1389,7 +1389,7 @@ pub(super) fn spawn_subagent_with_optional_updates(
|
||||
let _ = handle(
|
||||
make_ext_session_notification_with_method(
|
||||
"sess-parent",
|
||||
"x.ai/session/update",
|
||||
"kigi/session/update",
|
||||
test_subagent_spawned("sess-parent", child_sid),
|
||||
),
|
||||
app,
|
||||
@@ -1421,7 +1421,7 @@ pub(super) fn dispatch_goal_update(
|
||||
let (tx, _rx) = tokio::sync::oneshot::channel();
|
||||
handle(
|
||||
AcpClientMessage::ExtNotification(kigi_acp_lib::AcpArgs {
|
||||
request: acp::ExtNotification::new("x.ai/session_notification", raw.into()),
|
||||
request: acp::ExtNotification::new("kigi/session_notification", raw.into()),
|
||||
response_tx: tx,
|
||||
}),
|
||||
app,
|
||||
@@ -1464,7 +1464,7 @@ pub(super) fn make_permission_message(
|
||||
});
|
||||
(msg, rx)
|
||||
}
|
||||
/// Build an `x.ai/session_notification` carrying
|
||||
/// Build an `kigi/session_notification` carrying
|
||||
/// `InteractionResolved{tool_call_id}` (the first-answer-wins broadcast that
|
||||
/// tells every other pane to retract its shared interaction modal).
|
||||
pub(super) fn interaction_resolved_ext(
|
||||
@@ -1479,7 +1479,7 @@ pub(super) fn interaction_resolved_ext(
|
||||
meta: None,
|
||||
};
|
||||
let raw = serde_json::value::to_raw_value(¬if).unwrap();
|
||||
acp::ExtNotification::new("x.ai/session_notification", std::sync::Arc::from(raw))
|
||||
acp::ExtNotification::new("kigi/session_notification", std::sync::Arc::from(raw))
|
||||
}
|
||||
pub(super) fn make_git_head_changed_notif(
|
||||
session_id: &str,
|
||||
@@ -1494,7 +1494,7 @@ pub(super) fn make_git_head_changed_notif(
|
||||
main_repo: main_repo.map(str::to_string),
|
||||
};
|
||||
let raw = serde_json::value::to_raw_value(&payload).unwrap();
|
||||
acp::ExtNotification::new("x.ai/git_head_changed", std::sync::Arc::from(raw))
|
||||
acp::ExtNotification::new("kigi/git_head_changed", std::sync::Arc::from(raw))
|
||||
}
|
||||
pub(super) fn make_task_backgrounded_notif(
|
||||
session_id: &str,
|
||||
@@ -1516,7 +1516,7 @@ pub(super) fn make_task_backgrounded_notif(
|
||||
meta: None,
|
||||
};
|
||||
let raw = serde_json::value::to_raw_value(¬if).unwrap();
|
||||
acp::ExtNotification::new("x.ai/task_backgrounded", std::sync::Arc::from(raw))
|
||||
acp::ExtNotification::new("kigi/task_backgrounded", std::sync::Arc::from(raw))
|
||||
}
|
||||
/// Like [`make_task_backgrounded_notif`] but stamped `_meta.isReplay:
|
||||
/// true` via the typed [`ReplayMetaStamp`](crate::acp::meta::ReplayMetaStamp),
|
||||
@@ -1541,7 +1541,7 @@ pub(super) fn make_replayed_task_backgrounded_notif(
|
||||
meta: Some(crate::acp::meta::ReplayMetaStamp::replayed()),
|
||||
};
|
||||
let raw = serde_json::value::to_raw_value(¬if).unwrap();
|
||||
acp::ExtNotification::new("x.ai/session/update", std::sync::Arc::from(raw))
|
||||
acp::ExtNotification::new("kigi/session/update", std::sync::Arc::from(raw))
|
||||
}
|
||||
/// Register a pending Execute tool call in the tracker and send an InProgress
|
||||
/// update to create the scrollback entry. Returns the agent for further use.
|
||||
@@ -1670,7 +1670,7 @@ pub(super) fn task_completed_notif(
|
||||
meta: None,
|
||||
};
|
||||
let raw = serde_json::value::to_raw_value(¬if).unwrap();
|
||||
acp::ExtNotification::new("x.ai/task_completed", std::sync::Arc::from(raw))
|
||||
acp::ExtNotification::new("kigi/task_completed", std::sync::Arc::from(raw))
|
||||
}
|
||||
pub(super) fn make_monitor_event_notif(
|
||||
session_id: &str,
|
||||
@@ -1687,7 +1687,7 @@ pub(super) fn make_monitor_event_notif(
|
||||
meta: None,
|
||||
};
|
||||
let raw = serde_json::value::to_raw_value(¬if).unwrap();
|
||||
acp::ExtNotification::new("x.ai/monitor_event", std::sync::Arc::from(raw))
|
||||
acp::ExtNotification::new("kigi/monitor_event", std::sync::Arc::from(raw))
|
||||
}
|
||||
pub(super) fn make_model_info(id: &str) -> acp::ModelInfo {
|
||||
acp::ModelInfo::new(acp::ModelId::new(std::sync::Arc::from(id)), id.to_string())
|
||||
@@ -1705,9 +1705,9 @@ pub(super) fn make_models_update_notif(
|
||||
models,
|
||||
);
|
||||
let raw = serde_json::value::to_raw_value(&state).unwrap();
|
||||
acp::ExtNotification::new("x.ai/models/update", std::sync::Arc::from(raw))
|
||||
acp::ExtNotification::new("kigi/models/update", std::sync::Arc::from(raw))
|
||||
}
|
||||
/// `x.ai/models/update` carrying a single reasoning-capable model whose
|
||||
/// `kigi/models/update` carrying a single reasoning-capable model whose
|
||||
/// catalog-default effort is `default_effort` (what the broadcast reports
|
||||
/// for every client — never the per-session selection).
|
||||
pub(super) fn make_reasoning_models_update_notif(
|
||||
@@ -1725,7 +1725,7 @@ pub(super) fn make_reasoning_models_update_notif(
|
||||
vec![info],
|
||||
);
|
||||
let raw = serde_json::value::to_raw_value(&state).unwrap();
|
||||
acp::ExtNotification::new("x.ai/models/update", std::sync::Arc::from(raw))
|
||||
acp::ExtNotification::new("kigi/models/update", std::sync::Arc::from(raw))
|
||||
}
|
||||
/// Seed a session's model catalog with the given ids and mark
|
||||
/// `current_model_id` as the active one (must be in the list). Used by
|
||||
@@ -1754,7 +1754,7 @@ pub(super) fn model_changed_ext(
|
||||
meta: None,
|
||||
};
|
||||
let raw = serde_json::value::to_raw_value(&payload).unwrap();
|
||||
acp::ExtNotification::new("x.ai/session_notification", std::sync::Arc::from(raw))
|
||||
acp::ExtNotification::new("kigi/session_notification", std::sync::Arc::from(raw))
|
||||
}
|
||||
pub(super) fn model_changed_ext_with_event(
|
||||
session_id: &str,
|
||||
@@ -1770,7 +1770,7 @@ pub(super) fn model_changed_ext_with_event(
|
||||
meta: Some(serde_json::json!({ "eventId" : event_id })),
|
||||
};
|
||||
let raw = serde_json::value::to_raw_value(&payload).unwrap();
|
||||
acp::ExtNotification::new("x.ai/session_notification", std::sync::Arc::from(raw))
|
||||
acp::ExtNotification::new("kigi/session_notification", std::sync::Arc::from(raw))
|
||||
}
|
||||
pub(super) fn make_tool_call_update(title: &str) -> acp::SessionUpdate {
|
||||
acp::SessionUpdate::ToolCallUpdate(
|
||||
@@ -1796,7 +1796,7 @@ pub(super) fn make_current_mode_update(mode_id: &str) -> acp::SessionUpdate {
|
||||
acp::CurrentModeUpdate::new(acp::SessionModeId::new(mode_id)),
|
||||
)
|
||||
}
|
||||
/// Helper: build an `x.ai/mcp/init_progress` notification.
|
||||
/// Helper: build an `kigi/mcp/init_progress` notification.
|
||||
pub(super) fn make_mcp_init_progress_notif(
|
||||
total: u32,
|
||||
connected: u32,
|
||||
@@ -1805,7 +1805,7 @@ pub(super) fn make_mcp_init_progress_notif(
|
||||
&serde_json::json!({ "total" : total, "connected" : connected, }),
|
||||
)
|
||||
.unwrap();
|
||||
acp::ExtNotification::new("x.ai/mcp/init_progress", std::sync::Arc::from(raw))
|
||||
acp::ExtNotification::new("kigi/mcp/init_progress", std::sync::Arc::from(raw))
|
||||
}
|
||||
pub(super) fn make_mcps_modal_with_servers(
|
||||
servers: Vec<crate::views::mcps_modal::McpServerInfo>,
|
||||
@@ -1854,7 +1854,7 @@ pub(super) fn make_server_status_notif(
|
||||
tools,
|
||||
};
|
||||
let raw = serde_json::value::to_raw_value(&payload).unwrap();
|
||||
acp::ExtNotification::new("x.ai/mcp/server_status", std::sync::Arc::from(raw))
|
||||
acp::ExtNotification::new("kigi/mcp/server_status", std::sync::Arc::from(raw))
|
||||
}
|
||||
/// `mcp/servers_updated` real wire shape — `{ mcpServers: [...] }`
|
||||
/// with NO `sessionId`. Regression guard: anything that tries to
|
||||
@@ -1863,7 +1863,7 @@ pub(super) fn make_server_status_notif(
|
||||
pub(super) fn make_servers_updated_notif() -> acp::ExtNotification {
|
||||
let payload = serde_json::json!({ "mcpServers" : [] });
|
||||
let raw = serde_json::value::to_raw_value(&payload).unwrap();
|
||||
acp::ExtNotification::new("x.ai/mcp/servers_updated", std::sync::Arc::from(raw))
|
||||
acp::ExtNotification::new("kigi/mcp/servers_updated", std::sync::Arc::from(raw))
|
||||
}
|
||||
/// Real post-handshake / auth-recovery wire shape:
|
||||
/// `McpToolsChanged { sessionId, serverName, tools }`.
|
||||
@@ -1872,19 +1872,19 @@ pub(super) fn make_tools_changed_notif_post_h2(
|
||||
) -> acp::ExtNotification {
|
||||
let payload = kigi_shell::extensions::mcp::McpToolsChanged {
|
||||
session_id: session_id.to_string(),
|
||||
server_name: "grok_com_linear".to_string(),
|
||||
server_name: "kigi_com_linear".to_string(),
|
||||
tools: Vec::new(),
|
||||
};
|
||||
let raw = serde_json::value::to_raw_value(&payload).unwrap();
|
||||
acp::ExtNotification::new("x.ai/mcp/tools_changed", std::sync::Arc::from(raw))
|
||||
acp::ExtNotification::new("kigi/mcp/tools_changed", std::sync::Arc::from(raw))
|
||||
}
|
||||
/// Legacy / forward-compat wire shape: older shells emit
|
||||
/// `{ serverName, tools }` with NO sessionId. The pager must fall
|
||||
/// back to active_view for this shape.
|
||||
pub(super) fn make_tools_changed_notif_pre_h2() -> acp::ExtNotification {
|
||||
let payload = serde_json::json!({ "serverName" : "grok_com_linear", "tools" : [] });
|
||||
let payload = serde_json::json!({ "serverName" : "kigi_com_linear", "tools" : [] });
|
||||
let raw = serde_json::value::to_raw_value(&payload).unwrap();
|
||||
acp::ExtNotification::new("x.ai/mcp/tools_changed", std::sync::Arc::from(raw))
|
||||
acp::ExtNotification::new("kigi/mcp/tools_changed", std::sync::Arc::from(raw))
|
||||
}
|
||||
/// Real `mcp_initialized` wire shape:
|
||||
/// `{ sessionId, mcpToolCount, elapsedMs }`.
|
||||
@@ -1893,7 +1893,7 @@ pub(super) fn make_mcp_initialized_notif(session_id: &str) -> acp::ExtNotificati
|
||||
{ "sessionId" : session_id, "mcpToolCount" : 12_u64, "elapsedMs" : 250_u64, }
|
||||
);
|
||||
let raw = serde_json::value::to_raw_value(&payload).unwrap();
|
||||
acp::ExtNotification::new("x.ai/mcp_initialized", std::sync::Arc::from(raw))
|
||||
acp::ExtNotification::new("kigi/mcp_initialized", std::sync::Arc::from(raw))
|
||||
}
|
||||
/// Helper: `init_progress` notification carrying an explicit sessionId.
|
||||
pub(super) fn make_mcp_init_progress_notif_for(
|
||||
@@ -1907,7 +1907,7 @@ pub(super) fn make_mcp_init_progress_notif_for(
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
acp::ExtNotification::new("x.ai/mcp/init_progress", std::sync::Arc::from(raw))
|
||||
acp::ExtNotification::new("kigi/mcp/init_progress", std::sync::Arc::from(raw))
|
||||
}
|
||||
/// Helper: `mcp_initialized` notification for a specific sessionId.
|
||||
pub(super) fn make_mcp_initialized_notif_for(session_id: &str) -> acp::ExtNotification {
|
||||
@@ -1917,7 +1917,7 @@ pub(super) fn make_mcp_initialized_notif_for(session_id: &str) -> acp::ExtNotifi
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
acp::ExtNotification::new("x.ai/mcp_initialized", std::sync::Arc::from(raw))
|
||||
acp::ExtNotification::new("kigi/mcp_initialized", std::sync::Arc::from(raw))
|
||||
}
|
||||
mod permissions;
|
||||
mod session_events;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#![cfg_attr(rustfmt, rustfmt::skip)]
|
||||
use super::*;
|
||||
|
||||
/// Regression: a machine-wide `x.ai/models/update` broadcast
|
||||
/// Regression: a machine-wide `kigi/models/update` broadcast
|
||||
/// carries each model's static catalog-default effort (`high`), not the
|
||||
/// session's chosen `xhigh`, and must not clobber the per-session choice.
|
||||
#[test]
|
||||
@@ -44,20 +44,20 @@
|
||||
let mut app = make_app_with_agent("sess-1");
|
||||
|
||||
let agent = app.agents.get_mut(&AgentId(0)).unwrap();
|
||||
let id_3 = acp::ModelId::new(std::sync::Arc::from("grok-3"));
|
||||
let id_3 = acp::ModelId::new(std::sync::Arc::from("kigi-3"));
|
||||
agent
|
||||
.session
|
||||
.models
|
||||
.available
|
||||
.insert(id_3.clone(), make_model_info("grok-3"));
|
||||
.insert(id_3.clone(), make_model_info("kigi-3"));
|
||||
agent.session.models.current = Some(id_3);
|
||||
|
||||
let notif = make_models_update_notif("grok-4", &["grok-3", "grok-4"]);
|
||||
let notif = make_models_update_notif("kigi-4", &["kigi-3", "kigi-4"]);
|
||||
handle_models_update(¬if, &mut app);
|
||||
|
||||
assert_eq!(
|
||||
app.models.current.as_ref().map(|id| id.0.as_ref()),
|
||||
Some("grok-3"),
|
||||
Some("kigi-3"),
|
||||
"app.models.current must preserve active agent's model, not remote settings default"
|
||||
);
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
.current
|
||||
.as_ref()
|
||||
.map(|id| id.0.as_ref()),
|
||||
Some("grok-3"),
|
||||
Some("kigi-3"),
|
||||
"agent's per-session model must be preserved"
|
||||
);
|
||||
}
|
||||
@@ -79,21 +79,21 @@
|
||||
let mut app = make_app_with_agent("sess-1");
|
||||
|
||||
let agent = app.agents.get_mut(&AgentId(0)).unwrap();
|
||||
let id_3 = acp::ModelId::new(std::sync::Arc::from("grok-3"));
|
||||
let id_3 = acp::ModelId::new(std::sync::Arc::from("kigi-3"));
|
||||
agent
|
||||
.session
|
||||
.models
|
||||
.available
|
||||
.insert(id_3.clone(), make_model_info("grok-3"));
|
||||
.insert(id_3.clone(), make_model_info("kigi-3"));
|
||||
agent.session.models.current = Some(id_3);
|
||||
|
||||
// grok-3 removed from catalog.
|
||||
let notif = make_models_update_notif("grok-4.3", &["grok-4.3", "grok-4.5"]);
|
||||
// kigi-3 removed from catalog.
|
||||
let notif = make_models_update_notif("kigi-4.3", &["kigi-4.3", "kigi-4.5"]);
|
||||
handle_models_update(¬if, &mut app);
|
||||
|
||||
assert_eq!(
|
||||
app.models.current.as_ref().map(|id| id.0.as_ref()),
|
||||
Some("grok-4.3"),
|
||||
Some("kigi-4.3"),
|
||||
"app.models.current must use shell default when agent model removed"
|
||||
);
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
.current
|
||||
.as_ref()
|
||||
.map(|id| id.0.as_ref()),
|
||||
Some("grok-4.3"),
|
||||
Some("kigi-4.3"),
|
||||
"agent must fall back to shell default when its model is removed"
|
||||
);
|
||||
}
|
||||
@@ -115,12 +115,12 @@
|
||||
let (tx, _rx) = tokio::sync::mpsc::unbounded_channel();
|
||||
let mut app = AppView::new(tx, ModelState::default(), Vec::new());
|
||||
|
||||
let notif = make_models_update_notif("grok-4", &["grok-3", "grok-4"]);
|
||||
let notif = make_models_update_notif("kigi-4", &["kigi-3", "kigi-4"]);
|
||||
handle_models_update(¬if, &mut app);
|
||||
|
||||
assert_eq!(
|
||||
app.models.current.as_ref().map(|id| id.0.as_ref()),
|
||||
Some("grok-4"),
|
||||
Some("kigi-4"),
|
||||
"without an active agent, shell default must be used"
|
||||
);
|
||||
}
|
||||
@@ -130,21 +130,21 @@
|
||||
let mut app = make_app_with_agent("sess-1");
|
||||
|
||||
let agent = app.agents.get_mut(&AgentId(0)).unwrap();
|
||||
let id_4 = acp::ModelId::new(std::sync::Arc::from("grok-4"));
|
||||
let id_4 = acp::ModelId::new(std::sync::Arc::from("kigi-4"));
|
||||
agent
|
||||
.session
|
||||
.models
|
||||
.available
|
||||
.insert(id_4.clone(), make_model_info("grok-4"));
|
||||
.insert(id_4.clone(), make_model_info("kigi-4"));
|
||||
agent.session.models.current = Some(id_4);
|
||||
|
||||
let notif = make_models_update_notif("grok-4", &["grok-3", "grok-4"]);
|
||||
let notif = make_models_update_notif("kigi-4", &["kigi-3", "kigi-4"]);
|
||||
handle_models_update(¬if, &mut app);
|
||||
|
||||
assert_eq!(
|
||||
app.models.current.as_ref().map(|id| id.0.as_ref()),
|
||||
Some("grok-4"),
|
||||
"app.models.current must be grok-4 when agent and shell agree"
|
||||
Some("kigi-4"),
|
||||
"app.models.current must be kigi-4 when agent and shell agree"
|
||||
);
|
||||
let agent = app.agents.get(&AgentId(0)).unwrap();
|
||||
assert_eq!(
|
||||
@@ -154,8 +154,8 @@
|
||||
.current
|
||||
.as_ref()
|
||||
.map(|id| id.0.as_ref()),
|
||||
Some("grok-4"),
|
||||
"agent model must remain grok-4"
|
||||
Some("kigi-4"),
|
||||
"agent model must remain kigi-4"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -166,33 +166,33 @@
|
||||
|
||||
{
|
||||
let agent_a = app.agents.get_mut(&AgentId(0)).unwrap();
|
||||
let id_3 = acp::ModelId::new(std::sync::Arc::from("grok-3"));
|
||||
let id_3 = acp::ModelId::new(std::sync::Arc::from("kigi-3"));
|
||||
agent_a
|
||||
.session
|
||||
.models
|
||||
.available
|
||||
.insert(id_3.clone(), make_model_info("grok-3"));
|
||||
.insert(id_3.clone(), make_model_info("kigi-3"));
|
||||
agent_a.session.models.current = Some(id_3);
|
||||
}
|
||||
|
||||
{
|
||||
let agent_b = app.agents.get_mut(&AgentId(1)).unwrap();
|
||||
let id_5 = acp::ModelId::new(std::sync::Arc::from("grok-4.5"));
|
||||
let id_5 = acp::ModelId::new(std::sync::Arc::from("kigi-4.5"));
|
||||
agent_b
|
||||
.session
|
||||
.models
|
||||
.available
|
||||
.insert(id_5.clone(), make_model_info("grok-4.5"));
|
||||
.insert(id_5.clone(), make_model_info("kigi-4.5"));
|
||||
agent_b.session.models.current = Some(id_5);
|
||||
}
|
||||
|
||||
// grok-5 removed from catalog.
|
||||
let notif = make_models_update_notif("grok-4", &["grok-3", "grok-4"]);
|
||||
// kigi-5 removed from catalog.
|
||||
let notif = make_models_update_notif("kigi-4", &["kigi-3", "kigi-4"]);
|
||||
handle_models_update(¬if, &mut app);
|
||||
|
||||
assert_eq!(
|
||||
app.models.current.as_ref().map(|id| id.0.as_ref()),
|
||||
Some("grok-3"),
|
||||
Some("kigi-3"),
|
||||
);
|
||||
let agent_a = app.agents.get(&AgentId(0)).unwrap();
|
||||
assert_eq!(
|
||||
@@ -202,11 +202,11 @@
|
||||
.current
|
||||
.as_ref()
|
||||
.map(|id| id.0.as_ref()),
|
||||
Some("grok-3"),
|
||||
Some("kigi-3"),
|
||||
"agent A's model must be preserved"
|
||||
);
|
||||
|
||||
// B's grok-5 was removed — must fall back to shell's grok-4, not A's grok-3.
|
||||
// B's kigi-5 was removed — must fall back to shell's kigi-4, not A's kigi-3.
|
||||
let agent_b = app.agents.get(&AgentId(1)).unwrap();
|
||||
assert_eq!(
|
||||
agent_b
|
||||
@@ -215,7 +215,7 @@
|
||||
.current
|
||||
.as_ref()
|
||||
.map(|id| id.0.as_ref()),
|
||||
Some("grok-4"),
|
||||
Some("kigi-4"),
|
||||
"inactive agent must fall back to shell default, not active agent's model"
|
||||
);
|
||||
}
|
||||
@@ -228,12 +228,12 @@
|
||||
fn model_changed_updates_state_silently_on_follower() {
|
||||
let mut app = make_app_with_agent("sess-1");
|
||||
let agent = app.agents.get_mut(&AgentId(0)).unwrap();
|
||||
seed_models(agent, "grok-3", &["grok-3", "grok-4"]);
|
||||
seed_models(agent, "kigi-3", &["kigi-3", "kigi-4"]);
|
||||
let scrollback_before = agent.scrollback.len();
|
||||
// Follower: no local switch in flight.
|
||||
assert!(!agent.session.model_switch_pending);
|
||||
|
||||
let notif = model_changed_ext("sess-1", "grok-4", None);
|
||||
let notif = model_changed_ext("sess-1", "kigi-4", None);
|
||||
let changed = handle_ext_notification(¬if, &mut app);
|
||||
assert!(
|
||||
changed,
|
||||
@@ -248,7 +248,7 @@
|
||||
.current
|
||||
.as_ref()
|
||||
.map(|id| id.0.as_ref()),
|
||||
Some("grok-4"),
|
||||
Some("kigi-4"),
|
||||
"follower must mirror the remote switch into its local model state",
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -325,13 +325,13 @@
|
||||
fn model_changed_skipped_when_local_switch_in_flight() {
|
||||
let mut app = make_app_with_agent("sess-1");
|
||||
let agent = app.agents.get_mut(&AgentId(0)).unwrap();
|
||||
seed_models(agent, "grok-3", &["grok-3", "grok-4"]);
|
||||
seed_models(agent, "kigi-3", &["kigi-3", "kigi-4"]);
|
||||
// Invoker: a local switch is in flight (set by Action::SwitchModel /
|
||||
// set_default_model before the SetSessionModelRequest is sent).
|
||||
agent.session.model_switch_pending = true;
|
||||
let scrollback_before = agent.scrollback.len();
|
||||
|
||||
let notif = model_changed_ext("sess-1", "grok-4", None);
|
||||
let notif = model_changed_ext("sess-1", "kigi-4", None);
|
||||
let changed = handle_ext_notification(¬if, &mut app);
|
||||
assert!(
|
||||
!changed,
|
||||
@@ -346,7 +346,7 @@
|
||||
.current
|
||||
.as_ref()
|
||||
.map(|id| id.0.as_ref()),
|
||||
Some("grok-3"),
|
||||
Some("kigi-3"),
|
||||
"models.current must stay at the pre-response snapshot — \
|
||||
SwitchModelComplete owns the final apply + system message"
|
||||
);
|
||||
@@ -370,9 +370,9 @@
|
||||
fn model_changed_dropped_when_model_unknown_to_catalog() {
|
||||
let mut app = make_app_with_agent("sess-1");
|
||||
let agent = app.agents.get_mut(&AgentId(0)).unwrap();
|
||||
seed_models(agent, "grok-3", &["grok-3", "grok-4"]);
|
||||
seed_models(agent, "kigi-3", &["kigi-3", "kigi-4"]);
|
||||
|
||||
let notif = model_changed_ext("sess-1", "grok-99-unknown", None);
|
||||
let notif = model_changed_ext("sess-1", "kigi-99-unknown", None);
|
||||
let changed = handle_ext_notification(¬if, &mut app);
|
||||
assert!(
|
||||
!changed,
|
||||
@@ -387,7 +387,7 @@
|
||||
.current
|
||||
.as_ref()
|
||||
.map(|id| id.0.as_ref()),
|
||||
Some("grok-3"),
|
||||
Some("kigi-3"),
|
||||
"models.current must stay on the previously-known model"
|
||||
);
|
||||
}
|
||||
@@ -395,15 +395,15 @@
|
||||
/// `reasoning_effort` round-trips through the broadcast: the follower
|
||||
/// applies it alongside the model id so the prompt header / status bar
|
||||
/// show the right effort without waiting for a subsequent
|
||||
/// `x.ai/models/update`.
|
||||
/// `kigi/models/update`.
|
||||
#[test]
|
||||
fn model_changed_applies_reasoning_effort_on_follower() {
|
||||
use kigi_shell::sampling::types::ReasoningEffort;
|
||||
let mut app = make_app_with_agent("sess-1");
|
||||
let agent = app.agents.get_mut(&AgentId(0)).unwrap();
|
||||
seed_models(agent, "grok-3", &["grok-3", "grok-4"]);
|
||||
seed_models(agent, "kigi-3", &["kigi-3", "kigi-4"]);
|
||||
|
||||
let notif = model_changed_ext("sess-1", "grok-4", Some("high"));
|
||||
let notif = model_changed_ext("sess-1", "kigi-4", Some("high"));
|
||||
assert!(handle_ext_notification(¬if, &mut app));
|
||||
|
||||
let agent = app.agents.get(&AgentId(0)).unwrap();
|
||||
@@ -423,9 +423,9 @@
|
||||
fn model_changed_dropped_for_unknown_session_id() {
|
||||
let mut app = make_app_with_agent("sess-1");
|
||||
let agent = app.agents.get_mut(&AgentId(0)).unwrap();
|
||||
seed_models(agent, "grok-3", &["grok-3", "grok-4"]);
|
||||
seed_models(agent, "kigi-3", &["kigi-3", "kigi-4"]);
|
||||
|
||||
let notif = model_changed_ext("sess-OTHER", "grok-4", None);
|
||||
let notif = model_changed_ext("sess-OTHER", "kigi-4", None);
|
||||
let changed = handle_ext_notification(¬if, &mut app);
|
||||
assert!(!changed);
|
||||
|
||||
@@ -437,7 +437,7 @@
|
||||
.current
|
||||
.as_ref()
|
||||
.map(|id| id.0.as_ref()),
|
||||
Some("grok-3"),
|
||||
Some("kigi-3"),
|
||||
"unrelated-session broadcast must not touch this agent's model"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -213,7 +213,7 @@
|
||||
};
|
||||
let raw = serde_json::value::to_raw_value(&ext_req).unwrap();
|
||||
let msg = AcpClientMessage::ExtMethod(kigi_acp_lib::AcpArgs {
|
||||
request: acp::ExtRequest::new("x.ai/exit_plan_mode", raw.into()),
|
||||
request: acp::ExtRequest::new("kigi/exit_plan_mode", raw.into()),
|
||||
response_tx: tx,
|
||||
});
|
||||
|
||||
@@ -244,7 +244,7 @@
|
||||
};
|
||||
let raw = serde_json::value::to_raw_value(&ext_req).unwrap();
|
||||
let msg = AcpClientMessage::ExtMethod(kigi_acp_lib::AcpArgs {
|
||||
request: acp::ExtRequest::new("x.ai/exit_plan_mode", raw.into()),
|
||||
request: acp::ExtRequest::new("kigi/exit_plan_mode", raw.into()),
|
||||
response_tx: tx,
|
||||
});
|
||||
|
||||
@@ -275,7 +275,7 @@
|
||||
};
|
||||
let raw = serde_json::value::to_raw_value(&ext_req).unwrap();
|
||||
let msg = AcpClientMessage::ExtMethod(kigi_acp_lib::AcpArgs {
|
||||
request: acp::ExtRequest::new("x.ai/exit_plan_mode", raw.into()),
|
||||
request: acp::ExtRequest::new("kigi/exit_plan_mode", raw.into()),
|
||||
response_tx: tx,
|
||||
});
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
XaiSessionUpdate::PluginsChanged {
|
||||
plugins: vec![crate::views::extensions_modal::test_plugin_info(
|
||||
"user-tool",
|
||||
Some(kigi_hooks_plugins_types::PluginOrigin::UserGrok),
|
||||
Some(kigi_hooks_plugins_types::PluginOrigin::UserKigi),
|
||||
)],
|
||||
},
|
||||
),
|
||||
@@ -60,7 +60,7 @@
|
||||
plugins: vec![
|
||||
crate::views::extensions_modal::test_plugin_info(
|
||||
"user-tool",
|
||||
Some(kigi_hooks_plugins_types::PluginOrigin::UserGrok),
|
||||
Some(kigi_hooks_plugins_types::PluginOrigin::UserKigi),
|
||||
),
|
||||
crate::views::extensions_modal::test_plugin_info(
|
||||
"claude-tool",
|
||||
@@ -103,7 +103,7 @@
|
||||
XaiSessionUpdate::PluginsChanged {
|
||||
plugins: vec![crate::views::extensions_modal::test_plugin_info(
|
||||
"user-tool",
|
||||
Some(kigi_hooks_plugins_types::PluginOrigin::UserGrok),
|
||||
Some(kigi_hooks_plugins_types::PluginOrigin::UserKigi),
|
||||
)],
|
||||
},
|
||||
),
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
use super::*;
|
||||
|
||||
/// The pager reconciles the authoritative shared prompt queue from the
|
||||
/// `x.ai/queue/changed` broadcast, and an empty broadcast clears it.
|
||||
/// `kigi/queue/changed` broadcast, and an empty broadcast clears it.
|
||||
#[test]
|
||||
fn queue_changed_reconciles_shared_queue() {
|
||||
let mut app = make_app_with_agent("sess-1");
|
||||
@@ -144,7 +144,7 @@
|
||||
params["runningPromptId"] = serde_json::json!(r);
|
||||
}
|
||||
acp::ExtNotification::new(
|
||||
"x.ai/queue/changed",
|
||||
"kigi/queue/changed",
|
||||
std::sync::Arc::from(serde_json::value::to_raw_value(¶ms).unwrap()),
|
||||
)
|
||||
}
|
||||
@@ -336,7 +336,7 @@
|
||||
serde_json::from_str(&json_str).unwrap();
|
||||
assert_eq!(mirror.running_prompt_id.as_deref(), Some("prompt-running"));
|
||||
|
||||
let notif = acp::ExtNotification::new("x.ai/queue/changed", raw.into());
|
||||
let notif = acp::ExtNotification::new("kigi/queue/changed", raw.into());
|
||||
|
||||
// Case 1: current_prompt_id is None -> adopt it.
|
||||
let mut app = make_app_with_agent("sess-1");
|
||||
@@ -415,7 +415,7 @@
|
||||
/// Regression: when the shell promotes
|
||||
/// a server-initiated / auto-wake prompt (synthetic id `task-completed-…`,
|
||||
/// injected when a background task finishes) to the running turn, it
|
||||
/// broadcasts `x.ai/queue/changed` with `runningPromptId` = that synthetic
|
||||
/// broadcasts `kigi/queue/changed` with `runningPromptId` = that synthetic
|
||||
/// id. The pager must NOT adopt it via the turn-start shim: those turns run
|
||||
/// inside the actor and emit no `prompt_complete` / `PromptResponse`, so
|
||||
/// `start_turn()` here would strand the pager on "Responding…" forever
|
||||
@@ -1736,7 +1736,7 @@
|
||||
"promptId": "p1",
|
||||
});
|
||||
let notif = acp::ExtNotification::new(
|
||||
"x.ai/session/prompt_complete",
|
||||
"kigi/session/prompt_complete",
|
||||
serde_json::value::to_raw_value(¶ms).unwrap().into(),
|
||||
);
|
||||
handle_prompt_complete(¬if, &mut app);
|
||||
@@ -2093,7 +2093,7 @@
|
||||
fn viewer_does_not_enter_turn_running_for_server_initiated_turn() {
|
||||
// A server-initiated / auto-wake turn (synthetic prompt id, e.g. a
|
||||
// background subagent or task completion: `task-completed-…`) runs inside
|
||||
// the actor and emits NO `x.ai/session/prompt_complete`. If a viewer
|
||||
// the actor and emits NO `kigi/session/prompt_complete`. If a viewer
|
||||
// entered TurnRunning for it, nothing would ever finish the turn and the
|
||||
// viewer would be stuck "Responding…" forever — exactly the bug where one
|
||||
// dashboard showed "Worked for" while the other was stuck responding.
|
||||
@@ -2131,7 +2131,7 @@
|
||||
fn viewer_enters_turn_running_for_scheduler_fired_cron_turn() {
|
||||
// A `/loop` (scheduled-task) turn has a synthetic `scheduler-fired-…`
|
||||
// prompt id, but UNLIKE auto-wake turns it is client-driven via
|
||||
// `MvpAgent::prompt()` and DOES emit `x.ai/session/prompt_complete`. So a
|
||||
// `MvpAgent::prompt()` and DOES emit `kigi/session/prompt_complete`. So a
|
||||
// viewer MUST enter TurnRunning for it — otherwise the dashboard's
|
||||
// locally-tracked row for a running `/loop` session never shows Working.
|
||||
let mut app = make_app_with_agent("sess-view");
|
||||
@@ -2173,7 +2173,7 @@
|
||||
|
||||
#[test]
|
||||
fn viewer_prompt_complete_finishes_turn() {
|
||||
// A viewer in TurnRunning receives x.ai/session/prompt_complete for its
|
||||
// A viewer in TurnRunning receives kigi/session/prompt_complete for its
|
||||
// session -> finish_turn: state Idle, current_prompt_id cleared.
|
||||
let mut app = make_app_with_agent("sess-view");
|
||||
app.agents.get_mut(&AgentId(0)).unwrap().attached_as_viewer = true;
|
||||
|
||||
@@ -802,7 +802,7 @@
|
||||
meta,
|
||||
};
|
||||
acp::ExtNotification::new(
|
||||
"x.ai/session/update",
|
||||
"kigi/session/update",
|
||||
std::sync::Arc::from(serde_json::value::to_raw_value(&payload).unwrap()),
|
||||
)
|
||||
}
|
||||
@@ -882,7 +882,7 @@
|
||||
meta: Some(serde_json::json!({ "isReplay": true, "eventId": "sess-sub-3" })),
|
||||
};
|
||||
let notif = acp::ExtNotification::new(
|
||||
"x.ai/session_notification",
|
||||
"kigi/session_notification",
|
||||
serde_json::value::to_raw_value(&payload).unwrap().into(),
|
||||
);
|
||||
assert!(handle_ext_notification(¬if, &mut app));
|
||||
@@ -996,12 +996,12 @@
|
||||
let id = AgentId(0);
|
||||
{
|
||||
let agent = app.agents.get_mut(&id).unwrap();
|
||||
seed_models(agent, "grok-3", &["grok-3", "grok-4"]);
|
||||
seed_models(agent, "kigi-3", &["kigi-3", "kigi-4"]);
|
||||
}
|
||||
|
||||
// Unknown model → ignored → both markers untouched.
|
||||
assert!(!handle_ext_notification(
|
||||
&model_changed_ext_with_event("sess-1", "grok-99-unknown", "sess-1-7"),
|
||||
&model_changed_ext_with_event("sess-1", "kigi-99-unknown", "sess-1-7"),
|
||||
&mut app
|
||||
));
|
||||
assert_eq!(
|
||||
@@ -1015,7 +1015,7 @@
|
||||
|
||||
// Known model → applied → both markers advance.
|
||||
assert!(handle_ext_notification(
|
||||
&model_changed_ext_with_event("sess-1", "grok-4", "sess-1-8"),
|
||||
&model_changed_ext_with_event("sess-1", "kigi-4", "sess-1-8"),
|
||||
&mut app
|
||||
));
|
||||
assert_eq!(
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
|
||||
#[test]
|
||||
fn inject_prompt_drives_even_when_attached_as_viewer() {
|
||||
// The leader routes `x.ai/scheduled_task_inject_prompt` to the SINGLE
|
||||
// The leader routes `kigi/scheduled_task_inject_prompt` to the SINGLE
|
||||
// session driver, so any client that receives it IS the driver and must
|
||||
// enqueue + run it — even one that attached via `session/load`
|
||||
// (`attached_as_viewer == true`). Previously this handler latched on
|
||||
@@ -92,7 +92,7 @@
|
||||
fn inject_prompt_malformed_json_returns_false() {
|
||||
let mut app = make_app_with_agent("sess-1");
|
||||
let raw = serde_json::value::to_raw_value(&"not a json object").unwrap();
|
||||
let notif = acp::ExtNotification::new("x.ai/scheduled_task_inject_prompt", raw.into());
|
||||
let notif = acp::ExtNotification::new("kigi/scheduled_task_inject_prompt", raw.into());
|
||||
|
||||
// The JSON is valid (a string), but sessionId/prompt fields won't exist.
|
||||
let result = handle_scheduled_task_inject_prompt(¬if, &mut app);
|
||||
|
||||
@@ -217,7 +217,7 @@
|
||||
app.current_ui.permission_mode = Some("ask".into());
|
||||
|
||||
let killswitch = acp::ExtNotification::new(
|
||||
"x.ai/settings/update",
|
||||
"kigi/settings/update",
|
||||
serde_json::value::to_raw_value(
|
||||
&serde_json::json!({ "auto_permission_mode_enabled": false }),
|
||||
)
|
||||
@@ -253,7 +253,7 @@
|
||||
app.agents.get_mut(&AgentId(2)).unwrap().session.yolo_mode = true;
|
||||
|
||||
let killswitch = acp::ExtNotification::new(
|
||||
"x.ai/settings/update",
|
||||
"kigi/settings/update",
|
||||
serde_json::value::to_raw_value(
|
||||
&serde_json::json!({ "auto_permission_mode_enabled": false }),
|
||||
)
|
||||
@@ -272,7 +272,7 @@
|
||||
let mut leave_auto_notifs = 0;
|
||||
while let Ok(msg) = rx.try_recv() {
|
||||
if let kigi_acp_lib::AcpAgentMessage::ExtNotification(args) = msg {
|
||||
if args.request.method.as_ref() != "x.ai/yolo_mode_changed" {
|
||||
if args.request.method.as_ref() != "kigi/yolo_mode_changed" {
|
||||
continue;
|
||||
}
|
||||
let params: serde_json::Value =
|
||||
@@ -302,7 +302,7 @@
|
||||
app.default_yolo = false;
|
||||
|
||||
let apply_yolo = acp::ExtNotification::new(
|
||||
"x.ai/settings/update",
|
||||
"kigi/settings/update",
|
||||
serde_json::value::to_raw_value(&serde_json::json!({
|
||||
"permission_mode": "always-approve",
|
||||
}))
|
||||
@@ -334,7 +334,7 @@
|
||||
app.auto_mode_gate = true;
|
||||
|
||||
let unrelated = acp::ExtNotification::new(
|
||||
"x.ai/settings/update",
|
||||
"kigi/settings/update",
|
||||
serde_json::value::to_raw_value(&serde_json::json!({
|
||||
"show_resolved_model": true,
|
||||
}))
|
||||
@@ -372,7 +372,7 @@
|
||||
app.current_ui.permission_mode = Some("sentinel-not-a-mode".into());
|
||||
|
||||
let push = acp::ExtNotification::new(
|
||||
"x.ai/settings/update",
|
||||
"kigi/settings/update",
|
||||
serde_json::value::to_raw_value(&serde_json::json!({
|
||||
"permission_mode": "always-approve",
|
||||
}))
|
||||
|
||||
@@ -157,7 +157,7 @@
|
||||
);
|
||||
}
|
||||
|
||||
/// Regression: replay from `updates.jsonl` emits `x.ai/session/update` (not
|
||||
/// Regression: replay from `updates.jsonl` emits `kigi/session/update` (not
|
||||
/// `session_notification`). Subagent lifecycle events must still populate
|
||||
/// `subagent_sessions` and the parent scrollback `SubagentBlock`.
|
||||
#[test]
|
||||
@@ -168,7 +168,7 @@
|
||||
let affected = handle(
|
||||
make_ext_session_notification_with_method(
|
||||
"sess-parent",
|
||||
"x.ai/session/update",
|
||||
"kigi/session/update",
|
||||
test_subagent_spawned("sess-parent", child_sid),
|
||||
),
|
||||
&mut app,
|
||||
@@ -204,7 +204,7 @@
|
||||
let affected = handle(
|
||||
make_ext_session_notification_with_method(
|
||||
"sess-parent",
|
||||
"x.ai/session/update",
|
||||
"kigi/session/update",
|
||||
test_subagent_finished(child_sid),
|
||||
),
|
||||
&mut app,
|
||||
@@ -424,7 +424,7 @@
|
||||
let _ = handle(
|
||||
make_ext_session_notification_with_method(
|
||||
"sess-parent",
|
||||
"x.ai/session/update",
|
||||
"kigi/session/update",
|
||||
test_subagent_finished(child_sid),
|
||||
),
|
||||
&mut app,
|
||||
@@ -674,9 +674,9 @@
|
||||
fn ext_session_notification_and_update_equivalent_for_subagent_spawned() {
|
||||
let child_sid = "child-equiv";
|
||||
let (spawn_notif, finish_notif) =
|
||||
run_subagent_lifecycle_via_method("x.ai/session_notification", child_sid);
|
||||
run_subagent_lifecycle_via_method("kigi/session_notification", child_sid);
|
||||
let (spawn_update, finish_update) =
|
||||
run_subagent_lifecycle_via_method("x.ai/session/update", child_sid);
|
||||
run_subagent_lifecycle_via_method("kigi/session/update", child_sid);
|
||||
|
||||
assert_eq!(spawn_notif.description, spawn_update.description);
|
||||
assert_eq!(spawn_notif.subagent_type, spawn_update.subagent_type);
|
||||
@@ -725,7 +725,7 @@
|
||||
let affected = handle(
|
||||
make_ext_session_notification_with_method(
|
||||
"sess-A",
|
||||
"x.ai/session/update",
|
||||
"kigi/session/update",
|
||||
test_subagent_spawned("sess-A", child_sid),
|
||||
),
|
||||
&mut app,
|
||||
@@ -757,7 +757,7 @@
|
||||
let affected = handle(
|
||||
make_ext_session_notification_with_method(
|
||||
"sess-A",
|
||||
"x.ai/session/update",
|
||||
"kigi/session/update",
|
||||
test_subagent_finished(child_sid),
|
||||
),
|
||||
&mut app,
|
||||
@@ -784,7 +784,7 @@
|
||||
let affected = handle(
|
||||
make_ext_session_notification_with_method(
|
||||
"sess-unknown",
|
||||
"x.ai/session/update",
|
||||
"kigi/session/update",
|
||||
test_subagent_spawned("sess-unknown", "child-unknown"),
|
||||
),
|
||||
&mut app,
|
||||
@@ -809,7 +809,7 @@
|
||||
// Valid JSON but not a SessionNotification — parse must fail quietly.
|
||||
let raw =
|
||||
serde_json::value::to_raw_value(&serde_json::json!({"unexpected": true})).unwrap();
|
||||
let request = acp::ExtNotification::new("x.ai/session/update", raw.into());
|
||||
let request = acp::ExtNotification::new("kigi/session/update", raw.into());
|
||||
let msg = AcpClientMessage::ExtNotification(kigi_acp_lib::AcpArgs {
|
||||
request,
|
||||
response_tx: tx,
|
||||
@@ -819,7 +819,7 @@
|
||||
|
||||
assert!(
|
||||
!affected,
|
||||
"malformed x.ai/session/update params must not redraw"
|
||||
"malformed kigi/session/update params must not redraw"
|
||||
);
|
||||
assert!(
|
||||
app.agents.get(&AgentId(0)).unwrap().scrollback.is_empty(),
|
||||
|
||||
@@ -971,7 +971,7 @@
|
||||
.remove("will_wake")
|
||||
.expect("the typed builder stamps the field");
|
||||
let legacy = acp::ExtNotification::new(
|
||||
"x.ai/task_completed",
|
||||
"kigi/task_completed",
|
||||
std::sync::Arc::from(serde_json::value::to_raw_value(&v).unwrap()),
|
||||
);
|
||||
let _ = handle_ext_notification(&legacy, &mut app);
|
||||
|
||||
Reference in New Issue
Block a user