opencode-supertask 0.1.38 → 0.1.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/README.md +152 -352
- package/README.zh-CN.md +243 -0
- package/dist/cli/index.js +250 -60
- package/dist/cli/index.js.map +1 -1
- package/dist/gateway/index.js +195 -43
- package/dist/gateway/index.js.map +1 -1
- package/dist/plugin/supertask.js +347 -10
- package/dist/plugin/supertask.js.map +1 -1
- package/dist/web/index.js +179 -41
- package/dist/web/index.js.map +1 -1
- package/dist/worker/index.d.ts +1 -0
- package/dist/worker/index.js +34 -3
- package/dist/worker/index.js.map +1 -1
- package/drizzle/0008_good_smasher.sql +3 -0
- package/drizzle/meta/0008_snapshot.json +606 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +1 -1
package/dist/web/index.js
CHANGED
|
@@ -16395,6 +16395,7 @@ var tasks = sqliteTable("tasks", {
|
|
|
16395
16395
|
name: text("name").notNull(),
|
|
16396
16396
|
agent: text("agent").notNull(),
|
|
16397
16397
|
model: text("model").default("default"),
|
|
16398
|
+
variant: text("variant"),
|
|
16398
16399
|
prompt: text("prompt").notNull(),
|
|
16399
16400
|
cwd: text("cwd"),
|
|
16400
16401
|
// 分类与优先级
|
|
@@ -16439,6 +16440,7 @@ var taskRuns = sqliteTable("task_runs", {
|
|
|
16439
16440
|
taskId: integer("task_id").notNull().references(() => tasks.id, { onDelete: "cascade" }),
|
|
16440
16441
|
sessionId: text("session_id"),
|
|
16441
16442
|
model: text("model"),
|
|
16443
|
+
variant: text("variant"),
|
|
16442
16444
|
status: text("status").default("running"),
|
|
16443
16445
|
startedAt: integer("started_at", { mode: "timestamp" }).$defaultFn(() => /* @__PURE__ */ new Date()),
|
|
16444
16446
|
finishedAt: integer("finished_at", { mode: "timestamp" }),
|
|
@@ -16459,6 +16461,7 @@ var taskTemplates = sqliteTable("task_templates", {
|
|
|
16459
16461
|
name: text("name").notNull(),
|
|
16460
16462
|
agent: text("agent").notNull(),
|
|
16461
16463
|
model: text("model").default("default"),
|
|
16464
|
+
variant: text("variant"),
|
|
16462
16465
|
prompt: text("prompt").notNull(),
|
|
16463
16466
|
cwd: text("cwd"),
|
|
16464
16467
|
category: text("category").default("general"),
|
|
@@ -16657,6 +16660,8 @@ var CATALOG_CACHE_MS = 3e4;
|
|
|
16657
16660
|
var COMMAND_TIMEOUT_MS = 2e4;
|
|
16658
16661
|
var MAX_OUTPUT_BYTES = 4 * 1024 * 1024;
|
|
16659
16662
|
var ANSI_PATTERN = /\x1B(?:[@-_][0-?]*[ -/]*[@-~]|\][^\x07]*(?:\x07|\x1B\\))/g;
|
|
16663
|
+
var OpenCodeCommandExitError = class extends Error {
|
|
16664
|
+
};
|
|
16660
16665
|
var catalogCache = /* @__PURE__ */ new Map();
|
|
16661
16666
|
function cleanOutput(value) {
|
|
16662
16667
|
return value.replace(ANSI_PATTERN, "").replace(/\r/g, "");
|
|
@@ -16666,17 +16671,49 @@ function runOpenCode(executable, args, cwd, timeoutMs) {
|
|
|
16666
16671
|
const child = spawn(executable, args, {
|
|
16667
16672
|
cwd,
|
|
16668
16673
|
env: process.env,
|
|
16669
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
16674
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
16675
|
+
detached: process.platform !== "win32"
|
|
16670
16676
|
});
|
|
16671
16677
|
let stdout = "";
|
|
16672
16678
|
let stderr = "";
|
|
16673
16679
|
let failure = null;
|
|
16674
|
-
let
|
|
16680
|
+
let settled = false;
|
|
16681
|
+
let forceKillTimer = null;
|
|
16682
|
+
let finalRejectTimer = null;
|
|
16683
|
+
let timer;
|
|
16684
|
+
const signalProcessTree = (signal) => {
|
|
16685
|
+
if (process.platform !== "win32" && child.pid) {
|
|
16686
|
+
try {
|
|
16687
|
+
process.kill(-child.pid, signal);
|
|
16688
|
+
return;
|
|
16689
|
+
} catch {
|
|
16690
|
+
}
|
|
16691
|
+
}
|
|
16692
|
+
child.kill(signal);
|
|
16693
|
+
};
|
|
16694
|
+
const rejectOnce = (error) => {
|
|
16695
|
+
failure ??= error;
|
|
16696
|
+
if (settled) return;
|
|
16697
|
+
settled = true;
|
|
16698
|
+
clearTimeout(timer);
|
|
16699
|
+
if (forceKillTimer) clearTimeout(forceKillTimer);
|
|
16700
|
+
if (finalRejectTimer) clearTimeout(finalRejectTimer);
|
|
16701
|
+
reject(failure);
|
|
16702
|
+
};
|
|
16703
|
+
const terminate = (error) => {
|
|
16704
|
+
if (failure) return;
|
|
16705
|
+
failure = error;
|
|
16706
|
+
signalProcessTree("SIGTERM");
|
|
16707
|
+
forceKillTimer = setTimeout(() => {
|
|
16708
|
+
signalProcessTree("SIGKILL");
|
|
16709
|
+
rejectOnce(error);
|
|
16710
|
+
}, 1e3);
|
|
16711
|
+
finalRejectTimer = setTimeout(() => rejectOnce(error), 2e3);
|
|
16712
|
+
};
|
|
16675
16713
|
const append = (current, chunk) => {
|
|
16676
16714
|
const next = current + chunk.toString();
|
|
16677
16715
|
if (Buffer.byteLength(next) > MAX_OUTPUT_BYTES && failure === null) {
|
|
16678
|
-
|
|
16679
|
-
child.kill("SIGTERM");
|
|
16716
|
+
terminate(new Error(`OpenCode \u8F93\u51FA\u8D85\u8FC7 ${MAX_OUTPUT_BYTES} bytes`));
|
|
16680
16717
|
}
|
|
16681
16718
|
return next.slice(-MAX_OUTPUT_BYTES);
|
|
16682
16719
|
};
|
|
@@ -16687,23 +16724,25 @@ function runOpenCode(executable, args, cwd, timeoutMs) {
|
|
|
16687
16724
|
stderr = append(stderr, chunk);
|
|
16688
16725
|
});
|
|
16689
16726
|
child.once("error", (error) => {
|
|
16690
|
-
|
|
16727
|
+
if (forceKillTimer) return;
|
|
16728
|
+
rejectOnce(error);
|
|
16691
16729
|
});
|
|
16692
|
-
|
|
16693
|
-
|
|
16694
|
-
child.kill("SIGTERM");
|
|
16730
|
+
timer = setTimeout(() => {
|
|
16731
|
+
terminate(new Error(`OpenCode \u547D\u4EE4\u8D85\u8FC7 ${timeoutMs}ms \u672A\u5B8C\u6210`));
|
|
16695
16732
|
}, timeoutMs);
|
|
16696
16733
|
child.once("close", (code) => {
|
|
16697
|
-
if (finished) return;
|
|
16698
|
-
finished = true;
|
|
16699
16734
|
clearTimeout(timer);
|
|
16735
|
+
if (forceKillTimer) return;
|
|
16736
|
+
if (finalRejectTimer) clearTimeout(finalRejectTimer);
|
|
16737
|
+
if (settled) return;
|
|
16738
|
+
settled = true;
|
|
16700
16739
|
if (failure) {
|
|
16701
16740
|
reject(failure);
|
|
16702
16741
|
return;
|
|
16703
16742
|
}
|
|
16704
16743
|
if (code !== 0) {
|
|
16705
16744
|
const detail = cleanOutput(stderr).trim() || `\u9000\u51FA\u7801 ${code ?? "null"}`;
|
|
16706
|
-
reject(new
|
|
16745
|
+
reject(new OpenCodeCommandExitError(`OpenCode ${args.join(" ")} \u5931\u8D25\uFF1A${detail}`));
|
|
16707
16746
|
return;
|
|
16708
16747
|
}
|
|
16709
16748
|
resolve3(cleanOutput(stdout));
|
|
@@ -16713,6 +16752,52 @@ function runOpenCode(executable, args, cwd, timeoutMs) {
|
|
|
16713
16752
|
function parseOpenCodeModels(output) {
|
|
16714
16753
|
return [...new Set(cleanOutput(output).split("\n").map((line) => line.trim()).filter((line) => /^[^\s/]+\/.+/.test(line)))].sort((left, right) => left.localeCompare(right));
|
|
16715
16754
|
}
|
|
16755
|
+
function isRecord(value) {
|
|
16756
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16757
|
+
}
|
|
16758
|
+
function findJsonObjectEnd(value, start) {
|
|
16759
|
+
let depth = 0;
|
|
16760
|
+
let inString = false;
|
|
16761
|
+
let escaped = false;
|
|
16762
|
+
for (let index2 = start; index2 < value.length; index2 += 1) {
|
|
16763
|
+
const character = value[index2];
|
|
16764
|
+
if (inString) {
|
|
16765
|
+
if (escaped) escaped = false;
|
|
16766
|
+
else if (character === "\\") escaped = true;
|
|
16767
|
+
else if (character === '"') inString = false;
|
|
16768
|
+
continue;
|
|
16769
|
+
}
|
|
16770
|
+
if (character === '"') inString = true;
|
|
16771
|
+
else if (character === "{") depth += 1;
|
|
16772
|
+
else if (character === "}" && --depth === 0) return index2 + 1;
|
|
16773
|
+
}
|
|
16774
|
+
return null;
|
|
16775
|
+
}
|
|
16776
|
+
function parseOpenCodeModelMetadata(output) {
|
|
16777
|
+
const cleaned = cleanOutput(output);
|
|
16778
|
+
const models = /* @__PURE__ */ new Set();
|
|
16779
|
+
const variantsByModel = {};
|
|
16780
|
+
const headingPattern = /^([^\s/]+\/[^\r\n]+)\r?\n\s*(?=\{)/gm;
|
|
16781
|
+
for (const match2 of cleaned.matchAll(headingPattern)) {
|
|
16782
|
+
const model = match2[1].trim();
|
|
16783
|
+
models.add(model);
|
|
16784
|
+
let objectStart = (match2.index ?? 0) + match2[0].length;
|
|
16785
|
+
while (/\s/.test(cleaned[objectStart] ?? "")) objectStart += 1;
|
|
16786
|
+
if (cleaned[objectStart] !== "{") continue;
|
|
16787
|
+
const objectEnd = findJsonObjectEnd(cleaned, objectStart);
|
|
16788
|
+
if (objectEnd === null) continue;
|
|
16789
|
+
try {
|
|
16790
|
+
const metadata = JSON.parse(cleaned.slice(objectStart, objectEnd));
|
|
16791
|
+
if (!isRecord(metadata) || !isRecord(metadata.variants)) continue;
|
|
16792
|
+
variantsByModel[model] = Object.keys(metadata.variants).filter((variant) => variant.trim().length > 0).sort((left, right) => left.localeCompare(right));
|
|
16793
|
+
} catch {
|
|
16794
|
+
}
|
|
16795
|
+
}
|
|
16796
|
+
return {
|
|
16797
|
+
models: [...models].sort((left, right) => left.localeCompare(right)),
|
|
16798
|
+
variantsByModel
|
|
16799
|
+
};
|
|
16800
|
+
}
|
|
16716
16801
|
function parseOpenCodeAgents(output) {
|
|
16717
16802
|
const agents = /* @__PURE__ */ new Map();
|
|
16718
16803
|
for (const line of cleanOutput(output).split("\n")) {
|
|
@@ -16736,14 +16821,18 @@ async function loadOpenCodeCatalog(cwd, options = {}) {
|
|
|
16736
16821
|
return cached.result;
|
|
16737
16822
|
}
|
|
16738
16823
|
const result = Promise.all([
|
|
16739
|
-
runOpenCode(executable, ["models"], cwd, timeoutMs)
|
|
16824
|
+
runOpenCode(executable, ["models", "--verbose"], cwd, timeoutMs).catch((error) => {
|
|
16825
|
+
if (!(error instanceof OpenCodeCommandExitError)) throw error;
|
|
16826
|
+
return runOpenCode(executable, ["models"], cwd, timeoutMs);
|
|
16827
|
+
}),
|
|
16740
16828
|
runOpenCode(executable, ["agent", "list"], cwd, timeoutMs)
|
|
16741
16829
|
]).then(([modelsOutput, agentsOutput]) => {
|
|
16742
|
-
const
|
|
16830
|
+
const metadata = parseOpenCodeModelMetadata(modelsOutput);
|
|
16831
|
+
const models = metadata.models.length > 0 ? metadata.models : parseOpenCodeModels(modelsOutput);
|
|
16743
16832
|
const agents = parseOpenCodeAgents(agentsOutput).filter((agent) => agent.mode !== "subagent");
|
|
16744
16833
|
if (models.length === 0) throw new Error("OpenCode \u6CA1\u6709\u8FD4\u56DE\u53EF\u7528\u6A21\u578B");
|
|
16745
16834
|
if (agents.length === 0) throw new Error("OpenCode \u6CA1\u6709\u8FD4\u56DE\u53EF\u76F4\u63A5\u8FD0\u884C\u7684\u4E3B Agent");
|
|
16746
|
-
return { cwd, models, agents };
|
|
16835
|
+
return { cwd, models, variantsByModel: metadata.variantsByModel, agents };
|
|
16747
16836
|
});
|
|
16748
16837
|
if (options.useCache !== false) {
|
|
16749
16838
|
catalogCache.set(cacheKey, { expiresAt: Date.now() + CATALOG_CACHE_MS, result });
|
|
@@ -17394,6 +17483,22 @@ function normalizeTaskBatchId(batchId) {
|
|
|
17394
17483
|
return batchId.trim() || null;
|
|
17395
17484
|
}
|
|
17396
17485
|
|
|
17486
|
+
// src/core/model-variant.ts
|
|
17487
|
+
var MAX_MODEL_VARIANT_LENGTH = 128;
|
|
17488
|
+
var CONTROL_CHARACTER_PATTERN = /[\u0000-\u001F\u007F]/;
|
|
17489
|
+
function normalizeModelVariant(value) {
|
|
17490
|
+
if (value === void 0 || value === null) return value;
|
|
17491
|
+
const normalized = value.trim();
|
|
17492
|
+
if (!normalized) return null;
|
|
17493
|
+
if (normalized.length > MAX_MODEL_VARIANT_LENGTH) {
|
|
17494
|
+
throw new Error(`variant \u957F\u5EA6\u4E0D\u80FD\u8D85\u8FC7 ${MAX_MODEL_VARIANT_LENGTH} \u4E2A\u5B57\u7B26`);
|
|
17495
|
+
}
|
|
17496
|
+
if (CONTROL_CHARACTER_PATTERN.test(normalized)) {
|
|
17497
|
+
throw new Error("variant \u4E0D\u80FD\u5305\u542B\u63A7\u5236\u5B57\u7B26");
|
|
17498
|
+
}
|
|
17499
|
+
return normalized;
|
|
17500
|
+
}
|
|
17501
|
+
|
|
17397
17502
|
// src/core/services/task.service.ts
|
|
17398
17503
|
var { tasks: tasks3, taskRuns: taskRuns3 } = schema_exports;
|
|
17399
17504
|
var cleanupInvocation = 0;
|
|
@@ -17459,7 +17564,8 @@ var TaskService = class {
|
|
|
17459
17564
|
static async add(data) {
|
|
17460
17565
|
const normalizedData = {
|
|
17461
17566
|
...data,
|
|
17462
|
-
batchId: normalizeTaskBatchId(data.batchId)
|
|
17567
|
+
batchId: normalizeTaskBatchId(data.batchId),
|
|
17568
|
+
variant: normalizeModelVariant(data.variant)
|
|
17463
17569
|
};
|
|
17464
17570
|
this.validateNewTask(normalizedData);
|
|
17465
17571
|
return db.transaction((tx) => {
|
|
@@ -17487,7 +17593,11 @@ var TaskService = class {
|
|
|
17487
17593
|
}
|
|
17488
17594
|
static async update(id, data, scope = {}) {
|
|
17489
17595
|
if (Object.keys(data).length === 0) throw new Error("\u81F3\u5C11\u63D0\u4F9B\u4E00\u4E2A\u8981\u4FEE\u6539\u7684\u5B57\u6BB5");
|
|
17490
|
-
const normalizedData =
|
|
17596
|
+
const normalizedData = {
|
|
17597
|
+
...data,
|
|
17598
|
+
...data.batchId === void 0 ? {} : { batchId: normalizeTaskBatchId(data.batchId) ?? null },
|
|
17599
|
+
...data.variant === void 0 ? {} : { variant: normalizeModelVariant(data.variant) ?? null }
|
|
17600
|
+
};
|
|
17491
17601
|
return db.transaction((tx) => {
|
|
17492
17602
|
const task = tx.select().from(tasks3).where(and(
|
|
17493
17603
|
eq(tasks3.id, id),
|
|
@@ -17499,6 +17609,7 @@ var TaskService = class {
|
|
|
17499
17609
|
name: normalizedData.name ?? task.name,
|
|
17500
17610
|
agent: normalizedData.agent ?? task.agent,
|
|
17501
17611
|
model: normalizedData.model ?? task.model,
|
|
17612
|
+
variant: normalizedData.variant === void 0 ? task.variant : normalizedData.variant,
|
|
17502
17613
|
prompt: normalizedData.prompt ?? task.prompt,
|
|
17503
17614
|
cwd: task.cwd,
|
|
17504
17615
|
category: normalizedData.category ?? task.category,
|
|
@@ -18273,7 +18384,8 @@ var TaskTemplateService = class {
|
|
|
18273
18384
|
static async create(data) {
|
|
18274
18385
|
const normalizedData = {
|
|
18275
18386
|
...data,
|
|
18276
|
-
batchId: normalizeTaskBatchId(data.batchId)
|
|
18387
|
+
batchId: normalizeTaskBatchId(data.batchId),
|
|
18388
|
+
variant: normalizeModelVariant(data.variant)
|
|
18277
18389
|
};
|
|
18278
18390
|
this.validate(normalizedData);
|
|
18279
18391
|
const now = Date.now();
|
|
@@ -18339,7 +18451,8 @@ var TaskTemplateService = class {
|
|
|
18339
18451
|
static async update(id, data) {
|
|
18340
18452
|
const normalizedData = {
|
|
18341
18453
|
...data,
|
|
18342
|
-
batchId: normalizeTaskBatchId(data.batchId) ?? null
|
|
18454
|
+
batchId: normalizeTaskBatchId(data.batchId) ?? null,
|
|
18455
|
+
...data.variant === void 0 ? {} : { variant: normalizeModelVariant(data.variant) ?? null }
|
|
18343
18456
|
};
|
|
18344
18457
|
this.validate(normalizedData);
|
|
18345
18458
|
const now = Date.now();
|
|
@@ -18680,6 +18793,7 @@ function createTaskFromTemplate(templateId, options) {
|
|
|
18680
18793
|
name: `${options.namePrefix ?? ""}${tmpl.name}`,
|
|
18681
18794
|
agent: tmpl.agent,
|
|
18682
18795
|
model: tmpl.model ?? "default",
|
|
18796
|
+
variant: tmpl.variant,
|
|
18683
18797
|
prompt: tmpl.prompt,
|
|
18684
18798
|
cwd: tmpl.cwd ?? null,
|
|
18685
18799
|
category: tmpl.category ?? "general",
|
|
@@ -19316,6 +19430,7 @@ var ZH = {
|
|
|
19316
19430
|
"template.cwdHint": "OpenCode \u4F1A\u5728\u8FD9\u4E2A\u76EE\u5F55\u4E2D\u6267\u884C\u4EFB\u52A1\u3002",
|
|
19317
19431
|
"template.agent": "Agent",
|
|
19318
19432
|
"template.model": "\u6A21\u578B",
|
|
19433
|
+
"template.variant": "\u6A21\u578B Variant",
|
|
19319
19434
|
"template.prompt": "\u63D0\u793A\u8BCD",
|
|
19320
19435
|
"template.scheduleType": "\u6267\u884C\u65B9\u5F0F",
|
|
19321
19436
|
"template.cronExpr": "Cron \u8868\u8FBE\u5F0F",
|
|
@@ -19353,9 +19468,11 @@ var ZH = {
|
|
|
19353
19468
|
"catalog.chooseProject": "\u8BF7\u5148\u9009\u62E9\u9879\u76EE\u76EE\u5F55",
|
|
19354
19469
|
"catalog.defaultModel": "\u8DDF\u968F Agent / OpenCode \u9ED8\u8BA4\u6A21\u578B",
|
|
19355
19470
|
"catalog.defaultProvider": "\u9ED8\u8BA4\u6A21\u578B",
|
|
19471
|
+
"catalog.defaultVariant": "\u8DDF\u968F Agent / \u6A21\u578B\u9ED8\u8BA4\u8BBE\u7F6E",
|
|
19356
19472
|
"catalog.provider": "\u6A21\u578B\u63D0\u4F9B\u5546",
|
|
19357
19473
|
"catalog.model": "\u5177\u4F53\u6A21\u578B",
|
|
19358
|
-
"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",
|
|
19474
|
+
"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",
|
|
19475
|
+
"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",
|
|
19359
19476
|
"catalog.agentHint": "\u6765\u81EA\u5F53\u524D\u9879\u76EE\u7684 opencode agent list\u3002",
|
|
19360
19477
|
"catalog.loading": "\u6B63\u5728\u8BFB\u53D6\u6B64\u9879\u76EE\u53EF\u7528\u7684 Agent \u548C\u6A21\u578B\u2026",
|
|
19361
19478
|
"catalog.loaded": "\u5DF2\u4ECE\u672C\u673A OpenCode \u8BFB\u53D6 {agents} \u4E2A Agent\u3001{models} \u4E2A\u6A21\u578B\u3002",
|
|
@@ -19386,6 +19503,7 @@ var ZH = {
|
|
|
19386
19503
|
"details.copySuccess": "\u539F\u59CB\u6570\u636E\u5DF2\u590D\u5236",
|
|
19387
19504
|
"details.id": "\u7F16\u53F7",
|
|
19388
19505
|
"details.project": "\u9879\u76EE\u76EE\u5F55",
|
|
19506
|
+
"details.variant": "\u6A21\u578B Variant",
|
|
19389
19507
|
"details.prompt": "\u63D0\u793A\u8BCD",
|
|
19390
19508
|
"details.result": "\u6267\u884C\u7ED3\u679C / \u5931\u8D25\u539F\u56E0",
|
|
19391
19509
|
"details.category": "\u5206\u7C7B",
|
|
@@ -19617,6 +19735,7 @@ var EN = {
|
|
|
19617
19735
|
"template.cwdHint": "OpenCode runs the task in this directory.",
|
|
19618
19736
|
"template.agent": "Agent",
|
|
19619
19737
|
"template.model": "Model",
|
|
19738
|
+
"template.variant": "Model variant",
|
|
19620
19739
|
"template.prompt": "Prompt",
|
|
19621
19740
|
"template.scheduleType": "Schedule",
|
|
19622
19741
|
"template.cronExpr": "Cron expression",
|
|
@@ -19654,9 +19773,11 @@ var EN = {
|
|
|
19654
19773
|
"catalog.chooseProject": "Choose a project directory first",
|
|
19655
19774
|
"catalog.defaultModel": "Use the Agent / OpenCode default model",
|
|
19656
19775
|
"catalog.defaultProvider": "Default model",
|
|
19776
|
+
"catalog.defaultVariant": "Use the Agent / model default",
|
|
19657
19777
|
"catalog.provider": "Model provider",
|
|
19658
19778
|
"catalog.model": "Model",
|
|
19659
|
-
"catalog.modelHint": "Choose a provider, then a model returned by opencode models for this project. Default does not pass -m.",
|
|
19779
|
+
"catalog.modelHint": "Choose a provider, then a model returned by opencode models --verbose for this project. Default does not pass -m.",
|
|
19780
|
+
"catalog.variantHint": "Only variants declared by the selected model are shown. Default does not pass --variant.",
|
|
19660
19781
|
"catalog.agentHint": "Loaded from opencode agent list for this project.",
|
|
19661
19782
|
"catalog.loading": "Loading Agents and models available to this project\u2026",
|
|
19662
19783
|
"catalog.loaded": "Loaded {agents} Agents and {models} models from local OpenCode.",
|
|
@@ -19687,6 +19808,7 @@ var EN = {
|
|
|
19687
19808
|
"details.copySuccess": "Raw data copied",
|
|
19688
19809
|
"details.id": "ID",
|
|
19689
19810
|
"details.project": "Project directory",
|
|
19811
|
+
"details.variant": "Model variant",
|
|
19690
19812
|
"details.prompt": "Prompt",
|
|
19691
19813
|
"details.result": "Result / failure reason",
|
|
19692
19814
|
"details.category": "Category",
|
|
@@ -20211,6 +20333,7 @@ function clientMessages(locale) {
|
|
|
20211
20333
|
"details.copySuccess",
|
|
20212
20334
|
"details.id",
|
|
20213
20335
|
"details.project",
|
|
20336
|
+
"details.variant",
|
|
20214
20337
|
"details.prompt",
|
|
20215
20338
|
"details.result",
|
|
20216
20339
|
"details.category",
|
|
@@ -20311,6 +20434,7 @@ function clientMessages(locale) {
|
|
|
20311
20434
|
"catalog.chooseProject",
|
|
20312
20435
|
"catalog.defaultModel",
|
|
20313
20436
|
"catalog.defaultProvider",
|
|
20437
|
+
"catalog.defaultVariant",
|
|
20314
20438
|
"catalog.loading",
|
|
20315
20439
|
"catalog.loaded",
|
|
20316
20440
|
"catalog.failed",
|
|
@@ -20435,23 +20559,23 @@ function renderLayout(options) {
|
|
|
20435
20559
|
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)}
|
|
20436
20560
|
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')}
|
|
20437
20561
|
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}
|
|
20438
|
-
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}
|
|
20562
|
+
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}
|
|
20439
20563
|
function detailFields(type,data){if(type==='task')return [
|
|
20440
20564
|
[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}],
|
|
20441
|
-
[text('table.agent'),data.agent],[text('table.model'),detailModel(data.model)],[text('details.prompt'),data.prompt,{wide:true,long:true}],
|
|
20565
|
+
[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}],
|
|
20442
20566
|
[text('details.category'),data.category],[text('details.batch'),data.batchId],[text('details.dependency'),data.dependsOn?'#'+data.dependsOn:text('details.none')],
|
|
20443
20567
|
[text('details.importance'),data.importance],[text('details.urgency'),data.urgency],[text('details.retryCount'),String(data.retryCount??0)+' / '+String(data.maxRetries??0)],
|
|
20444
20568
|
[text('details.retryBackoff'),detailDuration(data.retryBackoffMs)],[text('details.timeout'),detailDuration(data.timeoutMs)],[text('details.scheduledAt'),detailDate(data.scheduledAt)],
|
|
20445
20569
|
[text('details.createdAt'),detailDate(data.createdAt)],[text('details.startedAt'),detailDate(data.startedAt)],[text('details.finishedAt'),detailDate(data.finishedAt)],
|
|
20446
20570
|
[text('details.result'),detailTaskResult(data),{wide:true,long:true}]
|
|
20447
20571
|
];if(type==='run'){const started=data.startedAt?new Date(data.startedAt).getTime():null;const finished=data.finishedAt?new Date(data.finishedAt).getTime():null;return [
|
|
20448
|
-
[text('details.id'),'Run #'+data.id],[text('details.taskId'),'#'+data.taskId],[text('table.status'),detailStatus('run',data.status)],[text('table.model'),detailModel(data.model)],
|
|
20572
|
+
[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')],
|
|
20449
20573
|
[text('details.session'),detailSession(data.sessionId)],[text('details.startedAt'),detailDate(data.startedAt)],[text('details.finishedAt'),detailDate(data.finishedAt)],
|
|
20450
20574
|
[text('table.duration'),started!==null?detailDuration((finished??Date.now())-started):text('details.none')],[text('details.heartbeat'),detailDate(data.heartbeatAt)],
|
|
20451
20575
|
[text('details.process'),'Worker PID '+String(data.workerPid??'\u2014')+' \xB7 OpenCode PID '+String(data.childPid??'\u2014'),{wide:true,mono:true}]
|
|
20452
20576
|
];}const scheduleRule=data.scheduleType==='cron'?data.cronExpr:data.scheduleType==='recurring'?detailDuration(data.intervalMs):detailDate(data.runAt);return [
|
|
20453
20577
|
[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}],
|
|
20454
|
-
[text('table.agent'),data.agent],[text('table.model'),detailModel(data.model)],[text('details.prompt'),data.prompt,{wide:true,long:true}],
|
|
20578
|
+
[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}],
|
|
20455
20579
|
[text('template.scheduleType'),detailScheduleType(data.scheduleType)],[text('details.scheduleRule'),scheduleRule],[text('details.category'),data.category],[text('details.batch'),data.batchId],
|
|
20456
20580
|
[text('details.importance'),data.importance],[text('details.urgency'),data.urgency],[text('details.maxInstances'),data.maxInstances],[text('details.maxRetries'),data.maxRetries??0],
|
|
20457
20581
|
[text('details.retryBackoff'),detailDuration(data.retryBackoffMs)],[text('details.timeout'),detailDuration(data.timeoutMs)],[text('details.lastRun'),detailDate(data.lastRunAt)],[text('details.nextRun'),detailDate(data.nextRunAt)],
|
|
@@ -20468,12 +20592,20 @@ function renderLayout(options) {
|
|
|
20468
20592
|
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')}
|
|
20469
20593
|
const catalogTimers={};const catalogRequests={};const catalogModels={};
|
|
20470
20594
|
function catalogField(prefix,name){return document.getElementById(prefix+'-'+name)}
|
|
20471
|
-
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='';}
|
|
20595
|
+
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='';}
|
|
20472
20596
|
function appendCurrentOption(select,value){if(!value||[...select.options].some(option=>option.value===value))return;select.appendChild(new Option(value,value));}
|
|
20597
|
+
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}
|
|
20598
|
+
function invalidateVariantRequest(prefix){const key=prefix+'-variant';catalogRequests[key]=(catalogRequests[key]||0)+1}
|
|
20599
|
+
function invalidateCatalogRequests(prefix){clearTimeout(catalogTimers[prefix]);catalogRequests[prefix]=(catalogRequests[prefix]||0)+1;invalidateVariantRequest(prefix)}
|
|
20600
|
+
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}
|
|
20601
|
+
function handleProviderChange(prefix){clearVariantPreference(prefix);populateModelOptions(prefix)}
|
|
20602
|
+
function handleModelChange(prefix){clearVariantPreference(prefix);populateVariantOptions(prefix)}
|
|
20603
|
+
function handleVariantChange(prefix){const variant=catalogField(prefix,'variant');if(!variant)return;invalidateVariantRequest(prefix);variant.dataset.preferred='';variant.dataset.preferredModel=''}
|
|
20473
20604
|
function modelProvider(value){const slash=value.indexOf('/');return slash>0?value.slice(0,slash):''}
|
|
20474
|
-
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}
|
|
20605
|
+
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)}
|
|
20606
|
+
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}}
|
|
20475
20607
|
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}}}
|
|
20476
|
-
function scheduleCatalogLoad(prefix){
|
|
20608
|
+
function scheduleCatalogLoad(prefix){invalidateCatalogRequests(prefix);resetCatalog(prefix);catalogTimers[prefix]=setTimeout(()=>loadCatalog(prefix),450)}
|
|
20477
20609
|
let directoryTargetId='';let directoryCurrent='';let directoryEntries=[];let directoryShowHidden=false;
|
|
20478
20610
|
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)}}
|
|
20479
20611
|
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}}
|
|
@@ -20483,16 +20615,16 @@ function renderLayout(options) {
|
|
|
20483
20615
|
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'}
|
|
20484
20616
|
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}
|
|
20485
20617
|
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)}
|
|
20486
|
-
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)}
|
|
20487
|
-
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')}}
|
|
20488
|
-
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}}
|
|
20618
|
+
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)}
|
|
20619
|
+
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')}}
|
|
20620
|
+
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}}
|
|
20489
20621
|
function localDateTime(milliseconds){const date=new Date(milliseconds);const local=new Date(milliseconds-date.getTimezoneOffset()*60000);return local.toISOString().slice(0,23)}
|
|
20490
20622
|
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')}}
|
|
20491
20623
|
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}
|
|
20492
20624
|
function selectedRunAt(){const input=templateField('run-at');return resolveEditedRunAt(input.dataset.originalEpoch?Number(input.dataset.originalEpoch):null,input.dataset.originalLocal||'',input.value)}
|
|
20493
|
-
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)}
|
|
20494
|
-
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')}}
|
|
20495
|
-
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}}
|
|
20625
|
+
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)}
|
|
20626
|
+
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')}}
|
|
20627
|
+
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}}
|
|
20496
20628
|
async function enableTmpl(id){try{await readJson(await fetch('/api/templates/'+id+'/enable',{method:'POST'}));location.reload()}catch(error){showToast(error.message,'error')}}
|
|
20497
20629
|
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')}}
|
|
20498
20630
|
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')}}
|
|
@@ -20621,6 +20753,7 @@ function parseTaskPayload(value) {
|
|
|
20621
20753
|
cwd: requiredString("cwd"),
|
|
20622
20754
|
agent: requiredString("agent"),
|
|
20623
20755
|
model: optionalString("model", "default"),
|
|
20756
|
+
variant: Object.hasOwn(input, "variant") ? optionalString("variant") : void 0,
|
|
20624
20757
|
prompt: requiredString("prompt"),
|
|
20625
20758
|
category: optionalString("category", "general"),
|
|
20626
20759
|
batchId: optionalString("batchId"),
|
|
@@ -20636,6 +20769,7 @@ function editableTaskPayload(input) {
|
|
|
20636
20769
|
name: input.name,
|
|
20637
20770
|
agent: input.agent,
|
|
20638
20771
|
model: input.model ?? "default",
|
|
20772
|
+
...input.variant === void 0 ? {} : { variant: input.variant },
|
|
20639
20773
|
prompt: input.prompt,
|
|
20640
20774
|
category: input.category ?? "general",
|
|
20641
20775
|
batchId: input.batchId ?? null,
|
|
@@ -20691,6 +20825,7 @@ function parseTemplatePayload(value) {
|
|
|
20691
20825
|
name: requiredString("name"),
|
|
20692
20826
|
agent: requiredString("agent"),
|
|
20693
20827
|
model: optionalString("model", "default"),
|
|
20828
|
+
variant: Object.hasOwn(input, "variant") ? optionalString("variant") : void 0,
|
|
20694
20829
|
prompt: requiredString("prompt"),
|
|
20695
20830
|
cwd: requiredString("cwd"),
|
|
20696
20831
|
category: optionalString("category", "general"),
|
|
@@ -20992,7 +21127,7 @@ app.get("/", async (c) => {
|
|
|
20992
21127
|
const latestRun = latestRuns.get(task.id);
|
|
20993
21128
|
const executionActive = latestRun?.status === "running";
|
|
20994
21129
|
const batchId = task.batchId?.trim() || null;
|
|
20995
|
-
const searchable = esc(`${task.name} ${task.agent} ${task.prompt} ${task.cwd ?? ""} ${task.batchId ?? ""} ${task.category ?? ""}`);
|
|
21130
|
+
const searchable = esc(`${task.name} ${task.agent} ${task.model ?? ""} ${task.variant ?? ""} ${task.prompt} ${task.cwd ?? ""} ${task.batchId ?? ""} ${task.category ?? ""}`);
|
|
20996
21131
|
return `<tr data-task-row data-search="${searchable}">
|
|
20997
21132
|
<td class="faint" data-label="${t(locale, "table.id")}">#${task.id}</td>
|
|
20998
21133
|
<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>
|
|
@@ -21070,11 +21205,12 @@ app.get("/", async (c) => {
|
|
|
21070
21205
|
<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>
|
|
21071
21206
|
<datalist id="task-cwd-options">${projects.map((project) => `<option value="${esc(project.cwd)}"></option>`).join("")}</datalist>
|
|
21072
21207
|
<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>
|
|
21073
|
-
<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="
|
|
21208
|
+
<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>
|
|
21209
|
+
<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>
|
|
21074
21210
|
<label class="form-field form-field-wide"><span>${t(locale, "template.prompt")}</span><textarea id="task-prompt" rows="6" required></textarea></label>
|
|
21075
21211
|
</div>
|
|
21076
21212
|
<p id="task-project-status" class="form-note"></p>
|
|
21077
|
-
<p id="task-catalog-status" class="form-note catalog-status"></p>
|
|
21213
|
+
<p id="task-catalog-status" class="form-note catalog-status" role="status" aria-live="polite"></p>
|
|
21078
21214
|
<details class="advanced-fields">
|
|
21079
21215
|
<summary>${t(locale, "template.advanced")}</summary>
|
|
21080
21216
|
<div class="template-form-grid">
|
|
@@ -21116,7 +21252,7 @@ app.get("/templates", async (c) => {
|
|
|
21116
21252
|
return `<tr>
|
|
21117
21253
|
<td class="faint" data-label="${t(locale, "table.id")}">#${template.id}</td>
|
|
21118
21254
|
<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>
|
|
21119
|
-
<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>
|
|
21255
|
+
<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>
|
|
21120
21256
|
<td data-label="${t(locale, "table.type")}"><span class="tag t-${scheduleType}">${typeLabel}</span></td>
|
|
21121
21257
|
<td data-label="${t(locale, "table.rule")}" class="m small">${esc(rule)}</td>
|
|
21122
21258
|
<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>
|
|
@@ -21146,14 +21282,15 @@ app.get("/templates", async (c) => {
|
|
|
21146
21282
|
<label class="form-field"><span>${t(locale, "template.name")}</span><input id="template-name" required maxlength="200" autocomplete="off"></label>
|
|
21147
21283
|
<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>
|
|
21148
21284
|
<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>
|
|
21149
|
-
<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="
|
|
21285
|
+
<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>
|
|
21286
|
+
<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>
|
|
21150
21287
|
<label class="form-field form-field-wide"><span>${t(locale, "template.prompt")}</span><textarea id="template-prompt" rows="6" required></textarea></label>
|
|
21151
21288
|
<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>
|
|
21152
21289
|
<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>
|
|
21153
21290
|
<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>
|
|
21154
21291
|
<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>
|
|
21155
21292
|
</div>
|
|
21156
|
-
<p id="template-catalog-status" class="form-note catalog-status"></p>
|
|
21293
|
+
<p id="template-catalog-status" class="form-note catalog-status" role="status" aria-live="polite"></p>
|
|
21157
21294
|
<details class="advanced-fields">
|
|
21158
21295
|
<summary>${t(locale, "template.advanced")}</summary>
|
|
21159
21296
|
<div class="template-form-grid">
|
|
@@ -21187,6 +21324,7 @@ app.get("/runs", async (c) => {
|
|
|
21187
21324
|
taskId: taskRuns4.taskId,
|
|
21188
21325
|
sessionId: taskRuns4.sessionId,
|
|
21189
21326
|
model: taskRuns4.model,
|
|
21327
|
+
variant: taskRuns4.variant,
|
|
21190
21328
|
status: taskRuns4.status,
|
|
21191
21329
|
startedAt: taskRuns4.startedAt,
|
|
21192
21330
|
finishedAt: taskRuns4.finishedAt,
|
|
@@ -21207,7 +21345,7 @@ app.get("/runs", async (c) => {
|
|
|
21207
21345
|
const log = run.log ? renderRunLog(run.id, run.taskName, run.log, locale, run.status !== "done") : "";
|
|
21208
21346
|
return `<tr class="run-summary-row">
|
|
21209
21347
|
<td class="faint" data-label="${t(locale, "table.run")}">#${run.id}</td>
|
|
21210
|
-
<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"
|
|
21348
|
+
<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>
|
|
21211
21349
|
<td data-label="${t(locale, "table.agent")}"><span class="tag">${esc(run.taskAgent)}</span></td>
|
|
21212
21350
|
<td data-label="${t(locale, "table.session")}" class="m small">${esc(maskSessionId(run.sessionId))}</td>
|
|
21213
21351
|
<td data-label="${t(locale, "table.status")}"><span class="badge b-${status}">${runStatusText(locale, run.status ?? "unknown")}</span></td>
|
|
@@ -21257,7 +21395,7 @@ app.get("/system", async (c) => {
|
|
|
21257
21395
|
const runRows = runningRuns.map((run) => {
|
|
21258
21396
|
const session = maskSessionId(run.sessionId);
|
|
21259
21397
|
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>
|
|
21260
|
-
<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>
|
|
21398
|
+
<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>
|
|
21261
21399
|
<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>
|
|
21262
21400
|
<td data-label="${t(locale, "table.duration")}" class="small">${formatDuration(run.startedAt, null)}</td></tr>`;
|
|
21263
21401
|
}).join("");
|