opencode-supertask 0.1.39 → 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 +9 -0
- package/README.md +152 -352
- package/README.zh-CN.md +243 -0
- package/dist/cli/index.js +215 -47
- 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 +37 -4
- 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();
|
|
@@ -22880,6 +22915,7 @@ var init_worker = __esm({
|
|
|
22880
22915
|
const run = await TaskRunService.create({
|
|
22881
22916
|
taskId: task.id,
|
|
22882
22917
|
model: this.resolveModel(task.model),
|
|
22918
|
+
variant: this.resolveVariant(task.variant),
|
|
22883
22919
|
status: "running",
|
|
22884
22920
|
workerPid: process.pid,
|
|
22885
22921
|
lockedAt: Date.now(),
|
|
@@ -22942,8 +22978,10 @@ var init_worker = __esm({
|
|
|
22942
22978
|
}
|
|
22943
22979
|
async spawnTask(task, runId, launchIdentity) {
|
|
22944
22980
|
const model = this.resolveModel(task.model);
|
|
22981
|
+
const variant = this.resolveVariant(task.variant);
|
|
22945
22982
|
const args = ["run", "--agent", task.agent, "--format", "json"];
|
|
22946
22983
|
if (model) args.push("-m", model);
|
|
22984
|
+
if (variant) args.push("--variant", variant);
|
|
22947
22985
|
args.push(task.prompt);
|
|
22948
22986
|
const cwd = task.cwd || process.cwd();
|
|
22949
22987
|
const child = spawn(process.execPath, [
|
|
@@ -23102,7 +23140,7 @@ var init_worker = __esm({
|
|
|
23102
23140
|
);
|
|
23103
23141
|
return;
|
|
23104
23142
|
}
|
|
23105
|
-
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`;
|
|
23106
23144
|
this.runDetached(
|
|
23107
23145
|
this.settleEntry(entry, code, failure),
|
|
23108
23146
|
"task settlement failed",
|
|
@@ -23291,6 +23329,9 @@ ${output}` : ""}`;
|
|
|
23291
23329
|
if (!taskModel || taskModel === "default") return null;
|
|
23292
23330
|
return taskModel;
|
|
23293
23331
|
}
|
|
23332
|
+
resolveVariant(taskVariant) {
|
|
23333
|
+
return taskVariant?.trim() || null;
|
|
23334
|
+
}
|
|
23294
23335
|
runDetached(operation, message, taskId) {
|
|
23295
23336
|
operation.catch((error) => {
|
|
23296
23337
|
markGatewayFailure("worker", error);
|
|
@@ -23668,6 +23709,7 @@ function createTaskFromTemplate(templateId, options) {
|
|
|
23668
23709
|
name: `${options.namePrefix ?? ""}${tmpl.name}`,
|
|
23669
23710
|
agent: tmpl.agent,
|
|
23670
23711
|
model: tmpl.model ?? "default",
|
|
23712
|
+
variant: tmpl.variant,
|
|
23671
23713
|
prompt: tmpl.prompt,
|
|
23672
23714
|
cwd: tmpl.cwd ?? null,
|
|
23673
23715
|
category: tmpl.category ?? "general",
|
|
@@ -26073,17 +26115,49 @@ function runOpenCode(executable, args, cwd, timeoutMs) {
|
|
|
26073
26115
|
const child = spawn2(executable, args, {
|
|
26074
26116
|
cwd,
|
|
26075
26117
|
env: process.env,
|
|
26076
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
26118
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
26119
|
+
detached: process.platform !== "win32"
|
|
26077
26120
|
});
|
|
26078
26121
|
let stdout = "";
|
|
26079
26122
|
let stderr = "";
|
|
26080
26123
|
let failure = null;
|
|
26081
|
-
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
|
+
};
|
|
26082
26157
|
const append = (current, chunk) => {
|
|
26083
26158
|
const next = current + chunk.toString();
|
|
26084
26159
|
if (Buffer.byteLength(next) > MAX_OUTPUT_BYTES && failure === null) {
|
|
26085
|
-
|
|
26086
|
-
child.kill("SIGTERM");
|
|
26160
|
+
terminate(new Error(`OpenCode \u8F93\u51FA\u8D85\u8FC7 ${MAX_OUTPUT_BYTES} bytes`));
|
|
26087
26161
|
}
|
|
26088
26162
|
return next.slice(-MAX_OUTPUT_BYTES);
|
|
26089
26163
|
};
|
|
@@ -26094,23 +26168,25 @@ function runOpenCode(executable, args, cwd, timeoutMs) {
|
|
|
26094
26168
|
stderr = append(stderr, chunk);
|
|
26095
26169
|
});
|
|
26096
26170
|
child.once("error", (error) => {
|
|
26097
|
-
|
|
26171
|
+
if (forceKillTimer) return;
|
|
26172
|
+
rejectOnce(error);
|
|
26098
26173
|
});
|
|
26099
|
-
|
|
26100
|
-
|
|
26101
|
-
child.kill("SIGTERM");
|
|
26174
|
+
timer = setTimeout(() => {
|
|
26175
|
+
terminate(new Error(`OpenCode \u547D\u4EE4\u8D85\u8FC7 ${timeoutMs}ms \u672A\u5B8C\u6210`));
|
|
26102
26176
|
}, timeoutMs);
|
|
26103
26177
|
child.once("close", (code) => {
|
|
26104
|
-
if (finished) return;
|
|
26105
|
-
finished = true;
|
|
26106
26178
|
clearTimeout(timer);
|
|
26179
|
+
if (forceKillTimer) return;
|
|
26180
|
+
if (finalRejectTimer) clearTimeout(finalRejectTimer);
|
|
26181
|
+
if (settled) return;
|
|
26182
|
+
settled = true;
|
|
26107
26183
|
if (failure) {
|
|
26108
26184
|
reject(failure);
|
|
26109
26185
|
return;
|
|
26110
26186
|
}
|
|
26111
26187
|
if (code !== 0) {
|
|
26112
26188
|
const detail = cleanOutput(stderr).trim() || `\u9000\u51FA\u7801 ${code ?? "null"}`;
|
|
26113
|
-
reject(new
|
|
26189
|
+
reject(new OpenCodeCommandExitError(`OpenCode ${args.join(" ")} \u5931\u8D25\uFF1A${detail}`));
|
|
26114
26190
|
return;
|
|
26115
26191
|
}
|
|
26116
26192
|
resolve6(cleanOutput(stdout));
|
|
@@ -26120,6 +26196,52 @@ function runOpenCode(executable, args, cwd, timeoutMs) {
|
|
|
26120
26196
|
function parseOpenCodeModels(output) {
|
|
26121
26197
|
return [...new Set(cleanOutput(output).split("\n").map((line) => line.trim()).filter((line) => /^[^\s/]+\/.+/.test(line)))].sort((left, right) => left.localeCompare(right));
|
|
26122
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
|
+
}
|
|
26123
26245
|
function parseOpenCodeAgents(output) {
|
|
26124
26246
|
const agents = /* @__PURE__ */ new Map();
|
|
26125
26247
|
for (const line of cleanOutput(output).split("\n")) {
|
|
@@ -26143,14 +26265,18 @@ async function loadOpenCodeCatalog(cwd, options = {}) {
|
|
|
26143
26265
|
return cached.result;
|
|
26144
26266
|
}
|
|
26145
26267
|
const result = Promise.all([
|
|
26146
|
-
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
|
+
}),
|
|
26147
26272
|
runOpenCode(executable, ["agent", "list"], cwd, timeoutMs)
|
|
26148
26273
|
]).then(([modelsOutput, agentsOutput]) => {
|
|
26149
|
-
const
|
|
26274
|
+
const metadata = parseOpenCodeModelMetadata(modelsOutput);
|
|
26275
|
+
const models = metadata.models.length > 0 ? metadata.models : parseOpenCodeModels(modelsOutput);
|
|
26150
26276
|
const agents = parseOpenCodeAgents(agentsOutput).filter((agent) => agent.mode !== "subagent");
|
|
26151
26277
|
if (models.length === 0) throw new Error("OpenCode \u6CA1\u6709\u8FD4\u56DE\u53EF\u7528\u6A21\u578B");
|
|
26152
26278
|
if (agents.length === 0) throw new Error("OpenCode \u6CA1\u6709\u8FD4\u56DE\u53EF\u76F4\u63A5\u8FD0\u884C\u7684\u4E3B Agent");
|
|
26153
|
-
return { cwd, models, agents };
|
|
26279
|
+
return { cwd, models, variantsByModel: metadata.variantsByModel, agents };
|
|
26154
26280
|
});
|
|
26155
26281
|
if (options.useCache !== false) {
|
|
26156
26282
|
catalogCache.set(cacheKey, { expiresAt: Date.now() + CATALOG_CACHE_MS, result });
|
|
@@ -26160,7 +26286,7 @@ async function loadOpenCodeCatalog(cwd, options = {}) {
|
|
|
26160
26286
|
}
|
|
26161
26287
|
return result;
|
|
26162
26288
|
}
|
|
26163
|
-
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;
|
|
26164
26290
|
var init_opencode_catalog = __esm({
|
|
26165
26291
|
"src/core/opencode-catalog.ts"() {
|
|
26166
26292
|
"use strict";
|
|
@@ -26169,6 +26295,8 @@ var init_opencode_catalog = __esm({
|
|
|
26169
26295
|
COMMAND_TIMEOUT_MS = 2e4;
|
|
26170
26296
|
MAX_OUTPUT_BYTES = 4 * 1024 * 1024;
|
|
26171
26297
|
ANSI_PATTERN = /\x1B(?:[@-_][0-?]*[ -/]*[@-~]|\][^\x07]*(?:\x07|\x1B\\))/g;
|
|
26298
|
+
OpenCodeCommandExitError = class extends Error {
|
|
26299
|
+
};
|
|
26172
26300
|
catalogCache = /* @__PURE__ */ new Map();
|
|
26173
26301
|
}
|
|
26174
26302
|
});
|
|
@@ -26259,6 +26387,7 @@ function clientMessages(locale) {
|
|
|
26259
26387
|
"details.copySuccess",
|
|
26260
26388
|
"details.id",
|
|
26261
26389
|
"details.project",
|
|
26390
|
+
"details.variant",
|
|
26262
26391
|
"details.prompt",
|
|
26263
26392
|
"details.result",
|
|
26264
26393
|
"details.category",
|
|
@@ -26359,6 +26488,7 @@ function clientMessages(locale) {
|
|
|
26359
26488
|
"catalog.chooseProject",
|
|
26360
26489
|
"catalog.defaultModel",
|
|
26361
26490
|
"catalog.defaultProvider",
|
|
26491
|
+
"catalog.defaultVariant",
|
|
26362
26492
|
"catalog.loading",
|
|
26363
26493
|
"catalog.loaded",
|
|
26364
26494
|
"catalog.failed",
|
|
@@ -26483,23 +26613,23 @@ function renderLayout(options) {
|
|
|
26483
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)}
|
|
26484
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')}
|
|
26485
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}
|
|
26486
|
-
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}
|
|
26487
26617
|
function detailFields(type,data){if(type==='task')return [
|
|
26488
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}],
|
|
26489
|
-
[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}],
|
|
26490
26620
|
[text('details.category'),data.category],[text('details.batch'),data.batchId],[text('details.dependency'),data.dependsOn?'#'+data.dependsOn:text('details.none')],
|
|
26491
26621
|
[text('details.importance'),data.importance],[text('details.urgency'),data.urgency],[text('details.retryCount'),String(data.retryCount??0)+' / '+String(data.maxRetries??0)],
|
|
26492
26622
|
[text('details.retryBackoff'),detailDuration(data.retryBackoffMs)],[text('details.timeout'),detailDuration(data.timeoutMs)],[text('details.scheduledAt'),detailDate(data.scheduledAt)],
|
|
26493
26623
|
[text('details.createdAt'),detailDate(data.createdAt)],[text('details.startedAt'),detailDate(data.startedAt)],[text('details.finishedAt'),detailDate(data.finishedAt)],
|
|
26494
26624
|
[text('details.result'),detailTaskResult(data),{wide:true,long:true}]
|
|
26495
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 [
|
|
26496
|
-
[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')],
|
|
26497
26627
|
[text('details.session'),detailSession(data.sessionId)],[text('details.startedAt'),detailDate(data.startedAt)],[text('details.finishedAt'),detailDate(data.finishedAt)],
|
|
26498
26628
|
[text('table.duration'),started!==null?detailDuration((finished??Date.now())-started):text('details.none')],[text('details.heartbeat'),detailDate(data.heartbeatAt)],
|
|
26499
26629
|
[text('details.process'),'Worker PID '+String(data.workerPid??'\u2014')+' \xB7 OpenCode PID '+String(data.childPid??'\u2014'),{wide:true,mono:true}]
|
|
26500
26630
|
];}const scheduleRule=data.scheduleType==='cron'?data.cronExpr:data.scheduleType==='recurring'?detailDuration(data.intervalMs):detailDate(data.runAt);return [
|
|
26501
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}],
|
|
26502
|
-
[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}],
|
|
26503
26633
|
[text('template.scheduleType'),detailScheduleType(data.scheduleType)],[text('details.scheduleRule'),scheduleRule],[text('details.category'),data.category],[text('details.batch'),data.batchId],
|
|
26504
26634
|
[text('details.importance'),data.importance],[text('details.urgency'),data.urgency],[text('details.maxInstances'),data.maxInstances],[text('details.maxRetries'),data.maxRetries??0],
|
|
26505
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)],
|
|
@@ -26516,12 +26646,20 @@ function renderLayout(options) {
|
|
|
26516
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')}
|
|
26517
26647
|
const catalogTimers={};const catalogRequests={};const catalogModels={};
|
|
26518
26648
|
function catalogField(prefix,name){return document.getElementById(prefix+'-'+name)}
|
|
26519
|
-
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='';}
|
|
26520
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=''}
|
|
26521
26658
|
function modelProvider(value){const slash=value.indexOf('/');return slash>0?value.slice(0,slash):''}
|
|
26522
|
-
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}}
|
|
26523
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}}}
|
|
26524
|
-
function scheduleCatalogLoad(prefix){
|
|
26662
|
+
function scheduleCatalogLoad(prefix){invalidateCatalogRequests(prefix);resetCatalog(prefix);catalogTimers[prefix]=setTimeout(()=>loadCatalog(prefix),450)}
|
|
26525
26663
|
let directoryTargetId='';let directoryCurrent='';let directoryEntries=[];let directoryShowHidden=false;
|
|
26526
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)}}
|
|
26527
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}}
|
|
@@ -26531,16 +26669,16 @@ function renderLayout(options) {
|
|
|
26531
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'}
|
|
26532
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}
|
|
26533
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)}
|
|
26534
|
-
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)}
|
|
26535
|
-
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')}}
|
|
26536
|
-
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}}
|
|
26537
26675
|
function localDateTime(milliseconds){const date=new Date(milliseconds);const local=new Date(milliseconds-date.getTimezoneOffset()*60000);return local.toISOString().slice(0,23)}
|
|
26538
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')}}
|
|
26539
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}
|
|
26540
26678
|
function selectedRunAt(){const input=templateField('run-at');return resolveEditedRunAt(input.dataset.originalEpoch?Number(input.dataset.originalEpoch):null,input.dataset.originalLocal||'',input.value)}
|
|
26541
|
-
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)}
|
|
26542
|
-
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')}}
|
|
26543
|
-
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}}
|
|
26544
26682
|
async function enableTmpl(id){try{await readJson(await fetch('/api/templates/'+id+'/enable',{method:'POST'}));location.reload()}catch(error){showToast(error.message,'error')}}
|
|
26545
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')}}
|
|
26546
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')}}
|
|
@@ -26722,6 +26860,7 @@ var init_ui = __esm({
|
|
|
26722
26860
|
"template.cwdHint": "OpenCode \u4F1A\u5728\u8FD9\u4E2A\u76EE\u5F55\u4E2D\u6267\u884C\u4EFB\u52A1\u3002",
|
|
26723
26861
|
"template.agent": "Agent",
|
|
26724
26862
|
"template.model": "\u6A21\u578B",
|
|
26863
|
+
"template.variant": "\u6A21\u578B Variant",
|
|
26725
26864
|
"template.prompt": "\u63D0\u793A\u8BCD",
|
|
26726
26865
|
"template.scheduleType": "\u6267\u884C\u65B9\u5F0F",
|
|
26727
26866
|
"template.cronExpr": "Cron \u8868\u8FBE\u5F0F",
|
|
@@ -26759,9 +26898,11 @@ var init_ui = __esm({
|
|
|
26759
26898
|
"catalog.chooseProject": "\u8BF7\u5148\u9009\u62E9\u9879\u76EE\u76EE\u5F55",
|
|
26760
26899
|
"catalog.defaultModel": "\u8DDF\u968F Agent / OpenCode \u9ED8\u8BA4\u6A21\u578B",
|
|
26761
26900
|
"catalog.defaultProvider": "\u9ED8\u8BA4\u6A21\u578B",
|
|
26901
|
+
"catalog.defaultVariant": "\u8DDF\u968F Agent / \u6A21\u578B\u9ED8\u8BA4\u8BBE\u7F6E",
|
|
26762
26902
|
"catalog.provider": "\u6A21\u578B\u63D0\u4F9B\u5546",
|
|
26763
26903
|
"catalog.model": "\u5177\u4F53\u6A21\u578B",
|
|
26764
|
-
"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",
|
|
26765
26906
|
"catalog.agentHint": "\u6765\u81EA\u5F53\u524D\u9879\u76EE\u7684 opencode agent list\u3002",
|
|
26766
26907
|
"catalog.loading": "\u6B63\u5728\u8BFB\u53D6\u6B64\u9879\u76EE\u53EF\u7528\u7684 Agent \u548C\u6A21\u578B\u2026",
|
|
26767
26908
|
"catalog.loaded": "\u5DF2\u4ECE\u672C\u673A OpenCode \u8BFB\u53D6 {agents} \u4E2A Agent\u3001{models} \u4E2A\u6A21\u578B\u3002",
|
|
@@ -26792,6 +26933,7 @@ var init_ui = __esm({
|
|
|
26792
26933
|
"details.copySuccess": "\u539F\u59CB\u6570\u636E\u5DF2\u590D\u5236",
|
|
26793
26934
|
"details.id": "\u7F16\u53F7",
|
|
26794
26935
|
"details.project": "\u9879\u76EE\u76EE\u5F55",
|
|
26936
|
+
"details.variant": "\u6A21\u578B Variant",
|
|
26795
26937
|
"details.prompt": "\u63D0\u793A\u8BCD",
|
|
26796
26938
|
"details.result": "\u6267\u884C\u7ED3\u679C / \u5931\u8D25\u539F\u56E0",
|
|
26797
26939
|
"details.category": "\u5206\u7C7B",
|
|
@@ -27023,6 +27165,7 @@ var init_ui = __esm({
|
|
|
27023
27165
|
"template.cwdHint": "OpenCode runs the task in this directory.",
|
|
27024
27166
|
"template.agent": "Agent",
|
|
27025
27167
|
"template.model": "Model",
|
|
27168
|
+
"template.variant": "Model variant",
|
|
27026
27169
|
"template.prompt": "Prompt",
|
|
27027
27170
|
"template.scheduleType": "Schedule",
|
|
27028
27171
|
"template.cronExpr": "Cron expression",
|
|
@@ -27060,9 +27203,11 @@ var init_ui = __esm({
|
|
|
27060
27203
|
"catalog.chooseProject": "Choose a project directory first",
|
|
27061
27204
|
"catalog.defaultModel": "Use the Agent / OpenCode default model",
|
|
27062
27205
|
"catalog.defaultProvider": "Default model",
|
|
27206
|
+
"catalog.defaultVariant": "Use the Agent / model default",
|
|
27063
27207
|
"catalog.provider": "Model provider",
|
|
27064
27208
|
"catalog.model": "Model",
|
|
27065
|
-
"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.",
|
|
27066
27211
|
"catalog.agentHint": "Loaded from opencode agent list for this project.",
|
|
27067
27212
|
"catalog.loading": "Loading Agents and models available to this project\u2026",
|
|
27068
27213
|
"catalog.loaded": "Loaded {agents} Agents and {models} models from local OpenCode.",
|
|
@@ -27093,6 +27238,7 @@ var init_ui = __esm({
|
|
|
27093
27238
|
"details.copySuccess": "Raw data copied",
|
|
27094
27239
|
"details.id": "ID",
|
|
27095
27240
|
"details.project": "Project directory",
|
|
27241
|
+
"details.variant": "Model variant",
|
|
27096
27242
|
"details.prompt": "Prompt",
|
|
27097
27243
|
"details.result": "Result / failure reason",
|
|
27098
27244
|
"details.category": "Category",
|
|
@@ -27655,6 +27801,7 @@ function parseTaskPayload(value) {
|
|
|
27655
27801
|
cwd: requiredString("cwd"),
|
|
27656
27802
|
agent: requiredString("agent"),
|
|
27657
27803
|
model: optionalString("model", "default"),
|
|
27804
|
+
variant: Object.hasOwn(input, "variant") ? optionalString("variant") : void 0,
|
|
27658
27805
|
prompt: requiredString("prompt"),
|
|
27659
27806
|
category: optionalString("category", "general"),
|
|
27660
27807
|
batchId: optionalString("batchId"),
|
|
@@ -27670,6 +27817,7 @@ function editableTaskPayload(input) {
|
|
|
27670
27817
|
name: input.name,
|
|
27671
27818
|
agent: input.agent,
|
|
27672
27819
|
model: input.model ?? "default",
|
|
27820
|
+
...input.variant === void 0 ? {} : { variant: input.variant },
|
|
27673
27821
|
prompt: input.prompt,
|
|
27674
27822
|
category: input.category ?? "general",
|
|
27675
27823
|
batchId: input.batchId ?? null,
|
|
@@ -27725,6 +27873,7 @@ function parseTemplatePayload(value) {
|
|
|
27725
27873
|
name: requiredString("name"),
|
|
27726
27874
|
agent: requiredString("agent"),
|
|
27727
27875
|
model: optionalString("model", "default"),
|
|
27876
|
+
variant: Object.hasOwn(input, "variant") ? optionalString("variant") : void 0,
|
|
27728
27877
|
prompt: requiredString("prompt"),
|
|
27729
27878
|
cwd: requiredString("cwd"),
|
|
27730
27879
|
category: optionalString("category", "general"),
|
|
@@ -28058,7 +28207,7 @@ var init_web = __esm({
|
|
|
28058
28207
|
const latestRun = latestRuns.get(task.id);
|
|
28059
28208
|
const executionActive = latestRun?.status === "running";
|
|
28060
28209
|
const batchId = task.batchId?.trim() || null;
|
|
28061
|
-
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 ?? ""}`);
|
|
28062
28211
|
return `<tr data-task-row data-search="${searchable}">
|
|
28063
28212
|
<td class="faint" data-label="${t(locale, "table.id")}">#${task.id}</td>
|
|
28064
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>
|
|
@@ -28136,11 +28285,12 @@ var init_web = __esm({
|
|
|
28136
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>
|
|
28137
28286
|
<datalist id="task-cwd-options">${projects.map((project) => `<option value="${esc(project.cwd)}"></option>`).join("")}</datalist>
|
|
28138
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>
|
|
28139
|
-
<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>
|
|
28140
28290
|
<label class="form-field form-field-wide"><span>${t(locale, "template.prompt")}</span><textarea id="task-prompt" rows="6" required></textarea></label>
|
|
28141
28291
|
</div>
|
|
28142
28292
|
<p id="task-project-status" class="form-note"></p>
|
|
28143
|
-
<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>
|
|
28144
28294
|
<details class="advanced-fields">
|
|
28145
28295
|
<summary>${t(locale, "template.advanced")}</summary>
|
|
28146
28296
|
<div class="template-form-grid">
|
|
@@ -28182,7 +28332,7 @@ var init_web = __esm({
|
|
|
28182
28332
|
return `<tr>
|
|
28183
28333
|
<td class="faint" data-label="${t(locale, "table.id")}">#${template.id}</td>
|
|
28184
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>
|
|
28185
|
-
<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>
|
|
28186
28336
|
<td data-label="${t(locale, "table.type")}"><span class="tag t-${scheduleType}">${typeLabel}</span></td>
|
|
28187
28337
|
<td data-label="${t(locale, "table.rule")}" class="m small">${esc(rule)}</td>
|
|
28188
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>
|
|
@@ -28212,14 +28362,15 @@ var init_web = __esm({
|
|
|
28212
28362
|
<label class="form-field"><span>${t(locale, "template.name")}</span><input id="template-name" required maxlength="200" autocomplete="off"></label>
|
|
28213
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>
|
|
28214
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>
|
|
28215
|
-
<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>
|
|
28216
28367
|
<label class="form-field form-field-wide"><span>${t(locale, "template.prompt")}</span><textarea id="template-prompt" rows="6" required></textarea></label>
|
|
28217
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>
|
|
28218
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>
|
|
28219
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>
|
|
28220
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>
|
|
28221
28372
|
</div>
|
|
28222
|
-
<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>
|
|
28223
28374
|
<details class="advanced-fields">
|
|
28224
28375
|
<summary>${t(locale, "template.advanced")}</summary>
|
|
28225
28376
|
<div class="template-form-grid">
|
|
@@ -28253,6 +28404,7 @@ var init_web = __esm({
|
|
|
28253
28404
|
taskId: taskRuns4.taskId,
|
|
28254
28405
|
sessionId: taskRuns4.sessionId,
|
|
28255
28406
|
model: taskRuns4.model,
|
|
28407
|
+
variant: taskRuns4.variant,
|
|
28256
28408
|
status: taskRuns4.status,
|
|
28257
28409
|
startedAt: taskRuns4.startedAt,
|
|
28258
28410
|
finishedAt: taskRuns4.finishedAt,
|
|
@@ -28273,7 +28425,7 @@ var init_web = __esm({
|
|
|
28273
28425
|
const log = run.log ? renderRunLog(run.id, run.taskName, run.log, locale, run.status !== "done") : "";
|
|
28274
28426
|
return `<tr class="run-summary-row">
|
|
28275
28427
|
<td class="faint" data-label="${t(locale, "table.run")}">#${run.id}</td>
|
|
28276
|
-
<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>
|
|
28277
28429
|
<td data-label="${t(locale, "table.agent")}"><span class="tag">${esc(run.taskAgent)}</span></td>
|
|
28278
28430
|
<td data-label="${t(locale, "table.session")}" class="m small">${esc(maskSessionId(run.sessionId))}</td>
|
|
28279
28431
|
<td data-label="${t(locale, "table.status")}"><span class="badge b-${status}">${runStatusText(locale, run.status ?? "unknown")}</span></td>
|
|
@@ -28323,7 +28475,7 @@ var init_web = __esm({
|
|
|
28323
28475
|
const runRows = runningRuns.map((run) => {
|
|
28324
28476
|
const session = maskSessionId(run.sessionId);
|
|
28325
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>
|
|
28326
|
-
<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>
|
|
28327
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>
|
|
28328
28480
|
<td data-label="${t(locale, "table.duration")}" class="small">${formatDuration(run.startedAt, null)}</td></tr>`;
|
|
28329
28481
|
}).join("");
|
|
@@ -29152,11 +29304,13 @@ async function runDoctorSmoke(options) {
|
|
|
29152
29304
|
const cwd = resolve5(options.cwd);
|
|
29153
29305
|
const marker = options.marker ?? `SUPERTASK_SMOKE_${randomUUID2().replaceAll("-", "").toUpperCase()}`;
|
|
29154
29306
|
const model = options.model && options.model !== "default" ? options.model : void 0;
|
|
29307
|
+
const variant = options.variant?.trim() || void 0;
|
|
29155
29308
|
const startedAt = Date.now();
|
|
29156
29309
|
const task = await TaskService.add({
|
|
29157
29310
|
name: "[doctor] Gateway real smoke test",
|
|
29158
29311
|
agent: options.agent,
|
|
29159
29312
|
model,
|
|
29313
|
+
variant,
|
|
29160
29314
|
prompt: `\u4E0D\u8981\u8C03\u7528\u4EFB\u4F55\u5DE5\u5177\u3002\u53EA\u56DE\u590D\u8FD9\u4E00\u884C\uFF1A${marker}`,
|
|
29161
29315
|
cwd,
|
|
29162
29316
|
category: "diagnostic",
|
|
@@ -29180,6 +29334,7 @@ async function runDoctorSmoke(options) {
|
|
|
29180
29334
|
status: "missing",
|
|
29181
29335
|
agent: options.agent,
|
|
29182
29336
|
model: model ?? null,
|
|
29337
|
+
variant: variant ?? null,
|
|
29183
29338
|
cwd,
|
|
29184
29339
|
durationMs: Date.now() - startedAt,
|
|
29185
29340
|
error: "\u5192\u70DF\u4EFB\u52A1\u5728\u5B8C\u6210\u524D\u88AB\u5220\u9664"
|
|
@@ -29195,6 +29350,7 @@ async function runDoctorSmoke(options) {
|
|
|
29195
29350
|
status: current2.status,
|
|
29196
29351
|
agent: options.agent,
|
|
29197
29352
|
model: model ?? null,
|
|
29353
|
+
variant: variant ?? null,
|
|
29198
29354
|
cwd,
|
|
29199
29355
|
durationMs: Date.now() - startedAt,
|
|
29200
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"
|
|
@@ -29208,6 +29364,7 @@ async function runDoctorSmoke(options) {
|
|
|
29208
29364
|
status: current2.status,
|
|
29209
29365
|
agent: options.agent,
|
|
29210
29366
|
model: model ?? null,
|
|
29367
|
+
variant: variant ?? null,
|
|
29211
29368
|
cwd,
|
|
29212
29369
|
durationMs: Date.now() - startedAt,
|
|
29213
29370
|
error: tail(run2?.log ?? current2.resultLog) ?? `\u4EFB\u52A1\u8FDB\u5165 ${current2.status}`
|
|
@@ -29225,6 +29382,7 @@ async function runDoctorSmoke(options) {
|
|
|
29225
29382
|
status: current?.status ?? "missing",
|
|
29226
29383
|
agent: options.agent,
|
|
29227
29384
|
model: model ?? null,
|
|
29385
|
+
variant: variant ?? null,
|
|
29228
29386
|
cwd,
|
|
29229
29387
|
durationMs: Date.now() - startedAt,
|
|
29230
29388
|
error: `\u7B49\u5F85 Gateway \u6267\u884C\u8D85\u8FC7 ${options.timeoutMs}ms\uFF0C\u5192\u70DF\u4EFB\u52A1\u5DF2\u8BF7\u6C42\u53D6\u6D88`
|
|
@@ -29265,7 +29423,7 @@ if (cliLocale === "zh-CN") {
|
|
|
29265
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"))
|
|
29266
29424
|
});
|
|
29267
29425
|
}
|
|
29268
|
-
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 () => {
|
|
29269
29427
|
const submitCwd = process.cwd();
|
|
29270
29428
|
const retryBackoffMs = parseDuration(options.retryBackoff);
|
|
29271
29429
|
const timeoutMs = options.timeout ? parseDuration(options.timeout) : null;
|
|
@@ -29277,6 +29435,7 @@ program2.command("add").description(t2("\u521B\u5EFA\u65B0\u4EFB\u52A1", "create
|
|
|
29277
29435
|
agent: options.agent,
|
|
29278
29436
|
prompt: options.prompt,
|
|
29279
29437
|
model: options.model,
|
|
29438
|
+
variant: options.variant,
|
|
29280
29439
|
category: options.category,
|
|
29281
29440
|
importance: parseBoundedInteger(options.importance, "importance", 1, 5),
|
|
29282
29441
|
urgency: parseBoundedInteger(options.urgency, "urgency", 1, 5),
|
|
@@ -29289,17 +29448,23 @@ program2.command("add").description(t2("\u521B\u5EFA\u65B0\u4EFB\u52A1", "create
|
|
|
29289
29448
|
});
|
|
29290
29449
|
console.log(JSON.stringify({ id: task.id, status: "created" }, null, 2));
|
|
29291
29450
|
}));
|
|
29292
|
-
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 () => {
|
|
29293
29452
|
if (options.batch !== void 0 && options.clearBatch) {
|
|
29294
29453
|
throw new Error("batch \u548C clear-batch \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528");
|
|
29295
29454
|
}
|
|
29296
29455
|
if (options.timeout !== void 0 && options.clearTimeout) {
|
|
29297
29456
|
throw new Error("timeout \u548C clear-timeout \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528");
|
|
29298
29457
|
}
|
|
29458
|
+
if (options.variant !== void 0 && options.clearVariant) {
|
|
29459
|
+
throw new Error("variant \u548C clear-variant \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528");
|
|
29460
|
+
}
|
|
29299
29461
|
const update = {};
|
|
29300
29462
|
for (const field of ["name", "agent", "model", "prompt", "category"]) {
|
|
29301
29463
|
if (options[field] !== void 0) update[field] = options[field];
|
|
29302
29464
|
}
|
|
29465
|
+
if (options.variant !== void 0 || options.clearVariant) {
|
|
29466
|
+
update.variant = options.clearVariant ? null : options.variant;
|
|
29467
|
+
}
|
|
29303
29468
|
if (options.importance !== void 0) {
|
|
29304
29469
|
update.importance = parseBoundedInteger(options.importance, "importance", 1, 5);
|
|
29305
29470
|
}
|
|
@@ -29335,6 +29500,7 @@ program2.command("next").description(t2("\u83B7\u53D6\u4E0B\u4E00\u4E2A\u5F85\u6
|
|
|
29335
29500
|
name: task.name,
|
|
29336
29501
|
agent: task.agent,
|
|
29337
29502
|
model: task.model,
|
|
29503
|
+
variant: task.variant,
|
|
29338
29504
|
prompt: task.prompt,
|
|
29339
29505
|
cwd: task.cwd,
|
|
29340
29506
|
category: task.category,
|
|
@@ -29411,7 +29577,7 @@ program2.command("delete").description(t2("\u5220\u9664\u4EFB\u52A1", "delete a
|
|
|
29411
29577
|
console.log(JSON.stringify({ deleted, id }));
|
|
29412
29578
|
}));
|
|
29413
29579
|
program2.command("template").description(t2("\u7BA1\u7406\u5B9A\u65F6\u4EFB\u52A1\u6A21\u677F", "manage scheduled task templates")).addCommand(
|
|
29414
|
-
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 () => {
|
|
29415
29581
|
let intervalMs = null;
|
|
29416
29582
|
let runAt = null;
|
|
29417
29583
|
const retryBackoffMs = parseDuration(options.retryBackoff);
|
|
@@ -29439,6 +29605,7 @@ program2.command("template").description(t2("\u7BA1\u7406\u5B9A\u65F6\u4EFB\u52A
|
|
|
29439
29605
|
agent: options.agent,
|
|
29440
29606
|
prompt: options.prompt,
|
|
29441
29607
|
model: options.model,
|
|
29608
|
+
variant: options.variant,
|
|
29442
29609
|
category: options.category,
|
|
29443
29610
|
importance: parseBoundedInteger(options.importance, "importance", 1, 5),
|
|
29444
29611
|
urgency: parseBoundedInteger(options.urgency, "urgency", 1, 5),
|
|
@@ -29565,7 +29732,7 @@ program2.command("config").description(t2("\u663E\u793A\u5F53\u524D\u914D\u7F6E"
|
|
|
29565
29732
|
const cfg = loadConfig2();
|
|
29566
29733
|
console.log(JSON.stringify(cfg, null, 2));
|
|
29567
29734
|
});
|
|
29568
|
-
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 () => {
|
|
29569
29736
|
const config = loadConfig();
|
|
29570
29737
|
const database = DatabaseMaintenanceService.check();
|
|
29571
29738
|
const legacyQuarantinedRuns = await TaskRunService.listLegacyQuarantinedRuns(
|
|
@@ -29678,6 +29845,7 @@ program2.command("doctor").description(t2("\u68C0\u67E5 OpenCode\u3001\u6570\u63
|
|
|
29678
29845
|
smoke = await runDoctorSmoke({
|
|
29679
29846
|
agent: options.smokeAgent,
|
|
29680
29847
|
model: options.smokeModel,
|
|
29848
|
+
variant: options.smokeVariant,
|
|
29681
29849
|
cwd: options.smokeCwd ?? process.cwd(),
|
|
29682
29850
|
timeoutMs: smokeTimeoutMs
|
|
29683
29851
|
});
|