mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-26 18:31:34 +01:00
feat(watchdogs): add experimental self-mode watchdogs
- Add enableWatchdogEverything experimental instance setting and UI toggle. - Add issue_watchdogs.mode and accept mode in the watchdog endpoint. - Wake task assignees directly for stopped self-mode watchdogs. - Add first-instruction guidance for assignment-shaped wakes. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
9574cad3e8
commit
7b4722e26c
21 files changed
+554
-4
No files matched your search
@@ -104,6 +104,14 @@ export const INSTANCE_FEATURE_CATALOG: Record<InstanceFeatureKey, FeatureCatalog
|
||||
cloudDefault: false,
|
||||
selfHostedDefault: false,
|
||||
},
|
||||
enableWatchdogEverything: {
|
||||
title: "Watchdog Everything",
|
||||
description:
|
||||
"On new task assignments, instruct the assignee to triage whether the task needs a completion goal and, if so, register it as a self-mode watchdog on the task itself; the watchdog then wakes the same agent directly on the task to verify the goal — no separate watchdog sub-task.",
|
||||
tier: "managed",
|
||||
cloudDefault: false,
|
||||
selfHostedDefault: false,
|
||||
},
|
||||
enableIssuePlanDecompositions: {
|
||||
title: "Task Plan Decomposition Panel",
|
||||
description: "Show accepted-plan decomposition history on task detail pages.",
|
||||
|
||||
@@ -655,6 +655,7 @@ export type {
|
||||
IssueAttachment,
|
||||
IssueLabel,
|
||||
IssueWatchdog,
|
||||
IssueWatchdogMode,
|
||||
IssueWatchdogStatus,
|
||||
IssueWatchdogSummary,
|
||||
} from "./issue.js";
|
||||
|
||||
@@ -53,6 +53,7 @@ export interface InstanceExperimentalSettings {
|
||||
enableCases: boolean;
|
||||
enableConferenceRoomChat: boolean;
|
||||
enableTaskWatchdogs: boolean;
|
||||
enableWatchdogEverything: boolean;
|
||||
enableIssuePlanDecompositions: boolean;
|
||||
enableExperimentalFileViewer: boolean;
|
||||
enableCloudSync: boolean;
|
||||
|
||||
@@ -683,6 +683,14 @@ export interface IssueExecutionDecision {
|
||||
|
||||
export type IssueWatchdogStatus = "active" | "disabled";
|
||||
|
||||
// "subtask": stopped subtrees are reviewed through a separate reusable
|
||||
// watchdog issue assigned to the watchdog agent (default, original behavior).
|
||||
// "self": the watchdog agent is woken directly on the watched issue itself and
|
||||
// reviews/verifies in place — no watchdog sub-task is created (used by the
|
||||
// experimental "watchdog everything" flow where agents self-watchdog their
|
||||
// own tasks).
|
||||
export type IssueWatchdogMode = "subtask" | "self";
|
||||
|
||||
export interface IssueWatchdogSummary {
|
||||
id: string;
|
||||
companyId: string;
|
||||
@@ -690,6 +698,7 @@ export interface IssueWatchdogSummary {
|
||||
watchdogAgentId: string;
|
||||
instructions: string | null;
|
||||
status: IssueWatchdogStatus;
|
||||
mode?: IssueWatchdogMode;
|
||||
watchdogIssueId: string | null;
|
||||
lastObservedFingerprint: string | null;
|
||||
lastReviewedFingerprint: string | null;
|
||||
|
||||
@@ -130,6 +130,19 @@ describe("instance experimental settings validators", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("defaults watchdog everything off and accepts patches", () => {
|
||||
const settings = instanceExperimentalSettingsSchema.parse({});
|
||||
expect(settings.enableWatchdogEverything).toBe(false);
|
||||
|
||||
expect(
|
||||
patchInstanceExperimentalSettingsSchema.parse({
|
||||
enableWatchdogEverything: true,
|
||||
}),
|
||||
).toEqual({
|
||||
enableWatchdogEverything: true,
|
||||
});
|
||||
});
|
||||
|
||||
it("accepts apps patches", () => {
|
||||
expect(
|
||||
patchInstanceExperimentalSettingsSchema.parse({
|
||||
|
||||
@@ -47,6 +47,7 @@ export const instanceExperimentalSettingsSchema = z.object({
|
||||
enableCases: z.boolean().default(false),
|
||||
enableConferenceRoomChat: z.boolean().default(false),
|
||||
enableTaskWatchdogs: z.boolean().default(false),
|
||||
enableWatchdogEverything: z.boolean().default(false),
|
||||
enableIssuePlanDecompositions: z.boolean().default(false),
|
||||
enableExperimentalFileViewer: z.boolean().default(false),
|
||||
enableCloudSync: z.boolean().default(false),
|
||||
|
||||
@@ -497,6 +497,10 @@ export type CreateIssue = z.infer<typeof createIssueSchema>;
|
||||
export const upsertIssueWatchdogSchema = z.object({
|
||||
agentId: z.string().uuid(),
|
||||
instructions: multilineTextSchema.optional().nullable(),
|
||||
// "subtask" (default) reviews stopped subtrees through a separate watchdog
|
||||
// issue; "self" wakes the watchdog agent directly on the watched issue
|
||||
// (experimental "watchdog everything"). Omitted on update keeps the current mode.
|
||||
mode: z.enum(["subtask", "self"]).optional(),
|
||||
}).strict();
|
||||
|
||||
export type UpsertIssueWatchdog = z.infer<typeof upsertIssueWatchdogSchema>;
|
||||
|
||||
Reference in new issue
Block a user