greetingカードの作成

This commit is contained in:
2026-04-15 10:35:15 +09:00
parent c48abf062e
commit 0c29de1b10
11 changed files with 369 additions and 56 deletions
+33
View File
@@ -58,10 +58,12 @@ impl PodController {
let (event_tx, _) = broadcast::channel::<Event>(256);
let manifest_toml = toml::to_string_pretty(pod.manifest()).unwrap_or_default();
let greeting = build_greeting(&pod);
let shared_state = Arc::new(PodSharedState::new(
pod.manifest().pod.name.clone(),
pod.session_id(),
manifest_toml.clone(),
greeting,
));
// Create runtime directory and write initial files
@@ -337,6 +339,37 @@ where
}
}
fn build_greeting<C, St>(pod: &Pod<C, St>) -> protocol::Greeting
where
C: LlmClient,
St: Store,
{
let manifest = pod.manifest();
let provider = match manifest.provider.kind {
manifest::ProviderKind::Anthropic => "anthropic",
manifest::ProviderKind::Openai => "openai",
manifest::ProviderKind::Gemini => "gemini",
manifest::ProviderKind::Ollama => "ollama",
};
// The tool list mirrors `builtin_tools`. A fresh `ScopedFs`/`Tracker`
// is instantiated only to invoke the factories for name extraction;
// the instances themselves are discarded.
let fs = tools::ScopedFs::new(pod.scope().clone(), pod.pwd().to_path_buf());
let tracker = tools::Tracker::new();
let tool_names = tools::builtin_tools(fs, tracker)
.iter()
.map(|def| def().0.name)
.collect();
protocol::Greeting {
pod_name: manifest.pod.name.clone(),
cwd: pod.pwd().display().to_string(),
provider: provider.into(),
model: manifest.provider.model.clone(),
scope_summary: pod.scope().summary(),
tools: tool_names,
}
}
fn worker_error_code(e: &PodError) -> ErrorCode {
match e {
PodError::Worker(we) => match we {
+8
View File
@@ -109,6 +109,14 @@ mod tests {
"test-pod".into(),
session_store::new_session_id(),
"[pod]\nname = \"test-pod\"".into(),
protocol::Greeting {
pod_name: "test-pod".into(),
cwd: "/tmp".into(),
provider: "anthropic".into(),
model: "claude".into(),
scope_summary: String::new(),
tools: Vec::new(),
},
)
}
+20 -1
View File
@@ -12,6 +12,7 @@ pub struct PodSharedState {
pub pod_name: String,
pub session_id: SessionId,
pub manifest_toml: String,
pub greeting: protocol::Greeting,
pub status: RwLock<PodStatus>,
pub history: RwLock<Vec<Item>>,
}
@@ -25,11 +26,17 @@ pub enum PodStatus {
}
impl PodSharedState {
pub fn new(pod_name: String, session_id: SessionId, manifest_toml: String) -> Self {
pub fn new(
pod_name: String,
session_id: SessionId,
manifest_toml: String,
greeting: protocol::Greeting,
) -> Self {
Self {
pod_name,
session_id,
manifest_toml,
greeting,
status: RwLock::new(PodStatus::Idle),
history: RwLock::new(Vec::new()),
}
@@ -86,9 +93,21 @@ mod tests {
"test-pod".into(),
session_store::new_session_id(),
"[pod]\nname = \"test-pod\"".into(),
test_greeting(),
)
}
fn test_greeting() -> protocol::Greeting {
protocol::Greeting {
pod_name: "test-pod".into(),
cwd: "/tmp".into(),
provider: "anthropic".into(),
model: "claude".into(),
scope_summary: String::new(),
tools: Vec::new(),
}
}
#[test]
fn initial_status_is_idle() {
let state = test_state();
+9 -1
View File
@@ -85,7 +85,15 @@ async fn handle_connection(stream: tokio::net::UnixStream, handle: PodHandle) {
.iter()
.map(|item| serde_json::to_value(item).expect("Item is Serialize"))
.collect();
if writer.write(&Event::History { items: values }).await.is_err() {
let greeting = handle.shared_state.greeting.clone();
if writer
.write(&Event::History {
items: values,
greeting,
})
.await
.is_err()
{
break;
}
}