mirror of
https://github.com/katanemo/plano.git
synced 2026-06-08 14:55:14 +02:00
fix(claude-cli): keep upstream path as /v1/messages for ClaudeCli
target_endpoint_for_provider was rewriting the upstream path to /v1/chat/completions for any provider that wasn't Anthropic/Vercel, which made Plano POST /v1/chat/completions to the brightstaff bridge. The bridge only accepts POST /v1/messages, so it returned a plain "not found" 404 to the client. Treat ClaudeCli the same as Anthropic for path selection (and force /v1/messages even when the client framed the request as OpenAI Chat Completions or Responses, since the bridge always speaks Anthropic Messages on the wire).
This commit is contained in:
parent
9fdfeb7cbf
commit
fc0ccfb416
1 changed files with 40 additions and 1 deletions
|
|
@ -175,7 +175,10 @@ impl SupportedAPIsFromClient {
|
|||
match self {
|
||||
SupportedAPIsFromClient::AnthropicMessagesAPI(AnthropicApi::Messages) => {
|
||||
match provider_id {
|
||||
ProviderId::Anthropic | ProviderId::Vercel => {
|
||||
// ClaudeCli speaks Anthropic Messages on the wire (the
|
||||
// brightstaff bridge only accepts `POST /v1/messages`),
|
||||
// so keep the path as-is just like the real Anthropic.
|
||||
ProviderId::Anthropic | ProviderId::Vercel | ProviderId::ClaudeCli => {
|
||||
build_endpoint("/v1", "/messages")
|
||||
}
|
||||
ProviderId::AmazonBedrock => {
|
||||
|
|
@ -198,11 +201,18 @@ impl SupportedAPIsFromClient {
|
|||
| ProviderId::XAI
|
||||
| ProviderId::ChatGPT
|
||||
| ProviderId::Vercel => route_by_provider("/responses"),
|
||||
// ClaudeCli: bridge only accepts Anthropic Messages.
|
||||
ProviderId::ClaudeCli => build_endpoint("/v1", "/messages"),
|
||||
// All other providers: translate to /chat/completions
|
||||
_ => route_by_provider("/chat/completions"),
|
||||
}
|
||||
}
|
||||
SupportedAPIsFromClient::OpenAIChatCompletions(_) => {
|
||||
// ClaudeCli: bridge only accepts Anthropic Messages, regardless
|
||||
// of how the client framed the request.
|
||||
if matches!(provider_id, ProviderId::ClaudeCli) {
|
||||
return build_endpoint("/v1", "/messages");
|
||||
}
|
||||
// For Chat Completions API, use the standard chat/completions path
|
||||
route_by_provider("/chat/completions")
|
||||
}
|
||||
|
|
@ -633,6 +643,35 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
/// The brightstaff `claude-cli` bridge only accepts `POST /v1/messages`.
|
||||
/// Make sure that no matter how a client framed the request, the upstream
|
||||
/// path stays `/v1/messages`.
|
||||
#[test]
|
||||
fn test_claude_cli_endpoint_always_v1_messages() {
|
||||
for client_api in [
|
||||
SupportedAPIsFromClient::AnthropicMessagesAPI(AnthropicApi::Messages),
|
||||
SupportedAPIsFromClient::OpenAIChatCompletions(OpenAIApi::ChatCompletions),
|
||||
SupportedAPIsFromClient::OpenAIResponsesAPI(OpenAIApi::Responses),
|
||||
] {
|
||||
for request_path in ["/v1/messages", "/v1/chat/completions", "/v1/responses"] {
|
||||
assert_eq!(
|
||||
client_api.target_endpoint_for_provider(
|
||||
&ProviderId::ClaudeCli,
|
||||
request_path,
|
||||
"claude-cli/sonnet",
|
||||
false,
|
||||
None,
|
||||
false
|
||||
),
|
||||
"/v1/messages",
|
||||
"client_api={:?} request_path={} should map to /v1/messages",
|
||||
client_api,
|
||||
request_path,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_non_v1_request_paths() {
|
||||
let api = SupportedAPIsFromClient::OpenAIChatCompletions(OpenAIApi::ChatCompletions);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue