Completion complete - #121
Conversation
Signed-off-by: cafalchio <mcafalchio@gmail.com>
Signed-off-by: cafalchio <mcafalchio@gmail.com>
Signed-off-by: Matheus <mcafalchio@gmail.com>
c424ce4 to
a34675f
Compare
lucarlig
left a comment
There was a problem hiding this comment.
Requesting changes: completion routing uses the wrong table, rewrites the wrong field, and is not advertised through discovery; please also enable a positive dataplane-only test.
| let Some(downstream_name) = (match &request.r#ref { | ||
| Reference::Prompt(_) => request.r#ref.as_prompt_name(), | ||
| Reference::Resource(_) => request.r#ref.as_resource_uri(), | ||
| _ => None, | ||
| }) else { | ||
| return Err(ErrorData { | ||
| code: ErrorCode::INVALID_PARAMS, | ||
| message: "Routing problem... completion not found".into(), | ||
| data: None, | ||
| }); | ||
| }; | ||
|
|
||
| let Some(route) = virtual_host.tools.get(downstream_name) else { | ||
| return Err(ErrorData { | ||
| code: ErrorCode::INVALID_PARAMS, | ||
| message: "Routing problem... tool not found".into(), | ||
| data: None, | ||
| }); | ||
| }; |
There was a problem hiding this comment.
Completion references are keyed in the prompt/resource routing tables, so looking them up in tools makes every valid completion return tool not found.
| let Some(downstream_name) = (match &request.r#ref { | |
| Reference::Prompt(_) => request.r#ref.as_prompt_name(), | |
| Reference::Resource(_) => request.r#ref.as_resource_uri(), | |
| _ => None, | |
| }) else { | |
| return Err(ErrorData { | |
| code: ErrorCode::INVALID_PARAMS, | |
| message: "Routing problem... completion not found".into(), | |
| data: None, | |
| }); | |
| }; | |
| let Some(route) = virtual_host.tools.get(downstream_name) else { | |
| return Err(ErrorData { | |
| code: ErrorCode::INVALID_PARAMS, | |
| message: "Routing problem... tool not found".into(), | |
| data: None, | |
| }); | |
| }; | |
| let route = match &request.r#ref { | |
| Reference::Prompt(prompt) => virtual_host.prompts.get(&prompt.name), | |
| Reference::Resource(resource) => virtual_host | |
| .resource_templates | |
| .get(&resource.uri) | |
| .or_else(|| virtual_host.resources.get(&resource.uri)), | |
| _ => None, | |
| }; | |
| let Some(route) = route else { | |
| return Err(ErrorData { | |
| code: ErrorCode::INVALID_PARAMS, | |
| message: "Routing problem... completion not found".into(), | |
| data: None, | |
| }); | |
| }; |
| let mut backend_service = connect_backend_for_request(mcp_service, &backend_name, backend, &cx).await?; | ||
|
|
||
| let mut routed_request = request; | ||
| routed_request.argument.name = completion_name; |
There was a problem hiding this comment.
argument.name is the parameter being completed, so replacing it with the backend identifier leaves the namespaced ref unchanged and makes the backend reject the request.
| routed_request.argument.name = completion_name; | |
| match &mut routed_request.r#ref { | |
| Reference::Prompt(prompt) => prompt.name = completion_name, | |
| Reference::Resource(resource) => resource.uri = completion_name, | |
| _ => {}, | |
| } |
| use super::McpService; | ||
|
|
||
| #[allow(clippy::unused_async)] | ||
| pub(super) async fn complete( |
There was a problem hiding this comment.
server/discover currently advertises no completions capability, so capability-aware clients will never invoke this handler.
Added support for completions.
Conformance test is passing.
Completion tests are still marked are ignored as they are dependent on list_prompt and list_resources.