feat: add declarative Feature chat invocations and typed composers

This commit is contained in:
2026-10-05 18:44:41 +09:00
parent cc97987482
commit f7783b3d2a
69 changed files with 10065 additions and 657 deletions
+48 -4
View File
@@ -735,6 +735,8 @@ pub struct WorkerCompletionsRequest {
pub kind: protocol::CompletionKind,
#[serde(default)]
pub prefix: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub context: Option<protocol::CompletionContext>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
@@ -3333,10 +3335,12 @@ impl WorkspaceWorkerRuntime for EmbeddedWorkerRuntime {
)],
};
};
match self
.runtime
.worker_completions(&worker_ref, request.kind, &request.prefix)
{
match self.runtime.worker_completions(
&worker_ref,
request.kind,
&request.prefix,
request.context.as_ref(),
) {
Ok(entries) => WorkerCompletionsResult {
worker: RuntimeWorkerRef::new(self.runtime_id.clone(), worker_id.to_string()),
kind: request.kind,
@@ -5415,6 +5419,7 @@ impl WorkspaceWorkerRuntime for RemoteWorkerRuntime {
let request = runtime_api::CompletionRequest {
kind: request.kind,
prefix: request.prefix,
context: request.context,
};
let failure_kind = request.kind;
let failure_prefix = request.prefix.clone();
@@ -6711,6 +6716,45 @@ mod tests {
}
}
#[test]
fn feature_invocation_and_completion_context_survive_runtime_contract() {
let segments = vec![
protocol::Segment::FeatureInvoke {
invocation: protocol::FeatureInvocation {
invocation_id: "stable-request".into(),
identity: protocol::FeatureInvocationIdentity("builtin:test/prepare".into()),
name: "prepare".into(),
arguments: vec![protocol::InvocationArgumentValue {
name: "path".into(),
value: protocol::InvocationValue::String("資料/a b".into()),
}],
},
},
protocol::Segment::text(" subsequent prose"),
];
let input = EmbeddedWorkerInput {
kind: EmbeddedWorkerInputKind::User,
content: protocol::Segment::flatten_to_text(&segments),
submission_request_id: Some("submit-request".into()),
segments: Some(segments),
};
let wire: runtime_api::WorkerInput = runtime_contract_convert(input.clone()).unwrap();
let restored: EmbeddedWorkerInput = runtime_contract_convert(wire).unwrap();
assert_eq!(restored, input);
let request = WorkerCompletionsRequest {
kind: protocol::CompletionKind::FeatureArgument,
prefix: "資料/".into(),
context: Some(protocol::CompletionContext {
invocation: protocol::FeatureInvocationIdentity("builtin:test/prepare".into()),
argument: Some("path".into()),
}),
};
let wire: runtime_api::CompletionRequest =
runtime_contract_convert(request.clone()).unwrap();
let restored: WorkerCompletionsRequest = runtime_contract_convert(wire).unwrap();
assert_eq!(restored, request);
}
#[test]
fn remote_profile_source_uses_workspace_config_archive_reference() {
let request = embedded_spawn_request();
+9 -25
View File
@@ -6304,23 +6304,11 @@ fn worker_input_request_from_api(
)));
}
};
let segments = request
.segments
.map(|segments| {
segments
.into_iter()
.map(|segment| {
serde_json::from_value::<Segment>(segment)
.map_err(|error| invalid_contract_value("Worker input segment", error))
})
.collect::<Result<Vec<_>>>()
})
.transpose()?;
Ok(WorkerInputRequest {
kind,
content: request.content,
submission_request_id: None,
segments,
segments: request.segments,
})
}
@@ -6339,9 +6327,9 @@ fn worker_completions_request_from_api(
request: server_api::RuntimeWorkerCompletionsRequest,
) -> Result<WorkerCompletionsRequest> {
Ok(WorkerCompletionsRequest {
kind: serde_json::from_value(request.kind)
.map_err(|error| invalid_contract_value("Worker completion kind", error))?,
kind: request.kind,
prefix: request.prefix,
context: request.context,
})
}
@@ -6437,17 +6425,9 @@ fn worker_completions_result_to_api(
Ok(server_api::RuntimeWorkerCompletionsResult {
runtime_id: result.worker.runtime_id,
worker_id: result.worker.worker_id,
kind: serde_json::to_value(result.kind)
.map_err(|error| invalid_contract_value("Worker completion kind", error))?,
kind: result.kind,
prefix: result.prefix,
entries: result
.entries
.into_iter()
.map(|entry| {
serde_json::to_value(entry)
.map_err(|error| invalid_contract_value("Worker completion entry", error))
})
.collect::<Result<Vec<_>>>()?,
entries: result.entries,
diagnostics: result.diagnostics.into_iter().map(Into::into).collect(),
})
}
@@ -54822,6 +54802,8 @@ mod tests {
serde_json::to_string(&protocol::Method::ListCompletions {
kind: protocol::CompletionKind::File,
prefix: String::new(),
request_id: None,
context: None,
})
.unwrap()
.into(),
@@ -55301,6 +55283,8 @@ mod tests {
method: protocol::Method::ListCompletions {
kind: protocol::CompletionKind::File,
prefix: String::new(),
request_id: None,
context: None,
},
},
),