opencode-supertask 0.1.38 → 0.1.40
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/CHANGELOG.md +19 -0
- package/README.md +152 -352
- package/README.zh-CN.md +243 -0
- package/dist/cli/index.js +250 -60
- package/dist/cli/index.js.map +1 -1
- package/dist/gateway/index.js +195 -43
- package/dist/gateway/index.js.map +1 -1
- package/dist/plugin/supertask.js +347 -10
- package/dist/plugin/supertask.js.map +1 -1
- package/dist/web/index.js +179 -41
- package/dist/web/index.js.map +1 -1
- package/dist/worker/index.d.ts +1 -0
- package/dist/worker/index.js +34 -3
- package/dist/worker/index.js.map +1 -1
- package/drizzle/0008_good_smasher.sql +3 -0
- package/drizzle/meta/0008_snapshot.json +606 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -9307,6 +9307,7 @@ var init_schema = __esm({
|
|
|
9307
9307
|
name: text("name").notNull(),
|
|
9308
9308
|
agent: text("agent").notNull(),
|
|
9309
9309
|
model: text("model").default("default"),
|
|
9310
|
+
variant: text("variant"),
|
|
9310
9311
|
prompt: text("prompt").notNull(),
|
|
9311
9312
|
cwd: text("cwd"),
|
|
9312
9313
|
// 分类与优先级
|
|
@@ -9351,6 +9352,7 @@ var init_schema = __esm({
|
|
|
9351
9352
|
taskId: integer("task_id").notNull().references(() => tasks.id, { onDelete: "cascade" }),
|
|
9352
9353
|
sessionId: text("session_id"),
|
|
9353
9354
|
model: text("model"),
|
|
9355
|
+
variant: text("variant"),
|
|
9354
9356
|
status: text("status").default("running"),
|
|
9355
9357
|
startedAt: integer("started_at", { mode: "timestamp" }).$defaultFn(() => /* @__PURE__ */ new Date()),
|
|
9356
9358
|
finishedAt: integer("finished_at", { mode: "timestamp" }),
|
|
@@ -9371,6 +9373,7 @@ var init_schema = __esm({
|
|
|
9371
9373
|
name: text("name").notNull(),
|
|
9372
9374
|
agent: text("agent").notNull(),
|
|
9373
9375
|
model: text("model").default("default"),
|
|
9376
|
+
variant: text("variant"),
|
|
9374
9377
|
prompt: text("prompt").notNull(),
|
|
9375
9378
|
cwd: text("cwd"),
|
|
9376
9379
|
category: text("category").default("general"),
|
|
@@ -9631,6 +9634,28 @@ var init_task_batch = __esm({
|
|
|
9631
9634
|
}
|
|
9632
9635
|
});
|
|
9633
9636
|
|
|
9637
|
+
// src/core/model-variant.ts
|
|
9638
|
+
function normalizeModelVariant(value) {
|
|
9639
|
+
if (value === void 0 || value === null) return value;
|
|
9640
|
+
const normalized = value.trim();
|
|
9641
|
+
if (!normalized) return null;
|
|
9642
|
+
if (normalized.length > MAX_MODEL_VARIANT_LENGTH) {
|
|
9643
|
+
throw new Error(`variant \u957F\u5EA6\u4E0D\u80FD\u8D85\u8FC7 ${MAX_MODEL_VARIANT_LENGTH} \u4E2A\u5B57\u7B26`);
|
|
9644
|
+
}
|
|
9645
|
+
if (CONTROL_CHARACTER_PATTERN.test(normalized)) {
|
|
9646
|
+
throw new Error("variant \u4E0D\u80FD\u5305\u542B\u63A7\u5236\u5B57\u7B26");
|
|
9647
|
+
}
|
|
9648
|
+
return normalized;
|
|
9649
|
+
}
|
|
9650
|
+
var MAX_MODEL_VARIANT_LENGTH, CONTROL_CHARACTER_PATTERN;
|
|
9651
|
+
var init_model_variant = __esm({
|
|
9652
|
+
"src/core/model-variant.ts"() {
|
|
9653
|
+
"use strict";
|
|
9654
|
+
MAX_MODEL_VARIANT_LENGTH = 128;
|
|
9655
|
+
CONTROL_CHARACTER_PATTERN = /[\u0000-\u001F\u007F]/;
|
|
9656
|
+
}
|
|
9657
|
+
});
|
|
9658
|
+
|
|
9634
9659
|
// src/core/services/task.service.ts
|
|
9635
9660
|
function hasNoExecutableDependents() {
|
|
9636
9661
|
return sql`NOT EXISTS (
|
|
@@ -9686,6 +9711,7 @@ var init_task_service = __esm({
|
|
|
9686
9711
|
init_backoff();
|
|
9687
9712
|
init_task_working_directory();
|
|
9688
9713
|
init_task_batch();
|
|
9714
|
+
init_model_variant();
|
|
9689
9715
|
({ tasks: tasks2, taskRuns: taskRuns2 } = schema_exports);
|
|
9690
9716
|
cleanupInvocation = 0;
|
|
9691
9717
|
TaskDeletionConflictError = class extends Error {
|
|
@@ -9705,7 +9731,8 @@ var init_task_service = __esm({
|
|
|
9705
9731
|
static async add(data) {
|
|
9706
9732
|
const normalizedData = {
|
|
9707
9733
|
...data,
|
|
9708
|
-
batchId: normalizeTaskBatchId(data.batchId)
|
|
9734
|
+
batchId: normalizeTaskBatchId(data.batchId),
|
|
9735
|
+
variant: normalizeModelVariant(data.variant)
|
|
9709
9736
|
};
|
|
9710
9737
|
this.validateNewTask(normalizedData);
|
|
9711
9738
|
return db.transaction((tx) => {
|
|
@@ -9733,7 +9760,11 @@ var init_task_service = __esm({
|
|
|
9733
9760
|
}
|
|
9734
9761
|
static async update(id, data, scope = {}) {
|
|
9735
9762
|
if (Object.keys(data).length === 0) throw new Error("\u81F3\u5C11\u63D0\u4F9B\u4E00\u4E2A\u8981\u4FEE\u6539\u7684\u5B57\u6BB5");
|
|
9736
|
-
const normalizedData =
|
|
9763
|
+
const normalizedData = {
|
|
9764
|
+
...data,
|
|
9765
|
+
...data.batchId === void 0 ? {} : { batchId: normalizeTaskBatchId(data.batchId) ?? null },
|
|
9766
|
+
...data.variant === void 0 ? {} : { variant: normalizeModelVariant(data.variant) ?? null }
|
|
9767
|
+
};
|
|
9737
9768
|
return db.transaction((tx) => {
|
|
9738
9769
|
const task = tx.select().from(tasks2).where(and(
|
|
9739
9770
|
eq(tasks2.id, id),
|
|
@@ -9745,6 +9776,7 @@ var init_task_service = __esm({
|
|
|
9745
9776
|
name: normalizedData.name ?? task.name,
|
|
9746
9777
|
agent: normalizedData.agent ?? task.agent,
|
|
9747
9778
|
model: normalizedData.model ?? task.model,
|
|
9779
|
+
variant: normalizedData.variant === void 0 ? task.variant : normalizedData.variant,
|
|
9748
9780
|
prompt: normalizedData.prompt ?? task.prompt,
|
|
9749
9781
|
cwd: task.cwd,
|
|
9750
9782
|
category: normalizedData.category ?? task.category,
|
|
@@ -20106,12 +20138,14 @@ var init_task_template_service = __esm({
|
|
|
20106
20138
|
init_cron_parser();
|
|
20107
20139
|
init_task_working_directory();
|
|
20108
20140
|
init_task_batch();
|
|
20141
|
+
init_model_variant();
|
|
20109
20142
|
({ taskTemplates: taskTemplates2 } = schema_exports);
|
|
20110
20143
|
TaskTemplateService = class {
|
|
20111
20144
|
static async create(data) {
|
|
20112
20145
|
const normalizedData = {
|
|
20113
20146
|
...data,
|
|
20114
|
-
batchId: normalizeTaskBatchId(data.batchId)
|
|
20147
|
+
batchId: normalizeTaskBatchId(data.batchId),
|
|
20148
|
+
variant: normalizeModelVariant(data.variant)
|
|
20115
20149
|
};
|
|
20116
20150
|
this.validate(normalizedData);
|
|
20117
20151
|
const now = Date.now();
|
|
@@ -20177,7 +20211,8 @@ var init_task_template_service = __esm({
|
|
|
20177
20211
|
static async update(id, data) {
|
|
20178
20212
|
const normalizedData = {
|
|
20179
20213
|
...data,
|
|
20180
|
-
batchId: normalizeTaskBatchId(data.batchId) ?? null
|
|
20214
|
+
batchId: normalizeTaskBatchId(data.batchId) ?? null,
|
|
20215
|
+
...data.variant === void 0 ? {} : { variant: normalizeModelVariant(data.variant) ?? null }
|
|
20181
20216
|
};
|
|
20182
20217
|
this.validate(normalizedData);
|
|
20183
20218
|
const now = Date.now();
|
|
@@ -22220,9 +22255,11 @@ var init_semver = __esm({
|
|
|
22220
22255
|
var update_exports = {};
|
|
22221
22256
|
__export(update_exports, {
|
|
22222
22257
|
getGlobalCliDiagnostic: () => getGlobalCliDiagnostic,
|
|
22258
|
+
getLatestVersion: () => getLatestVersion,
|
|
22223
22259
|
getOpenCodePluginDiagnostic: () => getOpenCodePluginDiagnostic,
|
|
22224
22260
|
installLatestPlugin: () => installLatestPlugin,
|
|
22225
22261
|
installPluginVersion: () => installPluginVersion,
|
|
22262
|
+
isVersionConverged: () => isVersionConverged,
|
|
22226
22263
|
resolveConfiguredPluginSpec: () => resolveConfiguredPluginSpec,
|
|
22227
22264
|
resolveInstalledPlugin: () => resolveInstalledPlugin,
|
|
22228
22265
|
resolveInstalledPluginVersion: () => resolveInstalledPluginVersion,
|
|
@@ -22242,6 +22279,9 @@ import {
|
|
|
22242
22279
|
} from "fs";
|
|
22243
22280
|
import { homedir as homedir4, tmpdir as tmpdir2 } from "os";
|
|
22244
22281
|
import { dirname as dirname7, join as join5, resolve as resolve4 } from "path";
|
|
22282
|
+
function isVersionConverged(version2, state2) {
|
|
22283
|
+
return state2.packageVersion === version2 && state2.plugin.ok && state2.plugin.version === version2 && state2.plugin.cachedVersion === version2 && (!state2.cli.installed || state2.cli.version === version2) && state2.gateway.pm2Installed && state2.gateway.processFound && state2.gateway.status === "online" && state2.gateway.ready && state2.gateway.runningVersion === version2 && state2.gateway.gatewayPackageVersion === version2 && state2.gateway.scopeMatches;
|
|
22284
|
+
}
|
|
22245
22285
|
function pluginAt(packageDir) {
|
|
22246
22286
|
const packageJson = join5(packageDir, "package.json");
|
|
22247
22287
|
const gatewayEntry = join5(packageDir, "dist/gateway/index.js");
|
|
@@ -22409,7 +22449,7 @@ function updateGlobalCli(version2) {
|
|
|
22409
22449
|
}
|
|
22410
22450
|
return { ...after, action: "updated" };
|
|
22411
22451
|
}
|
|
22412
|
-
function
|
|
22452
|
+
function getLatestVersion() {
|
|
22413
22453
|
const result = spawnSync3(npmBin(), [
|
|
22414
22454
|
"view",
|
|
22415
22455
|
PACKAGE_NAME,
|
|
@@ -22583,7 +22623,7 @@ function installPluginVersion(version2) {
|
|
|
22583
22623
|
return resolveInstalledPluginVersion(version2);
|
|
22584
22624
|
}
|
|
22585
22625
|
function installLatestPlugin() {
|
|
22586
|
-
return installPluginVersion(
|
|
22626
|
+
return installPluginVersion(getLatestVersion());
|
|
22587
22627
|
}
|
|
22588
22628
|
var PACKAGE_NAME;
|
|
22589
22629
|
var init_update2 = __esm({
|
|
@@ -22875,6 +22915,7 @@ var init_worker = __esm({
|
|
|
22875
22915
|
const run = await TaskRunService.create({
|
|
22876
22916
|
taskId: task.id,
|
|
22877
22917
|
model: this.resolveModel(task.model),
|
|
22918
|
+
variant: this.resolveVariant(task.variant),
|
|
22878
22919
|
status: "running",
|
|
22879
22920
|
workerPid: process.pid,
|
|
22880
22921
|
lockedAt: Date.now(),
|
|
@@ -22937,8 +22978,10 @@ var init_worker = __esm({
|
|
|
22937
22978
|
}
|
|
22938
22979
|
async spawnTask(task, runId, launchIdentity) {
|
|
22939
22980
|
const model = this.resolveModel(task.model);
|
|
22981
|
+
const variant = this.resolveVariant(task.variant);
|
|
22940
22982
|
const args = ["run", "--agent", task.agent, "--format", "json"];
|
|
22941
22983
|
if (model) args.push("-m", model);
|
|
22984
|
+
if (variant) args.push("--variant", variant);
|
|
22942
22985
|
args.push(task.prompt);
|
|
22943
22986
|
const cwd = task.cwd || process.cwd();
|
|
22944
22987
|
const child = spawn(process.execPath, [
|
|
@@ -23097,7 +23140,7 @@ var init_worker = __esm({
|
|
|
23097
23140
|
);
|
|
23098
23141
|
return;
|
|
23099
23142
|
}
|
|
23100
|
-
const failure = code === 0 ? void 0 : `${spawnError ? "\u65E0\u6CD5\u542F\u52A8 opencode" : "opencode \u9000\u51FA\u7801"} ${spawnError?.message ?? code ?? "null"}${signal ? `\uFF0C\u4FE1\u53F7 ${signal}` : ""}\uFF08agent=${entry.task.agent}\uFF0Cmodel=${this.resolveModel(entry.task.model) ?? "Agent/\u9ED8\u8BA4\u914D\u7F6E"}\uFF0Ccwd=${entry.task.cwd ?? process.cwd()}\uFF09`;
|
|
23143
|
+
const failure = code === 0 ? void 0 : `${spawnError ? "\u65E0\u6CD5\u542F\u52A8 opencode" : "opencode \u9000\u51FA\u7801"} ${spawnError?.message ?? code ?? "null"}${signal ? `\uFF0C\u4FE1\u53F7 ${signal}` : ""}\uFF08agent=${entry.task.agent}\uFF0Cmodel=${this.resolveModel(entry.task.model) ?? "Agent/\u9ED8\u8BA4\u914D\u7F6E"}\uFF0Cvariant=${this.resolveVariant(entry.task.variant) ?? "Agent/\u6A21\u578B\u9ED8\u8BA4\u914D\u7F6E"}\uFF0Ccwd=${entry.task.cwd ?? process.cwd()}\uFF09`;
|
|
23101
23144
|
this.runDetached(
|
|
23102
23145
|
this.settleEntry(entry, code, failure),
|
|
23103
23146
|
"task settlement failed",
|
|
@@ -23286,6 +23329,9 @@ ${output}` : ""}`;
|
|
|
23286
23329
|
if (!taskModel || taskModel === "default") return null;
|
|
23287
23330
|
return taskModel;
|
|
23288
23331
|
}
|
|
23332
|
+
resolveVariant(taskVariant) {
|
|
23333
|
+
return taskVariant?.trim() || null;
|
|
23334
|
+
}
|
|
23289
23335
|
runDetached(operation, message, taskId) {
|
|
23290
23336
|
operation.catch((error) => {
|
|
23291
23337
|
markGatewayFailure("worker", error);
|
|
@@ -23663,6 +23709,7 @@ function createTaskFromTemplate(templateId, options) {
|
|
|
23663
23709
|
name: `${options.namePrefix ?? ""}${tmpl.name}`,
|
|
23664
23710
|
agent: tmpl.agent,
|
|
23665
23711
|
model: tmpl.model ?? "default",
|
|
23712
|
+
variant: tmpl.variant,
|
|
23666
23713
|
prompt: tmpl.prompt,
|
|
23667
23714
|
cwd: tmpl.cwd ?? null,
|
|
23668
23715
|
category: tmpl.category ?? "general",
|
|
@@ -26068,17 +26115,49 @@ function runOpenCode(executable, args, cwd, timeoutMs) {
|
|
|
26068
26115
|
const child = spawn2(executable, args, {
|
|
26069
26116
|
cwd,
|
|
26070
26117
|
env: process.env,
|
|
26071
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
26118
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
26119
|
+
detached: process.platform !== "win32"
|
|
26072
26120
|
});
|
|
26073
26121
|
let stdout = "";
|
|
26074
26122
|
let stderr = "";
|
|
26075
26123
|
let failure = null;
|
|
26076
|
-
let
|
|
26124
|
+
let settled = false;
|
|
26125
|
+
let forceKillTimer = null;
|
|
26126
|
+
let finalRejectTimer = null;
|
|
26127
|
+
let timer;
|
|
26128
|
+
const signalProcessTree = (signal) => {
|
|
26129
|
+
if (process.platform !== "win32" && child.pid) {
|
|
26130
|
+
try {
|
|
26131
|
+
process.kill(-child.pid, signal);
|
|
26132
|
+
return;
|
|
26133
|
+
} catch {
|
|
26134
|
+
}
|
|
26135
|
+
}
|
|
26136
|
+
child.kill(signal);
|
|
26137
|
+
};
|
|
26138
|
+
const rejectOnce = (error) => {
|
|
26139
|
+
failure ??= error;
|
|
26140
|
+
if (settled) return;
|
|
26141
|
+
settled = true;
|
|
26142
|
+
clearTimeout(timer);
|
|
26143
|
+
if (forceKillTimer) clearTimeout(forceKillTimer);
|
|
26144
|
+
if (finalRejectTimer) clearTimeout(finalRejectTimer);
|
|
26145
|
+
reject(failure);
|
|
26146
|
+
};
|
|
26147
|
+
const terminate = (error) => {
|
|
26148
|
+
if (failure) return;
|
|
26149
|
+
failure = error;
|
|
26150
|
+
signalProcessTree("SIGTERM");
|
|
26151
|
+
forceKillTimer = setTimeout(() => {
|
|
26152
|
+
signalProcessTree("SIGKILL");
|
|
26153
|
+
rejectOnce(error);
|
|
26154
|
+
}, 1e3);
|
|
26155
|
+
finalRejectTimer = setTimeout(() => rejectOnce(error), 2e3);
|
|
26156
|
+
};
|
|
26077
26157
|
const append = (current, chunk) => {
|
|
26078
26158
|
const next = current + chunk.toString();
|
|
26079
26159
|
if (Buffer.byteLength(next) > MAX_OUTPUT_BYTES && failure === null) {
|
|
26080
|
-
|
|
26081
|
-
child.kill("SIGTERM");
|
|
26160
|
+
terminate(new Error(`OpenCode \u8F93\u51FA\u8D85\u8FC7 ${MAX_OUTPUT_BYTES} bytes`));
|
|
26082
26161
|
}
|
|
26083
26162
|
return next.slice(-MAX_OUTPUT_BYTES);
|
|
26084
26163
|
};
|
|
@@ -26089,23 +26168,25 @@ function runOpenCode(executable, args, cwd, timeoutMs) {
|
|
|
26089
26168
|
stderr = append(stderr, chunk);
|
|
26090
26169
|
});
|
|
26091
26170
|
child.once("error", (error) => {
|
|
26092
|
-
|
|
26171
|
+
if (forceKillTimer) return;
|
|
26172
|
+
rejectOnce(error);
|
|
26093
26173
|
});
|
|
26094
|
-
|
|
26095
|
-
|
|
26096
|
-
child.kill("SIGTERM");
|
|
26174
|
+
timer = setTimeout(() => {
|
|
26175
|
+
terminate(new Error(`OpenCode \u547D\u4EE4\u8D85\u8FC7 ${timeoutMs}ms \u672A\u5B8C\u6210`));
|
|
26097
26176
|
}, timeoutMs);
|
|
26098
26177
|
child.once("close", (code) => {
|
|
26099
|
-
if (finished) return;
|
|
26100
|
-
finished = true;
|
|
26101
26178
|
clearTimeout(timer);
|
|
26179
|
+
if (forceKillTimer) return;
|
|
26180
|
+
if (finalRejectTimer) clearTimeout(finalRejectTimer);
|
|
26181
|
+
if (settled) return;
|
|
26182
|
+
settled = true;
|
|
26102
26183
|
if (failure) {
|
|
26103
26184
|
reject(failure);
|
|
26104
26185
|
return;
|
|
26105
26186
|
}
|
|
26106
26187
|
if (code !== 0) {
|
|
26107
26188
|
const detail = cleanOutput(stderr).trim() || `\u9000\u51FA\u7801 ${code ?? "null"}`;
|
|
26108
|
-
reject(new
|
|
26189
|
+
reject(new OpenCodeCommandExitError(`OpenCode ${args.join(" ")} \u5931\u8D25\uFF1A${detail}`));
|
|
26109
26190
|
return;
|
|
26110
26191
|
}
|
|
26111
26192
|
resolve6(cleanOutput(stdout));
|
|
@@ -26115,6 +26196,52 @@ function runOpenCode(executable, args, cwd, timeoutMs) {
|
|
|
26115
26196
|
function parseOpenCodeModels(output) {
|
|
26116
26197
|
return [...new Set(cleanOutput(output).split("\n").map((line) => line.trim()).filter((line) => /^[^\s/]+\/.+/.test(line)))].sort((left, right) => left.localeCompare(right));
|
|
26117
26198
|
}
|
|
26199
|
+
function isRecord(value) {
|
|
26200
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
26201
|
+
}
|
|
26202
|
+
function findJsonObjectEnd(value, start) {
|
|
26203
|
+
let depth = 0;
|
|
26204
|
+
let inString = false;
|
|
26205
|
+
let escaped = false;
|
|
26206
|
+
for (let index2 = start; index2 < value.length; index2 += 1) {
|
|
26207
|
+
const character = value[index2];
|
|
26208
|
+
if (inString) {
|
|
26209
|
+
if (escaped) escaped = false;
|
|
26210
|
+
else if (character === "\\") escaped = true;
|
|
26211
|
+
else if (character === '"') inString = false;
|
|
26212
|
+
continue;
|
|
26213
|
+
}
|
|
26214
|
+
if (character === '"') inString = true;
|
|
26215
|
+
else if (character === "{") depth += 1;
|
|
26216
|
+
else if (character === "}" && --depth === 0) return index2 + 1;
|
|
26217
|
+
}
|
|
26218
|
+
return null;
|
|
26219
|
+
}
|
|
26220
|
+
function parseOpenCodeModelMetadata(output) {
|
|
26221
|
+
const cleaned = cleanOutput(output);
|
|
26222
|
+
const models = /* @__PURE__ */ new Set();
|
|
26223
|
+
const variantsByModel = {};
|
|
26224
|
+
const headingPattern = /^([^\s/]+\/[^\r\n]+)\r?\n\s*(?=\{)/gm;
|
|
26225
|
+
for (const match2 of cleaned.matchAll(headingPattern)) {
|
|
26226
|
+
const model = match2[1].trim();
|
|
26227
|
+
models.add(model);
|
|
26228
|
+
let objectStart = (match2.index ?? 0) + match2[0].length;
|
|
26229
|
+
while (/\s/.test(cleaned[objectStart] ?? "")) objectStart += 1;
|
|
26230
|
+
if (cleaned[objectStart] !== "{") continue;
|
|
26231
|
+
const objectEnd = findJsonObjectEnd(cleaned, objectStart);
|
|
26232
|
+
if (objectEnd === null) continue;
|
|
26233
|
+
try {
|
|
26234
|
+
const metadata = JSON.parse(cleaned.slice(objectStart, objectEnd));
|
|
26235
|
+
if (!isRecord(metadata) || !isRecord(metadata.variants)) continue;
|
|
26236
|
+
variantsByModel[model] = Object.keys(metadata.variants).filter((variant) => variant.trim().length > 0).sort((left, right) => left.localeCompare(right));
|
|
26237
|
+
} catch {
|
|
26238
|
+
}
|
|
26239
|
+
}
|
|
26240
|
+
return {
|
|
26241
|
+
models: [...models].sort((left, right) => left.localeCompare(right)),
|
|
26242
|
+
variantsByModel
|
|
26243
|
+
};
|
|
26244
|
+
}
|
|
26118
26245
|
function parseOpenCodeAgents(output) {
|
|
26119
26246
|
const agents = /* @__PURE__ */ new Map();
|
|
26120
26247
|
for (const line of cleanOutput(output).split("\n")) {
|
|
@@ -26138,14 +26265,18 @@ async function loadOpenCodeCatalog(cwd, options = {}) {
|
|
|
26138
26265
|
return cached.result;
|
|
26139
26266
|
}
|
|
26140
26267
|
const result = Promise.all([
|
|
26141
|
-
runOpenCode(executable, ["models"], cwd, timeoutMs)
|
|
26268
|
+
runOpenCode(executable, ["models", "--verbose"], cwd, timeoutMs).catch((error) => {
|
|
26269
|
+
if (!(error instanceof OpenCodeCommandExitError)) throw error;
|
|
26270
|
+
return runOpenCode(executable, ["models"], cwd, timeoutMs);
|
|
26271
|
+
}),
|
|
26142
26272
|
runOpenCode(executable, ["agent", "list"], cwd, timeoutMs)
|
|
26143
26273
|
]).then(([modelsOutput, agentsOutput]) => {
|
|
26144
|
-
const
|
|
26274
|
+
const metadata = parseOpenCodeModelMetadata(modelsOutput);
|
|
26275
|
+
const models = metadata.models.length > 0 ? metadata.models : parseOpenCodeModels(modelsOutput);
|
|
26145
26276
|
const agents = parseOpenCodeAgents(agentsOutput).filter((agent) => agent.mode !== "subagent");
|
|
26146
26277
|
if (models.length === 0) throw new Error("OpenCode \u6CA1\u6709\u8FD4\u56DE\u53EF\u7528\u6A21\u578B");
|
|
26147
26278
|
if (agents.length === 0) throw new Error("OpenCode \u6CA1\u6709\u8FD4\u56DE\u53EF\u76F4\u63A5\u8FD0\u884C\u7684\u4E3B Agent");
|
|
26148
|
-
return { cwd, models, agents };
|
|
26279
|
+
return { cwd, models, variantsByModel: metadata.variantsByModel, agents };
|
|
26149
26280
|
});
|
|
26150
26281
|
if (options.useCache !== false) {
|
|
26151
26282
|
catalogCache.set(cacheKey, { expiresAt: Date.now() + CATALOG_CACHE_MS, result });
|
|
@@ -26155,7 +26286,7 @@ async function loadOpenCodeCatalog(cwd, options = {}) {
|
|
|
26155
26286
|
}
|
|
26156
26287
|
return result;
|
|
26157
26288
|
}
|
|
26158
|
-
var CATALOG_CACHE_MS, COMMAND_TIMEOUT_MS, MAX_OUTPUT_BYTES, ANSI_PATTERN, catalogCache;
|
|
26289
|
+
var CATALOG_CACHE_MS, COMMAND_TIMEOUT_MS, MAX_OUTPUT_BYTES, ANSI_PATTERN, OpenCodeCommandExitError, catalogCache;
|
|
26159
26290
|
var init_opencode_catalog = __esm({
|
|
26160
26291
|
"src/core/opencode-catalog.ts"() {
|
|
26161
26292
|
"use strict";
|
|
@@ -26164,6 +26295,8 @@ var init_opencode_catalog = __esm({
|
|
|
26164
26295
|
COMMAND_TIMEOUT_MS = 2e4;
|
|
26165
26296
|
MAX_OUTPUT_BYTES = 4 * 1024 * 1024;
|
|
26166
26297
|
ANSI_PATTERN = /\x1B(?:[@-_][0-?]*[ -/]*[@-~]|\][^\x07]*(?:\x07|\x1B\\))/g;
|
|
26298
|
+
OpenCodeCommandExitError = class extends Error {
|
|
26299
|
+
};
|
|
26167
26300
|
catalogCache = /* @__PURE__ */ new Map();
|
|
26168
26301
|
}
|
|
26169
26302
|
});
|
|
@@ -26254,6 +26387,7 @@ function clientMessages(locale) {
|
|
|
26254
26387
|
"details.copySuccess",
|
|
26255
26388
|
"details.id",
|
|
26256
26389
|
"details.project",
|
|
26390
|
+
"details.variant",
|
|
26257
26391
|
"details.prompt",
|
|
26258
26392
|
"details.result",
|
|
26259
26393
|
"details.category",
|
|
@@ -26354,6 +26488,7 @@ function clientMessages(locale) {
|
|
|
26354
26488
|
"catalog.chooseProject",
|
|
26355
26489
|
"catalog.defaultModel",
|
|
26356
26490
|
"catalog.defaultProvider",
|
|
26491
|
+
"catalog.defaultVariant",
|
|
26357
26492
|
"catalog.loading",
|
|
26358
26493
|
"catalog.loaded",
|
|
26359
26494
|
"catalog.failed",
|
|
@@ -26478,23 +26613,23 @@ function renderLayout(options) {
|
|
|
26478
26613
|
function detailSession(value){if(!value)return text('details.none');const session=String(value);return session.length<=10?session:session.slice(0,6)+'***'+session.slice(-4)}
|
|
26479
26614
|
function detailTaskResult(data){const presentation=data._resultPresentation;if(!presentation)return text('details.none');const parts=[];if(Array.isArray(presentation.errors)&&presentation.errors.length)parts.push(presentation.errors.join('\\n'));if(presentation.text)parts.push(presentation.text);return parts.join('\\n\\n')||text('details.none')}
|
|
26480
26615
|
function detailField(label,value,options={}){const item=document.createElement('div');item.className='detail-item'+(options.wide?' wide':'');const name=document.createElement('div');name.className='detail-label';name.textContent=label;const content=options.long?document.createElement('pre'):document.createElement('div');content.className='detail-value'+(options.mono?' mono':'')+(options.long?' long':'');content.textContent=value===null||value===undefined||value===''?text('details.none'):String(value);item.append(name,content);return item}
|
|
26481
|
-
function renderDetailHistory(runs){const section=document.createElement('section');section.className='detail-history';const title=document.createElement('h3');title.textContent=text('details.history');section.appendChild(title);if(!Array.isArray(runs)||runs.length===0){const empty=document.createElement('div');empty.className='muted small';empty.textContent=text('details.noHistory');section.appendChild(empty);return section}const list=document.createElement('div');list.className='detail-history-list';for(const run of runs){const item=document.createElement('div');item.className='detail-history-item';const primary=document.createElement('strong');primary.textContent='Run #'+run.id+' \xB7 '+detailStatus('run',run.status);const secondary=document.createElement('span');secondary.className='muted';secondary.textContent=detailDate(run.startedAt)+(run.model?' \xB7 '+detailModel(run.model):'');item.append(primary,secondary);list.appendChild(item)}section.appendChild(list);return section}
|
|
26616
|
+
function renderDetailHistory(runs){const section=document.createElement('section');section.className='detail-history';const title=document.createElement('h3');title.textContent=text('details.history');section.appendChild(title);if(!Array.isArray(runs)||runs.length===0){const empty=document.createElement('div');empty.className='muted small';empty.textContent=text('details.noHistory');section.appendChild(empty);return section}const list=document.createElement('div');list.className='detail-history-list';for(const run of runs){const item=document.createElement('div');item.className='detail-history-item';const primary=document.createElement('strong');primary.textContent='Run #'+run.id+' \xB7 '+detailStatus('run',run.status);const secondary=document.createElement('span');secondary.className='muted';secondary.textContent=detailDate(run.startedAt)+(run.model?' \xB7 '+detailModel(run.model):'')+(run.variant?' \xB7 '+run.variant:'');item.append(primary,secondary);list.appendChild(item)}section.appendChild(list);return section}
|
|
26482
26617
|
function detailFields(type,data){if(type==='task')return [
|
|
26483
26618
|
[text('details.id'),'#'+data.id],[text('table.name'),data.name],[text('table.status'),detailStatus('task',data.status)],[text('details.project'),data.cwd,{wide:true,mono:true}],
|
|
26484
|
-
[text('table.agent'),data.agent],[text('table.model'),detailModel(data.model)],[text('details.prompt'),data.prompt,{wide:true,long:true}],
|
|
26619
|
+
[text('table.agent'),data.agent],[text('table.model'),detailModel(data.model)],[text('details.variant'),data.variant||text('details.default')],[text('details.prompt'),data.prompt,{wide:true,long:true}],
|
|
26485
26620
|
[text('details.category'),data.category],[text('details.batch'),data.batchId],[text('details.dependency'),data.dependsOn?'#'+data.dependsOn:text('details.none')],
|
|
26486
26621
|
[text('details.importance'),data.importance],[text('details.urgency'),data.urgency],[text('details.retryCount'),String(data.retryCount??0)+' / '+String(data.maxRetries??0)],
|
|
26487
26622
|
[text('details.retryBackoff'),detailDuration(data.retryBackoffMs)],[text('details.timeout'),detailDuration(data.timeoutMs)],[text('details.scheduledAt'),detailDate(data.scheduledAt)],
|
|
26488
26623
|
[text('details.createdAt'),detailDate(data.createdAt)],[text('details.startedAt'),detailDate(data.startedAt)],[text('details.finishedAt'),detailDate(data.finishedAt)],
|
|
26489
26624
|
[text('details.result'),detailTaskResult(data),{wide:true,long:true}]
|
|
26490
26625
|
];if(type==='run'){const started=data.startedAt?new Date(data.startedAt).getTime():null;const finished=data.finishedAt?new Date(data.finishedAt).getTime():null;return [
|
|
26491
|
-
[text('details.id'),'Run #'+data.id],[text('details.taskId'),'#'+data.taskId],[text('table.status'),detailStatus('run',data.status)],[text('table.model'),detailModel(data.model)],
|
|
26626
|
+
[text('details.id'),'Run #'+data.id],[text('details.taskId'),'#'+data.taskId],[text('table.status'),detailStatus('run',data.status)],[text('table.model'),detailModel(data.model)],[text('details.variant'),data.variant||text('details.default')],
|
|
26492
26627
|
[text('details.session'),detailSession(data.sessionId)],[text('details.startedAt'),detailDate(data.startedAt)],[text('details.finishedAt'),detailDate(data.finishedAt)],
|
|
26493
26628
|
[text('table.duration'),started!==null?detailDuration((finished??Date.now())-started):text('details.none')],[text('details.heartbeat'),detailDate(data.heartbeatAt)],
|
|
26494
26629
|
[text('details.process'),'Worker PID '+String(data.workerPid??'\u2014')+' \xB7 OpenCode PID '+String(data.childPid??'\u2014'),{wide:true,mono:true}]
|
|
26495
26630
|
];}const scheduleRule=data.scheduleType==='cron'?data.cronExpr:data.scheduleType==='recurring'?detailDuration(data.intervalMs):detailDate(data.runAt);return [
|
|
26496
26631
|
[text('details.id'),'#'+data.id],[text('table.name'),data.name],[text('details.enabled'),data.enabled?text('details.enabledYes'):text('details.enabledNo')],[text('details.project'),data.cwd,{wide:true,mono:true}],
|
|
26497
|
-
[text('table.agent'),data.agent],[text('table.model'),detailModel(data.model)],[text('details.prompt'),data.prompt,{wide:true,long:true}],
|
|
26632
|
+
[text('table.agent'),data.agent],[text('table.model'),detailModel(data.model)],[text('details.variant'),data.variant||text('details.default')],[text('details.prompt'),data.prompt,{wide:true,long:true}],
|
|
26498
26633
|
[text('template.scheduleType'),detailScheduleType(data.scheduleType)],[text('details.scheduleRule'),scheduleRule],[text('details.category'),data.category],[text('details.batch'),data.batchId],
|
|
26499
26634
|
[text('details.importance'),data.importance],[text('details.urgency'),data.urgency],[text('details.maxInstances'),data.maxInstances],[text('details.maxRetries'),data.maxRetries??0],
|
|
26500
26635
|
[text('details.retryBackoff'),detailDuration(data.retryBackoffMs)],[text('details.timeout'),detailDuration(data.timeoutMs)],[text('details.lastRun'),detailDate(data.lastRunAt)],[text('details.nextRun'),detailDate(data.nextRunAt)],
|
|
@@ -26511,12 +26646,20 @@ function renderLayout(options) {
|
|
|
26511
26646
|
function updateTaskProjectStatus(){const node=taskField('project-status');if(!node)return;const cwd=taskField('cwd').value.trim();if(!cwd){node.textContent='';return}const project=taskProjects()[cwd];node.textContent=project?text('task.projectExisting',project):text('task.projectNew')}
|
|
26512
26647
|
const catalogTimers={};const catalogRequests={};const catalogModels={};
|
|
26513
26648
|
function catalogField(prefix,name){return document.getElementById(prefix+'-'+name)}
|
|
26514
|
-
function resetCatalog(prefix){const agent=catalogField(prefix,'agent');const provider=catalogField(prefix,'model-provider');const model=catalogField(prefix,'model');if(!agent||!provider||!model)return;catalogModels[prefix]=[];agent.replaceChildren(new Option(text('catalog.chooseProject'),''));provider.replaceChildren(new Option(text('catalog.defaultProvider'),''));model.replaceChildren(new Option(text('catalog.defaultModel'),'default'));agent.disabled=false;provider.disabled=true;model.disabled=true;catalogField(prefix,'catalog-status').textContent='';}
|
|
26649
|
+
function resetCatalog(prefix){const agent=catalogField(prefix,'agent');const provider=catalogField(prefix,'model-provider');const model=catalogField(prefix,'model');const variant=catalogField(prefix,'variant');if(!agent||!provider||!model||!variant)return;const preferredVariant=variant.dataset.preferred||'';catalogModels[prefix]=[];agent.replaceChildren(new Option(text('catalog.chooseProject'),''));provider.replaceChildren(new Option(text('catalog.defaultProvider'),''));model.replaceChildren(new Option(text('catalog.defaultModel'),'default'));variant.replaceChildren(new Option(text('catalog.defaultVariant'),''));if(preferredVariant)appendCurrentOption(variant,preferredVariant);variant.value=preferredVariant;agent.disabled=false;provider.disabled=true;model.disabled=true;variant.disabled=!preferredVariant;catalogField(prefix,'catalog-status').textContent='';}
|
|
26515
26650
|
function appendCurrentOption(select,value){if(!value||[...select.options].some(option=>option.value===value))return;select.appendChild(new Option(value,value));}
|
|
26651
|
+
function setPreferredVariant(prefix,modelValue,variantValue){const variant=catalogField(prefix,'variant');if(!variant)return;const preferred=variantValue||'';variant.dataset.preferred=preferred;variant.dataset.preferredModel=modelValue||'default';variant.replaceChildren(new Option(text('catalog.defaultVariant'),''));if(preferred)appendCurrentOption(variant,preferred);variant.value=preferred;variant.disabled=!preferred}
|
|
26652
|
+
function invalidateVariantRequest(prefix){const key=prefix+'-variant';catalogRequests[key]=(catalogRequests[key]||0)+1}
|
|
26653
|
+
function invalidateCatalogRequests(prefix){clearTimeout(catalogTimers[prefix]);catalogRequests[prefix]=(catalogRequests[prefix]||0)+1;invalidateVariantRequest(prefix)}
|
|
26654
|
+
function clearVariantPreference(prefix){const variant=catalogField(prefix,'variant');if(!variant)return;invalidateVariantRequest(prefix);variant.dataset.preferred='';variant.dataset.preferredModel='';variant.replaceChildren(new Option(text('catalog.defaultVariant'),''));variant.value='';variant.disabled=true}
|
|
26655
|
+
function handleProviderChange(prefix){clearVariantPreference(prefix);populateModelOptions(prefix)}
|
|
26656
|
+
function handleModelChange(prefix){clearVariantPreference(prefix);populateVariantOptions(prefix)}
|
|
26657
|
+
function handleVariantChange(prefix){const variant=catalogField(prefix,'variant');if(!variant)return;invalidateVariantRequest(prefix);variant.dataset.preferred='';variant.dataset.preferredModel=''}
|
|
26516
26658
|
function modelProvider(value){const slash=value.indexOf('/');return slash>0?value.slice(0,slash):''}
|
|
26517
|
-
function populateModelOptions(prefix,preferredModel=''){const provider=catalogField(prefix,'model-provider');const model=catalogField(prefix,'model');if(!provider||!model)return;const selectedProvider=provider.value;model.replaceChildren();if(!selectedProvider){model.appendChild(new Option(text('catalog.defaultModel'),'default'));model.disabled=true;return}const available=(catalogModels[prefix]||[]).filter(value=>modelProvider(value)===selectedProvider);for(const value of available)model.appendChild(new Option(value,value));if(preferredModel&&available.includes(preferredModel))model.value=preferredModel;model.disabled=available.length===0}
|
|
26659
|
+
function populateModelOptions(prefix,preferredModel=''){const provider=catalogField(prefix,'model-provider');const model=catalogField(prefix,'model');if(!provider||!model)return;const selectedProvider=provider.value;model.replaceChildren();if(!selectedProvider){model.appendChild(new Option(text('catalog.defaultModel'),'default'));model.disabled=true;populateVariantOptions(prefix);return}const available=(catalogModels[prefix]||[]).filter(value=>modelProvider(value)===selectedProvider);for(const value of available)model.appendChild(new Option(value,value));if(preferredModel&&available.includes(preferredModel))model.value=preferredModel;model.disabled=available.length===0;populateVariantOptions(prefix)}
|
|
26660
|
+
async function populateVariantOptions(prefix,preferredVariant=''){const cwd=catalogField(prefix,'cwd')?.value.trim()||'';const model=catalogField(prefix,'model');const variant=catalogField(prefix,'variant');if(!model||!variant)return;const selectedModel=model.value;const preferred=preferredVariant||(variant.dataset.preferredModel===selectedModel?variant.dataset.preferred||'':'');if(!cwd||!selectedModel||selectedModel==='default'){variant.replaceChildren(new Option(text('catalog.defaultVariant'),''));if(preferred)appendCurrentOption(variant,preferred);variant.value=preferred;variant.dataset.preferred='';variant.dataset.preferredModel='';variant.disabled=!preferred;return}if(!preferred){variant.replaceChildren(new Option(text('catalog.defaultVariant'),''));variant.value=''}const requestKey=prefix+'-variant';const request=(catalogRequests[requestKey]||0)+1;catalogRequests[requestKey]=request;variant.disabled=true;try{const data=await readJson(await fetch('/api/opencode/catalog?cwd='+encodeURIComponent(cwd)));if(catalogRequests[requestKey]!==request||catalogField(prefix,'cwd')?.value.trim()!==cwd||model.value!==selectedModel)return;const available=Array.isArray(data.variantsByModel?.[selectedModel])?data.variantsByModel[selectedModel]:[];variant.replaceChildren(new Option(text('catalog.defaultVariant'),''));for(const value of available)variant.appendChild(new Option(value,value));if(preferred)appendCurrentOption(variant,preferred);variant.value=[...variant.options].some(option=>option.value===preferred)?preferred:'';variant.dataset.preferred='';variant.dataset.preferredModel='';variant.disabled=available.length===0&&!preferred}catch(error){if(catalogRequests[requestKey]!==request||catalogField(prefix,'cwd')?.value.trim()!==cwd||model.value!==selectedModel)return;if(preferred)appendCurrentOption(variant,preferred);variant.value=preferred;variant.dataset.preferred=preferred;variant.dataset.preferredModel=selectedModel;variant.disabled=!preferred}}
|
|
26518
26661
|
async function loadCatalog(prefix,preferredAgent='',preferredModel='default',preserveUnavailable=false){const cwd=catalogField(prefix,'cwd')?.value.trim()||'';const status=catalogField(prefix,'catalog-status');const agent=catalogField(prefix,'agent');const provider=catalogField(prefix,'model-provider');const model=catalogField(prefix,'model');if(!cwd||!status||!agent||!provider||!model){if(!cwd)resetCatalog(prefix);return}const request=(catalogRequests[prefix]||0)+1;catalogRequests[prefix]=request;status.dataset.state='loading';status.textContent=text('catalog.loading');agent.disabled=true;provider.disabled=true;model.disabled=true;try{const data=await readJson(await fetch('/api/opencode/catalog?cwd='+encodeURIComponent(cwd)));if(catalogRequests[prefix]!==request||catalogField(prefix,'cwd').value.trim()!==cwd)return;agent.replaceChildren();for(const item of data.agents){const label=item.name+' \u2014 '+text('catalog.'+item.mode);agent.appendChild(new Option(label,item.name))}if(preserveUnavailable)appendCurrentOption(agent,preferredAgent);const defaultAgent=preferredAgent||data.agents.find(item=>item.name==='build')?.name||data.agents.find(item=>item.mode==='primary')?.name||data.agents[0]?.name||'';agent.value=[...agent.options].some(option=>option.value===defaultAgent)?defaultAgent:(agent.options[0]?.value||'');catalogModels[prefix]=[...data.models];if(preserveUnavailable&&preferredModel&&preferredModel!=='default'&&!catalogModels[prefix].includes(preferredModel))catalogModels[prefix].push(preferredModel);provider.replaceChildren(new Option(text('catalog.defaultProvider'),''));for(const name of [...new Set(catalogModels[prefix].map(modelProvider).filter(Boolean))].sort())provider.appendChild(new Option(name,name));const preferredProvider=preferredModel==='default'?'':modelProvider(preferredModel);provider.value=[...provider.options].some(option=>option.value===preferredProvider)?preferredProvider:'';populateModelOptions(prefix,preferredModel);status.dataset.state='ready';status.textContent=text('catalog.loaded',{agents:data.agents.length,models:data.models.length})}catch(error){if(catalogRequests[prefix]!==request)return;resetCatalog(prefix);if(preserveUnavailable){appendCurrentOption(agent,preferredAgent);if(preferredModel&&preferredModel!=='default'){catalogModels[prefix]=[preferredModel];appendCurrentOption(provider,modelProvider(preferredModel));provider.value=modelProvider(preferredModel);populateModelOptions(prefix,preferredModel)}}status.dataset.state='error';status.textContent=text('catalog.failed',{error:error.message})}finally{if(catalogRequests[prefix]===request){agent.disabled=false;provider.disabled=false;if(provider.value)model.disabled=false}}}
|
|
26519
|
-
function scheduleCatalogLoad(prefix){
|
|
26662
|
+
function scheduleCatalogLoad(prefix){invalidateCatalogRequests(prefix);resetCatalog(prefix);catalogTimers[prefix]=setTimeout(()=>loadCatalog(prefix),450)}
|
|
26520
26663
|
let directoryTargetId='';let directoryCurrent='';let directoryEntries=[];let directoryShowHidden=false;
|
|
26521
26664
|
function renderDirectoryEntries(){const list=document.getElementById('directory-list');list.replaceChildren();const entries=directoryEntries.filter(entry=>directoryShowHidden||!entry.hidden);const hidden=document.getElementById('directory-hidden');hidden.textContent=text(directoryShowHidden?'action.hideHidden':'action.showHidden');if(entries.length===0){const empty=document.createElement('div');empty.className='directory-empty';empty.textContent=text('directory.empty');list.appendChild(empty);return}for(const entry of entries){const button=document.createElement('button');button.type='button';button.className='directory-item';button.innerHTML='${icon("folder")}<span></span>';button.querySelector('span').textContent=entry.name;button.onclick=()=>browseDirectory(entry.path);list.appendChild(button)}}
|
|
26522
26665
|
async function browseDirectory(path=''){const choose=document.getElementById('directory-choose');choose.disabled=true;try{const suffix=path?'?path='+encodeURIComponent(path):'';const data=await readJson(await fetch('/api/filesystem/directories'+suffix));directoryCurrent=data.path;directoryEntries=data.directories;document.getElementById('directory-path').textContent=data.path;document.getElementById('directory-up').disabled=data.parent===data.path;document.getElementById('directory-up').onclick=()=>browseDirectory(data.parent);document.getElementById('directory-home').onclick=()=>browseDirectory(data.home);renderDirectoryEntries();choose.disabled=false;return true}catch(error){directoryCurrent='';directoryEntries=[];document.getElementById('directory-path').textContent='';renderDirectoryEntries();showToast(error.message,'error');return false}}
|
|
@@ -26526,16 +26669,16 @@ function renderLayout(options) {
|
|
|
26526
26669
|
function updateDurationControl(id){const preset=document.getElementById(id+'-preset');const custom=document.getElementById(id+'-custom');const input=document.getElementById(id+'-value');const visible=preset.value==='custom';custom.hidden=!visible;input.required=visible;if(visible&&!input.value)input.value='1'}
|
|
26527
26670
|
function readDuration(id){const preset=document.getElementById(id+'-preset').value;if(preset==='')return '';if(preset!=='custom')return preset==='0'?'0':preset+'ms';const value=document.getElementById(id+'-value').value.trim();return value===''?'':value+document.getElementById(id+'-unit').value}
|
|
26528
26671
|
function setDuration(id,milliseconds){const preset=document.getElementById(id+'-preset');const exact=milliseconds==null?'':String(milliseconds);if([...preset.options].some(option=>option.value===exact)){preset.value=exact;updateDurationControl(id);return}preset.value='custom';const input=document.getElementById(id+'-value');const unit=document.getElementById(id+'-unit');const units=[['d',86400000],['h',3600000],['min',60000],['s',1000]];let matched=false;for(const [name,factor] of units){if(milliseconds!=null&&(milliseconds===0||milliseconds%factor===0)){input.value=String(milliseconds/factor);unit.value=name;matched=true;break}}if(!matched){input.value=String((milliseconds??60000)/1000);unit.value='s'}updateDurationControl(id)}
|
|
26529
|
-
function openTaskCreator(){const form=document.getElementById('task-form');form.reset();taskField('id').value='';taskField('cwd').readOnly=false;taskField('cwd-picker').hidden=false;taskField('cwd').value=form.dataset.defaultCwd||'';setDuration('task-retry-backoff',30000);setDuration('task-timeout',null);taskField('dialog-title').textContent=text('task.createTitle');taskField('save').textContent=text('action.saveTask');updateTaskProjectStatus();resetCatalog('task');document.getElementById('task-dialog').showModal();if(taskField('cwd').value)loadCatalog('task');setTimeout(()=>taskField('name').focus(),50)}
|
|
26530
|
-
async function openTaskEditor(id){try{const data=await readJson(await fetch('/api/tasks/'+id));taskField('id').value=String(id);taskField('cwd').value=data.cwd||'';taskField('cwd').readOnly=true;taskField('cwd-picker').hidden=true;taskField('name').value=data.name||'';taskField('prompt').value=data.prompt||'';taskField('category').value=data.category||'general';taskField('batch').value=data.batchId||'';taskField('importance').value=String(data.importance??3);taskField('urgency').value=String(data.urgency??3);taskField('max-retries').value=String(data.maxRetries??3);setDuration('task-retry-backoff',data.retryBackoffMs??30000);setDuration('task-timeout',data.timeoutMs);taskField('dialog-title').textContent=text('task.editTitle');taskField('save').textContent=text('action.updateTask');updateTaskProjectStatus();resetCatalog('task');document.getElementById('task-dialog').showModal();loadCatalog('task',data.agent||'',data.model||'default',true);setTimeout(()=>taskField('name').focus(),50)}catch(error){showToast(error.message,'error')}}
|
|
26531
|
-
async function saveTask(event){event.preventDefault();const form=document.getElementById('task-form');if(!form.reportValidity())return;const id=taskField('id').value;const body={name:taskField('name').value,cwd:taskField('cwd').value,agent:taskField('agent').value,model:taskField('model').value,prompt:taskField('prompt').value,category:taskField('category').value,batchId:taskField('batch').value,importance:Number(taskField('importance').value),urgency:Number(taskField('urgency').value),maxRetries:Number(taskField('max-retries').value),retryBackoff:readDuration('task-retry-backoff'),timeout:readDuration('task-timeout')};const button=taskField('save');button.disabled=true;try{const data=await readJson(await fetch(id?'/api/tasks/'+id:'/api/tasks',{method:id?'PUT':'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(body)}));showToast(text(id?'feedback.taskUpdated':'feedback.taskCreated',{id:data.task.id}));document.getElementById('task-dialog').close();setTimeout(()=>location.assign(id?location.href:'/?cwd='+encodeURIComponent(data.task.cwd||'')),450)}catch(error){showToast(error.message,'error')}finally{button.disabled=false}}
|
|
26672
|
+
function openTaskCreator(){invalidateCatalogRequests('task');const form=document.getElementById('task-form');form.reset();taskField('id').value='';setPreferredVariant('task','default','');taskField('cwd').readOnly=false;taskField('cwd-picker').hidden=false;taskField('cwd').value=form.dataset.defaultCwd||'';setDuration('task-retry-backoff',30000);setDuration('task-timeout',null);taskField('dialog-title').textContent=text('task.createTitle');taskField('save').textContent=text('action.saveTask');updateTaskProjectStatus();resetCatalog('task');document.getElementById('task-dialog').showModal();if(taskField('cwd').value)loadCatalog('task');setTimeout(()=>taskField('name').focus(),50)}
|
|
26673
|
+
async function openTaskEditor(id){invalidateCatalogRequests('task');try{const data=await readJson(await fetch('/api/tasks/'+id));document.getElementById('task-form').reset();taskField('id').value=String(id);taskField('cwd').value=data.cwd||'';taskField('cwd').readOnly=true;taskField('cwd-picker').hidden=true;taskField('name').value=data.name||'';taskField('prompt').value=data.prompt||'';taskField('category').value=data.category||'general';taskField('batch').value=data.batchId||'';taskField('importance').value=String(data.importance??3);taskField('urgency').value=String(data.urgency??3);taskField('max-retries').value=String(data.maxRetries??3);setDuration('task-retry-backoff',data.retryBackoffMs??30000);setDuration('task-timeout',data.timeoutMs);taskField('dialog-title').textContent=text('task.editTitle');taskField('save').textContent=text('action.updateTask');updateTaskProjectStatus();setPreferredVariant('task',data.model||'default',data.variant||'');resetCatalog('task');document.getElementById('task-dialog').showModal();loadCatalog('task',data.agent||'',data.model||'default',true);setTimeout(()=>taskField('name').focus(),50)}catch(error){showToast(error.message,'error')}}
|
|
26674
|
+
async function saveTask(event){event.preventDefault();const form=document.getElementById('task-form');if(!form.reportValidity())return;const id=taskField('id').value;const body={name:taskField('name').value,cwd:taskField('cwd').value,agent:taskField('agent').value,model:taskField('model').value,variant:taskField('variant').value,prompt:taskField('prompt').value,category:taskField('category').value,batchId:taskField('batch').value,importance:Number(taskField('importance').value),urgency:Number(taskField('urgency').value),maxRetries:Number(taskField('max-retries').value),retryBackoff:readDuration('task-retry-backoff'),timeout:readDuration('task-timeout')};const button=taskField('save');button.disabled=true;try{const data=await readJson(await fetch(id?'/api/tasks/'+id:'/api/tasks',{method:id?'PUT':'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(body)}));showToast(text(id?'feedback.taskUpdated':'feedback.taskCreated',{id:data.task.id}));document.getElementById('task-dialog').close();setTimeout(()=>location.assign(id?location.href:'/?cwd='+encodeURIComponent(data.task.cwd||'')),450)}catch(error){showToast(error.message,'error')}finally{button.disabled=false}}
|
|
26532
26675
|
function localDateTime(milliseconds){const date=new Date(milliseconds);const local=new Date(milliseconds-date.getTimezoneOffset()*60000);return local.toISOString().slice(0,23)}
|
|
26533
26676
|
function updateTemplateScheduleFields(){const type=templateField('schedule-type').value;const fields={cron:templateField('cron-field'),recurring:templateField('interval-field'),delayed:templateField('run-at-field')};for(const [name,node] of Object.entries(fields)){node.hidden=name!==type;for(const control of node.querySelectorAll('input,select'))control.required=false;const required=name==='recurring'?node.querySelector('[id$="-preset"]'):node.querySelector('input');if(required)required.required=name===type;if(name==='recurring'&&name===type)updateDurationControl('template-interval')}}
|
|
26534
26677
|
function setOriginalRunAt(epoch){const input=templateField('run-at');const local=epoch?localDateTime(epoch):'';input.value=local;input.dataset.originalEpoch=epoch?String(epoch):'';input.dataset.originalLocal=local}
|
|
26535
26678
|
function selectedRunAt(){const input=templateField('run-at');return resolveEditedRunAt(input.dataset.originalEpoch?Number(input.dataset.originalEpoch):null,input.dataset.originalLocal||'',input.value)}
|
|
26536
|
-
function openTemplateCreator(){const form=document.getElementById('template-form');form.reset();templateField('id').value='';templateField('dialog-title').textContent=text('template.createTitle');setDuration('template-interval',3600000);setDuration('template-retry-backoff',30000);setDuration('template-timeout',null);setOriginalRunAt(null);templateField('run-at').value=localDateTime(Date.now()+3600000);updateTemplateScheduleFields();resetCatalog('template');document.getElementById('template-dialog').showModal();if(templateField('cwd').value)loadCatalog('template');setTimeout(()=>templateField('name').focus(),50)}
|
|
26537
|
-
async function openTemplateEditor(id){try{const data=await readJson(await fetch('/api/templates/'+id));templateField('id').value=String(id);templateField('dialog-title').textContent=text('template.editTitle');templateField('name').value=data.name||'';templateField('cwd').value=data.cwd||'';templateField('prompt').value=data.prompt||'';templateField('schedule-type').value=data.scheduleType;templateField('cron').value=data.cronExpr||'';setDuration('template-interval',data.intervalMs);setOriginalRunAt(data.runAt||null);if(!data.runAt)templateField('run-at').value=localDateTime(Date.now()+3600000);templateField('category').value=data.category||'general';templateField('batch').value=data.batchId||'';templateField('importance').value=String(data.importance??3);templateField('urgency').value=String(data.urgency??3);templateField('max-instances').value=String(data.maxInstances??1);templateField('max-retries').value=String(data.maxRetries??3);setDuration('template-retry-backoff',data.retryBackoffMs??30000);setDuration('template-timeout',data.timeoutMs);updateTemplateScheduleFields();resetCatalog('template');document.getElementById('template-dialog').showModal();loadCatalog('template',data.agent||'',data.model||'default',true);setTimeout(()=>templateField('name').focus(),50)}catch(error){showToast(error.message,'error')}}
|
|
26538
|
-
async function saveTemplate(event){event.preventDefault();const form=document.getElementById('template-form');if(!form.reportValidity())return;const id=templateField('id').value;const type=templateField('schedule-type').value;const body={name:templateField('name').value,cwd:templateField('cwd').value,agent:templateField('agent').value,model:templateField('model').value,prompt:templateField('prompt').value,scheduleType:type,cronExpr:templateField('cron').value,interval:readDuration('template-interval'),runAt:type==='delayed'?selectedRunAt():null,category:templateField('category').value,batchId:templateField('batch').value,importance:Number(templateField('importance').value),urgency:Number(templateField('urgency').value),maxInstances:Number(templateField('max-instances').value),maxRetries:Number(templateField('max-retries').value),retryBackoff:readDuration('template-retry-backoff'),timeout:readDuration('template-timeout')};const button=templateField('save');button.disabled=true;try{await readJson(await fetch(id?'/api/templates/'+id:'/api/templates',{method:id?'PUT':'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(body)}));showToast(text(id?'feedback.templateUpdated':'feedback.templateCreated'));document.getElementById('template-dialog').close();setTimeout(()=>location.assign(id?location.href:'/templates'),450)}catch(error){showToast(error.message,'error')}finally{button.disabled=false}}
|
|
26679
|
+
function openTemplateCreator(){invalidateCatalogRequests('template');const form=document.getElementById('template-form');form.reset();templateField('id').value='';setPreferredVariant('template','default','');templateField('dialog-title').textContent=text('template.createTitle');setDuration('template-interval',3600000);setDuration('template-retry-backoff',30000);setDuration('template-timeout',null);setOriginalRunAt(null);templateField('run-at').value=localDateTime(Date.now()+3600000);updateTemplateScheduleFields();resetCatalog('template');document.getElementById('template-dialog').showModal();if(templateField('cwd').value)loadCatalog('template');setTimeout(()=>templateField('name').focus(),50)}
|
|
26680
|
+
async function openTemplateEditor(id){invalidateCatalogRequests('template');try{const data=await readJson(await fetch('/api/templates/'+id));document.getElementById('template-form').reset();templateField('id').value=String(id);templateField('dialog-title').textContent=text('template.editTitle');templateField('name').value=data.name||'';templateField('cwd').value=data.cwd||'';templateField('prompt').value=data.prompt||'';templateField('schedule-type').value=data.scheduleType;templateField('cron').value=data.cronExpr||'';setDuration('template-interval',data.intervalMs);setOriginalRunAt(data.runAt||null);if(!data.runAt)templateField('run-at').value=localDateTime(Date.now()+3600000);templateField('category').value=data.category||'general';templateField('batch').value=data.batchId||'';templateField('importance').value=String(data.importance??3);templateField('urgency').value=String(data.urgency??3);templateField('max-instances').value=String(data.maxInstances??1);templateField('max-retries').value=String(data.maxRetries??3);setDuration('template-retry-backoff',data.retryBackoffMs??30000);setDuration('template-timeout',data.timeoutMs);updateTemplateScheduleFields();setPreferredVariant('template',data.model||'default',data.variant||'');resetCatalog('template');document.getElementById('template-dialog').showModal();loadCatalog('template',data.agent||'',data.model||'default',true);setTimeout(()=>templateField('name').focus(),50)}catch(error){showToast(error.message,'error')}}
|
|
26681
|
+
async function saveTemplate(event){event.preventDefault();const form=document.getElementById('template-form');if(!form.reportValidity())return;const id=templateField('id').value;const type=templateField('schedule-type').value;const body={name:templateField('name').value,cwd:templateField('cwd').value,agent:templateField('agent').value,model:templateField('model').value,variant:templateField('variant').value,prompt:templateField('prompt').value,scheduleType:type,cronExpr:templateField('cron').value,interval:readDuration('template-interval'),runAt:type==='delayed'?selectedRunAt():null,category:templateField('category').value,batchId:templateField('batch').value,importance:Number(templateField('importance').value),urgency:Number(templateField('urgency').value),maxInstances:Number(templateField('max-instances').value),maxRetries:Number(templateField('max-retries').value),retryBackoff:readDuration('template-retry-backoff'),timeout:readDuration('template-timeout')};const button=templateField('save');button.disabled=true;try{await readJson(await fetch(id?'/api/templates/'+id:'/api/templates',{method:id?'PUT':'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(body)}));showToast(text(id?'feedback.templateUpdated':'feedback.templateCreated'));document.getElementById('template-dialog').close();setTimeout(()=>location.assign(id?location.href:'/templates'),450)}catch(error){showToast(error.message,'error')}finally{button.disabled=false}}
|
|
26539
26682
|
async function enableTmpl(id){try{await readJson(await fetch('/api/templates/'+id+'/enable',{method:'POST'}));location.reload()}catch(error){showToast(error.message,'error')}}
|
|
26540
26683
|
async function disableTmpl(id){if(!await ask(text('dialog.disableTemplate'),text('dialog.disableTemplateBody')))return;try{await readJson(await fetch('/api/templates/'+id+'/disable',{method:'POST'}));location.reload()}catch(error){showToast(error.message,'error')}}
|
|
26541
26684
|
async function deleteTmpl(id){if(!await ask(text('dialog.deleteTemplate'),text('dialog.deleteTemplateBody'),true))return;try{await readJson(await fetch('/api/templates/'+id,{method:'DELETE'}));location.reload()}catch(error){showToast(error.message,'error')}}
|
|
@@ -26717,6 +26860,7 @@ var init_ui = __esm({
|
|
|
26717
26860
|
"template.cwdHint": "OpenCode \u4F1A\u5728\u8FD9\u4E2A\u76EE\u5F55\u4E2D\u6267\u884C\u4EFB\u52A1\u3002",
|
|
26718
26861
|
"template.agent": "Agent",
|
|
26719
26862
|
"template.model": "\u6A21\u578B",
|
|
26863
|
+
"template.variant": "\u6A21\u578B Variant",
|
|
26720
26864
|
"template.prompt": "\u63D0\u793A\u8BCD",
|
|
26721
26865
|
"template.scheduleType": "\u6267\u884C\u65B9\u5F0F",
|
|
26722
26866
|
"template.cronExpr": "Cron \u8868\u8FBE\u5F0F",
|
|
@@ -26754,9 +26898,11 @@ var init_ui = __esm({
|
|
|
26754
26898
|
"catalog.chooseProject": "\u8BF7\u5148\u9009\u62E9\u9879\u76EE\u76EE\u5F55",
|
|
26755
26899
|
"catalog.defaultModel": "\u8DDF\u968F Agent / OpenCode \u9ED8\u8BA4\u6A21\u578B",
|
|
26756
26900
|
"catalog.defaultProvider": "\u9ED8\u8BA4\u6A21\u578B",
|
|
26901
|
+
"catalog.defaultVariant": "\u8DDF\u968F Agent / \u6A21\u578B\u9ED8\u8BA4\u8BBE\u7F6E",
|
|
26757
26902
|
"catalog.provider": "\u6A21\u578B\u63D0\u4F9B\u5546",
|
|
26758
26903
|
"catalog.model": "\u5177\u4F53\u6A21\u578B",
|
|
26759
|
-
"catalog.modelHint": "\u5148\u9009\u63D0\u4F9B\u5546\uFF0C\u518D\u9009\u672C\u9879\u76EE opencode models \u8FD4\u56DE\u7684\u6A21\u578B\uFF1B\u9ED8\u8BA4\u9009\u9879\u4E0D\u4F1A\u4F20\u5165 -m\u3002",
|
|
26904
|
+
"catalog.modelHint": "\u5148\u9009\u63D0\u4F9B\u5546\uFF0C\u518D\u9009\u672C\u9879\u76EE opencode models --verbose \u8FD4\u56DE\u7684\u6A21\u578B\uFF1B\u9ED8\u8BA4\u9009\u9879\u4E0D\u4F1A\u4F20\u5165 -m\u3002",
|
|
26905
|
+
"catalog.variantHint": "\u4EC5\u663E\u793A\u6240\u9009\u6A21\u578B\u58F0\u660E\u652F\u6301\u7684 variants\uFF1B\u9ED8\u8BA4\u9009\u9879\u4E0D\u4F1A\u4F20\u5165 --variant\u3002",
|
|
26760
26906
|
"catalog.agentHint": "\u6765\u81EA\u5F53\u524D\u9879\u76EE\u7684 opencode agent list\u3002",
|
|
26761
26907
|
"catalog.loading": "\u6B63\u5728\u8BFB\u53D6\u6B64\u9879\u76EE\u53EF\u7528\u7684 Agent \u548C\u6A21\u578B\u2026",
|
|
26762
26908
|
"catalog.loaded": "\u5DF2\u4ECE\u672C\u673A OpenCode \u8BFB\u53D6 {agents} \u4E2A Agent\u3001{models} \u4E2A\u6A21\u578B\u3002",
|
|
@@ -26787,6 +26933,7 @@ var init_ui = __esm({
|
|
|
26787
26933
|
"details.copySuccess": "\u539F\u59CB\u6570\u636E\u5DF2\u590D\u5236",
|
|
26788
26934
|
"details.id": "\u7F16\u53F7",
|
|
26789
26935
|
"details.project": "\u9879\u76EE\u76EE\u5F55",
|
|
26936
|
+
"details.variant": "\u6A21\u578B Variant",
|
|
26790
26937
|
"details.prompt": "\u63D0\u793A\u8BCD",
|
|
26791
26938
|
"details.result": "\u6267\u884C\u7ED3\u679C / \u5931\u8D25\u539F\u56E0",
|
|
26792
26939
|
"details.category": "\u5206\u7C7B",
|
|
@@ -27018,6 +27165,7 @@ var init_ui = __esm({
|
|
|
27018
27165
|
"template.cwdHint": "OpenCode runs the task in this directory.",
|
|
27019
27166
|
"template.agent": "Agent",
|
|
27020
27167
|
"template.model": "Model",
|
|
27168
|
+
"template.variant": "Model variant",
|
|
27021
27169
|
"template.prompt": "Prompt",
|
|
27022
27170
|
"template.scheduleType": "Schedule",
|
|
27023
27171
|
"template.cronExpr": "Cron expression",
|
|
@@ -27055,9 +27203,11 @@ var init_ui = __esm({
|
|
|
27055
27203
|
"catalog.chooseProject": "Choose a project directory first",
|
|
27056
27204
|
"catalog.defaultModel": "Use the Agent / OpenCode default model",
|
|
27057
27205
|
"catalog.defaultProvider": "Default model",
|
|
27206
|
+
"catalog.defaultVariant": "Use the Agent / model default",
|
|
27058
27207
|
"catalog.provider": "Model provider",
|
|
27059
27208
|
"catalog.model": "Model",
|
|
27060
|
-
"catalog.modelHint": "Choose a provider, then a model returned by opencode models for this project. Default does not pass -m.",
|
|
27209
|
+
"catalog.modelHint": "Choose a provider, then a model returned by opencode models --verbose for this project. Default does not pass -m.",
|
|
27210
|
+
"catalog.variantHint": "Only variants declared by the selected model are shown. Default does not pass --variant.",
|
|
27061
27211
|
"catalog.agentHint": "Loaded from opencode agent list for this project.",
|
|
27062
27212
|
"catalog.loading": "Loading Agents and models available to this project\u2026",
|
|
27063
27213
|
"catalog.loaded": "Loaded {agents} Agents and {models} models from local OpenCode.",
|
|
@@ -27088,6 +27238,7 @@ var init_ui = __esm({
|
|
|
27088
27238
|
"details.copySuccess": "Raw data copied",
|
|
27089
27239
|
"details.id": "ID",
|
|
27090
27240
|
"details.project": "Project directory",
|
|
27241
|
+
"details.variant": "Model variant",
|
|
27091
27242
|
"details.prompt": "Prompt",
|
|
27092
27243
|
"details.result": "Result / failure reason",
|
|
27093
27244
|
"details.category": "Category",
|
|
@@ -27650,6 +27801,7 @@ function parseTaskPayload(value) {
|
|
|
27650
27801
|
cwd: requiredString("cwd"),
|
|
27651
27802
|
agent: requiredString("agent"),
|
|
27652
27803
|
model: optionalString("model", "default"),
|
|
27804
|
+
variant: Object.hasOwn(input, "variant") ? optionalString("variant") : void 0,
|
|
27653
27805
|
prompt: requiredString("prompt"),
|
|
27654
27806
|
category: optionalString("category", "general"),
|
|
27655
27807
|
batchId: optionalString("batchId"),
|
|
@@ -27665,6 +27817,7 @@ function editableTaskPayload(input) {
|
|
|
27665
27817
|
name: input.name,
|
|
27666
27818
|
agent: input.agent,
|
|
27667
27819
|
model: input.model ?? "default",
|
|
27820
|
+
...input.variant === void 0 ? {} : { variant: input.variant },
|
|
27668
27821
|
prompt: input.prompt,
|
|
27669
27822
|
category: input.category ?? "general",
|
|
27670
27823
|
batchId: input.batchId ?? null,
|
|
@@ -27720,6 +27873,7 @@ function parseTemplatePayload(value) {
|
|
|
27720
27873
|
name: requiredString("name"),
|
|
27721
27874
|
agent: requiredString("agent"),
|
|
27722
27875
|
model: optionalString("model", "default"),
|
|
27876
|
+
variant: Object.hasOwn(input, "variant") ? optionalString("variant") : void 0,
|
|
27723
27877
|
prompt: requiredString("prompt"),
|
|
27724
27878
|
cwd: requiredString("cwd"),
|
|
27725
27879
|
category: optionalString("category", "general"),
|
|
@@ -28053,7 +28207,7 @@ var init_web = __esm({
|
|
|
28053
28207
|
const latestRun = latestRuns.get(task.id);
|
|
28054
28208
|
const executionActive = latestRun?.status === "running";
|
|
28055
28209
|
const batchId = task.batchId?.trim() || null;
|
|
28056
|
-
const searchable = esc(`${task.name} ${task.agent} ${task.prompt} ${task.cwd ?? ""} ${task.batchId ?? ""} ${task.category ?? ""}`);
|
|
28210
|
+
const searchable = esc(`${task.name} ${task.agent} ${task.model ?? ""} ${task.variant ?? ""} ${task.prompt} ${task.cwd ?? ""} ${task.batchId ?? ""} ${task.category ?? ""}`);
|
|
28057
28211
|
return `<tr data-task-row data-search="${searchable}">
|
|
28058
28212
|
<td class="faint" data-label="${t(locale, "table.id")}">#${task.id}</td>
|
|
28059
28213
|
<td data-primary data-label="${t(locale, "table.task")}"><div class="task-name">${esc(task.name)}</div><div class="task-prompt" title="${esc(task.prompt)}">${esc(task.prompt.substring(0, 160))}</div>
|
|
@@ -28131,11 +28285,12 @@ var init_web = __esm({
|
|
|
28131
28285
|
<label class="form-field"><span>${t(locale, "template.cwd")}</span><div class="field-action"><input id="task-cwd" required autocomplete="off" list="task-cwd-options" placeholder="/path/to/project" oninput="updateTaskProjectStatus();scheduleCatalogLoad('task')"><button id="task-cwd-picker" type="button" class="btn" onclick="openDirectoryPicker('task-cwd')">${icon("folder")}${t(locale, "action.chooseFolder")}</button></div><small>${t(locale, "template.cwdHint")}</small></label>
|
|
28132
28286
|
<datalist id="task-cwd-options">${projects.map((project) => `<option value="${esc(project.cwd)}"></option>`).join("")}</datalist>
|
|
28133
28287
|
<label class="form-field"><span>${t(locale, "template.agent")}</span><select id="task-agent" required><option value="">${t(locale, "catalog.chooseProject")}</option></select><small>${t(locale, "catalog.agentHint")}</small></label>
|
|
28134
|
-
<label class="form-field"><span>${t(locale, "template.model")}</span><div class="model-selector"><select id="task-model-provider" aria-label="${t(locale, "catalog.provider")}" onchange="
|
|
28288
|
+
<label class="form-field"><span>${t(locale, "template.model")}</span><div class="model-selector"><select id="task-model-provider" aria-label="${t(locale, "catalog.provider")}" onchange="handleProviderChange('task')"><option value="">${t(locale, "catalog.defaultProvider")}</option></select><select id="task-model" required aria-label="${t(locale, "catalog.model")}" onchange="handleModelChange('task')" disabled><option value="default">${t(locale, "catalog.defaultModel")}</option></select></div><small>${t(locale, "catalog.modelHint")}</small></label>
|
|
28289
|
+
<label class="form-field"><span>${t(locale, "template.variant")}</span><select id="task-variant" onchange="handleVariantChange('task')" disabled><option value="">${t(locale, "catalog.defaultVariant")}</option></select><small>${t(locale, "catalog.variantHint")}</small></label>
|
|
28135
28290
|
<label class="form-field form-field-wide"><span>${t(locale, "template.prompt")}</span><textarea id="task-prompt" rows="6" required></textarea></label>
|
|
28136
28291
|
</div>
|
|
28137
28292
|
<p id="task-project-status" class="form-note"></p>
|
|
28138
|
-
<p id="task-catalog-status" class="form-note catalog-status"></p>
|
|
28293
|
+
<p id="task-catalog-status" class="form-note catalog-status" role="status" aria-live="polite"></p>
|
|
28139
28294
|
<details class="advanced-fields">
|
|
28140
28295
|
<summary>${t(locale, "template.advanced")}</summary>
|
|
28141
28296
|
<div class="template-form-grid">
|
|
@@ -28177,7 +28332,7 @@ var init_web = __esm({
|
|
|
28177
28332
|
return `<tr>
|
|
28178
28333
|
<td class="faint" data-label="${t(locale, "table.id")}">#${template.id}</td>
|
|
28179
28334
|
<td data-primary data-label="${t(locale, "table.name")}"><div class="task-name">${esc(template.name)}</div><div class="task-prompt" title="${esc(template.prompt)}">${esc(template.prompt.substring(0, 140))}</div>
|
|
28180
|
-
<div class="actions" style="margin-top:5px"><span class="tag">${esc(template.agent)}</span>${template.model && template.model !== "default" ? `<span class="tag">${esc(template.model)}</span>` : ""}</div></td>
|
|
28335
|
+
<div class="actions" style="margin-top:5px"><span class="tag">${esc(template.agent)}</span>${template.model && template.model !== "default" ? `<span class="tag">${esc(template.model)}</span>` : ""}${template.variant ? `<span class="tag">${esc(template.variant)}</span>` : ""}</div></td>
|
|
28181
28336
|
<td data-label="${t(locale, "table.type")}"><span class="tag t-${scheduleType}">${typeLabel}</span></td>
|
|
28182
28337
|
<td data-label="${t(locale, "table.rule")}" class="m small">${esc(rule)}</td>
|
|
28183
28338
|
<td data-label="${t(locale, "table.status")}"><span class="badge ${template.enabled ? "b-done" : "b-cancelled"}">${t(locale, template.enabled ? "schedule.enabled" : "schedule.disabled")}</span></td>
|
|
@@ -28207,14 +28362,15 @@ var init_web = __esm({
|
|
|
28207
28362
|
<label class="form-field"><span>${t(locale, "template.name")}</span><input id="template-name" required maxlength="200" autocomplete="off"></label>
|
|
28208
28363
|
<label class="form-field"><span>${t(locale, "template.cwd")}</span><div class="field-action"><input id="template-cwd" required autocomplete="off" placeholder="/path/to/project" oninput="scheduleCatalogLoad('template')"><button type="button" class="btn" onclick="openDirectoryPicker('template-cwd')">${icon("folder")}${t(locale, "action.chooseFolder")}</button></div><small>${t(locale, "template.cwdHint")}</small></label>
|
|
28209
28364
|
<label class="form-field"><span>${t(locale, "template.agent")}</span><select id="template-agent" required><option value="">${t(locale, "catalog.chooseProject")}</option></select><small>${t(locale, "catalog.agentHint")}</small></label>
|
|
28210
|
-
<label class="form-field"><span>${t(locale, "template.model")}</span><div class="model-selector"><select id="template-model-provider" aria-label="${t(locale, "catalog.provider")}" onchange="
|
|
28365
|
+
<label class="form-field"><span>${t(locale, "template.model")}</span><div class="model-selector"><select id="template-model-provider" aria-label="${t(locale, "catalog.provider")}" onchange="handleProviderChange('template')"><option value="">${t(locale, "catalog.defaultProvider")}</option></select><select id="template-model" required aria-label="${t(locale, "catalog.model")}" onchange="handleModelChange('template')" disabled><option value="default">${t(locale, "catalog.defaultModel")}</option></select></div><small>${t(locale, "catalog.modelHint")}</small></label>
|
|
28366
|
+
<label class="form-field"><span>${t(locale, "template.variant")}</span><select id="template-variant" onchange="handleVariantChange('template')" disabled><option value="">${t(locale, "catalog.defaultVariant")}</option></select><small>${t(locale, "catalog.variantHint")}</small></label>
|
|
28211
28367
|
<label class="form-field form-field-wide"><span>${t(locale, "template.prompt")}</span><textarea id="template-prompt" rows="6" required></textarea></label>
|
|
28212
28368
|
<label class="form-field"><span>${t(locale, "template.scheduleType")}</span><select id="template-schedule-type" onchange="updateTemplateScheduleFields()"><option value="recurring">${t(locale, "schedule.recurring")}</option><option value="delayed">${t(locale, "schedule.delayed")}</option><option value="cron">${t(locale, "schedule.cron")}</option></select></label>
|
|
28213
28369
|
<label id="template-cron-field" class="form-field" hidden><span>${t(locale, "template.cronExpr")}</span><input id="template-cron" autocomplete="off" placeholder="0 9 * * *"><small>${t(locale, "template.cronHint")}</small></label>
|
|
28214
28370
|
<label id="template-interval-field" class="form-field"><span>${t(locale, "template.interval")}</span>${durationControl(locale, "template-interval", 36e5, "interval")}<small>${t(locale, "template.intervalHint")}</small></label>
|
|
28215
28371
|
<label id="template-run-at-field" class="form-field" hidden><span>${t(locale, "template.runAt")}</span><input id="template-run-at" type="datetime-local" step="0.001"></label>
|
|
28216
28372
|
</div>
|
|
28217
|
-
<p id="template-catalog-status" class="form-note catalog-status"></p>
|
|
28373
|
+
<p id="template-catalog-status" class="form-note catalog-status" role="status" aria-live="polite"></p>
|
|
28218
28374
|
<details class="advanced-fields">
|
|
28219
28375
|
<summary>${t(locale, "template.advanced")}</summary>
|
|
28220
28376
|
<div class="template-form-grid">
|
|
@@ -28248,6 +28404,7 @@ var init_web = __esm({
|
|
|
28248
28404
|
taskId: taskRuns4.taskId,
|
|
28249
28405
|
sessionId: taskRuns4.sessionId,
|
|
28250
28406
|
model: taskRuns4.model,
|
|
28407
|
+
variant: taskRuns4.variant,
|
|
28251
28408
|
status: taskRuns4.status,
|
|
28252
28409
|
startedAt: taskRuns4.startedAt,
|
|
28253
28410
|
finishedAt: taskRuns4.finishedAt,
|
|
@@ -28268,7 +28425,7 @@ var init_web = __esm({
|
|
|
28268
28425
|
const log = run.log ? renderRunLog(run.id, run.taskName, run.log, locale, run.status !== "done") : "";
|
|
28269
28426
|
return `<tr class="run-summary-row">
|
|
28270
28427
|
<td class="faint" data-label="${t(locale, "table.run")}">#${run.id}</td>
|
|
28271
|
-
<td data-primary data-label="${t(locale, "table.task")}"><div class="task-name">${esc(run.taskName)} <span class="faint">#${run.taskId}</span></div>${run.model ? `<div style="margin-top:4px"
|
|
28428
|
+
<td data-primary data-label="${t(locale, "table.task")}"><div class="task-name">${esc(run.taskName)} <span class="faint">#${run.taskId}</span></div>${run.model || run.variant ? `<div class="actions" style="margin-top:4px">${run.model ? `<span class="tag">${esc(run.model)}</span>` : ""}${run.variant ? `<span class="tag">${esc(run.variant)}</span>` : ""}</div>` : ""}</td>
|
|
28272
28429
|
<td data-label="${t(locale, "table.agent")}"><span class="tag">${esc(run.taskAgent)}</span></td>
|
|
28273
28430
|
<td data-label="${t(locale, "table.session")}" class="m small">${esc(maskSessionId(run.sessionId))}</td>
|
|
28274
28431
|
<td data-label="${t(locale, "table.status")}"><span class="badge b-${status}">${runStatusText(locale, run.status ?? "unknown")}</span></td>
|
|
@@ -28318,7 +28475,7 @@ var init_web = __esm({
|
|
|
28318
28475
|
const runRows = runningRuns.map((run) => {
|
|
28319
28476
|
const session = maskSessionId(run.sessionId);
|
|
28320
28477
|
return `<tr><td class="faint" data-label="${t(locale, "table.run")}">#${run.id}</td><td data-primary data-label="${t(locale, "table.task")}">#${run.taskId}</td><td data-label="${t(locale, "table.session")}" class="m small">${esc(session)}</td>
|
|
28321
|
-
<td data-label="${t(locale, "table.model")}" class="small">${esc(run.model) || "\u2014"}</td><td data-label="${t(locale, "table.startedAt")}" class="small">${formatDateTime(run.startedAt, locale)}</td>
|
|
28478
|
+
<td data-label="${t(locale, "table.model")}" class="small">${esc(run.model) || "\u2014"}${run.variant ? ` \xB7 ${esc(run.variant)}` : ""}</td><td data-label="${t(locale, "table.startedAt")}" class="small">${formatDateTime(run.startedAt, locale)}</td>
|
|
28322
28479
|
<td data-label="${t(locale, "table.heartbeat")}" class="small muted">${formatRelative(run.heartbeatAt, locale)}</td><td data-label="${t(locale, "table.pid")}" class="m small">W:${run.workerPid ?? "\u2014"} C:${run.childPid ?? "\u2014"}</td>
|
|
28323
28480
|
<td data-label="${t(locale, "table.duration")}" class="small">${formatDuration(run.startedAt, null)}</td></tr>`;
|
|
28324
28481
|
}).join("");
|
|
@@ -29147,11 +29304,13 @@ async function runDoctorSmoke(options) {
|
|
|
29147
29304
|
const cwd = resolve5(options.cwd);
|
|
29148
29305
|
const marker = options.marker ?? `SUPERTASK_SMOKE_${randomUUID2().replaceAll("-", "").toUpperCase()}`;
|
|
29149
29306
|
const model = options.model && options.model !== "default" ? options.model : void 0;
|
|
29307
|
+
const variant = options.variant?.trim() || void 0;
|
|
29150
29308
|
const startedAt = Date.now();
|
|
29151
29309
|
const task = await TaskService.add({
|
|
29152
29310
|
name: "[doctor] Gateway real smoke test",
|
|
29153
29311
|
agent: options.agent,
|
|
29154
29312
|
model,
|
|
29313
|
+
variant,
|
|
29155
29314
|
prompt: `\u4E0D\u8981\u8C03\u7528\u4EFB\u4F55\u5DE5\u5177\u3002\u53EA\u56DE\u590D\u8FD9\u4E00\u884C\uFF1A${marker}`,
|
|
29156
29315
|
cwd,
|
|
29157
29316
|
category: "diagnostic",
|
|
@@ -29175,6 +29334,7 @@ async function runDoctorSmoke(options) {
|
|
|
29175
29334
|
status: "missing",
|
|
29176
29335
|
agent: options.agent,
|
|
29177
29336
|
model: model ?? null,
|
|
29337
|
+
variant: variant ?? null,
|
|
29178
29338
|
cwd,
|
|
29179
29339
|
durationMs: Date.now() - startedAt,
|
|
29180
29340
|
error: "\u5192\u70DF\u4EFB\u52A1\u5728\u5B8C\u6210\u524D\u88AB\u5220\u9664"
|
|
@@ -29190,6 +29350,7 @@ async function runDoctorSmoke(options) {
|
|
|
29190
29350
|
status: current2.status,
|
|
29191
29351
|
agent: options.agent,
|
|
29192
29352
|
model: model ?? null,
|
|
29353
|
+
variant: variant ?? null,
|
|
29193
29354
|
cwd,
|
|
29194
29355
|
durationMs: Date.now() - startedAt,
|
|
29195
29356
|
error: markerObserved ? null : "OpenCode \u5DF2\u9000\u51FA\u6210\u529F\uFF0C\u4F46\u6A21\u578B\u6587\u672C\u4E0D\u662F\u9884\u671F\u7684\u7CBE\u786E\u6807\u8BB0"
|
|
@@ -29203,6 +29364,7 @@ async function runDoctorSmoke(options) {
|
|
|
29203
29364
|
status: current2.status,
|
|
29204
29365
|
agent: options.agent,
|
|
29205
29366
|
model: model ?? null,
|
|
29367
|
+
variant: variant ?? null,
|
|
29206
29368
|
cwd,
|
|
29207
29369
|
durationMs: Date.now() - startedAt,
|
|
29208
29370
|
error: tail(run2?.log ?? current2.resultLog) ?? `\u4EFB\u52A1\u8FDB\u5165 ${current2.status}`
|
|
@@ -29220,6 +29382,7 @@ async function runDoctorSmoke(options) {
|
|
|
29220
29382
|
status: current?.status ?? "missing",
|
|
29221
29383
|
agent: options.agent,
|
|
29222
29384
|
model: model ?? null,
|
|
29385
|
+
variant: variant ?? null,
|
|
29223
29386
|
cwd,
|
|
29224
29387
|
durationMs: Date.now() - startedAt,
|
|
29225
29388
|
error: `\u7B49\u5F85 Gateway \u6267\u884C\u8D85\u8FC7 ${options.timeoutMs}ms\uFF0C\u5192\u70DF\u4EFB\u52A1\u5DF2\u8BF7\u6C42\u53D6\u6D88`
|
|
@@ -29260,7 +29423,7 @@ if (cliLocale === "zh-CN") {
|
|
|
29260
29423
|
writeOut: (value) => process.stdout.write(value.replace(/^Usage:/gm, "\u7528\u6CD5\uFF1A").replace(/^Options:/gm, "\u9009\u9879\uFF1A").replace(/^Commands:/gm, "\u547D\u4EE4\uFF1A").replace(/^Arguments:/gm, "\u53C2\u6570\uFF1A"))
|
|
29261
29424
|
});
|
|
29262
29425
|
}
|
|
29263
|
-
program2.command("add").description(t2("\u521B\u5EFA\u65B0\u4EFB\u52A1", "create a queued task")).requiredOption("-n, --name <name>", t2("\u4EFB\u52A1\u540D\u79F0", "task name")).requiredOption("-a, --agent <agent>", t2("\u4E3B Agent \u540D\u79F0", "primary agent name")).requiredOption("-p, --prompt <prompt>", t2("\u63D0\u793A\u8BCD", "prompt")).option("-m, --model <model>", t2("\u6A21\u578B", "model")).option("-c, --category <category>", t2("\u5206\u7C7B", "category"), "general").option("-i, --importance <number>", t2("\u91CD\u8981\u7A0B\u5EA6 (1-5)", "importance (1-5)"), "3").option("-u, --urgency <number>", t2("\u7D27\u6025\u7A0B\u5EA6 (1-5)", "urgency (1-5)"), "3").option("-b, --batch <batchId>", t2("\u6279\u6B21 ID", "batch ID")).option("-d, --depends <taskId>", t2("\u4F9D\u8D56\u7684\u4EFB\u52A1 ID", "dependency task ID")).option("--max-retries <number>", t2("\u9996\u6B21\u6267\u884C\u4E4B\u5916\u5141\u8BB8\u7684\u91CD\u8BD5\u6B21\u6570", "retries allowed after the first attempt"), "3").option("--retry-backoff <duration>", t2("\u91CD\u8BD5\u9000\u907F\u57FA\u7840\u95F4\u9694\uFF0C\u5982 30s / 5min", "retry backoff base, e.g. 30s / 5min"), "30s").option("--timeout <duration>", t2("\u4EFB\u52A1\u786C\u8D85\u65F6\uFF0C\u5982 30min / 2h", "hard timeout, e.g. 30min / 2h")).option("-w, --cwd <path>", t2("(\u5DF2\u5E9F\u5F03) \u7CFB\u7EDF\u4F1A\u81EA\u52A8\u8BB0\u5F55\u63D0\u4EA4\u65F6\u7684\u5F53\u524D\u76EE\u5F55", "(deprecated) the submission directory is recorded automatically")).action(async (options) => withDb(async () => {
|
|
29426
|
+
program2.command("add").description(t2("\u521B\u5EFA\u65B0\u4EFB\u52A1", "create a queued task")).requiredOption("-n, --name <name>", t2("\u4EFB\u52A1\u540D\u79F0", "task name")).requiredOption("-a, --agent <agent>", t2("\u4E3B Agent \u540D\u79F0", "primary agent name")).requiredOption("-p, --prompt <prompt>", t2("\u63D0\u793A\u8BCD", "prompt")).option("-m, --model <model>", t2("\u6A21\u578B", "model")).option("--variant <variant>", t2("\u6A21\u578B variant\uFF0C\u5982 high / xhigh", "model variant, e.g. high / xhigh")).option("-c, --category <category>", t2("\u5206\u7C7B", "category"), "general").option("-i, --importance <number>", t2("\u91CD\u8981\u7A0B\u5EA6 (1-5)", "importance (1-5)"), "3").option("-u, --urgency <number>", t2("\u7D27\u6025\u7A0B\u5EA6 (1-5)", "urgency (1-5)"), "3").option("-b, --batch <batchId>", t2("\u6279\u6B21 ID", "batch ID")).option("-d, --depends <taskId>", t2("\u4F9D\u8D56\u7684\u4EFB\u52A1 ID", "dependency task ID")).option("--max-retries <number>", t2("\u9996\u6B21\u6267\u884C\u4E4B\u5916\u5141\u8BB8\u7684\u91CD\u8BD5\u6B21\u6570", "retries allowed after the first attempt"), "3").option("--retry-backoff <duration>", t2("\u91CD\u8BD5\u9000\u907F\u57FA\u7840\u95F4\u9694\uFF0C\u5982 30s / 5min", "retry backoff base, e.g. 30s / 5min"), "30s").option("--timeout <duration>", t2("\u4EFB\u52A1\u786C\u8D85\u65F6\uFF0C\u5982 30min / 2h", "hard timeout, e.g. 30min / 2h")).option("-w, --cwd <path>", t2("(\u5DF2\u5E9F\u5F03) \u7CFB\u7EDF\u4F1A\u81EA\u52A8\u8BB0\u5F55\u63D0\u4EA4\u65F6\u7684\u5F53\u524D\u76EE\u5F55", "(deprecated) the submission directory is recorded automatically")).action(async (options) => withDb(async () => {
|
|
29264
29427
|
const submitCwd = process.cwd();
|
|
29265
29428
|
const retryBackoffMs = parseDuration(options.retryBackoff);
|
|
29266
29429
|
const timeoutMs = options.timeout ? parseDuration(options.timeout) : null;
|
|
@@ -29272,6 +29435,7 @@ program2.command("add").description(t2("\u521B\u5EFA\u65B0\u4EFB\u52A1", "create
|
|
|
29272
29435
|
agent: options.agent,
|
|
29273
29436
|
prompt: options.prompt,
|
|
29274
29437
|
model: options.model,
|
|
29438
|
+
variant: options.variant,
|
|
29275
29439
|
category: options.category,
|
|
29276
29440
|
importance: parseBoundedInteger(options.importance, "importance", 1, 5),
|
|
29277
29441
|
urgency: parseBoundedInteger(options.urgency, "urgency", 1, 5),
|
|
@@ -29284,17 +29448,23 @@ program2.command("add").description(t2("\u521B\u5EFA\u65B0\u4EFB\u52A1", "create
|
|
|
29284
29448
|
});
|
|
29285
29449
|
console.log(JSON.stringify({ id: task.id, status: "created" }, null, 2));
|
|
29286
29450
|
}));
|
|
29287
|
-
program2.command("edit").description(t2("\u4FEE\u6539\u5F53\u524D\u9879\u76EE\u4E2D\u5C1A\u672A\u5B8C\u6210\u7684\u4EFB\u52A1", "edit an unfinished task in the current project")).requiredOption("--id <id>", t2("\u4EFB\u52A1 ID", "task ID")).option("-n, --name <name>", t2("\u4EFB\u52A1\u540D\u79F0", "task name")).option("-a, --agent <agent>", t2("Agent \u540D\u79F0", "agent name")).option("-m, --model <model>", t2("\u6A21\u578B", "model")).option("-p, --prompt <prompt>", t2("\u63D0\u793A\u8BCD", "prompt")).option("-c, --category <category>", t2("\u5206\u7C7B", "category")).option("-i, --importance <number>", t2("\u91CD\u8981\u7A0B\u5EA6 (1-5)", "importance (1-5)")).option("-u, --urgency <number>", t2("\u7D27\u6025\u7A0B\u5EA6 (1-5)", "urgency (1-5)")).option("-b, --batch <batchId>", t2("\u6279\u6B21 ID", "batch ID")).option("--clear-batch", t2("\u6E05\u7A7A\u6279\u6B21 ID", "clear the batch ID")).option("--max-retries <number>", t2("\u9996\u6B21\u6267\u884C\u4E4B\u5916\u5141\u8BB8\u7684\u91CD\u8BD5\u6B21\u6570", "retries allowed after the first attempt")).option("--retry-backoff <duration>", t2("\u91CD\u8BD5\u9000\u907F\u57FA\u7840\u95F4\u9694\uFF0C\u5982 30s / 5min", "retry backoff base, e.g. 30s / 5min")).option("--timeout <duration>", t2("\u4EFB\u52A1\u786C\u8D85\u65F6\uFF0C\u5982 30min / 2h", "hard timeout, e.g. 30min / 2h")).option("--clear-timeout", t2("\u6E05\u7A7A\u4EFB\u52A1\u7EA7\u8D85\u65F6\uFF0C\u6539\u7528 Gateway \u9ED8\u8BA4\u503C", "clear the task timeout and use the Gateway default")).action(async (options) => withDb(async () => {
|
|
29451
|
+
program2.command("edit").description(t2("\u4FEE\u6539\u5F53\u524D\u9879\u76EE\u4E2D\u5C1A\u672A\u5B8C\u6210\u7684\u4EFB\u52A1", "edit an unfinished task in the current project")).requiredOption("--id <id>", t2("\u4EFB\u52A1 ID", "task ID")).option("-n, --name <name>", t2("\u4EFB\u52A1\u540D\u79F0", "task name")).option("-a, --agent <agent>", t2("Agent \u540D\u79F0", "agent name")).option("-m, --model <model>", t2("\u6A21\u578B", "model")).option("--variant <variant>", t2("\u6A21\u578B variant\uFF0C\u5982 high / xhigh", "model variant, e.g. high / xhigh")).option("--clear-variant", t2("\u6E05\u7A7A\u4EFB\u52A1\u7EA7 variant\uFF0C\u8DDF\u968F Agent / \u6A21\u578B\u9ED8\u8BA4\u503C", "clear the task variant and use the Agent / model default")).option("-p, --prompt <prompt>", t2("\u63D0\u793A\u8BCD", "prompt")).option("-c, --category <category>", t2("\u5206\u7C7B", "category")).option("-i, --importance <number>", t2("\u91CD\u8981\u7A0B\u5EA6 (1-5)", "importance (1-5)")).option("-u, --urgency <number>", t2("\u7D27\u6025\u7A0B\u5EA6 (1-5)", "urgency (1-5)")).option("-b, --batch <batchId>", t2("\u6279\u6B21 ID", "batch ID")).option("--clear-batch", t2("\u6E05\u7A7A\u6279\u6B21 ID", "clear the batch ID")).option("--max-retries <number>", t2("\u9996\u6B21\u6267\u884C\u4E4B\u5916\u5141\u8BB8\u7684\u91CD\u8BD5\u6B21\u6570", "retries allowed after the first attempt")).option("--retry-backoff <duration>", t2("\u91CD\u8BD5\u9000\u907F\u57FA\u7840\u95F4\u9694\uFF0C\u5982 30s / 5min", "retry backoff base, e.g. 30s / 5min")).option("--timeout <duration>", t2("\u4EFB\u52A1\u786C\u8D85\u65F6\uFF0C\u5982 30min / 2h", "hard timeout, e.g. 30min / 2h")).option("--clear-timeout", t2("\u6E05\u7A7A\u4EFB\u52A1\u7EA7\u8D85\u65F6\uFF0C\u6539\u7528 Gateway \u9ED8\u8BA4\u503C", "clear the task timeout and use the Gateway default")).action(async (options) => withDb(async () => {
|
|
29288
29452
|
if (options.batch !== void 0 && options.clearBatch) {
|
|
29289
29453
|
throw new Error("batch \u548C clear-batch \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528");
|
|
29290
29454
|
}
|
|
29291
29455
|
if (options.timeout !== void 0 && options.clearTimeout) {
|
|
29292
29456
|
throw new Error("timeout \u548C clear-timeout \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528");
|
|
29293
29457
|
}
|
|
29458
|
+
if (options.variant !== void 0 && options.clearVariant) {
|
|
29459
|
+
throw new Error("variant \u548C clear-variant \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528");
|
|
29460
|
+
}
|
|
29294
29461
|
const update = {};
|
|
29295
29462
|
for (const field of ["name", "agent", "model", "prompt", "category"]) {
|
|
29296
29463
|
if (options[field] !== void 0) update[field] = options[field];
|
|
29297
29464
|
}
|
|
29465
|
+
if (options.variant !== void 0 || options.clearVariant) {
|
|
29466
|
+
update.variant = options.clearVariant ? null : options.variant;
|
|
29467
|
+
}
|
|
29298
29468
|
if (options.importance !== void 0) {
|
|
29299
29469
|
update.importance = parseBoundedInteger(options.importance, "importance", 1, 5);
|
|
29300
29470
|
}
|
|
@@ -29330,6 +29500,7 @@ program2.command("next").description(t2("\u83B7\u53D6\u4E0B\u4E00\u4E2A\u5F85\u6
|
|
|
29330
29500
|
name: task.name,
|
|
29331
29501
|
agent: task.agent,
|
|
29332
29502
|
model: task.model,
|
|
29503
|
+
variant: task.variant,
|
|
29333
29504
|
prompt: task.prompt,
|
|
29334
29505
|
cwd: task.cwd,
|
|
29335
29506
|
category: task.category,
|
|
@@ -29406,7 +29577,7 @@ program2.command("delete").description(t2("\u5220\u9664\u4EFB\u52A1", "delete a
|
|
|
29406
29577
|
console.log(JSON.stringify({ deleted, id }));
|
|
29407
29578
|
}));
|
|
29408
29579
|
program2.command("template").description(t2("\u7BA1\u7406\u5B9A\u65F6\u4EFB\u52A1\u6A21\u677F", "manage scheduled task templates")).addCommand(
|
|
29409
|
-
new Command("add").description(t2("\u521B\u5EFA\u5B9A\u65F6\u4EFB\u52A1\u6A21\u677F", "create a scheduled task template")).requiredOption("-n, --name <name>", t2("\u6A21\u677F\u540D\u79F0", "template name")).requiredOption("-a, --agent <agent>", t2("Agent \u540D\u79F0", "agent name")).requiredOption("-p, --prompt <prompt>", t2("\u63D0\u793A\u8BCD", "prompt")).requiredOption("-t, --type <type>", t2("\u5B9A\u65F6\u7C7B\u578B\uFF1Acron/delayed/recurring", "schedule type: cron/delayed/recurring")).option("--cron <expr>", t2("cron \u8868\u8FBE\u5F0F\uFF08cron \u7C7B\u578B\u5FC5\u586B\uFF09", "cron expression (required for cron)")).option("--delay <duration>", t2("\u5EF6\u8FDF\u65F6\u95F4\uFF08delayed \u5FC5\u586B\uFF09\uFF0C\u5982 30s / 5min / 1h / 2d", "delay (required for delayed), e.g. 30s / 5min / 1h / 2d")).option("--interval <duration>", t2("\u5FAA\u73AF\u95F4\u9694\uFF08recurring \u5FC5\u586B\uFF09\uFF0C\u5982 1h / 30min / 5s", "interval (required for recurring), e.g. 1h / 30min / 5s")).option("-m, --model <model>", t2("\u6A21\u578B", "model")).option("-c, --category <category>", t2("\u5206\u7C7B", "category"), "general").option("-i, --importance <number>", t2("\u91CD\u8981\u7A0B\u5EA6 1-5", "importance 1-5"), "3").option("-u, --urgency <number>", t2("\u7D27\u6025\u7A0B\u5EA6 1-5", "urgency 1-5"), "3").option("-b, --batch <batchId>", t2("\u6A21\u677F\u751F\u6210\u4EFB\u52A1\u7684\u6279\u6B21 ID", "batch ID for generated tasks")).option("--max-instances <number>", t2("\u81EA\u52A8\u5B9A\u65F6\u4EFB\u52A1\u7684\u6D3B\u8DC3\u5B9E\u4F8B\u4E0A\u9650\uFF08\u7ACB\u5373\u89E6\u53D1\u4E0D\u53D7\u9650\uFF09", "active instance limit for automatic scheduling (Run now is unrestricted)"), "1").option("--max-retries <number>", t2("\u6700\u5927\u91CD\u8BD5\u6B21\u6570", "maximum retries"), "3").option("--retry-backoff <duration>", t2("\u9000\u907F\u57FA\u7840\u95F4\u9694\uFF0C\u5982 30s / 5min", "retry backoff base, e.g. 30s / 5min"), "30s").option("--timeout <duration>", t2("\u6BCF\u6B21\u4EFB\u52A1\u786C\u8D85\u65F6\uFF0C\u5982 30min / 2h", "hard timeout per task, e.g. 30min / 2h")).action(async (options) => withDb(async () => {
|
|
29580
|
+
new Command("add").description(t2("\u521B\u5EFA\u5B9A\u65F6\u4EFB\u52A1\u6A21\u677F", "create a scheduled task template")).requiredOption("-n, --name <name>", t2("\u6A21\u677F\u540D\u79F0", "template name")).requiredOption("-a, --agent <agent>", t2("Agent \u540D\u79F0", "agent name")).requiredOption("-p, --prompt <prompt>", t2("\u63D0\u793A\u8BCD", "prompt")).requiredOption("-t, --type <type>", t2("\u5B9A\u65F6\u7C7B\u578B\uFF1Acron/delayed/recurring", "schedule type: cron/delayed/recurring")).option("--cron <expr>", t2("cron \u8868\u8FBE\u5F0F\uFF08cron \u7C7B\u578B\u5FC5\u586B\uFF09", "cron expression (required for cron)")).option("--delay <duration>", t2("\u5EF6\u8FDF\u65F6\u95F4\uFF08delayed \u5FC5\u586B\uFF09\uFF0C\u5982 30s / 5min / 1h / 2d", "delay (required for delayed), e.g. 30s / 5min / 1h / 2d")).option("--interval <duration>", t2("\u5FAA\u73AF\u95F4\u9694\uFF08recurring \u5FC5\u586B\uFF09\uFF0C\u5982 1h / 30min / 5s", "interval (required for recurring), e.g. 1h / 30min / 5s")).option("-m, --model <model>", t2("\u6A21\u578B", "model")).option("--variant <variant>", t2("\u6A21\u578B variant\uFF0C\u5982 high / xhigh", "model variant, e.g. high / xhigh")).option("-c, --category <category>", t2("\u5206\u7C7B", "category"), "general").option("-i, --importance <number>", t2("\u91CD\u8981\u7A0B\u5EA6 1-5", "importance 1-5"), "3").option("-u, --urgency <number>", t2("\u7D27\u6025\u7A0B\u5EA6 1-5", "urgency 1-5"), "3").option("-b, --batch <batchId>", t2("\u6A21\u677F\u751F\u6210\u4EFB\u52A1\u7684\u6279\u6B21 ID", "batch ID for generated tasks")).option("--max-instances <number>", t2("\u81EA\u52A8\u5B9A\u65F6\u4EFB\u52A1\u7684\u6D3B\u8DC3\u5B9E\u4F8B\u4E0A\u9650\uFF08\u7ACB\u5373\u89E6\u53D1\u4E0D\u53D7\u9650\uFF09", "active instance limit for automatic scheduling (Run now is unrestricted)"), "1").option("--max-retries <number>", t2("\u6700\u5927\u91CD\u8BD5\u6B21\u6570", "maximum retries"), "3").option("--retry-backoff <duration>", t2("\u9000\u907F\u57FA\u7840\u95F4\u9694\uFF0C\u5982 30s / 5min", "retry backoff base, e.g. 30s / 5min"), "30s").option("--timeout <duration>", t2("\u6BCF\u6B21\u4EFB\u52A1\u786C\u8D85\u65F6\uFF0C\u5982 30min / 2h", "hard timeout per task, e.g. 30min / 2h")).action(async (options) => withDb(async () => {
|
|
29410
29581
|
let intervalMs = null;
|
|
29411
29582
|
let runAt = null;
|
|
29412
29583
|
const retryBackoffMs = parseDuration(options.retryBackoff);
|
|
@@ -29434,6 +29605,7 @@ program2.command("template").description(t2("\u7BA1\u7406\u5B9A\u65F6\u4EFB\u52A
|
|
|
29434
29605
|
agent: options.agent,
|
|
29435
29606
|
prompt: options.prompt,
|
|
29436
29607
|
model: options.model,
|
|
29608
|
+
variant: options.variant,
|
|
29437
29609
|
category: options.category,
|
|
29438
29610
|
importance: parseBoundedInteger(options.importance, "importance", 1, 5),
|
|
29439
29611
|
urgency: parseBoundedInteger(options.urgency, "urgency", 1, 5),
|
|
@@ -29560,7 +29732,7 @@ program2.command("config").description(t2("\u663E\u793A\u5F53\u524D\u914D\u7F6E"
|
|
|
29560
29732
|
const cfg = loadConfig2();
|
|
29561
29733
|
console.log(JSON.stringify(cfg, null, 2));
|
|
29562
29734
|
});
|
|
29563
|
-
program2.command("doctor").description(t2("\u68C0\u67E5 OpenCode\u3001\u6570\u636E\u5E93\u3001Gateway\u3001Web \u754C\u9762\u548C\u65E5\u5FD7\u8F6E\u8F6C", "diagnose OpenCode, database, Gateway, Dashboard, and log rotation")).option("--json", t2("\u5F3A\u5236\u8F93\u51FA JSON", "force JSON output")).option("--smoke", t2("\u901A\u8FC7 Gateway \u63D0\u4EA4\u4E00\u4E2A\u771F\u5B9E OpenCode \u4EFB\u52A1\u5E76\u9A8C\u8BC1\u8F93\u51FA", "queue a real OpenCode task through Gateway and verify its output")).option("--smoke-agent <agent>", t2("\u771F\u5B9E\u5192\u70DF\u4EFB\u52A1\u4F7F\u7528\u7684 Agent", "Agent used by the real smoke task"), "build").option("--smoke-model <model>", t2("\u771F\u5B9E\u5192\u70DF\u4EFB\u52A1\u4F7F\u7528\u7684\u6A21\u578B\uFF1B\u9ED8\u8BA4\u8DDF\u968F Agent \u914D\u7F6E", "model used by the real smoke task; defaults to the Agent configuration")).option("--smoke-cwd <path>", t2("\u771F\u5B9E\u5192\u70DF\u4EFB\u52A1\u7684\u9879\u76EE\u76EE\u5F55\uFF1B\u9ED8\u8BA4\u4E3A\u5F53\u524D\u76EE\u5F55", "project directory for the real smoke task; defaults to the current directory")).option("--smoke-timeout <duration>", t2("\u771F\u5B9E\u5192\u70DF\u4EFB\u52A1\u7B49\u5F85\u4E0A\u9650\uFF0C\u5982 2min / 5min", "real smoke task timeout, e.g. 2min / 5min"), "3min").action(async (options) => withDb(async () => {
|
|
29735
|
+
program2.command("doctor").description(t2("\u68C0\u67E5 OpenCode\u3001\u6570\u636E\u5E93\u3001Gateway\u3001Web \u754C\u9762\u548C\u65E5\u5FD7\u8F6E\u8F6C", "diagnose OpenCode, database, Gateway, Dashboard, and log rotation")).option("--json", t2("\u5F3A\u5236\u8F93\u51FA JSON", "force JSON output")).option("--smoke", t2("\u901A\u8FC7 Gateway \u63D0\u4EA4\u4E00\u4E2A\u771F\u5B9E OpenCode \u4EFB\u52A1\u5E76\u9A8C\u8BC1\u8F93\u51FA", "queue a real OpenCode task through Gateway and verify its output")).option("--smoke-agent <agent>", t2("\u771F\u5B9E\u5192\u70DF\u4EFB\u52A1\u4F7F\u7528\u7684 Agent", "Agent used by the real smoke task"), "build").option("--smoke-model <model>", t2("\u771F\u5B9E\u5192\u70DF\u4EFB\u52A1\u4F7F\u7528\u7684\u6A21\u578B\uFF1B\u9ED8\u8BA4\u8DDF\u968F Agent \u914D\u7F6E", "model used by the real smoke task; defaults to the Agent configuration")).option("--smoke-variant <variant>", t2("\u771F\u5B9E\u5192\u70DF\u4EFB\u52A1\u4F7F\u7528\u7684\u6A21\u578B variant", "model variant used by the real smoke task")).option("--smoke-cwd <path>", t2("\u771F\u5B9E\u5192\u70DF\u4EFB\u52A1\u7684\u9879\u76EE\u76EE\u5F55\uFF1B\u9ED8\u8BA4\u4E3A\u5F53\u524D\u76EE\u5F55", "project directory for the real smoke task; defaults to the current directory")).option("--smoke-timeout <duration>", t2("\u771F\u5B9E\u5192\u70DF\u4EFB\u52A1\u7B49\u5F85\u4E0A\u9650\uFF0C\u5982 2min / 5min", "real smoke task timeout, e.g. 2min / 5min"), "3min").action(async (options) => withDb(async () => {
|
|
29564
29736
|
const config = loadConfig();
|
|
29565
29737
|
const database = DatabaseMaintenanceService.check();
|
|
29566
29738
|
const legacyQuarantinedRuns = await TaskRunService.listLegacyQuarantinedRuns(
|
|
@@ -29673,6 +29845,7 @@ program2.command("doctor").description(t2("\u68C0\u67E5 OpenCode\u3001\u6570\u63
|
|
|
29673
29845
|
smoke = await runDoctorSmoke({
|
|
29674
29846
|
agent: options.smokeAgent,
|
|
29675
29847
|
model: options.smokeModel,
|
|
29848
|
+
variant: options.smokeVariant,
|
|
29676
29849
|
cwd: options.smokeCwd ?? process.cwd(),
|
|
29677
29850
|
timeoutMs: smokeTimeoutMs
|
|
29678
29851
|
});
|
|
@@ -29732,25 +29905,43 @@ program2.command("uninstall").description(t2("\u505C\u6B62\u5E76\u79FB\u9664 PM2
|
|
|
29732
29905
|
process.exit(1);
|
|
29733
29906
|
}
|
|
29734
29907
|
});
|
|
29735
|
-
program2.command("upgrade").description(t2("\u66F4\u65B0 OpenCode \u63D2\u4EF6\
|
|
29736
|
-
console.log(t2("\u6B63\u5728\
|
|
29908
|
+
program2.command("upgrade").description(t2("\u66F4\u65B0 OpenCode \u63D2\u4EF6\u3001CLI \u548C Gateway\uFF1B\u5DF2\u662F\u6700\u65B0\u7248\u672C\u65F6\u4E0D\u91CD\u542F", "update the OpenCode plugin, CLI, and Gateway without restarting when already current")).option("--force", t2("\u5373\u4F7F\u5DF2\u662F\u6700\u65B0\u7248\u672C\u4E5F\u91CD\u65B0\u5B89\u88C5\u5E76\u91CD\u542F Gateway", "reinstall and restart the Gateway even when already current")).action(async (options) => {
|
|
29909
|
+
console.log(t2("\u6B63\u5728\u68C0\u67E5 opencode-supertask \u66F4\u65B0...", "Checking for opencode-supertask updates..."));
|
|
29737
29910
|
let installed;
|
|
29738
29911
|
let previousVersion;
|
|
29912
|
+
let targetVersion;
|
|
29913
|
+
let updater;
|
|
29739
29914
|
try {
|
|
29740
|
-
|
|
29741
|
-
|
|
29915
|
+
updater = await Promise.resolve().then(() => (init_update2(), update_exports));
|
|
29916
|
+
const { getGatewayDiagnostic: getGatewayDiagnostic2 } = await Promise.resolve().then(() => (init_pm2(), pm2_exports));
|
|
29917
|
+
targetVersion = updater.getLatestVersion();
|
|
29918
|
+
const plugin = updater.getOpenCodePluginDiagnostic();
|
|
29919
|
+
const cli = updater.getGlobalCliDiagnostic();
|
|
29920
|
+
const gateway = getGatewayDiagnostic2();
|
|
29921
|
+
if (!options.force && updater.isVersionConverged(targetVersion, {
|
|
29922
|
+
packageVersion: getPackageVersion(),
|
|
29923
|
+
plugin,
|
|
29924
|
+
cli,
|
|
29925
|
+
gateway
|
|
29926
|
+
})) {
|
|
29927
|
+
console.log(t2(
|
|
29928
|
+
`SuperTask \u5DF2\u662F\u6700\u65B0\u7248\u672C v${targetVersion}\uFF0C\u65E0\u9700\u5347\u7EA7\uFF1BGateway \u672A\u91CD\u542F\u3002`,
|
|
29929
|
+
`SuperTask is already up to date at v${targetVersion}; the Gateway was not restarted.`
|
|
29930
|
+
));
|
|
29931
|
+
return;
|
|
29932
|
+
}
|
|
29933
|
+
previousVersion = plugin.version ?? updater.resolveInstalledPlugin().version;
|
|
29742
29934
|
} catch (error) {
|
|
29743
|
-
console.error(t2("\u65E0\u6CD5\
|
|
29935
|
+
console.error(t2("\u65E0\u6CD5\u68C0\u67E5\u5F53\u524D\u7248\u672C\uFF0C\u5DF2\u53D6\u6D88\u5347\u7EA7\uFF1A", "Could not check the current version; upgrade cancelled: ") + (error instanceof Error ? error.message : String(error)));
|
|
29744
29936
|
process.exit(1);
|
|
29745
29937
|
}
|
|
29938
|
+
console.log(t2("\u6B63\u5728\u66F4\u65B0 opencode-supertask...", "Updating opencode-supertask..."));
|
|
29746
29939
|
try {
|
|
29747
|
-
|
|
29748
|
-
installed = installLatestPlugin2();
|
|
29940
|
+
installed = updater.installPluginVersion(targetVersion);
|
|
29749
29941
|
} catch (err) {
|
|
29750
29942
|
let detail = err instanceof Error ? err.message : String(err);
|
|
29751
29943
|
try {
|
|
29752
|
-
|
|
29753
|
-
installPluginVersion2(previousVersion);
|
|
29944
|
+
updater.installPluginVersion(previousVersion);
|
|
29754
29945
|
} catch (rollbackError) {
|
|
29755
29946
|
detail += `; OpenCode \u63D2\u4EF6\u56DE\u6EDA\u5931\u8D25: ${rollbackError instanceof Error ? rollbackError.message : String(rollbackError)}`;
|
|
29756
29947
|
}
|
|
@@ -29794,8 +29985,7 @@ SuperTask upgraded: ${result.before ?? "unknown"} \u2192 ${result.after}`
|
|
|
29794
29985
|
let detail = err instanceof Error ? err.message : String(err);
|
|
29795
29986
|
try {
|
|
29796
29987
|
if (previousVersion !== installed.version) {
|
|
29797
|
-
|
|
29798
|
-
installPluginVersion2(previousVersion);
|
|
29988
|
+
updater.installPluginVersion(previousVersion);
|
|
29799
29989
|
}
|
|
29800
29990
|
} catch (rollbackError) {
|
|
29801
29991
|
detail += `; Gateway \u5DF2\u56DE\u6EDA\uFF0C\u4F46 OpenCode \u63D2\u4EF6\u56DE\u6EDA\u5931\u8D25: ${rollbackError instanceof Error ? rollbackError.message : String(rollbackError)}`;
|