Commit Graph
6 Commits
Author SHA1 Message Date
m1saka ecdf0c44d1 Fix upstream 400: flatten multi-part content arrays and sanitize invalid tool_calls
build / build (push) Successful in 2m31s
The Zhanlu upstream gateway returns HTTP 400 (请求消息格式错误) for two
message-structure issues that AI coding tools like MiMoCode produce:

1. Multi-part content arrays — OpenAI SDKs send content as
   [{type:"text",text:"…"}] arrays; the gateway only accepts string
   content. normalizeMessages now flattens text-only arrays into a
   concatenated string (non-text parts like images are preserved).

2. Invalid tool_calls — when a tool call fails, MiMoCode emits
   {name:"invalid", arguments:{"tool":"task","error":"…"}}
   placeholders. The gateway rejects function names not in the tools list
   and non-object arguments (e.g. "-1"). normalizeMessages now
   sanitizes these in place: the real tool name is extracted from the
   arguments' "tool" field (falling back to an arbitrary declared
   tool), and non-JSON-object arguments are replaced with "{}". No
   messages or tool results are removed, preserving the full
   conversation context including error feedback.

Verified with the exact error.md request: 0/10 400 errors after fix
(vs 10/10 before). Model returns valid streaming responses with task
tool calls.
2026-08-23 22:16:32 +08:00
m1saka f988c47fec Fix silent data loss in function_call arguments/output non-string JSON parsing
build / build (push) Successful in 2m29s
responsesInputToMessages unmarshaled function_call.arguments and
function_call_output.output as bare strings, silently dropping the
value when it arrived as an object or content-parts array. This
caused the model to lose tool-call context in multi-turn
conversations, increasing the likelihood of malformed tool-call JSON.

Add rawJSONToString (re-encodes non-string values as JSON strings)
and outputToString (extracts text from content-parts arrays, re-encodes
other non-string values). Add 3 regression tests covering object
arguments, array output, and object output.
2026-08-23 14:15:01 +08:00
m1saka b9a3f8d5cd Mirror Zhanlu client: GLM tool_stream, shared v4 UUID request id, drop chat state:ERROR
build / build (push) Successful in 2m26s
2026-08-21 14:27:37 +08:00
m1saka 2517b4f730 Add OpenAI Responses API (/v1/responses) endpoint
Translate Responses API requests (input→messages, instructions→system,
max_output_tokens→max_tokens, text.format→response_format, flat tools→nested
{function:{…}}) to upstream chat/completions, then convert responses back to
Responses format (streaming SSE event lifecycle + non-streaming JSON).

Verified against OpenAI migration guide and Python SDK Response model:
- Echo back required fields parallel_tool_calls/tool_choice/tools
- Include content:[] in reasoning items, logprobs:[] in output_text parts
- Support function_call/function_call_output multi-turn input items
- Map usage fields prompt_tokens→input_tokens, completion_tokens→output_tokens
2026-08-20 10:02:11 +08:00
m1saka 7d8a5b6f74 Update proxy to Zhanlu v1.4.2 provider flow
The 1.4.2 extension replaced the old signed/encrypted chat gateway with an
OpenAI-compatible aigateway. Align the proxy with the new flow:

- Use ecloud.10086.cn login/model base URLs, zhanlu_ide plugin headers and
  v1.4.2 plugin version
- Provision the model API key via SM2-signed get-or-create after v1/login
  profile fetch; store api_key/model_base_url/email in credentials
- Chat via Bearer apiKey against {modelBaseUrl}/chat/completions with plain
  OpenAI SSE passthrough; fetch /v1/models from the gateway model-info endpoint
- Force HTTP/1.1 upstream (gateway drops HTTP/2 ALPN negotiation with EOF)
- Drop obsolete AES body encryption, model name mapping and vscode headers
2026-08-05 14:55:28 +08:00
M1saka d4dd3a0f1b Initial zhanlu OpenAI proxy
build / build (push) Successful in 53s
2026-07-08 09:13:45 +08:00