@wagemule/daemon 0.1.5 → 0.1.7

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/main.cjs CHANGED
@@ -1802,8 +1802,10 @@ var KimiAdapter = class {
1802
1802
  const wmDir = import_node_path.default.join(input.cwd, ".wm");
1803
1803
  await (0, import_promises.mkdir)(wmDir, { recursive: true });
1804
1804
  const agentFile = import_node_path.default.join(wmDir, "kimi-agent.yaml");
1805
+ const systemPromptFile = import_node_path.default.join(wmDir, "kimi-system.md");
1805
1806
  const mcpConfigFile = import_node_path.default.join(wmDir, "kimi-mcp.json");
1806
- await (0, import_promises.writeFile)(agentFile, kimiAgentYaml(input.systemPrompt), "utf8");
1807
+ await (0, import_promises.writeFile)(systemPromptFile, input.systemPrompt, "utf8");
1808
+ await (0, import_promises.writeFile)(agentFile, kimiAgentYaml(), "utf8");
1807
1809
  await (0, import_promises.writeFile)(mcpConfigFile, JSON.stringify({ mcpServers: {} }, null, 2), "utf8");
1808
1810
  const args = [
1809
1811
  "--wire",
@@ -1927,12 +1929,13 @@ var KimiAdapter = class {
1927
1929
  }
1928
1930
  }
1929
1931
  };
