@wagemule/daemon 0.1.8 → 0.1.10
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 +167 -21
- package/dist/main.cjs.map +3 -3
- package/package.json +2 -2
package/dist/main.cjs
CHANGED
|
@@ -1837,7 +1837,11 @@ var KimiAdapter = class {
|
|
|
1837
1837
|
});
|
|
1838
1838
|
this.lines = import_node_readline4.default.createInterface({ input: this.child.stdout });
|
|
1839
1839
|
this.lines.on("line", (line) => this.handleLine(line));
|
|
1840
|
-
this.writeWire("initialize", {
|
|
1840
|
+
this.writeWire("initialize", {
|
|
1841
|
+
protocol_version: "1.10",
|
|
1842
|
+
client: { name: "wm-daemon", version: "0.0.1" },
|
|
1843
|
+
capabilities: { supports_question: false, supports_plan_mode: false }
|
|
1844
|
+
});
|
|
1841
1845
|
}
|
|
1842
1846
|
async prompt(input) {
|
|
1843
1847
|
const startInput = this.startInput;
|
|
@@ -1878,8 +1882,17 @@ var KimiAdapter = class {
|
|
|
1878
1882
|
if (input.abortSignal?.aborted) throw new Error("Runtime aborted");
|
|
1879
1883
|
input.abortSignal?.addEventListener("abort", abortHandler, { once: true });
|
|
1880
1884
|
events.push({ type: "task_delivered", content: input.prompt });
|
|
1881
|
-
this.writeWire("prompt", {
|
|
1885
|
+
this.active.promptRequestId = this.writeWire("prompt", { user_input: input.prompt });
|
|
1882
1886
|
await withTimeout(turnFinished, input.timeoutMs ?? 18e4, "Kimi wire turn timeout");
|
|
1887
|
+
if (this.active.errorMessage) {
|
|
1888
|
+
return {
|
|
1889
|
+
status: this.active.status ?? "runtime_error",
|
|
1890
|
+
finalMessage,
|
|
1891
|
+
runtimeSessionId: this.sessionId,
|
|
1892
|
+
events,
|
|
1893
|
+
errorMessage: this.active.errorMessage
|
|
1894
|
+
};
|
|
1895
|
+
}
|
|
1883
1896
|
return { status: "ok", finalMessage, runtimeSessionId: this.sessionId, events };
|
|
1884
1897
|
} catch (error) {
|
|
1885
1898
|
return {
|
|
@@ -1908,20 +1921,34 @@ var KimiAdapter = class {
|
|
|
1908
1921
|
this.child = null;
|
|
1909
1922
|
}
|
|
1910
1923
|
writeWire(method, params) {
|
|
1911
|
-
|
|
1924
|
+
const id = String(this.nextId++);
|
|
1925
|
+
this.child?.stdin.write(`${JSON.stringify({ jsonrpc: "2.0", id, method, params })}
|
|
1912
1926
|
`);
|
|
1927
|
+
return id;
|
|
1913
1928
|
}
|
|
1914
1929
|
handleLine(line) {
|
|
1915
|
-
const parsed =
|
|
1930
|
+
const parsed = parseKimiWireLine(line);
|
|
1916
1931
|
if (!parsed) return;
|
|
1917
|
-
if (parsed.sessionId) this.sessionId = parsed.sessionId;
|
|
1918
1932
|
const active = this.active;
|
|
1919
1933
|
const runInput = active?.runInput ?? (this.startInput ? { ...this.startInput, prompt: "" } : void 0);
|
|
1920
1934
|
if (!runInput) return;
|
|
1935
|
+
if (parsed.errorMessage && active && parsed.id === active.promptRequestId) {
|
|
1936
|
+
active.errorMessage = parsed.errorMessage;
|
|
1937
|
+
active.status = "runtime_error";
|
|
1938
|
+
active.events.push({ type: "runtime_error", content: parsed.errorMessage, data: parsed.data });
|
|
1939
|
+
runInput.onEvent?.({ type: "runtime_error", content: parsed.errorMessage, data: parsed.data });
|
|
1940
|
+
active.finish();
|
|
1941
|
+
return;
|
|
1942
|
+
}
|
|
1921
1943
|
if (active) {
|
|
1944
|
+
if (parsed.retry) active.lastRetry = parsed.retry;
|
|
1945
|
+
if (parsed.interrupted) {
|
|
1946
|
+
active.status = "runtime_error";
|
|
1947
|
+
active.errorMessage = kimiInterruptedMessage(active.lastRetry);
|
|
1948
|
+
}
|
|
1922
1949
|
if (parsed.appendFinalMessage) active.append(parsed.appendFinalMessage);
|
|
1923
1950
|
if (parsed.finalMessage) active.set(parsed.finalMessage);
|
|
1924
|
-
if (parsed.events.some((event) => event.type === "turn_finished")) active.finish();
|
|
1951
|
+
if (parsed.finished || parsed.events.some((event) => event.type === "turn_finished")) active.finish();
|
|
1925
1952
|
for (const event of parsed.events) {
|
|
1926
1953
|
active.events.push(event);
|
|
1927
1954
|
runInput.onEvent?.(event);
|
|
@@ -1929,6 +1956,103 @@ var KimiAdapter = class {
|
|
|
1929
1956
|
}
|
|
1930
1957
|
}
|
|
1931
1958
|
};
|
|
1959
|
+
function parseKimiWireLine(line) {
|
|
1960
|
+
if (!line.trim()) return void 0;
|
|
1961
|
+
let value;
|
|
1962
|
+
try {
|
|
1963
|
+
value = JSON.parse(line);
|
|
1964
|
+
} catch {
|
|
1965
|
+
return {
|
|
1966
|
+
appendFinalMessage: `${line}
|
|
1967
|
+
`,
|
|
1968
|
+
events: [{ type: "runtime_stdout", content: line }]
|
|
1969
|
+
};
|
|
1970
|
+
}
|
|
1971
|
+
const msg = value;
|
|
1972
|
+
const id = typeof msg.id === "string" ? msg.id : void 0;
|
|
1973
|
+
if (msg.error && typeof msg.error === "object") {
|
|
1974
|
+
const error = msg.error;
|
|
1975
|
+
return {
|
|
1976
|
+
id,
|
|
1977
|
+
errorMessage: typeof error.message === "string" ? error.message : "Kimi wire request failed",
|
|
1978
|
+
data: msg,
|
|
1979
|
+
events: []
|
|
1980
|
+
};
|
|
1981
|
+
}
|
|
1982
|
+
if (msg.result && typeof msg.result === "object") {
|
|
1983
|
+
const result = msg.result;
|
|
1984
|
+
const status = typeof result.status === "string" ? result.status : void 0;
|
|
1985
|
+
return {
|
|
1986
|
+
id,
|
|
1987
|
+
finished: status === "finished" || status === "cancelled" || status === "max_steps_reached",
|
|
1988
|
+
data: msg,
|
|
1989
|
+
events: status ? [{ type: "turn_finished", data: { runtime: "kimi", status, result } }] : [{ type: "runtime_started", data: { runtime: "kimi", result } }]
|
|
1990
|
+
};
|
|
1991
|
+
}
|
|
1992
|
+
if (msg.method !== "event" || !msg.params || typeof msg.params !== "object") {
|
|
1993
|
+
return { id, events: [{ type: "runtime_event", data: msg }] };
|
|
1994
|
+
}
|
|
1995
|
+
const params = msg.params;
|
|
1996
|
+
const eventType = typeof params.type === "string" ? params.type : "runtime_event";
|
|
1997
|
+
const payload = params.payload && typeof params.payload === "object" ? params.payload : {};
|
|
1998
|
+
const text = stringValue5(payload.text) ?? stringValue5(payload.content) ?? stringValue5(payload.message) ?? stringValue5(payload.delta?.text);
|
|
1999
|
+
if ((eventType === "TextPart" || eventType === "ContentPart") && text) {
|
|
2000
|
+
return {
|
|
2001
|
+
appendFinalMessage: text,
|
|
2002
|
+
events: [{ type: "assistant_delta", content: text, data: msg }]
|
|
2003
|
+
};
|
|
2004
|
+
}
|
|
2005
|
+
if (eventType === "TurnEnd") {
|
|
2006
|
+
return { finished: true, events: [{ type: "turn_finished", data: msg }] };
|
|
2007
|
+
}
|
|
2008
|
+
if (eventType === "ToolCallPart") {
|
|
2009
|
+
return { events: [] };
|
|
2010
|
+
}
|
|
2011
|
+
if (eventType === "ToolCall") {
|
|
2012
|
+
return {
|
|
2013
|
+
events: [{ type: "tool_start", content: text ?? stringValue5(payload.name), data: msg }]
|
|
2014
|
+
};
|
|
2015
|
+
}
|
|
2016
|
+
if (eventType === "ToolResult") {
|
|
2017
|
+
return {
|
|
2018
|
+
events: [{ type: "tool_result", content: text, data: msg }]
|
|
2019
|
+
};
|
|
2020
|
+
}
|
|
2021
|
+
if (eventType === "StepRetry") {
|
|
2022
|
+
return {
|
|
2023
|
+
retry: kimiRetryInfo(payload),
|
|
2024
|
+
events: [{ type: "runtime_event", content: text, data: msg }]
|
|
2025
|
+
};
|
|
2026
|
+
}
|
|
2027
|
+
if (eventType === "StepInterrupted") {
|
|
2028
|
+
return {
|
|
2029
|
+
interrupted: true,
|
|
2030
|
+
events: [{ type: "runtime_error", content: "Kimi step interrupted", data: msg }]
|
|
2031
|
+
};
|
|
2032
|
+
}
|
|
2033
|
+
return {
|
|
2034
|
+
events: [{ type: kimiEventName(eventType), content: text, data: msg }]
|
|
2035
|
+
};
|
|
2036
|
+
}
|
|
2037
|
+
function kimiEventName(eventType) {
|
|
2038
|
+
if (/begin|status|loading|retry|compaction|hook|notification/i.test(eventType)) return "runtime_event";
|
|
2039
|
+
return eventType;
|
|
2040
|
+
}
|
|
2041
|
+
function kimiRetryInfo(payload) {
|
|
2042
|
+
const statusCode = typeof payload.status_code === "number" ? payload.status_code : void 0;
|
|
2043
|
+
const errorType = typeof payload.error_type === "string" ? payload.error_type : void 0;
|
|
2044
|
+
return { errorType, statusCode };
|
|
2045
|
+
}
|
|
2046
|
+
function kimiInterruptedMessage(retry) {
|
|
2047
|
+
if (retry?.statusCode) {
|
|
2048
|
+
const type = retry.errorType ? `${retry.errorType} ` : "";
|
|
2049
|
+
return `Kimi step interrupted after ${type}${retry.statusCode}`;
|
|
2050
|
+
}
|
|
2051
|
+
return "Kimi step interrupted";
|
|
2052
|
+
}
|
|
2053
|
+
function stringValue5(value) {
|
|
2054
|
+
return typeof value === "string" ? value : void 0;
|
|
2055
|
+
}
|
|
1932
2056
|
function kimiAgentYaml() {
|
|
1933
2057
|
return [
|
|
1934
2058
|
"version: 1",
|
|
@@ -3853,21 +3977,21 @@ function renderRuntimeLine(context, line) {
|
|
|
3853
3977
|
function extractTextFromRuntimeJsonLine(line) {
|
|
3854
3978
|
try {
|
|
3855
3979
|
const record = JSON.parse(line);
|
|
3856
|
-
const direct =
|
|
3980
|
+
const direct = stringValue6(record.result ?? record.text ?? record.content);
|
|
3857
3981
|
if (direct) return direct;
|
|
3858
3982
|
const message = record.message;
|
|
3859
|
-
const messageText = message ?
|
|
3983
|
+
const messageText = message ? stringValue6(message.text ?? message.content) : void 0;
|
|
3860
3984
|
if (messageText) return messageText;
|
|
3861
3985
|
const content = Array.isArray(message?.content) ? message?.content : [];
|
|
3862
3986
|
const parts = content.map(
|
|
3863
|
-
(part) => typeof part === "object" && part ?
|
|
3987
|
+
(part) => typeof part === "object" && part ? stringValue6(part.text) : void 0
|
|
3864
3988
|
).filter(Boolean);
|
|
3865
3989
|
return parts.length > 0 ? parts.join("") : void 0;
|
|
3866
3990
|
} catch {
|
|
3867
3991
|
return line;
|
|
3868
3992
|
}
|
|
3869
3993
|
}
|
|
3870
|
-
function
|
|
3994
|
+
function stringValue6(value) {
|
|
3871
3995
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
3872
3996
|
}
|
|
3873
3997
|
function writeLine(context, line) {
|
|
@@ -3891,7 +4015,7 @@ var import_ws = __toESM(require("ws"));
|
|
|
3891
4015
|
// package.json
|
|
3892
4016
|
var package_default = {
|
|
3893
4017
|
name: "@wagemule/daemon",
|
|
3894
|
-
version: "0.1.
|
|
4018
|
+
version: "0.1.10",
|
|
3895
4019
|
private: false,
|
|
3896
4020
|
description: "Wage Mule local daemon for connecting local agent runtimes to Workspace Server.",
|
|
3897
4021
|
main: "./dist/main.cjs",
|
|
@@ -3915,7 +4039,7 @@ var package_default = {
|
|
|
3915
4039
|
start: "node dist/main.cjs",
|
|
3916
4040
|
prepack: "npm run build",
|
|
3917
4041
|
"pack:check": "node scripts/pack-check.mjs",
|
|
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",
|
|
4042
|
+
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/runtime/kimi-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",
|
|
3919
4043
|
"test:real": "node --import tsx src/testing/integration-real.test.ts",
|
|
3920
4044
|
typecheck: "tsc --noEmit"
|
|
3921
4045
|
},
|
|
@@ -4075,7 +4199,7 @@ function summarizeDaemonMessage(msg) {
|
|
|
4075
4199
|
return base;
|
|
4076
4200
|
}
|
|
4077
4201
|
function shouldLogDaemonMessage(msg) {
|
|
4078
|
-
return !(msg.type === "agent:activity" && msg.detail === "assistant_delta");
|
|
4202
|
+
return !(msg.type === "agent:activity" && (msg.detail === "assistant_delta" || msg.detail === "tool_progress"));
|
|
4079
4203
|
}
|
|
4080
4204
|
function summarizeServerMessage(msg) {
|
|
4081
4205
|
const base = `type=${msg.type}`;
|
|
@@ -4311,20 +4435,24 @@ ${stderr}`);
|
|
|
4311
4435
|
};
|
|
4312
4436
|
function parseKimiModelConfig(configText) {
|
|
4313
4437
|
const ids = [];
|
|
4438
|
+
const labels = /* @__PURE__ */ new Map();
|
|
4314
4439
|
let defaultModel;
|
|
4315
4440
|
let section;
|
|
4441
|
+
let currentModelKey;
|
|
4316
4442
|
for (const rawLine of configText.split(/\r?\n/)) {
|
|
4317
4443
|
const line = stripYamlComment(rawLine).trim();
|
|
4318
4444
|
if (!line) continue;
|
|
4319
4445
|
const table = line.match(/^\[models\.([^\]]+)]$/);
|
|
4320
4446
|
if (table) {
|
|
4321
|
-
|
|
4322
|
-
|
|
4447
|
+
currentModelKey = unquote(table[1].trim());
|
|
4448
|
+
section = `models.${currentModelKey}`;
|
|
4449
|
+
pushUnique(ids, currentModelKey);
|
|
4323
4450
|
continue;
|
|
4324
4451
|
}
|
|
4325
4452
|
const anyTable = line.match(/^\[([^\]]+)]$/);
|
|
4326
4453
|
if (anyTable) {
|
|
4327
4454
|
section = anyTable[1]?.trim();
|
|
4455
|
+
currentModelKey = void 0;
|
|
4328
4456
|
continue;
|
|
4329
4457
|
}
|
|
4330
4458
|
const defaultModelLine = line.match(/^default_model\s*=\s*["']?([^"']+)["']?\s*$/);
|
|
@@ -4333,7 +4461,11 @@ function parseKimiModelConfig(configText) {
|
|
|
4333
4461
|
pushUnique(ids, defaultModel);
|
|
4334
4462
|
continue;
|
|
4335
4463
|
}
|
|
4336
|
-
if (section?.startsWith("models."))
|
|
4464
|
+
if (section?.startsWith("models.")) {
|
|
4465
|
+
const model2 = line.match(/^model\s*=\s*["']?([^"']+)["']?\s*$/);
|
|
4466
|
+
if (model2 && currentModelKey) labels.set(currentModelKey, model2[1].trim());
|
|
4467
|
+
continue;
|
|
4468
|
+
}
|
|
4337
4469
|
const model = line.match(/^model\s*=\s*["']?([^"']+)["']?\s*$/);
|
|
4338
4470
|
if (model) {
|
|
4339
4471
|
const value = model[1]?.trim();
|
|
@@ -4348,6 +4480,7 @@ function parseKimiModelConfig(configText) {
|
|
|
4348
4480
|
}
|
|
4349
4481
|
const models = ids.map((id) => ({
|
|
4350
4482
|
...defaultReasoningModel(id, id === defaultModel),
|
|
4483
|
+
label: labels.get(id) ?? id,
|
|
4351
4484
|
default: id === defaultModel ? true : void 0
|
|
4352
4485
|
}));
|
|
4353
4486
|
return { models: normalizeDefault(models, defaultModel), defaultModel };
|
|
@@ -4861,6 +4994,7 @@ function shellQuote(value) {
|
|
|
4861
4994
|
// src/agent-manager/activity-tracker.ts
|
|
4862
4995
|
var ActivityTracker = class {
|
|
4863
4996
|
clientSeq = 0;
|
|
4997
|
+
lastProgressAt = /* @__PURE__ */ new Map();
|
|
4864
4998
|
toEntries(events) {
|
|
4865
4999
|
return events.flatMap((event) => this.toEntry(event));
|
|
4866
5000
|
}
|
|
@@ -4868,6 +5002,13 @@ var ActivityTracker = class {
|
|
|
4868
5002
|
this.clientSeq += 1;
|
|
4869
5003
|
return this.clientSeq;
|
|
4870
5004
|
}
|
|
5005
|
+
shouldPublishProgress(key, intervalMs) {
|
|
5006
|
+
const now = Date.now();
|
|
5007
|
+
const last = this.lastProgressAt.get(key) ?? 0;
|
|
5008
|
+
if (now - last < intervalMs) return false;
|
|
5009
|
+
this.lastProgressAt.set(key, now);
|
|
5010
|
+
return true;
|
|
5011
|
+
}
|
|
4871
5012
|
toEntry(event) {
|
|
4872
5013
|
const timestamp = Date.now();
|
|
4873
5014
|
if (event.type.includes("tool")) {
|
|
@@ -5136,11 +5277,13 @@ var AgentProcessManager = class {
|
|
|
5136
5277
|
"Feishu delegation tick.",
|
|
5137
5278
|
`Human ID: ${delegation.human_id}`,
|
|
5138
5279
|
`Delegation ID: ${delegation.id}`,
|
|
5139
|
-
`Read Feishu messages from the last ${lookbackMinutes} minutes only.
|
|
5140
|
-
"For each new inbound Feishu message that needs a reply,
|
|
5280
|
+
`Read Feishu messages from the last ${lookbackMinutes} minutes only by using the injected .wm/lark-cli wrapper and the lark-im skill. Do not use runtime TaskList or background task tools for Feishu messages.`,
|
|
5281
|
+
"For each new inbound Feishu message that needs a reply, first create exactly one inbox item as the dedupe/process record:",
|
|
5141
5282
|
"wm inbox feishu-draft create --delegation-id <delegation_id> --human-id <human_id> --feishu-message-id <message_id> --chat-id <chat_id> --sender-name <name> --sender-open-id <open_id> --original-text <summary> --draft-text <draft>",
|
|
5142
|
-
"
|
|
5143
|
-
"
|
|
5283
|
+
"If the reply is low-risk and routine, send exactly that draft once with lark-cli im +messages-reply or lark-cli im +messages-send, then run: wm inbox feishu-draft sent --id <Inbox ID> --message-id <sent message_id>",
|
|
5284
|
+
"If the reply is uncertain, sensitive, or high-risk, do not send it; leave the inbox item open for human approval.",
|
|
5285
|
+
"If sending fails, run: wm inbox feishu-draft failed --id <Inbox ID> --error <short error>.",
|
|
5286
|
+
"Deduplicate by Feishu message_id. If there are no new relevant messages, do nothing."
|
|
5144
5287
|
].join("\n")
|
|
5145
5288
|
};
|
|
5146
5289
|
void this.enqueueStart({
|
|
@@ -5536,7 +5679,9 @@ var AgentProcessManager = class {
|
|
|
5536
5679
|
deltaLogCount += 1;
|
|
5537
5680
|
} else {
|
|
5538
5681
|
flushDeltaLog();
|
|
5539
|
-
|
|
5682
|
+
if (event.type !== "tool_progress") {
|
|
5683
|
+
this.log(`runtime event agent=${agentId} type=${event.type}${event.content ? ` text=${compact(event.content)}` : ""}`);
|
|
5684
|
+
}
|
|
5540
5685
|
}
|
|
5541
5686
|
const running = this.running.get(agentId);
|
|
5542
5687
|
if (running) {
|
|
@@ -5569,6 +5714,7 @@ var AgentProcessManager = class {
|
|
|
5569
5714
|
}
|
|
5570
5715
|
}
|
|
5571
5716
|
const entries = tracker.toEntries([event]);
|
|
5717
|
+
if (event.type === "tool_progress" && !tracker.shouldPublishProgress("tool_progress", 1e3)) return;
|
|
5572
5718
|
this.sendActivity({
|
|
5573
5719
|
agentId,
|
|
5574
5720
|
activity: "working",
|