mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-19 13:11:40 +00:00
fix(tasks): restore session key registry compatibility
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { resolveAgentModelPrimaryValue } from "openclaw/plugin-sdk/provider-onboard";
|
||||
import { SYNTHETIC_DEFAULT_MODEL_ID } from "openclaw/plugin-sdk/synthetic";
|
||||
import { SYNTHETIC_DEFAULT_MODEL_REF as SYNTHETIC_DEFAULT_MODEL_REF_PUBLIC } from "openclaw/plugin-sdk/synthetic";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { createLegacyProviderConfig } from "../../test/helpers/plugins/onboard-config.js";
|
||||
import {
|
||||
@@ -16,7 +16,7 @@ describe("synthetic onboard", () => {
|
||||
api: "anthropic-messages",
|
||||
});
|
||||
expect(resolveAgentModelPrimaryValue(cfg.agents?.defaults?.model)).toBe(
|
||||
SYNTHETIC_DEFAULT_MODEL_REF,
|
||||
SYNTHETIC_DEFAULT_MODEL_REF_PUBLIC,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -32,6 +32,6 @@ describe("synthetic onboard", () => {
|
||||
expect(cfg.models?.providers?.synthetic?.apiKey).toBe("old-key");
|
||||
const ids = cfg.models?.providers?.synthetic?.models.map((m) => m.id);
|
||||
expect(ids).toContain("old-model");
|
||||
expect(ids).toContain(SYNTHETIC_DEFAULT_MODEL_ID);
|
||||
expect(ids).toContain(SYNTHETIC_DEFAULT_MODEL_REF.replace(/^synthetic\//, ""));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,8 +14,9 @@ function createTask(partial: Partial<TaskRecord>): TaskRecord {
|
||||
return {
|
||||
taskId: partial.taskId ?? "task-1",
|
||||
runtime: partial.runtime ?? "acp",
|
||||
ownerKey: partial.ownerKey ?? "agent:main:main",
|
||||
scopeKind: "session",
|
||||
requesterSessionKey: partial.requesterSessionKey ?? partial.ownerKey ?? "agent:main:main",
|
||||
ownerKey: partial.ownerKey ?? partial.requesterSessionKey ?? "agent:main:main",
|
||||
scopeKind: partial.scopeKind ?? "session",
|
||||
task: partial.task ?? "Investigate issue",
|
||||
status: partial.status ?? "running",
|
||||
deliveryStatus: partial.deliveryStatus ?? "pending",
|
||||
|
||||
@@ -14,6 +14,7 @@ import type {
|
||||
TaskNotifyPolicy,
|
||||
TaskRecord,
|
||||
TaskRuntime,
|
||||
TaskScopeKind,
|
||||
TaskStatus,
|
||||
TaskTerminalOutcome,
|
||||
} from "./task-registry.types.js";
|
||||
@@ -21,7 +22,9 @@ import type {
|
||||
export function createQueuedTaskRun(params: {
|
||||
runtime: TaskRuntime;
|
||||
sourceId?: string;
|
||||
requesterSessionKey: string;
|
||||
requesterSessionKey?: string;
|
||||
ownerKey?: string;
|
||||
scopeKind?: TaskScopeKind;
|
||||
requesterOrigin?: TaskDeliveryState["requesterOrigin"];
|
||||
childSessionKey?: string;
|
||||
parentTaskId?: string;
|
||||
@@ -42,7 +45,9 @@ export function createQueuedTaskRun(params: {
|
||||
export function createRunningTaskRun(params: {
|
||||
runtime: TaskRuntime;
|
||||
sourceId?: string;
|
||||
requesterSessionKey: string;
|
||||
requesterSessionKey?: string;
|
||||
ownerKey?: string;
|
||||
scopeKind?: TaskScopeKind;
|
||||
requesterOrigin?: TaskDeliveryState["requesterOrigin"];
|
||||
childSessionKey?: string;
|
||||
parentTaskId?: string;
|
||||
|
||||
@@ -6,8 +6,9 @@ function createTask(partial: Partial<TaskRecord>): TaskRecord {
|
||||
return {
|
||||
taskId: partial.taskId ?? "task-1",
|
||||
runtime: partial.runtime ?? "acp",
|
||||
ownerKey: partial.ownerKey ?? "agent:main:main",
|
||||
scopeKind: "session",
|
||||
requesterSessionKey: partial.requesterSessionKey ?? partial.ownerKey ?? "agent:main:main",
|
||||
ownerKey: partial.ownerKey ?? partial.requesterSessionKey ?? "agent:main:main",
|
||||
scopeKind: partial.scopeKind ?? "session",
|
||||
task: partial.task ?? "Background task",
|
||||
status: partial.status ?? "queued",
|
||||
deliveryStatus: partial.deliveryStatus ?? "pending",
|
||||
|
||||
@@ -95,6 +95,7 @@ function rowToTaskRecord(row: TaskRegistryRow): TaskRecord {
|
||||
taskId: row.task_id,
|
||||
runtime: row.runtime,
|
||||
...(row.source_id ? { sourceId: row.source_id } : {}),
|
||||
requesterSessionKey: row.scope_kind === "system" ? "" : row.owner_key,
|
||||
ownerKey: row.owner_key,
|
||||
scopeKind: row.scope_kind,
|
||||
...(row.child_session_key ? { childSessionKey: row.child_session_key } : {}),
|
||||
|
||||
@@ -19,6 +19,7 @@ function createStoredTask(): TaskRecord {
|
||||
taskId: "task-restored",
|
||||
runtime: "acp",
|
||||
sourceId: "run-restored",
|
||||
requesterSessionKey: "agent:main:main",
|
||||
ownerKey: "agent:main:main",
|
||||
scopeKind: "session",
|
||||
childSessionKey: "agent:codex:acp:restored",
|
||||
|
||||
@@ -1051,6 +1051,8 @@ describe("task-registry", () => {
|
||||
taskId: "task-missing-cleanup",
|
||||
runtime: "cron",
|
||||
requesterSessionKey: "",
|
||||
ownerKey: "system:cron:task-missing-cleanup",
|
||||
scopeKind: "system",
|
||||
runId: "run-maintenance-cleanup",
|
||||
task: "Finished cron",
|
||||
status: "failed",
|
||||
@@ -1098,6 +1100,8 @@ describe("task-registry", () => {
|
||||
taskId: "task-audit-summary",
|
||||
runtime: "acp",
|
||||
requesterSessionKey: "agent:main:main",
|
||||
ownerKey: "agent:main:main",
|
||||
scopeKind: "session",
|
||||
runId: "run-audit-summary",
|
||||
task: "Hung task",
|
||||
status: "running",
|
||||
|
||||
@@ -35,6 +35,7 @@ import type {
|
||||
TaskRegistrySummary,
|
||||
TaskRegistrySnapshot,
|
||||
TaskRuntime,
|
||||
TaskScopeKind,
|
||||
TaskStatus,
|
||||
TaskTerminalOutcome,
|
||||
} from "./task-registry.types.js";
|
||||
@@ -97,6 +98,14 @@ function persistTaskRegistry() {
|
||||
|
||||
function persistTaskUpsert(task: TaskRecord) {
|
||||
const store = getTaskRegistryStore();
|
||||
const deliveryState = taskDeliveryStates.get(task.taskId);
|
||||
if (store.upsertTaskWithDeliveryState) {
|
||||
store.upsertTaskWithDeliveryState({
|
||||
task,
|
||||
...(deliveryState ? { deliveryState } : {}),
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (store.upsertTask) {
|
||||
store.upsertTask(task);
|
||||
return;
|
||||
@@ -109,6 +118,10 @@ function persistTaskUpsert(task: TaskRecord) {
|
||||
|
||||
function persistTaskDelete(taskId: string) {
|
||||
const store = getTaskRegistryStore();
|
||||
if (store.deleteTaskWithDeliveryState) {
|
||||
store.deleteTaskWithDeliveryState(taskId);
|
||||
return;
|
||||
}
|
||||
if (store.deleteTask) {
|
||||
store.deleteTask(taskId);
|
||||
return;
|
||||
@@ -159,6 +172,35 @@ function ensureNotifyPolicy(params: {
|
||||
return deliveryStatus === "not_applicable" ? "silent" : "done_only";
|
||||
}
|
||||
|
||||
function resolveTaskScopeKind(params: {
|
||||
scopeKind?: TaskScopeKind;
|
||||
requesterSessionKey: string;
|
||||
}): TaskScopeKind {
|
||||
if (params.scopeKind) {
|
||||
return params.scopeKind;
|
||||
}
|
||||
return params.requesterSessionKey.trim() ? "session" : "system";
|
||||
}
|
||||
|
||||
function resolveTaskRequesterSessionKey(params: {
|
||||
requesterSessionKey?: string;
|
||||
ownerKey?: string;
|
||||
scopeKind?: TaskScopeKind;
|
||||
}): string {
|
||||
const requesterSessionKey = params.requesterSessionKey?.trim();
|
||||
if (requesterSessionKey) {
|
||||
return requesterSessionKey;
|
||||
}
|
||||
if (params.scopeKind === "system") {
|
||||
return "";
|
||||
}
|
||||
return params.ownerKey?.trim() ?? "";
|
||||
}
|
||||
|
||||
function resolveTaskOwnerKey(params: { requesterSessionKey: string; ownerKey?: string }): string {
|
||||
return params.ownerKey?.trim() || params.requesterSessionKey.trim();
|
||||
}
|
||||
|
||||
function normalizeTaskSummary(value: string | null | undefined): string | undefined {
|
||||
const normalized = value?.replace(/\s+/g, " ").trim();
|
||||
return normalized || undefined;
|
||||
@@ -989,7 +1031,9 @@ function ensureListener() {
|
||||
export function createTaskRecord(params: {
|
||||
runtime: TaskRuntime;
|
||||
sourceId?: string;
|
||||
requesterSessionKey: string;
|
||||
requesterSessionKey?: string;
|
||||
ownerKey?: string;
|
||||
scopeKind?: TaskScopeKind;
|
||||
requesterOrigin?: TaskDeliveryState["requesterOrigin"];
|
||||
childSessionKey?: string;
|
||||
parentTaskId?: string;
|
||||
@@ -1009,25 +1053,39 @@ export function createTaskRecord(params: {
|
||||
terminalOutcome?: TaskTerminalOutcome | null;
|
||||
}): TaskRecord {
|
||||
ensureTaskRegistryReady();
|
||||
const existing = findExistingTaskForCreate(params);
|
||||
const requesterSessionKey = resolveTaskRequesterSessionKey(params);
|
||||
const scopeKind = resolveTaskScopeKind({
|
||||
scopeKind: params.scopeKind,
|
||||
requesterSessionKey,
|
||||
});
|
||||
const ownerKey = resolveTaskOwnerKey({
|
||||
requesterSessionKey,
|
||||
ownerKey: params.ownerKey,
|
||||
});
|
||||
const existing = findExistingTaskForCreate({
|
||||
...params,
|
||||
requesterSessionKey,
|
||||
});
|
||||
if (existing) {
|
||||
return mergeExistingTaskForCreate(existing, params);
|
||||
}
|
||||
const now = Date.now();
|
||||
const taskId = crypto.randomUUID();
|
||||
const status = normalizeTaskStatus(params.status);
|
||||
const deliveryStatus = params.deliveryStatus ?? ensureDeliveryStatus(params.requesterSessionKey);
|
||||
const deliveryStatus = params.deliveryStatus ?? ensureDeliveryStatus(requesterSessionKey);
|
||||
const notifyPolicy = ensureNotifyPolicy({
|
||||
notifyPolicy: params.notifyPolicy,
|
||||
deliveryStatus,
|
||||
requesterSessionKey: params.requesterSessionKey,
|
||||
requesterSessionKey,
|
||||
});
|
||||
const lastEventAt = params.lastEventAt ?? params.startedAt ?? now;
|
||||
const record: TaskRecord = {
|
||||
taskId,
|
||||
runtime: params.runtime,
|
||||
sourceId: params.sourceId?.trim() || undefined,
|
||||
requesterSessionKey: params.requesterSessionKey,
|
||||
requesterSessionKey,
|
||||
ownerKey,
|
||||
scopeKind,
|
||||
childSessionKey: params.childSessionKey,
|
||||
parentTaskId: params.parentTaskId?.trim() || undefined,
|
||||
agentId: params.agentId?.trim() || undefined,
|
||||
@@ -1376,6 +1434,14 @@ export function findLatestTaskForSessionKey(sessionKey: string): TaskRecord | un
|
||||
return task ? cloneTaskRecord(task) : undefined;
|
||||
}
|
||||
|
||||
export function findLatestTaskForOwnerKey(ownerKey: string): TaskRecord | undefined {
|
||||
return findLatestTaskForSessionKey(ownerKey);
|
||||
}
|
||||
|
||||
export function findLatestTaskForRelatedSessionKey(sessionKey: string): TaskRecord | undefined {
|
||||
return findLatestTaskForSessionKey(sessionKey);
|
||||
}
|
||||
|
||||
export function listTasksForSessionKey(sessionKey: string): TaskRecord[] {
|
||||
ensureTaskRegistryReady();
|
||||
const key = normalizeSessionIndexKey(sessionKey);
|
||||
@@ -1402,6 +1468,14 @@ export function listTasksForSessionKey(sessionKey: string): TaskRecord[] {
|
||||
.map(({ insertionIndex: _, ...task }) => task);
|
||||
}
|
||||
|
||||
export function listTasksForOwnerKey(ownerKey: string): TaskRecord[] {
|
||||
return listTasksForSessionKey(ownerKey);
|
||||
}
|
||||
|
||||
export function listTasksForRelatedSessionKey(sessionKey: string): TaskRecord[] {
|
||||
return listTasksForSessionKey(sessionKey);
|
||||
}
|
||||
|
||||
export function resolveTaskForLookupToken(token: string): TaskRecord | undefined {
|
||||
const lookup = token.trim();
|
||||
if (!lookup) {
|
||||
|
||||
@@ -54,6 +54,7 @@ export type TaskRecord = {
|
||||
taskId: string;
|
||||
runtime: TaskRuntime;
|
||||
sourceId?: string;
|
||||
requesterSessionKey: string;
|
||||
ownerKey: string;
|
||||
scopeKind: TaskScopeKind;
|
||||
childSessionKey?: string;
|
||||
|
||||
Reference in New Issue
Block a user