1930
- function kimiAgentYaml(systemPrompt) {
1932
+ function kimiAgentYaml() {
1931
1933
  return [
1932
- "name: wm",
1933
- "description: Wage Mule platform agent",
1934
- "instructions: |-",
1935
- ...systemPrompt.split(/\r?\n/).map((line) => ` ${line}`),
1934
+ "version: 1",
1935
+ "agent:",
1936
+ " extend: default",
1937
+ " name: wm",
1938
+ " system_prompt_path: ./kimi-system.md",
1936
1939
  ""
1937
1940
  ].join("\n");
1938
1941
  }
@@ -3888,7 +3891,7 @@ var import_ws = __toESM(require("ws"));
3888
3891
  // package.json
3889
3892
  var package_default = {
3890
3893
  name: "@wagemule/daemon",
3891
- version: "0.1.4",
3894
+ version: "0.1.7",
3892
3895
  private: false,
3893
3896
  description: "Wage Mule local daemon for connecting local agent runtimes to Workspace Server.",
3894
3897
  main: "./dist/main.cjs",
@@ -3910,6 +3913,7 @@ var package_default = {
3910
3913
  dev: "tsx watch src/main.ts",
3911
3914
  build: "node scripts/build.mjs",
3912
3915
  start: "node dist/main.cjs",
3916
+ prepack: "npm run build",
3913
3917
  "pack:check": "node scripts/pack-check.mjs",
3914
3918
  test: "node --import tsx src/workspace/agent-workspace.test.ts && node --import tsx src/workspace/feishu-token-writer.test.ts && node --import tsx src/agent-manager/workspace-browser.test.ts && node --import tsx src/agent-manager/agent-process-manager.memory.test.ts && node --import tsx src/agent-manager/agent-process-manager.delivery.test.ts && node --import tsx src/agent-manager/agent-process-manager.model-validation.test.ts && node --import tsx src/agent-manager/skill-scanner.test.ts && node --import tsx src/runtime/capabilities.test.ts && node --import tsx src/runtime/model-detector.test.ts && node --import tsx src/runtime/persistent-adapter.test.ts && node --import tsx src/runtime/json-rpc-stdio-client.test.ts && node --import tsx src/runtime/acp-adapter.test.ts && node --import tsx src/runtime/codex-adapter.test.ts && node --import tsx src/runtime/claude-adapter.test.ts && node --import tsx src/testing/smoke-harness.test.ts && node --import tsx src/lab/lab-store.test.ts && node --import tsx src/lab/lab-ui.test.ts && node --import tsx src/lab/interactive-lab.test.ts && node --import tsx src/main.test.ts && node --import tsx src/testing/integration.test.ts",
3915
3919
  "test:real": "node --import tsx src/testing/integration-real.test.ts",
@@ -3966,7 +3970,9 @@ var ServerConnection = class {
3966
3970
  this.log(`send skipped socket=closed msg=${summarizeDaemonMessage(msg)}`);
3967
3971
  return;
3968
3972
  }
3969
- this.log(`send ${summarizeDaemonMessage(msg)}`);
3973
+ if (shouldLogDaemonMessage(msg)) {
3974
+ this.log(`send ${summarizeDaemonMessage(msg)}`);
3975
+ }
3970
3976
  this.ws?.send(JSON.stringify(msg));
3971
3977
  }
3972
3978
  onMessage(handler) {
@@ -4055,6 +4061,9 @@ function summarizeDaemonMessage(msg) {
4055
4061
  if ("agentId" in msg) return `${base} agent=${msg.agentId}`;
4056
4062
  return base;
4057
4063
  }
4064
+ function shouldLogDaemonMessage(msg) {
4065
+ return !(msg.type === "agent:activity" && msg.detail === "assistant_delta");
4066
+ }
4058
4067
  function summarizeServerMessage(msg) {
4059
4068
  const base = `type=${msg.type}`;
4060
4069
  if ("agentId" in msg) return `${base} agent=${msg.agentId}`;
@@ -4290,15 +4299,35 @@ ${stderr}`);
4290
4299
  function parseKimiModelConfig(configText) {
4291
4300
  const ids = [];
4292
4301
  let defaultModel;
4302
+ let section;
4293
4303
  for (const rawLine of configText.split(/\r?\n/)) {
4294
4304
  const line = stripYamlComment(rawLine).trim();
4295
4305
  if (!line) continue;
4296
- const model = line.match(/^(?:model|default_model)\s*=\s*["']?([^"']+)["']?\s*$/);
4297
- if (model) {
4298
- defaultModel = model[1]?.trim();
4306
+ const table = line.match(/^\[models\.([^\]]+)]$/);
4307
+ if (table) {
4308
+ section = `models.${unquote(table[1].trim())}`;
4309
+ pushUnique(ids, section.slice("models.".length));
4310
+ continue;
4311
+ }
4312
+ const anyTable = line.match(/^\[([^\]]+)]$/);
4313
+ if (anyTable) {
4314
+ section = anyTable[1]?.trim();
4315
+ continue;
4316
+ }
4317
+ const defaultModelLine = line.match(/^default_model\s*=\s*["']?([^"']+)["']?\s*$/);
4318
+ if (defaultModelLine) {
4319
+ defaultModel = defaultModelLine[1]?.trim();
4299
4320
  pushUnique(ids, defaultModel);
4300
4321
  continue;
4301
4322
  }
4323
+ if (section?.startsWith("models.")) continue;
4324
+ const model = line.match(/^model\s*=\s*["']?([^"']+)["']?\s*$/);
4325
+ if (model) {
4326
+ const value = model[1]?.trim();
4327
+ defaultModel ??= value;
4328
+ pushUnique(ids, value);
4329
+ continue;
4330
+ }
4302
4331
  const array = line.match(/^(?:models|available_models)\s*=\s*\[(.+)\]\s*$/);
4303
4332
  if (array) {
4304
4333
  for (const part of array[1].split(",")) pushUnique(ids, unquote(part.trim()));
@@ -5036,14 +5065,7 @@ var AgentProcessManager = class {
5036
5065
  } else if (message.type === "feishu:token:clear") {
5037
5066
  await this.replyFeishuTokenClear(message.requestId, message.agentId, message.config);
5038
5067
  } else if (message.type === "feishu:delegation:start" || message.type === "feishu:delegation:update") {
5039
- this.startFeishuDelegationSchedule(message.delegation, message.config);
5040
- this.options.sendToServer({
5041
- type: "feishu:delegation:result",
5042
- requestId: message.requestId,
5043
- delegationId: message.delegation.id,
5044
- agentId: message.delegation.delegate_agent_id,
5045
- ok: true
5046
- });
5068
+ await this.replyFeishuDelegationStart(message.requestId, message.delegation, message.config);
5047
5069
  } else if (message.type === "feishu:delegation:stop") {
5048
5070
  this.stopFeishuDelegationSchedule(message.delegationId);
5049
5071
  this.options.sendToServer({
@@ -5084,8 +5106,12 @@ var AgentProcessManager = class {
5084
5106
  });
5085
5107
  if (!delegation.enabled) return;
5086
5108
  const intervalMs = Math.max(6e4, delegation.interval_seconds * 1e3);
5087
- const lookbackMinutes = Math.min(60, Math.max(10, Math.ceil(delegation.interval_seconds * 2 / 60)));
5109
+ const lookbackMinutes = feishuDelegationLookbackMinutes(delegation.interval_seconds);
5088
5110
  const timer = setInterval(() => {
5111
+ if (this.shouldSkipScheduledFeishuWake(delegation.delegate_agent_id)) {
5112
+ this.log(`feishu delegation tick skipped agent=${delegation.delegate_agent_id} delegation=${delegation.id} reason=agent_busy`);
5113
+ return;
5114
+ }
5089
5115
  const wakeMessage = {
5090
5116
  target: "feishu:delegation",
5091
5117
  message_id: `feishu-${delegation.id}-${Date.now()}`,
@@ -5120,8 +5146,37 @@ var AgentProcessManager = class {
5120
5146
  });
5121
5147
  });
5122
5148
  }, intervalMs);
5149
+ timer.unref?.();
5123
5150
  this.feishuDelegationTimers.set(delegation.id, timer);
5124
5151
  }
5152
+ async replyFeishuDelegationStart(requestId, delegation, config) {
5153
+ try {
5154
+ const feishuConfig = { ...config, feishuDelegationEnabled: true };
5155
+ await this.ensureAgentWorkspace(delegation.delegate_agent_id, feishuConfig);
5156
+ this.startFeishuDelegationSchedule(delegation, feishuConfig);
5157
+ this.options.sendToServer({
5158
+ type: "feishu:delegation:result",
5159
+ requestId,
5160
+ delegationId: delegation.id,
5161
+ agentId: delegation.delegate_agent_id,
5162
+ ok: true
5163
+ });
5164
+ } catch (error) {
5165
+ this.options.sendToServer({
5166
+ type: "feishu:delegation:result",
5167
+ requestId,
5168
+ delegationId: delegation.id,
5169
+ agentId: delegation.delegate_agent_id,
5170
+ ok: false,
5171
+ error: error instanceof Error ? error.message : "feishu delegation start failed"
5172
+ });
5173
+ }
5174
+ }
5175
+ shouldSkipScheduledFeishuWake(agentId) {
5176
+ if (this.starting.has(agentId)) return true;
5177
+ const running = this.running.get(agentId);
5178
+ return running !== void 0 && running.state !== "idle";
5179
+ }
5125
5180
  stopFeishuDelegationSchedule(delegationId) {
5126
5181
  const timer = this.feishuDelegationTimers.get(delegationId);
5127
5182
  if (timer) clearInterval(timer);
@@ -5316,7 +5371,7 @@ var AgentProcessManager = class {
5316
5371
  if (running && !config?.feishuDelegationEnabled) return { workspace: running.workspace };
5317
5372
  const idle = this.idleConfigs.get(agentId);
5318
5373
  if (idle?.workspace && !config?.feishuDelegationEnabled) return { workspace: idle.workspace };
5319
- const effectiveConfig = config ?? idle?.config;
5374
+ const effectiveConfig = this.mergeWorkspaceConfig(config ?? idle?.config, running?.config, idle?.config);
5320
5375
  if (!effectiveConfig) return { missing: true };
5321
5376
  const workspace = await createAgentWorkspace({
5322
5377
  rootDir: this.options.rootDir,
@@ -5339,6 +5394,13 @@ var AgentProcessManager = class {
5339
5394
  this.idleConfigs.set(agentId, { config: effectiveConfig, sessionId: effectiveConfig.sessionId, workspace });
5340
5395
  return { workspace };
5341
5396
  }
5397
+ mergeWorkspaceConfig(config, runningConfig, idleConfig) {
5398
+ if (!config) return config;
5399
+ if (config.feishuDelegationEnabled || runningConfig?.feishuDelegationEnabled || idleConfig?.feishuDelegationEnabled) {
5400
+ return { ...config, feishuDelegationEnabled: true };
5401
+ }
5402
+ return config;
5403
+ }
5342
5404
  async replyWorkspaceInit(requestId, agentId, config) {
5343
5405
  try {
5344
5406
  const { workspace } = await this.ensureAgentWorkspace(agentId, config);
@@ -5447,8 +5509,22 @@ var AgentProcessManager = class {
5447
5509
  [Runtime Profile Migration] Your runtime configuration has been updated. Before handling the above, re-ground yourself in the new context, then run: \`${workspace.wrapperPath} profile migration-ack --key ${migrationKey}\`` : basePrompt;
5448
5510
  const tracker = new ActivityTracker();
5449
5511
  const requestPermission = (request) => this.requestRuntimePermission(agentId, launchId, request);
5512
+ let deltaLogText = "";
5513
+ let deltaLogCount = 0;
5514
+ const flushDeltaLog = () => {
5515
+ if (!deltaLogCount) return;
5516
+ this.log(`runtime stream agent=${agentId} type=assistant_delta chunks=${deltaLogCount} text=${compact(deltaLogText)}`);
5517
+ deltaLogText = "";
5518
+ deltaLogCount = 0;
5519
+ };
5450
5520
  const onEvent = (event) => {
5451
- this.log(`runtime event agent=${agentId} type=${event.type}${event.content ? ` text=${compact(event.content)}` : ""}`);
5521
+ if (event.type === "assistant_delta") {
5522
+ if (event.content) deltaLogText += event.content;
5523
+ deltaLogCount += 1;
5524
+ } else {
5525
+ flushDeltaLog();
5526
+ this.log(`runtime event agent=${agentId} type=${event.type}${event.content ? ` text=${compact(event.content)}` : ""}`);
5527
+ }
5452
5528
  const running = this.running.get(agentId);
5453
5529
  if (running) {
5454
5530
  running.lastRuntimeEventAt = Date.now();
@@ -5557,6 +5633,7 @@ var AgentProcessManager = class {
5557
5633
  requestPermission
5558
5634
  });
5559
5635
  }
5636
+ flushDeltaLog();
5560
5637
  if (result.runtimeSessionId) {
5561
5638
  this.log(`runtime session agent=${agentId} session=${result.runtimeSessionId}`);
5562
5639
  const running = this.running.get(agentId);
@@ -6294,6 +6371,9 @@ function dedupeDeliveredMessages(messages) {
6294
6371
  }
6295
6372
  return deduped;
6296
6373
  }
6374
+ function feishuDelegationLookbackMinutes(intervalSeconds) {
6375
+ return Math.min(60, Math.max(2, Math.ceil((intervalSeconds + 60) / 60)));
6376
+ }
6297
6377
  function selectRuntimeModel(detection, requestedModel) {
6298
6378
  if (detection.models.length === 0) {
6299
6379
  if (requestedModel === "default") return void 0;