@agent-proxy/zcode 0.11.3 → 0.12.1

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.
@@ -1,3 +1,4 @@
1
+ import type { ClientProtocol } from "@agent-proxy/plugin-api";
1
2
  import { type ZcodeToolMap } from "./wire.ts";
2
3
  import { type ZcodeGatewayCall } from "./vision.ts";
3
4
  /** 网关代执行工具(analyze_image)的驱动层钩子:执行调用并按需发起上游续跑。 */
@@ -24,4 +25,11 @@ export interface ZcodeResponseOptions {
24
25
  /** 声明了网关代执行工具时必须提供;否则吸收到相关调用会让响应失败。 */
25
26
  gatewayTools?: ZcodeGatewayToolsHook;
26
27
  }
28
+ /**
29
+ * 四种客户端协议的统一入口:zcode 始终以帧级驱动器合成 Responses 事件(多腿、
30
+ * server tool 折叠与 thinking 信封都在该层),chat-completions / anthropic / gemini
31
+ * 客户端由 @agent-proxy/llm-bridge 从同一事件流渲染,语义与 Responses 输出一致。
32
+ */
33
+ /** to 为路由端点(客户端入口)协议:上游 anthropic → to。 */
34
+ export declare function createZcodeClientResponse(to: ClientProtocol, upstream: Response, options: ZcodeResponseOptions): Promise<Response>;
27
35
  export declare function createZcodeResponse(upstream: Response, options: ZcodeResponseOptions): Promise<Response>;
package/dist/response.js CHANGED
@@ -1,4 +1,4 @@
1
- import { parseAnthropicStream } from "@agent-proxy/llm-bridge";
1
+ import { createClientResponse } from "@agent-proxy/llm-bridge";
2
2
  import { encodeZcodeThinking, isZcodeRecord } from "./wire.js";
3
3
  import { gatewayToolCallNarration, gatewayToolResultNarration } from "./vision.js";
4
4
  /** z.ai 的服务端搜索按 web_search_prime/search_query 形状返回 query;兼容 Anthropic 标准的 query。 */
@@ -108,29 +108,74 @@ async function* readFrames(reader) {
108
108
  }
109
109
  }
110
110
  }
