@slock-ai/daemon 0.52.1 → 0.52.2
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/{chunk-WGO5H7XX.js → chunk-HSBOURQE.js} +164 -13
- package/dist/core.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -823,6 +823,7 @@ function buildPrompt(config, variant, opts) {
|
|
|
823
823
|
"- Always communicate through `slock` CLI commands. This is your only output channel.",
|
|
824
824
|
...opts.extraCriticalRules,
|
|
825
825
|
"- Use only the provided `slock` CLI commands for messaging.",
|
|
826
|
+
"- Do not combine multiple `slock` CLI commands in one shell command. Run one `slock` command per tool call, read its output, then decide the next command.",
|
|
826
827
|
"- Always claim a task via `slock task claim` before starting work on it. If the claim fails, move on to a different task."
|
|
827
828
|
] : [
|
|
828
829
|
`- Always communicate through ${sendCmd}. This is your only output channel.`,
|
|
@@ -1810,6 +1811,18 @@ function consumeVisibleResponse(registration, targetUrl, sendTarget, responseTex
|
|
|
1810
1811
|
});
|
|
1811
1812
|
return;
|
|
1812
1813
|
}
|
|
1814
|
+
if (targetUrl.pathname === "/internal/agent-api/send" && parsed.state === "sent") {
|
|
1815
|
+
const messageSeq2 = typeof parsed.messageSeq === "number" && Number.isFinite(parsed.messageSeq) ? Math.floor(parsed.messageSeq) : void 0;
|
|
1816
|
+
if (sendTarget && messageSeq2 && messageSeq2 > 0) {
|
|
1817
|
+
coordinator.consumeVisibleMessages({
|
|
1818
|
+
target: sendTarget,
|
|
1819
|
+
messages: normalizeVisibleMessages([{ seq: messageSeq2, id: parsed.messageId }], sendTarget),
|
|
1820
|
+
boundarySeq: messageSeq2,
|
|
1821
|
+
source: "agent_api_send_commit"
|
|
1822
|
+
});
|
|
1823
|
+
}
|
|
1824
|
+
return;
|
|
1825
|
+
}
|
|
1813
1826
|
if (targetUrl.pathname === "/internal/agent-api/events" && Array.isArray(parsed.events)) {
|
|
1814
1827
|
const messages = normalizeVisibleMessages(parsed.events);
|
|
1815
1828
|
coordinator.consumeVisibleMessages({ messages, source: "agent_api_events" });
|
|
@@ -3786,7 +3799,7 @@ function detectKimiModels(home = os4.homedir()) {
|
|
|
3786
3799
|
|
|
3787
3800
|
// src/drivers/opencode.ts
|
|
3788
3801
|
import { spawn as spawn7, spawnSync as spawnSync2 } from "child_process";
|
|
3789
|
-
import { readFileSync as readFileSync4 } from "fs";
|
|
3802
|
+
import { existsSync as existsSync8, readFileSync as readFileSync4 } from "fs";
|
|
3790
3803
|
import os5 from "os";
|
|
3791
3804
|
import path10 from "path";
|
|
3792
3805
|
var CHAT_MCP_SERVER_NAME = "chat";
|
|
@@ -4039,6 +4052,102 @@ function runOpenCodeModelsCommand(home, deps = {}) {
|
|
|
4039
4052
|
error: result.error
|
|
4040
4053
|
};
|
|
4041
4054
|
}
|
|
4055
|
+
function isWindowsCommandShim(commandPath) {
|
|
4056
|
+
const ext = path10.win32.extname(commandPath).toLowerCase();
|
|
4057
|
+
return ext === ".cmd" || ext === ".bat";
|
|
4058
|
+
}
|
|
4059
|
+
function opencodePackageEntryCandidates(packageRoot) {
|
|
4060
|
+
const winPath = path10.win32;
|
|
4061
|
+
return [
|
|
4062
|
+
winPath.join(packageRoot, "bin", "opencode.exe"),
|
|
4063
|
+
winPath.join(packageRoot, "bin", "opencode.js"),
|
|
4064
|
+
winPath.join(packageRoot, "bin", "opencode.mjs"),
|
|
4065
|
+
winPath.join(packageRoot, "dist", "index.js")
|
|
4066
|
+
];
|
|
4067
|
+
}
|
|
4068
|
+
function openCodeSpecForEntry(entry, commandArgs) {
|
|
4069
|
+
if (path10.win32.extname(entry).toLowerCase() === ".exe") {
|
|
4070
|
+
return { command: entry, args: commandArgs, shell: false };
|
|
4071
|
+
}
|
|
4072
|
+
return { command: process.execPath, args: [entry, ...commandArgs], shell: false };
|
|
4073
|
+
}
|
|
4074
|
+
function resolveWindowsOpenCodePackageEntry(commandPath, deps = {}) {
|
|
4075
|
+
const existsSyncFn = deps.existsSyncFn ?? existsSync8;
|
|
4076
|
+
const execFileSyncFn = deps.execFileSyncFn;
|
|
4077
|
+
const env = deps.env ?? process.env;
|
|
4078
|
+
const winPath = path10.win32;
|
|
4079
|
+
const candidates = [];
|
|
4080
|
+
if (execFileSyncFn) {
|
|
4081
|
+
try {
|
|
4082
|
+
const globalRoot = String(execFileSyncFn("npm", ["root", "-g"], {
|
|
4083
|
+
encoding: "utf8",
|
|
4084
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
4085
|
+
env
|
|
4086
|
+
})).trim();
|
|
4087
|
+
if (globalRoot) {
|
|
4088
|
+
candidates.push(...opencodePackageEntryCandidates(winPath.join(globalRoot, "opencode-ai")));
|
|
4089
|
+
}
|
|
4090
|
+
} catch {
|
|
4091
|
+
}
|
|
4092
|
+
}
|
|
4093
|
+
if (commandPath) {
|
|
4094
|
+
const commandDir = winPath.dirname(commandPath);
|
|
4095
|
+
candidates.push(...opencodePackageEntryCandidates(winPath.join(commandDir, "node_modules", "opencode-ai")));
|
|
4096
|
+
candidates.push(...extractWindowsShimTargets(commandPath, deps));
|
|
4097
|
+
}
|
|
4098
|
+
for (const candidate of candidates) {
|
|
4099
|
+
if (existsSyncFn(candidate)) return candidate;
|
|
4100
|
+
}
|
|
4101
|
+
return null;
|
|
4102
|
+
}
|
|
4103
|
+
function extractWindowsShimTargets(commandPath, deps = {}) {
|
|
4104
|
+
if (!isWindowsCommandShim(commandPath)) return [];
|
|
4105
|
+
const readFileSyncFn = deps.readFileSyncFn ?? readFileSync4;
|
|
4106
|
+
const commandDir = path10.win32.dirname(commandPath);
|
|
4107
|
+
let raw;
|
|
4108
|
+
try {
|
|
4109
|
+
raw = String(readFileSyncFn(commandPath, "utf8"));
|
|
4110
|
+
} catch {
|
|
4111
|
+
return [];
|
|
4112
|
+
}
|
|
4113
|
+
const candidates = [];
|
|
4114
|
+
const dp0Pattern = /%~dp0\\?([^"\r\n]*?opencode\.(?:exe|js|mjs|cjs))/gi;
|
|
4115
|
+
for (const match of raw.matchAll(dp0Pattern)) {
|
|
4116
|
+
const relative = match[1]?.replace(/^\\+/, "");
|
|
4117
|
+
if (relative) candidates.push(path10.win32.normalize(path10.win32.join(commandDir, relative)));
|
|
4118
|
+
}
|
|
4119
|
+
return candidates;
|
|
4120
|
+
}
|
|
4121
|
+
function resolveOpenCodeSpawn(commandArgs, deps = {}) {
|
|
4122
|
+
const platform = deps.platform ?? process.platform;
|
|
4123
|
+
if (platform !== "win32") {
|
|
4124
|
+
return {
|
|
4125
|
+
command: resolveCommandOnPath("opencode", deps) ?? "opencode",
|
|
4126
|
+
args: commandArgs,
|
|
4127
|
+
shell: false
|
|
4128
|
+
};
|
|
4129
|
+
}
|
|
4130
|
+
const command = resolveCommandOnPath("opencode", deps);
|
|
4131
|
+
if (command && path10.win32.extname(command).toLowerCase() === ".exe") {
|
|
4132
|
+
return { command, args: commandArgs, shell: false };
|
|
4133
|
+
}
|
|
4134
|
+
const packageEntry = resolveWindowsOpenCodePackageEntry(command, deps);
|
|
4135
|
+
if (packageEntry) return openCodeSpecForEntry(packageEntry, commandArgs);
|
|
4136
|
+
if (command && !isWindowsCommandShim(command)) {
|
|
4137
|
+
return { command, args: commandArgs, shell: false };
|
|
4138
|
+
}
|
|
4139
|
+
throw new Error(
|
|
4140
|
+
"Cannot resolve OpenCode CLI entry point on Windows without cmd.exe. Install the native OpenCode executable or install opencode-ai globally so Slock can launch node_modules/opencode-ai/bin/opencode.exe directly."
|
|
4141
|
+
);
|
|
4142
|
+
}
|
|
4143
|
+
function readOpenCodeVersion(deps = {}) {
|
|
4144
|
+
try {
|
|
4145
|
+
const launch = resolveOpenCodeSpawn([], deps);
|
|
4146
|
+
return readCommandVersion(launch.command, launch.args, deps);
|
|
4147
|
+
} catch {
|
|
4148
|
+
return null;
|
|
4149
|
+
}
|
|
4150
|
+
}
|
|
4042
4151
|
function isSystemFirstMessageTask(message) {
|
|
4043
4152
|
return message.sender_id === "system" && message.channel_type === "channel" && message.channel_name === "all" && message.content.trimStart().startsWith(FIRST_MESSAGE_TASK_PREFIX);
|
|
4044
4153
|
}
|
|
@@ -4081,7 +4190,7 @@ var OpenCodeDriver = class {
|
|
|
4081
4190
|
model: modelId
|
|
4082
4191
|
}
|
|
4083
4192
|
};
|
|
4084
|
-
const version =
|
|
4193
|
+
const version = readOpenCodeVersion();
|
|
4085
4194
|
const launch = buildOpenCodeLaunchOptions(launchCtx, opts?.home, version);
|
|
4086
4195
|
return {
|
|
4087
4196
|
args: launch.args,
|
|
@@ -4102,8 +4211,13 @@ var OpenCodeDriver = class {
|
|
|
4102
4211
|
sessionId = null;
|
|
4103
4212
|
sessionAnnounced = false;
|
|
4104
4213
|
probe() {
|
|
4105
|
-
|
|
4106
|
-
|
|
4214
|
+
let version;
|
|
4215
|
+
try {
|
|
4216
|
+
const launch = resolveOpenCodeSpawn([]);
|
|
4217
|
+
version = readCommandVersion(launch.command, launch.args);
|
|
4218
|
+
} catch {
|
|
4219
|
+
return { available: false };
|
|
4220
|
+
}
|
|
4107
4221
|
const unsupportedMessage = unsupportedOpenCodeVersionMessage(version);
|
|
4108
4222
|
if (unsupportedMessage) {
|
|
4109
4223
|
return {
|
|
@@ -4111,7 +4225,7 @@ var OpenCodeDriver = class {
|
|
|
4111
4225
|
version: `${version} (requires >= ${MIN_SUPPORTED_OPENCODE_VERSION})`
|
|
4112
4226
|
};
|
|
4113
4227
|
}
|
|
4114
|
-
return { available: true, version };
|
|
4228
|
+
return { available: true, version: version ?? void 0 };
|
|
4115
4229
|
}
|
|
4116
4230
|
async detectModels() {
|
|
4117
4231
|
return detectOpenCodeModels();
|
|
@@ -4119,17 +4233,18 @@ var OpenCodeDriver = class {
|
|
|
4119
4233
|
spawn(ctx) {
|
|
4120
4234
|
this.sessionId = ctx.config.sessionId || null;
|
|
4121
4235
|
this.sessionAnnounced = false;
|
|
4122
|
-
const version =
|
|
4236
|
+
const version = readOpenCodeVersion();
|
|
4123
4237
|
const unsupportedMessage = unsupportedOpenCodeVersionMessage(version);
|
|
4124
4238
|
if (unsupportedMessage) {
|
|
4125
4239
|
throw new Error(unsupportedMessage);
|
|
4126
4240
|
}
|
|
4127
4241
|
const launch = buildOpenCodeLaunchOptions(ctx, os5.homedir(), version);
|
|
4128
|
-
const
|
|
4242
|
+
const spawnSpec = resolveOpenCodeSpawn(launch.args);
|
|
4243
|
+
const proc = spawn7(spawnSpec.command, spawnSpec.args, {
|
|
4129
4244
|
cwd: ctx.workingDirectory,
|
|
4130
4245
|
stdio: ["pipe", "pipe", "pipe"],
|
|
4131
4246
|
env: launch.env,
|
|
4132
|
-
shell:
|
|
4247
|
+
shell: spawnSpec.shell
|
|
4133
4248
|
});
|
|
4134
4249
|
proc.stdin?.end();
|
|
4135
4250
|
return { process: proc };
|
|
@@ -4367,6 +4482,7 @@ function classifyRuntimeError(message, httpStatus) {
|
|
|
4367
4482
|
return "ProviderApiError";
|
|
4368
4483
|
}
|
|
4369
4484
|
if (/\btimeout|timed out\b/i.test(message)) return "TimeoutError";
|
|
4485
|
+
if (/stream closed before response\.completed|error decoding response body/i.test(message)) return "ProviderStreamError";
|
|
4370
4486
|
if (/\brate.?limit|too many requests\b/i.test(message)) return "RateLimitError";
|
|
4371
4487
|
if (/\bnot found\b/i.test(message)) return "NotFoundError";
|
|
4372
4488
|
return "RuntimeError";
|
|
@@ -5241,12 +5357,21 @@ function classifyTerminalFailure(ap) {
|
|
|
5241
5357
|
].filter((value) => !!value);
|
|
5242
5358
|
for (const text of candidates) {
|
|
5243
5359
|
const lower = text.toLowerCase();
|
|
5244
|
-
if (lower.includes("usage limit") || lower.includes("quota exceeded") || lower.includes("quota limit") || lower.includes("budget limit exceeded") || lower.includes("usage not included in your plan") || lower.includes("modelnotfounderror") || lower.includes("requested entity was not found") || lower.includes("model deprecated") || lower.includes("model not found")) {
|
|
5360
|
+
if (lower.includes("usage limit") || lower.includes("quota exceeded") || lower.includes("quota limit") || lower.includes("budget limit exceeded") || lower.includes("usage not included in your plan") || lower.includes("modelnotfounderror") || lower.includes("requested entity was not found") || lower.includes("model deprecated") || lower.includes("model not found") || isProviderStreamFailureText(text)) {
|
|
5245
5361
|
return text;
|
|
5246
5362
|
}
|
|
5247
5363
|
}
|
|
5248
5364
|
return null;
|
|
5249
5365
|
}
|
|
5366
|
+
function isProviderStreamFailureText(text) {
|
|
5367
|
+
return /stream closed before response\.completed|error decoding response body/i.test(text);
|
|
5368
|
+
}
|
|
5369
|
+
function isCodexProviderReconnectLog(text) {
|
|
5370
|
+
return /Reconnecting\.\.\.\s*\d+\s*\/\s*\d+/i.test(text);
|
|
5371
|
+
}
|
|
5372
|
+
function isCodexBenignTransportLog(text) {
|
|
5373
|
+
return /Falling back from WebSockets/i.test(text);
|
|
5374
|
+
}
|
|
5250
5375
|
function hasDirectStdinRecoveryEvidence(ap) {
|
|
5251
5376
|
const candidates = [
|
|
5252
5377
|
ap.lastRuntimeError,
|
|
@@ -6098,8 +6223,24 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
6098
6223
|
proc.stderr?.on("data", (chunk) => {
|
|
6099
6224
|
const text = chunk.toString().trim();
|
|
6100
6225
|
if (!text) return;
|
|
6101
|
-
if (/Reconnecting\.\.\.|Falling back from WebSockets/i.test(text)) return;
|
|
6102
6226
|
const current = this.agents.get(agentId);
|
|
6227
|
+
if (driver.id === "codex" && isCodexProviderReconnectLog(text)) {
|
|
6228
|
+
if (current) {
|
|
6229
|
+
current.recentStderr = pushRecentStderr(current.recentStderr, text);
|
|
6230
|
+
}
|
|
6231
|
+
this.recordDaemonTrace("daemon.agent.provider_reconnect", {
|
|
6232
|
+
agentId,
|
|
6233
|
+
launchId: current?.launchId || void 0,
|
|
6234
|
+
runtime: config.runtime,
|
|
6235
|
+
model: config.model
|
|
6236
|
+
});
|
|
6237
|
+
this.broadcastActivity(agentId, "working", "Codex reconnecting to provider\u2026", [
|
|
6238
|
+
{ kind: "text", text }
|
|
6239
|
+
]);
|
|
6240
|
+
logger.info(`[Agent ${agentId} stderr]: ${text}`);
|
|
6241
|
+
return;
|
|
6242
|
+
}
|
|
6243
|
+
if (driver.id === "codex" && isCodexBenignTransportLog(text)) return;
|
|
6103
6244
|
if (current) {
|
|
6104
6245
|
current.recentStderr = pushRecentStderr(current.recentStderr, text);
|
|
6105
6246
|
}
|
|
@@ -6243,10 +6384,20 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
6243
6384
|
}
|
|
6244
6385
|
this.broadcastActivity(agentId, "online", "Process idle");
|
|
6245
6386
|
} else {
|
|
6246
|
-
this.idleAgentConfigs.delete(agentId);
|
|
6247
6387
|
const reason = formatCrashReason(finalCode, finalSignal, ap);
|
|
6248
|
-
|
|
6249
|
-
|
|
6388
|
+
if (terminalFailureDetail && isProviderStreamFailureText(terminalFailureDetail)) {
|
|
6389
|
+
this.idleAgentConfigs.set(agentId, {
|
|
6390
|
+
config: { ...ap.config, sessionId: ap.sessionId },
|
|
6391
|
+
sessionId: ap.sessionId,
|
|
6392
|
+
launchId: ap.launchId
|
|
6393
|
+
});
|
|
6394
|
+
logger.warn(`[Agent ${agentId}] Recoverable provider stream failure (${reason}) \u2014 keeping agent wakeable`);
|
|
6395
|
+
this.sendAgentStatus(agentId, "active", ap.launchId);
|
|
6396
|
+
} else {
|
|
6397
|
+
this.idleAgentConfigs.delete(agentId);
|
|
6398
|
+
logger.error(`[Agent ${agentId}] Process crashed (${reason}) \u2014 marking inactive`);
|
|
6399
|
+
this.sendAgentStatus(agentId, "inactive", ap.launchId);
|
|
6400
|
+
}
|
|
6250
6401
|
if (terminalFailureDetail) {
|
|
6251
6402
|
this.broadcastActivity(
|
|
6252
6403
|
agentId,
|
package/dist/core.js
CHANGED
package/dist/index.js
CHANGED