@ynhcj/xiaoyi-channel 0.0.168-beta → 0.0.170-beta

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/dist/src/bot.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { getXYRuntime } from "./runtime.js";
2
2
  import { createXYReplyDispatcher } from "./reply-dispatcher.js";
3
- import { parseA2AMessage, extractTextFromParts, extractFileParts, extractPushId, extractDeviceType, extractTriggerData, extractRunCrossTaskContext } from "./parser.js";
3
+ import { parseA2AMessage, extractTextFromParts, extractFileParts, extractPushId, extractDeviceType, extractModelName, extractTriggerData, extractRunCrossTaskContext } from "./parser.js";
4
4
  import { downloadFilesFromParts } from "./file-download.js";
5
5
  import { resolveXYConfig } from "./config.js";
6
6
  import { sendStatusUpdate, sendClearContextResponse, sendTasksCancelResponse, sendA2AResponse } from "./formatter.js";
@@ -32,6 +32,7 @@ export async function handleXYMessage(params) {
32
32
  try {
33
33
  // Check for special messages BEFORE parsing (these have different param structures)
34
34
  const messageMethod = message.method;
35
+ logger.log(`[BOT] Received A2A message: ${JSON.stringify(message)}`);
35
36
  // Handle clearContext messages (sessionId at top level, no params)
36
37
  if (messageMethod === "clearContext" || messageMethod === "clear_context") {
37
38
  const sessionId = message.sessionId ?? message.params?.sessionId;
@@ -138,6 +139,11 @@ export async function handleXYMessage(params) {
138
139
  if (deviceType) {
139
140
  log.log(`[BOT] Extracted deviceType: ${deviceType}`);
140
141
  }
142
+ // Extract modelName if present (used by provider.ts to override model.id)
143
+ const modelName = extractModelName(parsed.parts);
144
+ if (modelName) {
145
+ log.log(`[BOT] Extracted modelName: ${modelName}`);
146
+ }
141
147
  const runCrossTaskContext = extractRunCrossTaskContext(parsed.parts);
142
148
  // Resolve configuration (needed for status updates)
143
149
  const config = resolveXYConfig(cfg);
@@ -164,6 +170,7 @@ export async function handleXYMessage(params) {
164
170
  messageId: parsed.messageId,
165
171
  agentId: route.accountId,
166
172
  deviceType,
173
+ modelName,
167
174
  runCrossTaskContext: runCrossTaskContext ?? undefined,
168
175
  });
169
176
  // 🔑 发送初始状态更新
@@ -311,6 +318,7 @@ export async function handleXYMessage(params) {
311
318
  messageId: parsed.messageId,
312
319
  agentId: route.accountId,
313
320
  deviceType,
321
+ modelName,
314
322
  runCrossTaskContext: runCrossTaskContext ?? undefined,
315
323
  };
316
324
  log.log(`[BOT-DISPATCH] withReplyDispatcher starting, sessionKey=${route.sessionKey}`);
@@ -50,6 +50,12 @@ export declare function extractPushId(parts: A2AMessagePart[]): string | null;
50
50
  * (same level as push_id).
51
51
  */
52
52
  export declare function extractDeviceType(parts: A2AMessagePart[]): string | null;
53
+ /**
54
+ * Extract modelName from message parts.
55
+ * Looks for modelName in data parts under variables.memoryVariables.modelName
56
+ * (same level as systemVariables).
57
+ */
58
+ export declare function extractModelName(parts: A2AMessagePart[]): string | null;
53
59
  /**
54
60
  * Extract Trigger event data from message parts.
55
61
  * Looks for Trigger events with pushDataId in data parts.
@@ -143,6 +143,22 @@ export function extractDeviceType(parts) {
143
143
  }
144
144
  return null;
145
145
  }
146
+ /**
147
+ * Extract modelName from message parts.
148
+ * Looks for modelName in data parts under variables.memoryVariables.modelName
149
+ * (same level as systemVariables).
150
+ */
151
+ export function extractModelName(parts) {
152
+ for (const part of parts) {
153
+ if (part.kind === "data" && part.data) {
154
+ const modelName = part.data.variables?.memoryVariables?.modelName;
155
+ if (modelName && typeof modelName === "string" && modelName.trim() !== "" && modelName.toLowerCase() !== "none") {
156
+ return modelName;
157
+ }
158
+ }
159
+ }
160
+ return null;
161
+ }
146
162
  /**
147
163
  * Extract Trigger event data from message parts.
148
164
  * Looks for Trigger events with pushDataId in data parts.
@@ -587,6 +587,12 @@ export const xiaoyiProvider = {
587
587
  }
588
588
  }
589
589
  }
590
+ // ── Override model.id if A2A message specified modelName ──
591
+ const modelNameOverride = getCurrentSessionContext()?.modelName;
592
+ if (modelNameOverride && modelNameOverride.trim() !== "" && modelNameOverride.toLowerCase() !== "none") {
593
+ logger.log(`[xiaoyiprovider] overriding model.id: ${model.id} → ${modelNameOverride}`);
594
+ model = { ...model, id: modelNameOverride };
595
+ }
590
596
  // ── Retry-capable streaming ──────────────────────────────
591
597
  const cronJob = isCronTriggered(context.messages);
592
598
  if (cronJob)
@@ -62,7 +62,9 @@ export function createCheckPluginPrivilegeTool(ctx) {
62
62
  "SendShortMessage(发送短信), " +
63
63
  "StartCall(打电话)。" +
64
64
  "【多次调用】如果用户的定时任务指令中涉及多个端侧工具,则依次分别调用此工具检查每个工具的权限。如果调用超时失败,最多重试一次。" +
65
- "【回复约束】如果工具返回没有授权或其他报错,只需要完整描述没有授权或其他报错内容即可,不需要主动给用户提供解决方案。",
65
+ "【回复约束】如果工具返回没有授权或其他报错,只需要完整描述没有授权或其他报错内容即可,不需要主动给用户提供解决方案。" +
66
+ "【使用约束1】只要是创建定时任务且涉及端插件的使用,则必须调用此工具检查权限" +
67
+ "【使用约束2】如果是定时任务执行过程中,禁止调用此工具,此工具仅在创建定时任务时按需调用",
66
68
  parameters: {
67
69
  type: "object",
68
70
  properties: {
@@ -8,6 +8,9 @@ export interface SessionContext {
8
8
  messageId: string;
9
9
  agentId: string;
10
10
  deviceType?: string;
11
+ /** Model name extracted from A2A user variables (variables.memoryVariables.modelName).
12
+ * When set, provider.ts replaces model.id in the OpenAI request body. */
13
+ modelName?: string;
11
14
  runCrossTaskContext?: RunCrossTaskContext;
12
15
  /** When true, this context was created for a cron/scheduled task execution.
13
16
  * Tools should use the push channel instead of WebSocket sendCommand. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ynhcj/xiaoyi-channel",
3
- "version": "0.0.168-beta",
3
+ "version": "0.0.170-beta",
4
4
  "description": "OpenClaw Xiaoyi Channel plugin - Xiaoyi A2A protocol integration",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",