mslxdff 0.1.119 → 0.1.120

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mslxdff",
3
- "version": "0.1.119",
3
+ "version": "0.1.120",
4
4
  "description": "测试项目,请勿使用。",
5
5
  "type": "module",
6
6
  "bin": {
@@ -100,11 +100,10 @@ export function createChatService({
100
100
  // (局部 MSLXDFF_WORKBUDDY_SDK,未设则继承全局 MSLXDFF_UPSTREAM_ENGINE)回退原生 transport;
101
101
  // 不可用(Node16/未安装)自动回退并告警一次。上层轮换/刷新/reshape 全链复用。
102
102
  // Note: 为什么默认 SDK、翻译层代价与回退语义 — 见 .agents/notes/implemented/feature/2026-09-12-workbuddy-sdk-channel.md
103
- // workbuddy 缺省 native transport(legacy):上游对 DeepSeek 有非标字段要求
104
- // (thinking 注入 / reasoning_content 回填,见 payload.js),AI SDK 序列化层 providerOptions
105
- // 白名单无法承载这些字段——v0.1.111~118 的 SDK 缺省即 tool 校验 400 的温床。
106
- // 显式 MSLXDFF_WORKBUDDY_SDK=sdk(或全局 MSLXDFF_UPSTREAM_ENGINE=sdk)仍可切回 SDK 通道。
107
- const engineMode = resolveEngineMode(process.env, "MSLXDFF_WORKBUDDY_SDK", "legacy");
103
+ // 上游非标字段(thinking / reasoning_effort / reasoning_content / tool_choice 字符串)不依赖 SDK 白名单:
104
+ // payload.js 前置语义改写 + AI SDK providerOptions 透传(非白名单 key 原样 spread 进 body,2.0.41 实测)。
105
+ // 序列化/流式/错误映射仍全部交 AI SDK;原生 transport 仅作 SDK 不可用时的回退。v0.1.120 实测见 .scratch/probe-sdk-body.mjs。
106
+ const engineMode = resolveEngineMode(process.env, "MSLXDFF_WORKBUDDY_SDK", "sdk");
108
107
  let sdkFallbackLogged = false;
109
108
  async function fetchOnce(url, body, key, auth) {
110
109
  const payload = rewriteWorkbuddyPayload(body);
@@ -1,7 +1,6 @@
1
1
  // 引擎模式解析(纯函数,零依赖):缺省 sdk,legacy/关闭词回退原实现。
2
2
  // 供应商级开关未设置时继承全局总闸,使 MSLXDFF_UPSTREAM_ENGINE=legacy 成为一键熔断。
3
- // defaultMode:调用方可自定缺省(workbuddy 因上游非标字段 thinking/reasoning_content
4
- // 无法经 AI SDK 序列化层注入,缺省 legacy);显式 env(供应商级或全局)始终优先。
3
+ // defaultMode:调用方可自定缺省(一般无需传,保持 sdk);显式 env(供应商级或全局)始终优先。
5
4
  // 供 upstream-engine/index.js(opencode 上游)与 providers/workbuddy/chat.js 共用。
6
5
  // 见 docs/adr/0017。
7
6
  const ENGINE_OFF_WORDS = new Set(["0", "off", "false", "no", "disable", "disabled"]);
@@ -52,8 +52,9 @@ export function toModelPrompt(messages) {
52
52
  const parts = [];
53
53
  const text = textOf(m.content);
54
54
  if (text) parts.push({ type: "text", text });
55
- // 带加密态的 reasoning items(responses 通道思考跨轮):AI SDK 会转成上游要的 encrypted reasoning item。
56
55
  // 无加密态时才退回纯文本 reasoning(chat 通道的 reasoning_content)。
56
+ // 空串是 payload 回填的有意标记(requiresReasoningContentOnAssistantMessages):所有 assistant
57
+ // 必须带该字段——AI SDK 以 length>0 判定是否输出,故用 " " 占位而非 ""。
57
58
  const items = Array.isArray(m.reasoning_items) ? m.reasoning_items : [];
58
59
  let pushedEncrypted = false;
59
60
  for (const r of items) {
@@ -66,7 +67,9 @@ export function toModelPrompt(messages) {
66
67
  });
67
68
  pushedEncrypted = true;
68
69
  }
69
- if (!pushedEncrypted && m.reasoning_content) parts.push({ type: "reasoning", text: String(m.reasoning_content) });
70
+ const rc = typeof m.reasoning_content === "string" ? m.reasoning_content
71
+ : (typeof m.reasoning === "string" ? m.reasoning : null);
72
+ if (!pushedEncrypted && rc !== null) parts.push({ type: "reasoning", text: rc || " " });
70
73
  for (const tc of Array.isArray(m.tool_calls) ? m.tool_calls : []) {
71
74
  if (!tc || typeof tc !== "object") continue;
72
75
  parts.push({