111
- /** 库只保存一个工具上下文;按帧补入对应块,使交错的块仍通过库正确归一化。 */
111
+ /**
112
+ * anthropic 帧级归一化(工具事件抽取)。库的 parseAnthropicStream 只保存一个工具
113
+ * 上下文,交错块会串扰;这里直接从帧结构提取 tool_call_start/delta 事件,不依赖
114
+ * npm llm-bridge(桥接包不再转发库原语)。
115
+ */
112
116
  async function normalize(frame, block) {
113
- const frames = [];
114
- if (block?.source.type === "tool_use" && (frame.type === "content_block_delta" || frame.type === "content_block_stop")) {
115
- frames.push({ type: "content_block_start", index: frame.index, content_block: block.source });
117
+ const events = [];
118
+ if (frame.type === "message_start") {
119
+ // 驱动器以事件存在性校验 message_start 的可归一化;保持该合同。
120
+ return [{ type: "message_start" }];
116
121
  }
117
- frames.push(frame);
118
- const stream = new ReadableStream({
119
- start(controller) {
120
- controller.enqueue(encoder.encode(frames.map((value) => `event: ${value.type}\ndata: ${JSON.stringify(value)}\n\n`).join("")));
121
- controller.close();
122
- },
123
- });
124
- const result = [];
125
- let skipContext = frames.length > 1;
126
- for await (const value of parseAnthropicStream(stream)) {
127
- if (skipContext) {
128
- skipContext = false;
129
- continue;
122
+ if (frame.type === "error") {
123
+ // 错误帧透传原始字段(request_id 等),并把 anthropic 的 type 映射为 code
124
+ //(驱动器按 code 生成 failed 终态的错误标识)。
125
+ const original = record(frame.error, "error");
126
+ return [{ type: "error", error: { ...original, ...(original.code === undefined && typeof original.type === "string" ? { code: original.type } : {}) } }];
127
+ }
128
+ if (frame.type === "content_block_start") {
129
+ const source = record(frame.content_block, "content_block");
130
+ if (source.type === "tool_use") {
131
+ events.push({ type: "tool_call_start", tool_call: { id: source.id ?? "", name: source.name ?? "" } });
132
+ }
133
+ return events;
134
+ }
135
+ if (frame.type === "content_block_delta") {
136
+ const delta = record(frame.delta, "delta");
137
+ if (block?.source.type === "tool_use") {
138
+ if (delta.type === "input_json_delta" && typeof delta.partial_json === "string") {
139
+ events.push({ type: "tool_call_delta", tool_call: { id: block.source.id ?? "", arguments_delta: delta.partial_json } });
140
+ }
141
+ return events;
142
+ }
143
+ // 文本/思考增量保持 content_delta 事件形状,驱动器按块类型取对应字段。
144
+ if (delta.type === "text_delta" && typeof delta.text === "string") {
145
+ events.push({ type: "content_delta", delta: { text: delta.text } });
146
+ }
147
+ else if (delta.type === "thinking_delta" && typeof delta.thinking === "string") {
148
+ events.push({ type: "content_delta", delta: { thinking: delta.thinking } });
130
149
  }
131
- result.push(value);
150
+ return events;
132
151
  }
133
- return result;
152
+ if (frame.type === "content_block_stop" && block?.source.type === "tool_use") {
153
+ events.push({ type: "tool_call_end", tool_call: { id: block.source.id ?? "" } });
154
+ return events;
155
+ }
156
+ return events;
157
+ }
158
+ /**
159
+ * 四种客户端协议的统一入口:zcode 始终以帧级驱动器合成 Responses 事件(多腿、
160
+ * server tool 折叠与 thinking 信封都在该层),chat-completions / anthropic / gemini
161
+ * 客户端由 @agent-proxy/llm-bridge 从同一事件流渲染,语义与 Responses 输出一致。
162
+ */
163
+ /** to 为路由端点(客户端入口)协议:上游 anthropic → to。 */
164
+ export async function createZcodeClientResponse(to, upstream, options) {
165
+ const responsesOutput = await createZcodeResponse(upstream, options);
166
+ if (to === "responses")
167
+ return responsesOutput;
168
+ const result = await createClientResponse(to, responsesOutput, {
169
+ upstreamProtocol: "responses",
170
+ model: options.model,
171
+ stream: options.stream,
172
+ signal: options.signal,
173
+ abort: options.abort,
174
+ onChunk: options.onChunk,
175
+ sanitizeError: options.sanitizeError,
176
+ // Responses 输出已由 zcode 驱动器还原原始工具名,无需再做身份映射。
177
+ });
178
+ return result.response;
134
179
  }
135
180
  export async function createZcodeResponse(upstream, options) {
136
181
  let reader = upstream.body?.getReader();
package/dist/wire.d.ts CHANGED
@@ -1,8 +1,6 @@
1
+ import type { ToolIdentity } from "@agent-proxy/llm-bridge";
1
2
  /** ZCode 协议共享类型;元数据不包含授权凭据。 */
2
- export interface ZcodeToolDefinition {
3
- name: string;
4
- custom: boolean;
5
- namespace?: string;
3
+ export interface ZcodeToolDefinition extends ToolIdentity {
6
4
  /** 网关代执行标记:该工具由网关在上游续跑中执行并吸收,不回传客户端。 */
7
5
  gateway?: "analyze_image";
8
6
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-proxy/zcode",
3
- "version": "0.11.3",
3
+ "version": "0.12.1",
4
4
  "description": "Agent Proxy zcode 插件;保留基线转换行为。",
5
5
  "type": "module",
6
6
  "exports": {
@@ -34,11 +34,11 @@
34
34
  "url": "git+https://github.com/aceHubert/codex-cliproxy-gateway.git"
35
35
  },
36
36
  "devDependencies": {
37
- "@agent-proxy/models": "0.11.1"
37
+ "@agent-proxy/models": "0.12.1"
38
38
  },
39
39
  "dependencies": {
40
- "@agent-proxy/llm-bridge": "0.11.1",
41
- "@agent-proxy/plugin-api": "0.11.1"
40
+ "@agent-proxy/llm-bridge": "0.12.1",
41
+ "@agent-proxy/plugin-api": "0.12.1"
42
42
  },
43
- "gitHead": "37235103f935530274005fa391dba83abe522888"
43
+ "gitHead": "50a77d2e514a6237b097361fd4eb794acaa582d5"
44
44
  }