This commit is contained in:
+19
-9
@@ -7,9 +7,16 @@ import { logger } from './logger.js';
|
||||
import { loadConfig } from './config.js';
|
||||
import { resolveAndRunUserScript } from './user-folder/script-orchestrator.js';
|
||||
|
||||
// 進行中とみなすステータス(これらの場合はスキップ)
|
||||
// 進行中とみなすステータス(これらの場合は次回スケジュール実行をスキップ)。
|
||||
// これらはいずれも「真に実行中」か「自動回復する一時状態」のみ:
|
||||
// queued/dispatching/running … 実行中
|
||||
// waiting_subtasks … 並列サブタスク完了待ち。requeueWaitingSubtasks が自動回復させる
|
||||
// waiting_human (ASK) は意図的に含めない。自動回復もタイムアウトも無いため、
|
||||
// 無人実行のスケジュールタスクが一度 ASK を出すとその後の実行が永久にスキップされ、
|
||||
// スケジュールが事実上死ぬ。各スケジュール実行は独立した新規タスクなので、
|
||||
// 前回の waiting_human タスクは残置し(ユーザーが後から回答 or 放置できる)、新規実行を走らせる。
|
||||
const IN_PROGRESS_STATUSES = new Set([
|
||||
'queued', 'dispatching', 'running', 'waiting_human', 'waiting_subtasks',
|
||||
'queued', 'dispatching', 'running', 'waiting_subtasks',
|
||||
]);
|
||||
|
||||
export interface ScheduleInput {
|
||||
@@ -295,9 +302,12 @@ export class Scheduler {
|
||||
if (!this.userFolderRoot) {
|
||||
throw new Error(`scheduled_task=${item.id}: task_kind='script' but Scheduler.userFolderRoot was not configured`);
|
||||
}
|
||||
if (!item.ownerId) {
|
||||
throw new Error(`scheduled_task=${item.id}: task_kind='script' requires an owner_id (scripts are per-user)`);
|
||||
}
|
||||
// No-auth mode stores scheduled tasks with ownerId=null (scheduled-tasks-api
|
||||
// has no authenticated user). Scripts are per-user (data/users/{id}/scripts/),
|
||||
// so resolve to the same 'local' namespace the RunUserScript tool uses in
|
||||
// no-auth (ctx.userId='local'). In auth mode item.ownerId is always set, so
|
||||
// scriptOwner === item.ownerId and behaviour is unchanged.
|
||||
const scriptOwner = item.ownerId ?? 'local';
|
||||
|
||||
// Same security gates as the LLM-facing RunUserScript tool: global config
|
||||
// toggle + optional per-user allowlist. A scheduled run is automated, so a
|
||||
@@ -308,9 +318,9 @@ export class Scheduler {
|
||||
`scheduled_task=${item.id}: user scripts are disabled (tools.user_scripts_enabled=false)`,
|
||||
);
|
||||
}
|
||||
if (Array.isArray(gate.allowUserids) && gate.allowUserids.length > 0 && !gate.allowUserids.includes(item.ownerId)) {
|
||||
if (Array.isArray(gate.allowUserids) && gate.allowUserids.length > 0 && !gate.allowUserids.includes(scriptOwner)) {
|
||||
throw new Error(
|
||||
`scheduled_task=${item.id}: owner "${item.ownerId}" is not in tools.user_scripts_allow_userids`,
|
||||
`scheduled_task=${item.id}: owner "${scriptOwner}" is not in tools.user_scripts_allow_userids`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -375,7 +385,7 @@ export class Scheduler {
|
||||
try {
|
||||
const runResult = await resolveAndRunUserScript({
|
||||
rootDir: this.userFolderRoot,
|
||||
userId: item.ownerId,
|
||||
userId: scriptOwner,
|
||||
name: item.scriptName,
|
||||
params,
|
||||
sessRepo: this.sessRepo,
|
||||
@@ -417,7 +427,7 @@ export class Scheduler {
|
||||
|
||||
await this.repo.addAuditLog(job.id, 'user_script_run', 'scheduler', {
|
||||
scheduledTaskId: item.id,
|
||||
userId: item.ownerId,
|
||||
userId: scriptOwner,
|
||||
scriptName: item.scriptName,
|
||||
ok: !runFailed,
|
||||
...(runFailed && errorMessage ? { error: errorMessage.slice(0, 500) } : {}),
|
||||
|
||||
Reference in New Issue
Block a user