dsh-task-dispatch-table 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/calendar-plan.d.ts +1 -1
- package/dist/calendar-plan.js +1 -1
- package/dist/client.js +70 -14
- package/dist/client.js.map +1 -1
- package/dist/dispatch.d.ts +5 -0
- package/dist/dispatch.js +17 -6
- package/dist/index.js +0 -0
- package/dist/reconcile.js +9 -3
- package/package.json +1 -1
package/dist/dispatch.d.ts
CHANGED
|
@@ -78,6 +78,11 @@ export interface DispatchAttachment {
|
|
|
78
78
|
/** link 型的工作区相对路径原文(基准未知时如实展示)。 */
|
|
79
79
|
ref: string;
|
|
80
80
|
path: string | null;
|
|
81
|
+
/**
|
|
82
|
+
* 该项是否为一整个**目录**(用户 2026-10-09:文件夹本身也能当附件)。
|
|
83
|
+
* 派发前 stat 得出,**不落库、不进快照**——服务侧刻意不区分目录与文件;测不出即缺位,按文件处理。
|
|
84
|
+
*/
|
|
85
|
+
isDir?: boolean;
|
|
81
86
|
}
|
|
82
87
|
/**
|
|
83
88
|
* 随附文件 → 官方 `file` 内容块(2026-10-03 拍板「附加文件走 A」)。
|
package/dist/dispatch.js
CHANGED
|
@@ -301,16 +301,27 @@ times) {
|
|
|
301
301
|
lines.push(receiptInstruction(snapshot.validStatuses));
|
|
302
302
|
return userNotice(lines.join('\n'), `[TASK] ${snapshot.title} · ${logicalDate}`, fileBlocks);
|
|
303
303
|
}
|
|
304
|
-
/**
|
|
304
|
+
/**
|
|
305
|
+
* 随附文件段(用户 2026-09-30:必须让模型明确知道文件在哪一层、在什么地方)。
|
|
306
|
+
*
|
|
307
|
+
* 段头那句「任务提示词里说的『附件 / 随附文件』就是指下面这些」是**用户称呼 → 绝对路径**的接缝
|
|
308
|
+
* (用户 2026-10-09:要在提示词里写「用附件里的 XX 执行」还能被找到)⇒ 没有它,模型只能靠文件名猜。
|
|
309
|
+
*/
|
|
305
310
|
function attachmentLines(list) {
|
|
306
311
|
if (list.length === 0)
|
|
307
312
|
return [];
|
|
308
|
-
const lines = ['', '
|
|
313
|
+
const lines = ['', '本次随附文件(只读输入,请勿修改;以下均为可直接读取的绝对路径。任务提示词里说的「附件 / 随附文件」就是指下面这些):'];
|
|
309
314
|
for (const item of list) {
|
|
310
|
-
const tag = item.kind === 'upload' ? '上传' : '工作区';
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
315
|
+
const tag = item.isDir === true ? '目录' : (item.kind === 'upload' ? '上传' : '工作区');
|
|
316
|
+
if (item.path === null) {
|
|
317
|
+
lines.push(` - ${item.name}(${tag}):${item.ref}(基准工作区未知,为工作区相对路径)`);
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
320
|
+
// 目录路径尾补 '/':与普通文件在字面上一眼分开,模型不会拿它当单文件去读。
|
|
321
|
+
lines.push(` - ${item.name}(${tag}):${item.path}${item.isDir === true ? '/' : ''}`);
|
|
322
|
+
}
|
|
323
|
+
if (list.some(item => item.isDir === true)) {
|
|
324
|
+
lines.push('标注「目录」的是一整个文件夹:需要里面某个文件时,按 <该项路径>/<相对路径> 拼出完整路径后再读取。');
|
|
314
325
|
}
|
|
315
326
|
return lines;
|
|
316
327
|
}
|
package/dist/index.js
CHANGED
|
Binary file
|
package/dist/reconcile.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
// 不读文件;跑完信号后无回执 → 宽限 → 追问×2 → 按失败收敛。
|
|
7
7
|
// 唯一例外(决策 41 兼容口):旧库实例无快照列值时,按 legacyTask 当场合成快照并固化(一次性
|
|
8
8
|
// 兼容、带 warn)——兜底也不落库 ⇒ 无法发动 / 无法校验,如实按失败收敛,绝不静默。
|
|
9
|
+
import { stat } from 'node:fs/promises';
|
|
9
10
|
import { existsSync } from 'node:fs';
|
|
10
11
|
import { resolve } from 'node:path';
|
|
11
12
|
import { displayNameOf, durationMs, sessionTitleOf } from './tasks.js';
|
|
@@ -382,7 +383,11 @@ export function createReconciler({ ctx, logger, store, options, runtime, emit })
|
|
|
382
383
|
// 随附文件段(2026-09-30):把快照里的附件 ref 解析成**绝对路径**随派发消息注入
|
|
383
384
|
// (用户要求:必须让模型明确知道文件在哪一层、在什么地方)。与上面存在性校验同款口径——
|
|
384
385
|
// link 按附件来源工作区、upload 按任务目录;解析不出 ⇒ path=null(如实标注,绝不猜)。
|
|
385
|
-
|
|
386
|
+
// 同上口径 + **是否目录**(用户 2026-10-09:文件夹本身也能当附件)。
|
|
387
|
+
// ref 指的是目录还是文件,只有这一刻 stat 才知道——服务侧刻意不区分两者,schema / 快照零改动。
|
|
388
|
+
// stat 失败 ⇒ 按文件处理:缺失项已被上面的 missingSnapshotAttachments 拦掉,这里不该失败,
|
|
389
|
+
// 标错也只退化成旧文案,绝不阻断派发。
|
|
390
|
+
const attachments = await Promise.all((snap.attachments ?? []).map(async (item) => {
|
|
386
391
|
let path = null;
|
|
387
392
|
if (item.kind === 'upload') {
|
|
388
393
|
path = assets === null ? null : attachmentAbsPath(assets, instance.task_id, item.ref);
|
|
@@ -398,8 +403,9 @@ export function createReconciler({ ctx, logger, store, options, runtime, emit })
|
|
|
398
403
|
}
|
|
399
404
|
if (path !== null && path.includes('..'))
|
|
400
405
|
path = null;
|
|
401
|
-
|
|
402
|
-
|
|
406
|
+
const isDir = path === null ? undefined : await stat(path).then(info => info.isDirectory()).catch(() => undefined);
|
|
407
|
+
return { name: item.name, kind: item.kind, ref: item.ref, path, isDir };
|
|
408
|
+
}));
|
|
403
409
|
const { sessionId, handle } = await dispatchTask({
|
|
404
410
|
ctx, logger, store,
|
|
405
411
|
instanceId: instance.id,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-task-dispatch-table",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Scheduled task dispatcher: a dsh host plugin that drives recurring agent tasks from a single task table, dispatching each run as an independent dsh session (scheduling itself uses zero model calls)",
|
|
5
5
|
"icon": "./assets/icon-scheduler.svg",
|
|
6
6
|
"keywords": [
|