@agent-native/dispatch 0.7.0 → 0.8.1
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/README.md +56 -3
- package/dist/actions/apply-dream-proposal.d.ts +3 -0
- package/dist/actions/apply-dream-proposal.d.ts.map +1 -0
- package/dist/actions/apply-dream-proposal.js +11 -0
- package/dist/actions/apply-dream-proposal.js.map +1 -0
- package/dist/actions/create-dream-report.d.ts +3 -0
- package/dist/actions/create-dream-report.d.ts.map +1 -0
- package/dist/actions/create-dream-report.js +67 -0
- package/dist/actions/create-dream-report.js.map +1 -0
- package/dist/actions/create-workspace-resource.js +3 -3
- package/dist/actions/create-workspace-resource.js.map +1 -1
- package/dist/actions/delete-workspace-resource.js +1 -1
- package/dist/actions/delete-workspace-resource.js.map +1 -1
- package/dist/actions/ensure-dream-job.d.ts +3 -0
- package/dist/actions/ensure-dream-job.d.ts.map +1 -0
- package/dist/actions/ensure-dream-job.js +73 -0
- package/dist/actions/ensure-dream-job.js.map +1 -0
- package/dist/actions/get-dream-settings.d.ts +3 -0
- package/dist/actions/get-dream-settings.d.ts.map +1 -0
- package/dist/actions/get-dream-settings.js +11 -0
- package/dist/actions/get-dream-settings.js.map +1 -0
- package/dist/actions/get-dream.d.ts +3 -0
- package/dist/actions/get-dream.d.ts.map +1 -0
- package/dist/actions/get-dream.js +13 -0
- package/dist/actions/get-dream.js.map +1 -0
- package/dist/actions/get-workspace-resource-effective-context.d.ts +3 -0
- package/dist/actions/get-workspace-resource-effective-context.d.ts.map +1 -0
- package/dist/actions/get-workspace-resource-effective-context.js +27 -0
- package/dist/actions/get-workspace-resource-effective-context.js.map +1 -0
- package/dist/actions/index.d.ts.map +1 -1
- package/dist/actions/index.js +30 -4
- package/dist/actions/index.js.map +1 -1
- package/dist/actions/list-dream-candidates.d.ts +3 -0
- package/dist/actions/list-dream-candidates.d.ts.map +1 -0
- package/dist/actions/list-dream-candidates.js +68 -0
- package/dist/actions/list-dream-candidates.js.map +1 -0
- package/dist/actions/list-dreams.d.ts +3 -0
- package/dist/actions/list-dreams.d.ts.map +1 -0
- package/dist/actions/list-dreams.js +17 -0
- package/dist/actions/list-dreams.js.map +1 -0
- package/dist/actions/list-workspace-resources-for-app.d.ts +3 -0
- package/dist/actions/list-workspace-resources-for-app.d.ts.map +1 -0
- package/dist/actions/list-workspace-resources-for-app.js +12 -0
- package/dist/actions/list-workspace-resources-for-app.js.map +1 -0
- package/dist/actions/list-workspace-resources.js +1 -1
- package/dist/actions/list-workspace-resources.js.map +1 -1
- package/dist/actions/navigate.d.ts +1 -0
- package/dist/actions/navigate.d.ts.map +1 -1
- package/dist/actions/navigate.js +2 -1
- package/dist/actions/navigate.js.map +1 -1
- package/dist/actions/preview-dream-proposal.d.ts +3 -0
- package/dist/actions/preview-dream-proposal.d.ts.map +1 -0
- package/dist/actions/preview-dream-proposal.js +13 -0
- package/dist/actions/preview-dream-proposal.js.map +1 -0
- package/dist/actions/preview-workspace-resource-change.d.ts +3 -0
- package/dist/actions/preview-workspace-resource-change.d.ts.map +1 -0
- package/dist/actions/preview-workspace-resource-change.js +24 -0
- package/dist/actions/preview-workspace-resource-change.js.map +1 -0
- package/dist/actions/reject-dream-proposal.d.ts +3 -0
- package/dist/actions/reject-dream-proposal.d.ts.map +1 -0
- package/dist/actions/reject-dream-proposal.js +12 -0
- package/dist/actions/reject-dream-proposal.js.map +1 -0
- package/dist/actions/restore-starter-workspace-resources.d.ts +3 -0
- package/dist/actions/restore-starter-workspace-resources.d.ts.map +1 -0
- package/dist/actions/restore-starter-workspace-resources.js +14 -0
- package/dist/actions/restore-starter-workspace-resources.js.map +1 -0
- package/dist/actions/send-code-agent-remote-command.d.ts +3 -0
- package/dist/actions/send-code-agent-remote-command.d.ts.map +1 -0
- package/dist/actions/send-code-agent-remote-command.js +53 -0
- package/dist/actions/send-code-agent-remote-command.js.map +1 -0
- package/dist/actions/set-dream-settings.d.ts +3 -0
- package/dist/actions/set-dream-settings.d.ts.map +1 -0
- package/dist/actions/set-dream-settings.js +41 -0
- package/dist/actions/set-dream-settings.js.map +1 -0
- package/dist/actions/start-workspace-app-creation.js +1 -1
- package/dist/actions/start-workspace-app-creation.js.map +1 -1
- package/dist/actions/update-workspace-resource.js +1 -1
- package/dist/actions/update-workspace-resource.js.map +1 -1
- package/dist/actions/view-screen.d.ts.map +1 -1
- package/dist/actions/view-screen.js +73 -2
- package/dist/actions/view-screen.js.map +1 -1
- package/dist/components/approval-value-block.d.ts +7 -0
- package/dist/components/approval-value-block.d.ts.map +1 -0
- package/dist/components/approval-value-block.js +22 -0
- package/dist/components/approval-value-block.js.map +1 -0
- package/dist/components/create-app-popover.d.ts.map +1 -1
- package/dist/components/create-app-popover.js +6 -5
- package/dist/components/create-app-popover.js.map +1 -1
- package/dist/components/layout/Layout.d.ts.map +1 -1
- package/dist/components/layout/Layout.js +8 -1
- package/dist/components/layout/Layout.js.map +1 -1
- package/dist/components/ui/chart.d.ts +1 -1
- package/dist/components/workspace-app-card.d.ts.map +1 -1
- package/dist/components/workspace-app-card.js +25 -4
- package/dist/components/workspace-app-card.js.map +1 -1
- package/dist/components/workspace-resource-effective-stack.d.ts +11 -0
- package/dist/components/workspace-resource-effective-stack.d.ts.map +1 -0
- package/dist/components/workspace-resource-effective-stack.js +59 -0
- package/dist/components/workspace-resource-effective-stack.js.map +1 -0
- package/dist/components/workspace-resource-impact-preview.d.ts +9 -0
- package/dist/components/workspace-resource-impact-preview.d.ts.map +1 -0
- package/dist/components/workspace-resource-impact-preview.js +39 -0
- package/dist/components/workspace-resource-impact-preview.js.map +1 -0
- package/dist/db/migrations.d.ts.map +1 -1
- package/dist/db/migrations.js +59 -0
- package/dist/db/migrations.js.map +1 -1
- package/dist/db/schema.d.ts +714 -0
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +44 -2
- package/dist/db/schema.js.map +1 -1
- package/dist/hooks/use-navigation-state.d.ts +3 -0
- package/dist/hooks/use-navigation-state.d.ts.map +1 -1
- package/dist/hooks/use-navigation-state.js +23 -3
- package/dist/hooks/use-navigation-state.js.map +1 -1
- package/dist/lib/utils.d.ts +2 -1
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +5 -1
- package/dist/lib/utils.js.map +1 -1
- package/dist/routes/index.d.ts.map +1 -1
- package/dist/routes/index.js +1 -0
- package/dist/routes/index.js.map +1 -1
- package/dist/routes/pages/approval.d.ts.map +1 -1
- package/dist/routes/pages/approval.js +4 -1
- package/dist/routes/pages/approval.js.map +1 -1
- package/dist/routes/pages/approvals.js +1 -1
- package/dist/routes/pages/approvals.js.map +1 -1
- package/dist/routes/pages/dream-settings.d.ts +34 -0
- package/dist/routes/pages/dream-settings.d.ts.map +1 -0
- package/dist/routes/pages/dream-settings.js +68 -0
- package/dist/routes/pages/dream-settings.js.map +1 -0
- package/dist/routes/pages/dreams.d.ts +5 -0
- package/dist/routes/pages/dreams.d.ts.map +1 -0
- package/dist/routes/pages/dreams.js +435 -0
- package/dist/routes/pages/dreams.js.map +1 -0
- package/dist/routes/pages/workspace.d.ts.map +1 -1
- package/dist/routes/pages/workspace.js +187 -35
- package/dist/routes/pages/workspace.js.map +1 -1
- package/dist/server/lib/app-creation-store.d.ts.map +1 -1
- package/dist/server/lib/app-creation-store.js +3 -2
- package/dist/server/lib/app-creation-store.js.map +1 -1
- package/dist/server/lib/dispatch-integrations.d.ts +1 -1
- package/dist/server/lib/dispatch-integrations.d.ts.map +1 -1
- package/dist/server/lib/dispatch-integrations.js +9 -4
- package/dist/server/lib/dispatch-integrations.js.map +1 -1
- package/dist/server/lib/dispatch-remote-commands.d.ts +83 -0
- package/dist/server/lib/dispatch-remote-commands.d.ts.map +1 -0
- package/dist/server/lib/dispatch-remote-commands.js +256 -0
- package/dist/server/lib/dispatch-remote-commands.js.map +1 -0
- package/dist/server/lib/dispatch-store.d.ts +26 -0
- package/dist/server/lib/dispatch-store.d.ts.map +1 -1
- package/dist/server/lib/dispatch-store.js +17 -1
- package/dist/server/lib/dispatch-store.js.map +1 -1
- package/dist/server/lib/dreams-store.d.ts +398 -0
- package/dist/server/lib/dreams-store.d.ts.map +1 -0
- package/dist/server/lib/dreams-store.js +2330 -0
- package/dist/server/lib/dreams-store.js.map +1 -0
- package/dist/server/lib/thread-debug-store.d.ts +2 -2
- package/dist/server/lib/vault-store.d.ts +1 -1
- package/dist/server/lib/workspace-resources-store.d.ts +181 -17
- package/dist/server/lib/workspace-resources-store.d.ts.map +1 -1
- package/dist/server/lib/workspace-resources-store.js +737 -108
- package/dist/server/lib/workspace-resources-store.js.map +1 -1
- package/dist/server/plugins/agent-chat.js +1 -1
- package/dist/server/plugins/agent-chat.js.map +1 -1
- package/dist/server/plugins/integrations.js +2 -2
- package/dist/server/plugins/integrations.js.map +1 -1
- package/package.json +4 -2
- package/src/actions/apply-dream-proposal.ts +12 -0
- package/src/actions/create-dream-report.ts +76 -0
- package/src/actions/create-workspace-resource.ts +3 -3
- package/src/actions/delete-workspace-resource.ts +1 -1
- package/src/actions/ensure-dream-job.ts +76 -0
- package/src/actions/get-dream-settings.ts +12 -0
- package/src/actions/get-dream.ts +14 -0
- package/src/actions/get-workspace-resource-effective-context.ts +34 -0
- package/src/actions/index.spec.ts +26 -0
- package/src/actions/index.ts +31 -4
- package/src/actions/list-dream-candidates.ts +77 -0
- package/src/actions/list-dreams.ts +17 -0
- package/src/actions/list-workspace-resources-for-app.ts +13 -0
- package/src/actions/list-workspace-resources.ts +1 -1
- package/src/actions/navigate.ts +2 -1
- package/src/actions/preview-dream-proposal.ts +14 -0
- package/src/actions/preview-workspace-resource-change.ts +25 -0
- package/src/actions/reject-dream-proposal.ts +12 -0
- package/src/actions/restore-starter-workspace-resources.ts +17 -0
- package/src/actions/send-code-agent-remote-command.ts +59 -0
- package/src/actions/set-dream-settings.spec.ts +81 -0
- package/src/actions/set-dream-settings.ts +44 -0
- package/src/actions/start-workspace-app-creation.ts +1 -1
- package/src/actions/update-workspace-resource.ts +1 -1
- package/src/actions/view-screen.ts +90 -2
- package/src/components/approval-value-block.spec.tsx +59 -0
- package/src/components/approval-value-block.tsx +33 -0
- package/src/components/create-app-popover.tsx +6 -5
- package/src/components/layout/Layout.tsx +8 -0
- package/src/components/workspace-app-card.tsx +166 -1
- package/src/components/workspace-resource-effective-stack.spec.tsx +125 -0
- package/src/components/workspace-resource-effective-stack.tsx +141 -0
- package/src/components/workspace-resource-impact-preview.spec.tsx +147 -0
- package/src/components/workspace-resource-impact-preview.tsx +116 -0
- package/src/db/migrations.spec.ts +79 -0
- package/src/db/migrations.ts +59 -0
- package/src/db/schema.ts +46 -2
- package/src/hooks/use-navigation-state.ts +24 -5
- package/src/lib/utils.ts +6 -1
- package/src/routes/index.ts +1 -0
- package/src/routes/pages/approval.tsx +14 -1
- package/src/routes/pages/approvals.tsx +1 -1
- package/src/routes/pages/dream-settings.spec.ts +130 -0
- package/src/routes/pages/dream-settings.ts +103 -0
- package/src/routes/pages/dreams.tsx +1828 -0
- package/src/routes/pages/workspace.tsx +577 -97
- package/src/server/lib/app-creation-store.ts +3 -2
- package/src/server/lib/dispatch-integrations.ts +10 -3
- package/src/server/lib/dispatch-remote-commands.spec.ts +167 -0
- package/src/server/lib/dispatch-remote-commands.ts +375 -0
- package/src/server/lib/dispatch-store.ts +37 -1
- package/src/server/lib/dreams-store.spec.ts +1492 -0
- package/src/server/lib/dreams-store.ts +3168 -0
- package/src/server/lib/workspace-resource-approval-lifecycle.spec.ts +226 -0
- package/src/server/lib/workspace-resources-store.spec.ts +1106 -0
- package/src/server/lib/workspace-resources-store.ts +1001 -134
- package/src/server/plugins/agent-chat.ts +1 -1
- package/src/server/plugins/integrations.ts +2 -2
- package/dist/actions/sync-workspace-resources-to-all.d.ts +0 -3
- package/dist/actions/sync-workspace-resources-to-all.d.ts.map +0 -1
- package/dist/actions/sync-workspace-resources-to-all.js +0 -9
- package/dist/actions/sync-workspace-resources-to-all.js.map +0 -1
- package/dist/actions/sync-workspace-resources-to-app.d.ts +0 -3
- package/dist/actions/sync-workspace-resources-to-app.d.ts.map +0 -1
- package/dist/actions/sync-workspace-resources-to-app.js +0 -11
- package/dist/actions/sync-workspace-resources-to-app.js.map +0 -1
- package/src/actions/sync-workspace-resources-to-all.ts +0 -10
- package/src/actions/sync-workspace-resources-to-app.ts +0 -12
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export interface DreamSettings {
|
|
2
|
+
enabled: boolean;
|
|
3
|
+
schedule: string;
|
|
4
|
+
sourceId: string;
|
|
5
|
+
sourceIds?: string[];
|
|
6
|
+
allSources: boolean;
|
|
7
|
+
query?: string | null;
|
|
8
|
+
limit: number;
|
|
9
|
+
sourceTimeoutMs: number;
|
|
10
|
+
sourceConcurrency?: number;
|
|
11
|
+
sourceStartStaggerMs?: number;
|
|
12
|
+
threadConcurrency?: number;
|
|
13
|
+
threadTimeoutMs?: number;
|
|
14
|
+
minCandidateCount: number;
|
|
15
|
+
}
|
|
16
|
+
export interface DreamSettingsDraft {
|
|
17
|
+
enabled: boolean;
|
|
18
|
+
schedule: string;
|
|
19
|
+
sourceId: string;
|
|
20
|
+
sourceIdsText: string;
|
|
21
|
+
allSources: boolean;
|
|
22
|
+
query: string;
|
|
23
|
+
limit: string;
|
|
24
|
+
sourceTimeoutMs: string;
|
|
25
|
+
sourceConcurrency: string;
|
|
26
|
+
sourceStartStaggerMs: string;
|
|
27
|
+
threadConcurrency: string;
|
|
28
|
+
threadTimeoutMs: string;
|
|
29
|
+
minCandidateCount: string;
|
|
30
|
+
}
|
|
31
|
+
export declare function dreamSettingsToDraft(settings: DreamSettings | null | undefined): DreamSettingsDraft;
|
|
32
|
+
export declare function splitSourceIds(value: string): string[];
|
|
33
|
+
export declare function dreamSettingsUpdateFromDraft(draft: DreamSettingsDraft): Partial<DreamSettings>;
|
|
34
|
+
//# sourceMappingURL=dream-settings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dream-settings.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/dream-settings.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,aAAa,GAAG,IAAI,GAAG,SAAS,GACzC,kBAAkB,CAgBpB;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAKtD;AASD,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC,aAAa,CAAC,CAkCxB"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export function dreamSettingsToDraft(settings) {
|
|
2
|
+
return {
|
|
3
|
+
enabled: settings?.enabled ?? false,
|
|
4
|
+
schedule: settings?.schedule ?? "0 9 * * 1",
|
|
5
|
+
sourceId: settings?.sourceId ?? "all",
|
|
6
|
+
sourceIdsText: (settings?.sourceIds ?? []).join("\n"),
|
|
7
|
+
allSources: settings?.allSources ?? true,
|
|
8
|
+
query: settings?.query ?? "",
|
|
9
|
+
limit: String(settings?.limit ?? 8),
|
|
10
|
+
sourceTimeoutMs: String(settings?.sourceTimeoutMs ?? 30_000),
|
|
11
|
+
sourceConcurrency: String(settings?.sourceConcurrency ?? 2),
|
|
12
|
+
sourceStartStaggerMs: String(settings?.sourceStartStaggerMs ?? 250),
|
|
13
|
+
threadConcurrency: String(settings?.threadConcurrency ?? 3),
|
|
14
|
+
threadTimeoutMs: String(settings?.threadTimeoutMs ?? 8_000),
|
|
15
|
+
minCandidateCount: String(settings?.minCandidateCount ?? 1),
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export function splitSourceIds(value) {
|
|
19
|
+
return value
|
|
20
|
+
.split(/[\n,]/)
|
|
21
|
+
.map((item) => item.trim())
|
|
22
|
+
.filter(Boolean);
|
|
23
|
+
}
|
|
24
|
+
function numberOrUndefined(value) {
|
|
25
|
+
const trimmed = value.trim();
|
|
26
|
+
if (!trimmed)
|
|
27
|
+
return undefined;
|
|
28
|
+
const numeric = Number(trimmed);
|
|
29
|
+
return Number.isFinite(numeric) ? numeric : undefined;
|
|
30
|
+
}
|
|
31
|
+
export function dreamSettingsUpdateFromDraft(draft) {
|
|
32
|
+
const sourceIds = splitSourceIds(draft.sourceIdsText);
|
|
33
|
+
const update = {
|
|
34
|
+
enabled: draft.enabled,
|
|
35
|
+
schedule: draft.schedule.trim(),
|
|
36
|
+
sourceId: draft.sourceId.trim() || (draft.allSources ? "all" : "current"),
|
|
37
|
+
sourceIds,
|
|
38
|
+
allSources: draft.allSources,
|
|
39
|
+
query: draft.query.trim(),
|
|
40
|
+
};
|
|
41
|
+
const limit = numberOrUndefined(draft.limit);
|
|
42
|
+
if (limit !== undefined)
|
|
43
|
+
update.limit = limit;
|
|
44
|
+
const sourceTimeoutMs = numberOrUndefined(draft.sourceTimeoutMs);
|
|
45
|
+
if (sourceTimeoutMs !== undefined)
|
|
46
|
+
update.sourceTimeoutMs = sourceTimeoutMs;
|
|
47
|
+
const sourceConcurrency = numberOrUndefined(draft.sourceConcurrency);
|
|
48
|
+
if (sourceConcurrency !== undefined) {
|
|
49
|
+
update.sourceConcurrency = sourceConcurrency;
|
|
50
|
+
}
|
|
51
|
+
const sourceStartStaggerMs = numberOrUndefined(draft.sourceStartStaggerMs);
|
|
52
|
+
if (sourceStartStaggerMs !== undefined) {
|
|
53
|
+
update.sourceStartStaggerMs = sourceStartStaggerMs;
|
|
54
|
+
}
|
|
55
|
+
const threadConcurrency = numberOrUndefined(draft.threadConcurrency);
|
|
56
|
+
if (threadConcurrency !== undefined) {
|
|
57
|
+
update.threadConcurrency = threadConcurrency;
|
|
58
|
+
}
|
|
59
|
+
const threadTimeoutMs = numberOrUndefined(draft.threadTimeoutMs);
|
|
60
|
+
if (threadTimeoutMs !== undefined)
|
|
61
|
+
update.threadTimeoutMs = threadTimeoutMs;
|
|
62
|
+
const minCandidateCount = numberOrUndefined(draft.minCandidateCount);
|
|
63
|
+
if (minCandidateCount !== undefined) {
|
|
64
|
+
update.minCandidateCount = minCandidateCount;
|
|
65
|
+
}
|
|
66
|
+
return update;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=dream-settings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dream-settings.js","sourceRoot":"","sources":["../../../src/routes/pages/dream-settings.ts"],"names":[],"mappings":"AAgCA,MAAM,UAAU,oBAAoB,CAClC,QAA0C;IAE1C,OAAO;QACL,OAAO,EAAE,QAAQ,EAAE,OAAO,IAAI,KAAK;QACnC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,IAAI,WAAW;QAC3C,QAAQ,EAAE,QAAQ,EAAE,QAAQ,IAAI,KAAK;QACrC,aAAa,EAAE,CAAC,QAAQ,EAAE,SAAS,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QACrD,UAAU,EAAE,QAAQ,EAAE,UAAU,IAAI,IAAI;QACxC,KAAK,EAAE,QAAQ,EAAE,KAAK,IAAI,EAAE;QAC5B,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,KAAK,IAAI,CAAC,CAAC;QACnC,eAAe,EAAE,MAAM,CAAC,QAAQ,EAAE,eAAe,IAAI,MAAM,CAAC;QAC5D,iBAAiB,EAAE,MAAM,CAAC,QAAQ,EAAE,iBAAiB,IAAI,CAAC,CAAC;QAC3D,oBAAoB,EAAE,MAAM,CAAC,QAAQ,EAAE,oBAAoB,IAAI,GAAG,CAAC;QACnE,iBAAiB,EAAE,MAAM,CAAC,QAAQ,EAAE,iBAAiB,IAAI,CAAC,CAAC;QAC3D,eAAe,EAAE,MAAM,CAAC,QAAQ,EAAE,eAAe,IAAI,KAAK,CAAC;QAC3D,iBAAiB,EAAE,MAAM,CAAC,QAAQ,EAAE,iBAAiB,IAAI,CAAC,CAAC;KAC5D,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,OAAO,KAAK;SACT,KAAK,CAAC,OAAO,CAAC;SACd,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,OAAO,CAAC,CAAC;AACrB,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAa;IACtC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAC/B,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAChC,OAAO,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,4BAA4B,CAC1C,KAAyB;IAEzB,MAAM,SAAS,GAAG,cAAc,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IACtD,MAAM,MAAM,GAA2B;QACrC,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE;QAC/B,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;QACzE,SAAS;QACT,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE;KAC1B,CAAC;IAEF,MAAM,KAAK,GAAG,iBAAiB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC7C,IAAI,KAAK,KAAK,SAAS;QAAE,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;IAC9C,MAAM,eAAe,GAAG,iBAAiB,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IACjE,IAAI,eAAe,KAAK,SAAS;QAAE,MAAM,CAAC,eAAe,GAAG,eAAe,CAAC;IAC5E,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACrE,IAAI,iBAAiB,KAAK,SAAS,EAAE,CAAC;QACpC,MAAM,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;IAC/C,CAAC;IACD,MAAM,oBAAoB,GAAG,iBAAiB,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IAC3E,IAAI,oBAAoB,KAAK,SAAS,EAAE,CAAC;QACvC,MAAM,CAAC,oBAAoB,GAAG,oBAAoB,CAAC;IACrD,CAAC;IACD,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACrE,IAAI,iBAAiB,KAAK,SAAS,EAAE,CAAC;QACpC,MAAM,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;IAC/C,CAAC;IACD,MAAM,eAAe,GAAG,iBAAiB,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IACjE,IAAI,eAAe,KAAK,SAAS;QAAE,MAAM,CAAC,eAAe,GAAG,eAAe,CAAC;IAC5E,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACrE,IAAI,iBAAiB,KAAK,SAAS,EAAE,CAAC;QACpC,MAAM,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;IAC/C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["export interface DreamSettings {\n enabled: boolean;\n schedule: string;\n sourceId: string;\n sourceIds?: string[];\n allSources: boolean;\n query?: string | null;\n limit: number;\n sourceTimeoutMs: number;\n sourceConcurrency?: number;\n sourceStartStaggerMs?: number;\n threadConcurrency?: number;\n threadTimeoutMs?: number;\n minCandidateCount: number;\n}\n\nexport interface DreamSettingsDraft {\n enabled: boolean;\n schedule: string;\n sourceId: string;\n sourceIdsText: string;\n allSources: boolean;\n query: string;\n limit: string;\n sourceTimeoutMs: string;\n sourceConcurrency: string;\n sourceStartStaggerMs: string;\n threadConcurrency: string;\n threadTimeoutMs: string;\n minCandidateCount: string;\n}\n\nexport function dreamSettingsToDraft(\n settings: DreamSettings | null | undefined,\n): DreamSettingsDraft {\n return {\n enabled: settings?.enabled ?? false,\n schedule: settings?.schedule ?? \"0 9 * * 1\",\n sourceId: settings?.sourceId ?? \"all\",\n sourceIdsText: (settings?.sourceIds ?? []).join(\"\\n\"),\n allSources: settings?.allSources ?? true,\n query: settings?.query ?? \"\",\n limit: String(settings?.limit ?? 8),\n sourceTimeoutMs: String(settings?.sourceTimeoutMs ?? 30_000),\n sourceConcurrency: String(settings?.sourceConcurrency ?? 2),\n sourceStartStaggerMs: String(settings?.sourceStartStaggerMs ?? 250),\n threadConcurrency: String(settings?.threadConcurrency ?? 3),\n threadTimeoutMs: String(settings?.threadTimeoutMs ?? 8_000),\n minCandidateCount: String(settings?.minCandidateCount ?? 1),\n };\n}\n\nexport function splitSourceIds(value: string): string[] {\n return value\n .split(/[\\n,]/)\n .map((item) => item.trim())\n .filter(Boolean);\n}\n\nfunction numberOrUndefined(value: string): number | undefined {\n const trimmed = value.trim();\n if (!trimmed) return undefined;\n const numeric = Number(trimmed);\n return Number.isFinite(numeric) ? numeric : undefined;\n}\n\nexport function dreamSettingsUpdateFromDraft(\n draft: DreamSettingsDraft,\n): Partial<DreamSettings> {\n const sourceIds = splitSourceIds(draft.sourceIdsText);\n const update: Partial<DreamSettings> = {\n enabled: draft.enabled,\n schedule: draft.schedule.trim(),\n sourceId: draft.sourceId.trim() || (draft.allSources ? \"all\" : \"current\"),\n sourceIds,\n allSources: draft.allSources,\n query: draft.query.trim(),\n };\n\n const limit = numberOrUndefined(draft.limit);\n if (limit !== undefined) update.limit = limit;\n const sourceTimeoutMs = numberOrUndefined(draft.sourceTimeoutMs);\n if (sourceTimeoutMs !== undefined) update.sourceTimeoutMs = sourceTimeoutMs;\n const sourceConcurrency = numberOrUndefined(draft.sourceConcurrency);\n if (sourceConcurrency !== undefined) {\n update.sourceConcurrency = sourceConcurrency;\n }\n const sourceStartStaggerMs = numberOrUndefined(draft.sourceStartStaggerMs);\n if (sourceStartStaggerMs !== undefined) {\n update.sourceStartStaggerMs = sourceStartStaggerMs;\n }\n const threadConcurrency = numberOrUndefined(draft.threadConcurrency);\n if (threadConcurrency !== undefined) {\n update.threadConcurrency = threadConcurrency;\n }\n const threadTimeoutMs = numberOrUndefined(draft.threadTimeoutMs);\n if (threadTimeoutMs !== undefined) update.threadTimeoutMs = threadTimeoutMs;\n const minCandidateCount = numberOrUndefined(draft.minCandidateCount);\n if (minCandidateCount !== undefined) {\n update.minCandidateCount = minCandidateCount;\n }\n return update;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dreams.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/dreams.tsx"],"names":[],"mappings":"AA+DA,wBAAgB,IAAI;;IAEnB;AAklCD,MAAM,CAAC,OAAO,UAAU,WAAW,4CAgpBlC"}
|
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useMemo, useState } from "react";
|
|
3
|
+
import { useSearchParams } from "react-router";
|
|
4
|
+
import { useActionMutation, useActionQuery } from "@agent-native/core/client";
|
|
5
|
+
import { toast } from "sonner";
|
|
6
|
+
import { IconAlertTriangle, IconBrain, IconCalendarTime, IconCheck, IconCircleDashed, IconClock, IconDatabase, IconFileDiff, IconPlayerPlay, IconRefresh, IconSettings, IconX, } from "@tabler/icons-react";
|
|
7
|
+
import { DispatchShell } from "../../components/dispatch-shell.js";
|
|
8
|
+
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger, } from "../../components/ui/accordion.js";
|
|
9
|
+
import { Alert, AlertDescription, AlertTitle } from "../../components/ui/alert.js";
|
|
10
|
+
import { Badge } from "../../components/ui/badge.js";
|
|
11
|
+
import { Button } from "../../components/ui/button.js";
|
|
12
|
+
import { Input } from "../../components/ui/input.js";
|
|
13
|
+
import { Label } from "../../components/ui/label.js";
|
|
14
|
+
import { ScrollArea } from "../../components/ui/scroll-area.js";
|
|
15
|
+
import { Separator } from "../../components/ui/separator.js";
|
|
16
|
+
import { Sheet, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, } from "../../components/ui/sheet.js";
|
|
17
|
+
import { Skeleton } from "../../components/ui/skeleton.js";
|
|
18
|
+
import { Spinner } from "../../components/ui/spinner.js";
|
|
19
|
+
import { Switch } from "../../components/ui/switch.js";
|
|
20
|
+
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "../../components/ui/table.js";
|
|
21
|
+
import { Tabs, TabsContent, TabsList, TabsTrigger } from "../../components/ui/tabs.js";
|
|
22
|
+
import { Textarea } from "../../components/ui/textarea.js";
|
|
23
|
+
import { cn } from "../../lib/utils.js";
|
|
24
|
+
import { dreamSettingsToDraft, dreamSettingsUpdateFromDraft, splitSourceIds, } from "./dream-settings.js";
|
|
25
|
+
export function meta() {
|
|
26
|
+
return [{ title: "Dreams — Dispatch" }];
|
|
27
|
+
}
|
|
28
|
+
function normalizeArray(value, keys) {
|
|
29
|
+
if (Array.isArray(value))
|
|
30
|
+
return value;
|
|
31
|
+
if (!value || typeof value !== "object")
|
|
32
|
+
return [];
|
|
33
|
+
const record = value;
|
|
34
|
+
for (const key of keys) {
|
|
35
|
+
if (Array.isArray(record[key]))
|
|
36
|
+
return record[key];
|
|
37
|
+
}
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
40
|
+
function normalizeSourceHealth(value) {
|
|
41
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
42
|
+
return [];
|
|
43
|
+
const record = value;
|
|
44
|
+
if (Array.isArray(record.sources)) {
|
|
45
|
+
return record.sources;
|
|
46
|
+
}
|
|
47
|
+
if (Array.isArray(record.sourceHealth)) {
|
|
48
|
+
return record.sourceHealth;
|
|
49
|
+
}
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
function formatDate(value) {
|
|
53
|
+
if (value == null || value === "")
|
|
54
|
+
return "n/a";
|
|
55
|
+
const numeric = Number(value);
|
|
56
|
+
const date = Number.isFinite(numeric) ? new Date(numeric) : new Date(value);
|
|
57
|
+
if (Number.isNaN(date.getTime()))
|
|
58
|
+
return "n/a";
|
|
59
|
+
return date.toLocaleString();
|
|
60
|
+
}
|
|
61
|
+
function compactDate(value) {
|
|
62
|
+
if (value == null || value === "")
|
|
63
|
+
return "n/a";
|
|
64
|
+
const numeric = Number(value);
|
|
65
|
+
const date = Number.isFinite(numeric) ? new Date(numeric) : new Date(value);
|
|
66
|
+
if (Number.isNaN(date.getTime()))
|
|
67
|
+
return "n/a";
|
|
68
|
+
return date.toLocaleDateString(undefined, {
|
|
69
|
+
month: "short",
|
|
70
|
+
day: "numeric",
|
|
71
|
+
hour: "numeric",
|
|
72
|
+
minute: "2-digit",
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
function json(value) {
|
|
76
|
+
try {
|
|
77
|
+
return JSON.stringify(value, null, 2);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return String(value);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function plural(value, singular, pluralLabel = `${singular}s`) {
|
|
84
|
+
return `${value} ${value === 1 ? singular : pluralLabel}`;
|
|
85
|
+
}
|
|
86
|
+
function dreamLabel(dream, index) {
|
|
87
|
+
return dream.title || `Dream pass ${index + 1}`;
|
|
88
|
+
}
|
|
89
|
+
function proposalTarget(proposal) {
|
|
90
|
+
return (proposal.targetPath ||
|
|
91
|
+
proposal.path ||
|
|
92
|
+
proposal.target ||
|
|
93
|
+
proposal.targetType ||
|
|
94
|
+
proposal.type ||
|
|
95
|
+
"memory");
|
|
96
|
+
}
|
|
97
|
+
function evidenceLabel(evidence, index) {
|
|
98
|
+
return (evidence.label ||
|
|
99
|
+
evidence.title ||
|
|
100
|
+
evidence.threadTitle ||
|
|
101
|
+
evidence.source ||
|
|
102
|
+
evidence.threadId ||
|
|
103
|
+
evidence.runId ||
|
|
104
|
+
`Evidence ${index + 1}`);
|
|
105
|
+
}
|
|
106
|
+
function candidateLabel(candidate) {
|
|
107
|
+
return (candidate.thread?.title ||
|
|
108
|
+
candidate.title ||
|
|
109
|
+
candidate.summary ||
|
|
110
|
+
candidate.thread?.preview ||
|
|
111
|
+
candidate.preview ||
|
|
112
|
+
candidate.thread?.id ||
|
|
113
|
+
candidate.threadId ||
|
|
114
|
+
candidate.runId ||
|
|
115
|
+
candidate.id ||
|
|
116
|
+
"candidate");
|
|
117
|
+
}
|
|
118
|
+
function candidateSignals(candidate) {
|
|
119
|
+
const reasons = (candidate.reasons ?? []).map((reason) => typeof reason === "string" ? reason : reason.label);
|
|
120
|
+
return [...reasons, ...(candidate.signals ?? [])].filter(Boolean);
|
|
121
|
+
}
|
|
122
|
+
function candidateId(candidate) {
|
|
123
|
+
return (candidate.id ||
|
|
124
|
+
candidate.thread?.id ||
|
|
125
|
+
candidate.threadId ||
|
|
126
|
+
candidate.runId ||
|
|
127
|
+
candidateLabel(candidate));
|
|
128
|
+
}
|
|
129
|
+
function candidateStatus(candidate) {
|
|
130
|
+
return candidate.latestRunStatus || candidate.status || "unknown";
|
|
131
|
+
}
|
|
132
|
+
function candidateOwner(candidate) {
|
|
133
|
+
return candidate.thread?.ownerEmail || candidate.ownerEmail || "n/a";
|
|
134
|
+
}
|
|
135
|
+
function candidateUpdatedAt(candidate) {
|
|
136
|
+
return (candidate.updatedAt ||
|
|
137
|
+
candidate.completedAt ||
|
|
138
|
+
candidate.startedAt ||
|
|
139
|
+
candidate.thread?.updatedAt ||
|
|
140
|
+
null);
|
|
141
|
+
}
|
|
142
|
+
function dreamProposalCount(dream) {
|
|
143
|
+
return dream.proposalCount ?? dream.proposalCounts?.total ?? 0;
|
|
144
|
+
}
|
|
145
|
+
function dreamInspectedCount(dream) {
|
|
146
|
+
return dream.inspectedThreadCount ?? dream.inspectedRunCount ?? 0;
|
|
147
|
+
}
|
|
148
|
+
function resultDreamId(result) {
|
|
149
|
+
return result?.dream?.id || result?.dreamId || result?.id || null;
|
|
150
|
+
}
|
|
151
|
+
function statusVariant(status) {
|
|
152
|
+
const normalized = String(status || "pending").toLowerCase();
|
|
153
|
+
if (normalized === "failed")
|
|
154
|
+
return "destructive";
|
|
155
|
+
if (normalized === "completed" || normalized === "applied")
|
|
156
|
+
return "default";
|
|
157
|
+
if (normalized === "rejected" || normalized === "stale")
|
|
158
|
+
return "outline";
|
|
159
|
+
return "secondary";
|
|
160
|
+
}
|
|
161
|
+
function sourceStatusVariant(status) {
|
|
162
|
+
const normalized = String(status || "ok").toLowerCase();
|
|
163
|
+
if (normalized === "error" || normalized === "timed_out") {
|
|
164
|
+
return "destructive";
|
|
165
|
+
}
|
|
166
|
+
return "secondary";
|
|
167
|
+
}
|
|
168
|
+
function StatusBadge({ status }) {
|
|
169
|
+
const normalized = String(status || "pending").toLowerCase();
|
|
170
|
+
return (_jsx(Badge, { variant: statusVariant(status), className: "capitalize", children: normalized.replace(/_/g, " ") }));
|
|
171
|
+
}
|
|
172
|
+
function SourceHealthPanel({ sources }) {
|
|
173
|
+
if (sources.length === 0)
|
|
174
|
+
return null;
|
|
175
|
+
const unhealthyCount = sources.filter((source) => String(source.status).toLowerCase() !== "ok").length;
|
|
176
|
+
return (_jsxs(Alert, { variant: unhealthyCount > 0 ? "destructive" : "default", children: [_jsx(IconDatabase, { className: "h-4 w-4" }), _jsx(AlertTitle, { children: "Source health" }), _jsx(AlertDescription, { children: _jsx("div", { className: "mt-2 flex flex-wrap gap-1.5", children: sources.map((source) => (_jsxs(Badge, { variant: sourceStatusVariant(source.status), className: "gap-1", title: source.message ||
|
|
177
|
+
`${source.inspectedThreadCount} inspected, ${source.candidateCount} candidates, ${source.durationMs}ms of ${source.timeoutMs ?? "n/a"}ms`, children: [source.label || source.sourceId, ":", " ", String(source.status).replace(/_/g, " "), " \u00B7 ", source.durationMs, "ms"] }, source.sourceId))) }) })] }));
|
|
178
|
+
}
|
|
179
|
+
function isApprovalRequestResult(value) {
|
|
180
|
+
if (!value || typeof value !== "object")
|
|
181
|
+
return false;
|
|
182
|
+
const record = value;
|
|
183
|
+
const result = record.result;
|
|
184
|
+
return result?.approvalRequired === true;
|
|
185
|
+
}
|
|
186
|
+
function QueryState({ error, label }) {
|
|
187
|
+
if (!error)
|
|
188
|
+
return null;
|
|
189
|
+
return (_jsxs(Alert, { variant: "destructive", children: [_jsx(IconAlertTriangle, { className: "h-4 w-4" }), _jsx(AlertTitle, { children: label }), _jsx(AlertDescription, { children: error instanceof Error ? error.message : String(error) })] }));
|
|
190
|
+
}
|
|
191
|
+
function RawBlock({ value }) {
|
|
192
|
+
return (_jsx("pre", { className: "max-h-64 overflow-auto rounded-md border bg-muted/30 p-3 text-xs leading-relaxed text-foreground whitespace-pre-wrap break-words", children: typeof value === "string" ? value : json(value) }));
|
|
193
|
+
}
|
|
194
|
+
function EmptyPanel({ title, description, }) {
|
|
195
|
+
return (_jsxs("div", { className: "rounded-lg border border-dashed bg-muted/20 px-4 py-8 text-center", children: [_jsx("div", { className: "text-sm font-medium text-foreground", children: title }), _jsx("div", { className: "mx-auto mt-1 max-w-md text-xs leading-relaxed text-muted-foreground", children: description })] }));
|
|
196
|
+
}
|
|
197
|
+
function DreamListSkeleton() {
|
|
198
|
+
return (_jsx("div", { className: "space-y-2", children: Array.from({ length: 5 }).map((_, index) => (_jsxs("div", { className: "rounded-lg border p-3", children: [_jsx(Skeleton, { className: "h-4 w-2/3" }), _jsx(Skeleton, { className: "mt-2 h-3 w-full" }), _jsx(Skeleton, { className: "mt-2 h-3 w-1/2" })] }, index))) }));
|
|
199
|
+
}
|
|
200
|
+
function ProposalSkeleton() {
|
|
201
|
+
return (_jsx("div", { className: "space-y-3", children: Array.from({ length: 3 }).map((_, index) => (_jsxs("div", { className: "rounded-lg border p-4", children: [_jsx(Skeleton, { className: "h-4 w-1/2" }), _jsx(Skeleton, { className: "mt-3 h-3 w-full" }), _jsx(Skeleton, { className: "mt-2 h-3 w-3/4" })] }, index))) }));
|
|
202
|
+
}
|
|
203
|
+
function StatTile({ label, value, icon: Icon, }) {
|
|
204
|
+
return (_jsx("div", { className: "rounded-lg border bg-card px-3 py-2.5", children: _jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsxs("div", { children: [_jsx("div", { className: "text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: label }), _jsx("div", { className: "mt-1 text-xl font-semibold tabular-nums text-foreground", children: value })] }), _jsx(Icon, { size: 18, className: "text-muted-foreground" })] }) }));
|
|
205
|
+
}
|
|
206
|
+
function DreamSettingsSheet({ open, onOpenChange, draft, onDraftChange, onSave, saving, loading, }) {
|
|
207
|
+
const sourceIds = splitSourceIds(draft.sourceIdsText);
|
|
208
|
+
const canSave = draft.schedule.trim().length > 0;
|
|
209
|
+
function update(key, value) {
|
|
210
|
+
onDraftChange({ ...draft, [key]: value });
|
|
211
|
+
}
|
|
212
|
+
return (_jsxs(Sheet, { open: open, onOpenChange: onOpenChange, children: [_jsx(SheetTrigger, { asChild: true, children: _jsxs(Button, { variant: "outline", disabled: loading, children: [_jsx(IconSettings, { size: 15, className: "mr-1.5" }), "Settings"] }) }), _jsxs(SheetContent, { className: "flex w-full flex-col p-0 sm:max-w-2xl", children: [_jsxs(SheetHeader, { className: "border-b px-5 py-4", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2 pr-8", children: [_jsx(Badge, { variant: draft.enabled ? "default" : "secondary", children: draft.enabled ? "Enabled" : "Paused" }), _jsx(Badge, { variant: "outline", className: "font-mono", children: draft.schedule || "No schedule" })] }), _jsx(SheetTitle, { className: "mt-2 text-base", children: "Dream settings" }), _jsx(SheetDescription, { children: "Configure recurring dream scope, schedule, and scan limits." })] }), _jsx(ScrollArea, { className: "min-h-0 flex-1", children: _jsxs("div", { className: "space-y-6 p-5", children: [_jsxs("section", { className: "space-y-3", children: [_jsx("div", { className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Schedule" }), _jsxs("div", { className: "flex items-center justify-between gap-4 rounded-lg border bg-muted/20 px-3 py-3", children: [_jsxs("div", { children: [_jsx(Label, { htmlFor: "dream-enabled", children: "Recurring dreams" }), _jsx("div", { className: "mt-1 text-xs text-muted-foreground", children: "Saved setting used by dream jobs." })] }), _jsx(Switch, { id: "dream-enabled", checked: draft.enabled, onCheckedChange: (checked) => update("enabled", checked) })] }), _jsxs("div", { className: "grid gap-4 sm:grid-cols-[minmax(0,1fr)_180px]", children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "dream-schedule", children: "Cron schedule" }), _jsx(Input, { id: "dream-schedule", value: draft.schedule, onChange: (event) => update("schedule", event.target.value), placeholder: "0 9 * * 1", className: "font-mono" })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "dream-min-candidates", children: "Min candidates" }), _jsx(Input, { id: "dream-min-candidates", type: "number", min: 0, max: 50, value: draft.minCandidateCount, onChange: (event) => update("minCandidateCount", event.target.value) })] })] })] }), _jsx(Separator, {}), _jsxs("section", { className: "space-y-3", children: [_jsx("div", { className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Sources" }), _jsxs("div", { className: "flex items-center justify-between gap-4 rounded-lg border bg-muted/20 px-3 py-3", children: [_jsxs("div", { children: [_jsx(Label, { htmlFor: "dream-all-sources", children: "All sources" }), _jsx("div", { className: "mt-1 text-xs text-muted-foreground", children: "Scan every connected thread-debug source." })] }), _jsx(Switch, { id: "dream-all-sources", checked: draft.allSources, onCheckedChange: (checked) => update("allSources", checked) })] }), _jsxs("div", { className: "grid gap-4 sm:grid-cols-2", children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "dream-source-id", children: "Source ID" }), _jsx(Input, { id: "dream-source-id", value: draft.sourceId, onChange: (event) => update("sourceId", event.target.value), disabled: draft.allSources || sourceIds.length > 0, placeholder: "current", className: "font-mono" })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "dream-query", children: "Query" }), _jsx(Input, { id: "dream-query", value: draft.query, onChange: (event) => update("query", event.target.value), placeholder: "Optional search term" })] })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "dream-source-ids", children: "Explicit source IDs" }), _jsx(Textarea, { id: "dream-source-ids", value: draft.sourceIdsText, onChange: (event) => update("sourceIdsText", event.target.value), disabled: draft.allSources, rows: 3, placeholder: "One source ID per line", className: "font-mono" })] })] }), _jsx(Separator, {}), _jsxs("section", { className: "space-y-3", children: [_jsx("div", { className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Scan Limits" }), _jsxs("div", { className: "grid gap-4 sm:grid-cols-2", children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "dream-limit", children: "Candidate limit" }), _jsx(Input, { id: "dream-limit", type: "number", min: 1, max: 50, value: draft.limit, onChange: (event) => update("limit", event.target.value) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "dream-source-timeout", children: "Source timeout ms" }), _jsx(Input, { id: "dream-source-timeout", type: "number", min: 1000, max: 60000, value: draft.sourceTimeoutMs, onChange: (event) => update("sourceTimeoutMs", event.target.value) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "dream-source-concurrency", children: "Source concurrency" }), _jsx(Input, { id: "dream-source-concurrency", type: "number", min: 1, max: 8, value: draft.sourceConcurrency, onChange: (event) => update("sourceConcurrency", event.target.value) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "dream-start-stagger", children: "Start stagger ms" }), _jsx(Input, { id: "dream-start-stagger", type: "number", min: 0, max: 5000, value: draft.sourceStartStaggerMs, onChange: (event) => update("sourceStartStaggerMs", event.target.value) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "dream-thread-concurrency", children: "Thread concurrency" }), _jsx(Input, { id: "dream-thread-concurrency", type: "number", min: 1, max: 10, value: draft.threadConcurrency, onChange: (event) => update("threadConcurrency", event.target.value) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "dream-thread-timeout", children: "Thread timeout ms" }), _jsx(Input, { id: "dream-thread-timeout", type: "number", min: 1000, max: 30000, value: draft.threadTimeoutMs, onChange: (event) => update("threadTimeoutMs", event.target.value) })] })] })] })] }) }), _jsxs(SheetFooter, { className: "gap-2 border-t px-5 py-4", children: [_jsx(Button, { variant: "outline", onClick: () => onOpenChange(false), children: "Close" }), _jsxs(Button, { disabled: !canSave || saving, onClick: onSave, children: [saving ? _jsx(Spinner, { className: "mr-1.5 size-3.5" }) : null, "Save settings"] })] })] })] }));
|
|
213
|
+
}
|
|
214
|
+
function ProposalCard({ proposal, applying, rejecting, onApply, onReject, }) {
|
|
215
|
+
const [open, setOpen] = useState(false);
|
|
216
|
+
const [rejectReason, setRejectReason] = useState("");
|
|
217
|
+
const evidence = proposal.evidence ?? [];
|
|
218
|
+
const sourceRunIds = proposal.sourceRunIds ?? [];
|
|
219
|
+
const status = String(proposal.status || "pending").toLowerCase();
|
|
220
|
+
const canAct = status === "pending";
|
|
221
|
+
const needsApproval = proposal.targetType != null && proposal.targetType !== "personal-memory";
|
|
222
|
+
const previewQuery = useActionQuery("preview-dream-proposal", { id: proposal.id }, { enabled: open, staleTime: 0 });
|
|
223
|
+
const preview = previewQuery.data;
|
|
224
|
+
return (_jsxs("div", { className: "rounded-lg border bg-card", children: [_jsxs("div", { className: "flex flex-col gap-3 border-b px-4 py-3 md:flex-row md:items-start md:justify-between", children: [_jsxs("div", { className: "min-w-0", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx(StatusBadge, { status: proposal.status }), _jsx(Badge, { variant: "outline", className: "font-mono", children: proposalTarget(proposal) }), proposal.risk ? (_jsxs(Badge, { variant: "secondary", className: "capitalize", children: [proposal.risk, " risk"] })) : null] }), _jsx("div", { className: "mt-2 text-sm font-medium text-foreground", children: proposal.title || proposal.summary || proposal.id }), proposal.summary && proposal.title ? (_jsx("div", { className: "mt-1 text-xs leading-relaxed text-muted-foreground", children: proposal.summary })) : null] }), _jsx("div", { className: "flex shrink-0 gap-2", children: _jsxs(Sheet, { open: open, onOpenChange: setOpen, children: [_jsx(SheetTrigger, { asChild: true, children: _jsxs(Button, { size: "sm", variant: canAct ? "default" : "outline", children: [_jsx(IconFileDiff, { size: 14, className: "mr-1.5" }), "Review"] }) }), _jsxs(SheetContent, { className: "flex w-full flex-col p-0 sm:max-w-3xl", children: [_jsxs(SheetHeader, { className: "border-b px-5 py-4", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2 pr-8", children: [_jsx(StatusBadge, { status: proposal.status }), _jsx(Badge, { variant: "outline", className: "font-mono", children: preview?.target?.path || proposalTarget(proposal) }), _jsx(Badge, { variant: "secondary", className: "capitalize", children: preview?.operation || "review" }), preview?.approval?.willRequestApproval ? (_jsx(Badge, { variant: "secondary", children: "Approval request" })) : null] }), _jsx(SheetTitle, { className: "mt-2 text-base", children: proposal.title || proposal.summary || proposal.id }), _jsx(SheetDescription, { children: proposal.summary ||
|
|
225
|
+
"Review the target, evidence, and proposed content before applying this dream proposal." })] }), _jsx(ScrollArea, { className: "min-h-0 flex-1", children: _jsxs("div", { className: "space-y-5 p-5", children: [previewQuery.error ? (_jsx(QueryState, { error: previewQuery.error, label: "Could not preview proposal" })) : null, previewQuery.isLoading ? _jsx(ProposalSkeleton, {}) : null, _jsxs("div", { className: "grid gap-3 sm:grid-cols-2", children: [_jsxs("div", { className: "rounded-lg border bg-muted/20 p-3", children: [_jsx("div", { className: "text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: "Target" }), _jsx("div", { className: "mt-1 break-all font-mono text-xs text-foreground", children: preview?.target?.path || proposalTarget(proposal) }), _jsxs("div", { className: "mt-2 flex flex-wrap gap-1.5", children: [_jsx(Badge, { variant: "outline", children: preview?.target?.type ||
|
|
226
|
+
proposal.targetType ||
|
|
227
|
+
"memory" }), preview?.targetExists ? (_jsx(Badge, { variant: "secondary", children: "Existing target" })) : (_jsx(Badge, { variant: "secondary", children: "New target" }))] })] }), _jsxs("div", { className: "rounded-lg border bg-muted/20 p-3", children: [_jsx("div", { className: "text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: "Review gate" }), _jsx("div", { className: "mt-1 text-xs leading-relaxed text-foreground", children: preview?.approval?.willRequestApproval
|
|
228
|
+
? "Applying will create a Dispatch approval request."
|
|
229
|
+
: needsApproval
|
|
230
|
+
? "Applying writes a shared/workspace resource because approvals are disabled."
|
|
231
|
+
: "Applying writes personal memory directly." }), _jsxs("div", { className: "mt-2 flex flex-wrap gap-1.5", children: [proposal.risk ? (_jsxs(Badge, { variant: "outline", className: "capitalize", children: [proposal.risk, " risk"] })) : null, proposal.confidence != null ? (_jsxs(Badge, { variant: "outline", children: [proposal.confidence, "% confidence"] })) : null] })] })] }), proposal.rationale ? (_jsxs("div", { children: [_jsx("div", { className: "text-xs font-medium text-foreground", children: "Rationale" }), _jsx("div", { className: "mt-1 text-xs leading-relaxed text-muted-foreground", children: proposal.rationale })] })) : null, _jsx(Separator, {}), _jsxs("div", { className: "grid gap-4 lg:grid-cols-2", children: [_jsxs("div", { children: [_jsx("div", { className: "mb-2 text-xs font-medium text-foreground", children: "Current target" }), preview?.currentContent ? (_jsx(RawBlock, { value: preview.currentContent })) : (_jsx(EmptyPanel, { title: "No existing content", description: "This proposal would create a new target or append to an empty target." }))] }), _jsxs("div", { children: [_jsx("div", { className: "mb-2 text-xs font-medium text-foreground", children: "Proposed content" }), _jsx(RawBlock, { value: preview?.proposedContent || proposal.content })] })] }), _jsx(Separator, {}), _jsxs("div", { children: [_jsx("div", { className: "mb-2 text-xs font-medium text-foreground", children: "Evidence" }), sourceRunIds.length > 0 ? (_jsx("div", { className: "mb-2 flex flex-wrap gap-1.5", children: sourceRunIds.map((id) => (_jsx(Badge, { variant: "outline", className: "font-mono", children: id }, id))) })) : null, evidence.length > 0 ? (_jsx("div", { className: "space-y-2", children: evidence.map((item, index) => (_jsxs("div", { className: "rounded-md border bg-muted/20 px-3 py-2", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [_jsx("div", { className: "text-xs font-medium text-foreground", children: evidenceLabel(item, index) }), _jsx("div", { className: "text-[11px] text-muted-foreground", children: formatDate(item.createdAt) })] }), _jsx("div", { className: "mt-1 text-xs leading-relaxed text-muted-foreground", children: item.quote ||
|
|
232
|
+
item.snippet ||
|
|
233
|
+
item.summary ||
|
|
234
|
+
"No text" })] }, item.id || `${proposal.id}-review-${index}`))) })) : (_jsx(EmptyPanel, { title: "No structured evidence", description: "The proposal did not include compact evidence records." }))] }), canAct ? (_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: `reject-${proposal.id}`, children: "Rejection reason" }), _jsx(Textarea, { id: `reject-${proposal.id}`, value: rejectReason, onChange: (event) => setRejectReason(event.target.value), placeholder: "Optional note for the audit log" })] })) : null] }) }), _jsxs(SheetFooter, { className: "gap-2 border-t px-5 py-4", children: [_jsxs(Button, { variant: "outline", disabled: !canAct || applying || rejecting, onClick: () => {
|
|
235
|
+
onReject(rejectReason.trim() || undefined);
|
|
236
|
+
setOpen(false);
|
|
237
|
+
}, children: [rejecting ? (_jsx(Spinner, { className: "mr-1.5 size-3.5" })) : (_jsx(IconX, { size: 14, className: "mr-1.5" })), "Reject"] }), _jsxs(Button, { disabled: !canAct || applying || rejecting, onClick: () => {
|
|
238
|
+
onApply();
|
|
239
|
+
setOpen(false);
|
|
240
|
+
}, children: [applying ? (_jsx(Spinner, { className: "mr-1.5 size-3.5" })) : (_jsx(IconCheck, { size: 14, className: "mr-1.5" })), needsApproval ? "Request approval" : "Apply"] })] })] })] }) })] }), _jsxs(Accordion, { type: "multiple", className: "px-4", children: [_jsxs(AccordionItem, { value: "evidence", className: "border-b-0", children: [_jsx(AccordionTrigger, { className: "py-3 text-xs hover:no-underline", children: "Evidence and provenance" }), _jsxs(AccordionContent, { className: "space-y-3 pb-4", children: [sourceRunIds.length > 0 ? (_jsx("div", { className: "flex flex-wrap gap-1.5", children: sourceRunIds.map((id) => (_jsx(Badge, { variant: "outline", className: "font-mono", children: id }, id))) })) : null, evidence.length > 0 ? (_jsx("div", { className: "space-y-2", children: evidence.map((item, index) => (_jsxs("div", { className: "rounded-md border bg-muted/20 px-3 py-2", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [_jsx("div", { className: "text-xs font-medium text-foreground", children: evidenceLabel(item, index) }), _jsx("div", { className: "text-[11px] text-muted-foreground", children: formatDate(item.createdAt) })] }), _jsx("div", { className: "mt-1 text-xs leading-relaxed text-muted-foreground", children: item.quote || item.snippet || item.summary || "No text" })] }, item.id || `${proposal.id}-evidence-${index}`))) })) : (_jsx("div", { className: "text-xs text-muted-foreground", children: "No structured evidence attached yet." }))] })] }), proposal.content ? (_jsxs(AccordionItem, { value: "content", className: "border-b-0", children: [_jsx(AccordionTrigger, { className: "py-3 text-xs hover:no-underline", children: "Proposed content" }), _jsx(AccordionContent, { className: "pb-4", children: _jsx(RawBlock, { value: proposal.content }) })] })) : null] })] }));
|
|
241
|
+
}
|
|
242
|
+
export default function DreamsRoute() {
|
|
243
|
+
const [searchParams, setSearchParams] = useSearchParams();
|
|
244
|
+
const [selectedDreamId, setSelectedDreamId] = useState(searchParams.get("dreamId"));
|
|
245
|
+
const [settingsOpen, setSettingsOpen] = useState(false);
|
|
246
|
+
const [settingsDraft, setSettingsDraft] = useState(() => dreamSettingsToDraft(null));
|
|
247
|
+
const dreamsQuery = useActionQuery("list-dreams", { limit: 25 }, { staleTime: 15_000 });
|
|
248
|
+
const candidatesQuery = useActionQuery("list-dream-candidates", {
|
|
249
|
+
limit: 25,
|
|
250
|
+
sourceTimeoutMs: 30_000,
|
|
251
|
+
sourceConcurrency: 2,
|
|
252
|
+
sourceStartStaggerMs: 250,
|
|
253
|
+
threadConcurrency: 3,
|
|
254
|
+
threadTimeoutMs: 8_000,
|
|
255
|
+
}, { staleTime: 15_000 });
|
|
256
|
+
const dreamSettingsQuery = useActionQuery("get-dream-settings", {}, { staleTime: 30_000 });
|
|
257
|
+
const dreamDetailQuery = useActionQuery("get-dream", { id: selectedDreamId ?? "" }, { enabled: !!selectedDreamId, staleTime: 10_000 });
|
|
258
|
+
const dreams = useMemo(() => normalizeArray(dreamsQuery.data, [
|
|
259
|
+
"dreams",
|
|
260
|
+
"items",
|
|
261
|
+
"results",
|
|
262
|
+
]), [dreamsQuery.data]);
|
|
263
|
+
const candidates = useMemo(() => normalizeArray(candidatesQuery.data, [
|
|
264
|
+
"candidates",
|
|
265
|
+
"items",
|
|
266
|
+
"results",
|
|
267
|
+
]), [candidatesQuery.data]);
|
|
268
|
+
const candidateSourceHealth = useMemo(() => normalizeSourceHealth(candidatesQuery.data), [candidatesQuery.data]);
|
|
269
|
+
useEffect(() => {
|
|
270
|
+
const urlDreamId = searchParams.get("dreamId");
|
|
271
|
+
if (urlDreamId && urlDreamId !== selectedDreamId) {
|
|
272
|
+
setSelectedDreamId(urlDreamId);
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
if (selectedDreamId && dreams.some((dream) => dream.id === selectedDreamId))
|
|
276
|
+
return;
|
|
277
|
+
const nextId = dreams[0]?.id ?? null;
|
|
278
|
+
setSelectedDreamId(nextId);
|
|
279
|
+
if (nextId && nextId !== urlDreamId) {
|
|
280
|
+
const next = new URLSearchParams(searchParams);
|
|
281
|
+
next.set("dreamId", nextId);
|
|
282
|
+
setSearchParams(next, { replace: true });
|
|
283
|
+
}
|
|
284
|
+
}, [dreams, searchParams, selectedDreamId, setSearchParams]);
|
|
285
|
+
function selectDream(dreamId) {
|
|
286
|
+
setSelectedDreamId(dreamId);
|
|
287
|
+
const next = new URLSearchParams(searchParams);
|
|
288
|
+
next.set("dreamId", dreamId);
|
|
289
|
+
setSearchParams(next, { replace: true });
|
|
290
|
+
}
|
|
291
|
+
const createDream = useActionMutation("create-dream-report", {
|
|
292
|
+
onSuccess: (result) => {
|
|
293
|
+
const nextId = resultDreamId(result);
|
|
294
|
+
if (nextId)
|
|
295
|
+
selectDream(nextId);
|
|
296
|
+
toast.success("Dream report created");
|
|
297
|
+
},
|
|
298
|
+
onError: (err) => toast.error(String(err)),
|
|
299
|
+
});
|
|
300
|
+
const applyProposal = useActionMutation("apply-dream-proposal", {
|
|
301
|
+
onSuccess: (result) => {
|
|
302
|
+
toast.success(isApprovalRequestResult(result)
|
|
303
|
+
? "Approval requested"
|
|
304
|
+
: "Proposal applied");
|
|
305
|
+
dreamDetailQuery.refetch();
|
|
306
|
+
dreamsQuery.refetch();
|
|
307
|
+
},
|
|
308
|
+
onError: (err) => toast.error(String(err)),
|
|
309
|
+
});
|
|
310
|
+
const rejectProposal = useActionMutation("reject-dream-proposal", {
|
|
311
|
+
onSuccess: () => {
|
|
312
|
+
toast.success("Proposal rejected");
|
|
313
|
+
dreamDetailQuery.refetch();
|
|
314
|
+
dreamsQuery.refetch();
|
|
315
|
+
},
|
|
316
|
+
onError: (err) => toast.error(String(err)),
|
|
317
|
+
});
|
|
318
|
+
const ensureDreamSchedule = useActionMutation("ensure-dream-job", {
|
|
319
|
+
onSuccess: () => {
|
|
320
|
+
toast.success("Dream schedule updated");
|
|
321
|
+
dreamSettingsQuery.refetch();
|
|
322
|
+
},
|
|
323
|
+
onError: (err) => toast.error(String(err)),
|
|
324
|
+
});
|
|
325
|
+
const saveDreamSettings = useActionMutation("set-dream-settings", {
|
|
326
|
+
onSuccess: (settings) => {
|
|
327
|
+
toast.success("Dream settings saved");
|
|
328
|
+
setSettingsDraft(dreamSettingsToDraft(settings));
|
|
329
|
+
setSettingsOpen(false);
|
|
330
|
+
dreamSettingsQuery.refetch();
|
|
331
|
+
candidatesQuery.refetch();
|
|
332
|
+
},
|
|
333
|
+
onError: (err) => toast.error(String(err)),
|
|
334
|
+
});
|
|
335
|
+
const detail = dreamDetailQuery.data ?? null;
|
|
336
|
+
const dreamSettings = dreamSettingsQuery.data ?? null;
|
|
337
|
+
const selectedDream = detail?.dream ?? dreams.find((dream) => dream.id === selectedDreamId);
|
|
338
|
+
const proposals = detail?.proposals ?? [];
|
|
339
|
+
const inspectedRuns = detail?.inspectedRuns ?? detail?.candidates ?? [];
|
|
340
|
+
const selectedSourceHealth = selectedDream?.sourceHealth ?? [];
|
|
341
|
+
const pendingProposalCount = proposals.filter((proposal) => String(proposal.status || "pending").toLowerCase() === "pending").length;
|
|
342
|
+
const appliedProposalCount = proposals.filter((proposal) => String(proposal.status || "").toLowerCase() === "applied").length;
|
|
343
|
+
useEffect(() => {
|
|
344
|
+
if (dreamSettings && !settingsOpen) {
|
|
345
|
+
setSettingsDraft(dreamSettingsToDraft(dreamSettings));
|
|
346
|
+
}
|
|
347
|
+
}, [dreamSettings, settingsOpen]);
|
|
348
|
+
function handleSettingsOpenChange(open) {
|
|
349
|
+
if (open) {
|
|
350
|
+
setSettingsDraft(dreamSettingsToDraft(dreamSettings));
|
|
351
|
+
}
|
|
352
|
+
setSettingsOpen(open);
|
|
353
|
+
}
|
|
354
|
+
function saveSettings() {
|
|
355
|
+
const update = dreamSettingsUpdateFromDraft(settingsDraft);
|
|
356
|
+
if (!update.schedule) {
|
|
357
|
+
toast.error("Add a cron schedule before saving");
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
saveDreamSettings.mutate(update);
|
|
361
|
+
}
|
|
362
|
+
function runDream(scanAllSources = false) {
|
|
363
|
+
createDream.mutate({
|
|
364
|
+
sourceId: scanAllSources ? "all" : "current",
|
|
365
|
+
allSources: scanAllSources,
|
|
366
|
+
limit: scanAllSources
|
|
367
|
+
? 8
|
|
368
|
+
: candidates.length > 0
|
|
369
|
+
? candidates.length
|
|
370
|
+
: 20,
|
|
371
|
+
sourceTimeoutMs: dreamSettings?.sourceTimeoutMs ?? 30_000,
|
|
372
|
+
sourceConcurrency: dreamSettings?.sourceConcurrency ?? 2,
|
|
373
|
+
sourceStartStaggerMs: dreamSettings?.sourceStartStaggerMs ?? 250,
|
|
374
|
+
threadConcurrency: dreamSettings?.threadConcurrency ?? 3,
|
|
375
|
+
threadTimeoutMs: dreamSettings?.threadTimeoutMs ?? 8_000,
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
function ensureSchedule() {
|
|
379
|
+
ensureDreamSchedule.mutate({
|
|
380
|
+
schedule: dreamSettings?.schedule,
|
|
381
|
+
sourceId: dreamSettings?.sourceId ?? "all",
|
|
382
|
+
sourceIds: dreamSettings?.sourceIds,
|
|
383
|
+
allSources: dreamSettings?.allSources ?? true,
|
|
384
|
+
query: dreamSettings?.query ?? undefined,
|
|
385
|
+
limit: dreamSettings?.limit ?? 8,
|
|
386
|
+
sourceTimeoutMs: dreamSettings?.sourceTimeoutMs ?? 30_000,
|
|
387
|
+
sourceConcurrency: dreamSettings?.sourceConcurrency ?? 2,
|
|
388
|
+
sourceStartStaggerMs: dreamSettings?.sourceStartStaggerMs ?? 250,
|
|
389
|
+
threadConcurrency: dreamSettings?.threadConcurrency ?? 3,
|
|
390
|
+
threadTimeoutMs: dreamSettings?.threadTimeoutMs ?? 8_000,
|
|
391
|
+
minCandidateCount: dreamSettings?.minCandidateCount ?? 1,
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
return (_jsx(DispatchShell, { title: "Dreams", description: "Review agent runs, propose memory improvements, and apply evidence-backed learning changes.", children: _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [_jsxs("div", { className: "grid flex-1 gap-2 sm:grid-cols-2 xl:grid-cols-4", children: [_jsx(StatTile, { label: "Dream passes", value: dreams.length, icon: IconBrain }), _jsx(StatTile, { label: "Pending proposals", value: pendingProposalCount, icon: IconCircleDashed }), _jsx(StatTile, { label: "Candidate runs", value: candidates.length, icon: IconClock }), _jsx(StatTile, { label: "Inspected threads", value: selectedDream ? dreamInspectedCount(selectedDream) : 0, icon: IconCheck })] }), _jsxs("div", { className: "flex shrink-0 flex-wrap gap-2", children: [dreamSettings ? (_jsxs(Badge, { variant: "outline", className: "h-9 px-3", children: [dreamSettings.enabled ? "Enabled" : "Paused", " \u00B7", " ", dreamSettings.allSources
|
|
395
|
+
? "All sources"
|
|
396
|
+
: dreamSettings.sourceId, " ", "\u00B7 ", dreamSettings.schedule] })) : null, _jsx(DreamSettingsSheet, { open: settingsOpen, onOpenChange: handleSettingsOpenChange, draft: settingsDraft, onDraftChange: setSettingsDraft, onSave: saveSettings, saving: saveDreamSettings.isPending, loading: dreamSettingsQuery.isLoading }), _jsxs(Button, { variant: "outline", onClick: () => {
|
|
397
|
+
dreamsQuery.refetch();
|
|
398
|
+
candidatesQuery.refetch();
|
|
399
|
+
if (selectedDreamId)
|
|
400
|
+
dreamDetailQuery.refetch();
|
|
401
|
+
}, children: [_jsx(IconRefresh, { size: 15, className: "mr-1.5" }), "Refresh"] }), _jsxs(Button, { variant: "outline", onClick: ensureSchedule, disabled: ensureDreamSchedule.isPending, children: [ensureDreamSchedule.isPending ? (_jsx(Spinner, { className: "mr-1.5 size-3.5" })) : (_jsx(IconCalendarTime, { size: 15, className: "mr-1.5" })), "Ensure schedule"] }), _jsxs(Button, { variant: "outline", onClick: () => runDream(true), disabled: createDream.isPending, children: [createDream.isPending ? (_jsx(Spinner, { className: "mr-1.5 size-3.5" })) : (_jsx(IconDatabase, { size: 15, className: "mr-1.5" })), "Run all sources"] }), _jsxs(Button, { onClick: () => runDream(false), disabled: createDream.isPending, children: [createDream.isPending ? (_jsx(Spinner, { className: "mr-1.5 size-3.5" })) : (_jsx(IconPlayerPlay, { size: 15, className: "mr-1.5" })), "Run dream"] })] })] }), _jsxs("div", { className: "grid gap-4 xl:grid-cols-[280px_minmax(0,1fr)_380px]", children: [_jsxs("section", { className: "rounded-lg border bg-card", children: [_jsxs("div", { className: "border-b px-4 py-3", children: [_jsx("div", { className: "text-sm font-semibold text-foreground", children: "Recent passes" }), _jsx("div", { className: "mt-1 text-xs text-muted-foreground", children: "Reports generated from prior agent activity." })] }), _jsxs("div", { className: "max-h-[720px] overflow-auto p-3", children: [_jsx(QueryState, { error: dreamsQuery.error, label: "Could not load dream passes" }), dreamsQuery.isLoading ? _jsx(DreamListSkeleton, {}) : null, !dreamsQuery.isLoading && !dreamsQuery.error ? (dreams.length > 0 ? (_jsx("div", { className: "space-y-2", children: dreams.map((dream, index) => {
|
|
402
|
+
const selected = dream.id === selectedDreamId;
|
|
403
|
+
return (_jsxs("button", { type: "button", onClick: () => selectDream(dream.id), className: cn("w-full rounded-lg border px-3 py-3 text-left transition-colors", selected
|
|
404
|
+
? "border-foreground bg-muted"
|
|
405
|
+
: "bg-background hover:border-foreground/30 hover:bg-muted/40"), children: [_jsxs("div", { className: "flex items-start justify-between gap-2", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "truncate text-sm font-medium text-foreground", children: dreamLabel(dream, index) }), _jsx("div", { className: "mt-1 truncate font-mono text-[11px] text-muted-foreground", children: dream.id })] }), _jsx(StatusBadge, { status: dream.status })] }), _jsx("div", { className: "mt-2 line-clamp-2 text-xs leading-relaxed text-muted-foreground", children: dream.summary || "No summary yet." }), _jsxs("div", { className: "mt-3 flex flex-wrap gap-1.5", children: [_jsx(Badge, { variant: "outline", children: plural(dreamProposalCount(dream), "proposal") }), _jsx(Badge, { variant: "outline", children: plural(dreamInspectedCount(dream), "run") })] }), _jsx("div", { className: "mt-2 text-[11px] text-muted-foreground", children: compactDate(dream.completedAt ??
|
|
406
|
+
dream.updatedAt ??
|
|
407
|
+
dream.startedAt ??
|
|
408
|
+
dream.createdAt) })] }, dream.id));
|
|
409
|
+
}) })) : (_jsx(EmptyPanel, { title: "No dreams yet", description: "Run the first dream pass to review recent agent history and generate proposed memory changes." }))) : null] })] }), _jsxs("section", { className: "min-w-0 rounded-lg border bg-card", children: [_jsx("div", { className: "border-b px-4 py-3", children: _jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "truncate text-sm font-semibold text-foreground", children: selectedDream
|
|
410
|
+
? selectedDream.title || selectedDream.id
|
|
411
|
+
: "Dream detail" }), _jsx("div", { className: "mt-1 text-xs text-muted-foreground", children: selectedDream
|
|
412
|
+
? `Completed ${formatDate(selectedDream.completedAt ??
|
|
413
|
+
selectedDream.updatedAt ??
|
|
414
|
+
selectedDream.createdAt)}`
|
|
415
|
+
: "Select a pass or run a new dream." })] }), selectedDream ? (_jsxs("div", { className: "flex flex-wrap gap-1.5", children: [_jsx(StatusBadge, { status: selectedDream.status }), _jsx(Badge, { variant: "outline", children: plural(appliedProposalCount, "applied", "applied") })] })) : null] }) }), _jsxs("div", { className: "p-4", children: [_jsx(QueryState, { error: dreamDetailQuery.error, label: "Could not load dream detail" }), dreamDetailQuery.isLoading ? _jsx(ProposalSkeleton, {}) : null, !selectedDreamId && !dreamDetailQuery.isLoading ? (_jsx(EmptyPanel, { title: "Nothing selected", description: "Choose a recent dream pass or run one from candidate agent runs." })) : null, selectedDreamId &&
|
|
416
|
+
!dreamDetailQuery.isLoading &&
|
|
417
|
+
!dreamDetailQuery.error ? (_jsxs(Tabs, { defaultValue: "proposals", className: "w-full", children: [_jsxs(TabsList, { className: "grid w-full grid-cols-3", children: [_jsx(TabsTrigger, { value: "proposals", children: "Proposals" }), _jsx(TabsTrigger, { value: "report", children: "Report" }), _jsx(TabsTrigger, { value: "sources", children: "Sources" })] }), _jsx(TabsContent, { value: "proposals", className: "mt-4", children: proposals.length > 0 ? (_jsx("div", { className: "space-y-3", children: proposals.map((proposal) => (_jsx(ProposalCard, { proposal: proposal, applying: applyProposal.isPending &&
|
|
418
|
+
applyProposal.variables?.id === proposal.id, rejecting: rejectProposal.isPending &&
|
|
419
|
+
rejectProposal.variables?.id === proposal.id, onApply: () => applyProposal.mutate({
|
|
420
|
+
id: proposal.id,
|
|
421
|
+
}), onReject: (reason) => rejectProposal.mutate({
|
|
422
|
+
id: proposal.id,
|
|
423
|
+
reason,
|
|
424
|
+
}) }, proposal.id))) })) : (_jsx(EmptyPanel, { title: "No proposals", description: "This dream did not produce reviewable memory, skill, job, or instruction changes." })) }), _jsx(TabsContent, { value: "report", className: "mt-4", children: detail?.report || detail?.summary ? (_jsx(RawBlock, { value: detail.report || detail.summary || "" })) : (_jsx(EmptyPanel, { title: "No report text", description: "The dream detail action did not return a report body." })) }), _jsxs(TabsContent, { value: "sources", className: "mt-4", children: [selectedSourceHealth.length > 0 ? (_jsx("div", { className: "mb-4", children: _jsx(SourceHealthPanel, { sources: selectedSourceHealth }) })) : null, inspectedRuns.length > 0 || detail?.evidence?.length ? (_jsxs(Accordion, { type: "multiple", className: "rounded-lg border", children: [inspectedRuns.map((run, index) => (_jsxs(AccordionItem, { value: candidateId(run) || `run-${index}`, className: "px-4", children: [_jsx(AccordionTrigger, { className: "text-sm hover:no-underline", children: _jsx("span", { className: "min-w-0 truncate text-left", children: candidateLabel(run) }) }), _jsxs(AccordionContent, { className: "pb-4", children: [_jsxs("div", { className: "grid gap-2 text-xs text-muted-foreground sm:grid-cols-2", children: [_jsxs("div", { children: ["Thread:", " ", _jsx("span", { className: "font-mono text-foreground", children: run.thread?.id ?? run.threadId ?? "n/a" })] }), _jsxs("div", { children: ["Run:", " ", _jsx("span", { className: "font-mono text-foreground", children: run.runId ?? run.id })] }), _jsxs("div", { children: ["Owner: ", candidateOwner(run)] }), _jsxs("div", { children: ["Status: ", candidateStatus(run)] })] }), candidateSignals(run).length > 0 ? (_jsx("div", { className: "mt-3 flex flex-wrap gap-1.5", children: candidateSignals(run).map((signal) => (_jsx(Badge, { variant: "outline", children: signal }, signal))) })) : null] })] }, candidateId(run)))), (detail?.evidence ?? []).map((item, index) => (_jsxs(AccordionItem, { value: item.id || `evidence-${index}`, className: "px-4", children: [_jsx(AccordionTrigger, { className: "text-sm hover:no-underline", children: evidenceLabel(item, index) }), _jsx(AccordionContent, { className: "pb-4", children: _jsx(RawBlock, { value: item }) })] }, item.id || `evidence-${index}`)))] })) : (_jsx(EmptyPanel, { title: "No source runs", description: "This dream has no structured source list yet." }))] })] })) : null] })] }), _jsxs("section", { className: "rounded-lg border bg-card", children: [_jsx("div", { className: "border-b px-4 py-3", children: _jsxs("div", { children: [_jsx("div", { className: "text-sm font-semibold text-foreground", children: "Candidate runs" }), _jsx("div", { className: "mt-1 text-xs text-muted-foreground", children: "Grounded signals ready for review." })] }) }), _jsxs("div", { className: "max-h-[720px] overflow-auto p-3", children: [_jsx(QueryState, { error: candidatesQuery.error, label: "Could not load candidates" }), candidatesQuery.isLoading ? _jsx(DreamListSkeleton, {}) : null, !candidatesQuery.isLoading &&
|
|
425
|
+
!candidatesQuery.error &&
|
|
426
|
+
candidateSourceHealth.length > 0 ? (_jsx("div", { className: "mb-3", children: _jsx(SourceHealthPanel, { sources: candidateSourceHealth }) })) : null, !candidatesQuery.isLoading && !candidatesQuery.error ? (candidates.length > 0 ? (_jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: "Run" }), _jsx(TableHead, { children: "Signals" }), _jsx(TableHead, { className: "w-20 text-right", children: "Score" })] }) }), _jsx(TableBody, { children: candidates.map((candidate) => {
|
|
427
|
+
const id = candidateId(candidate);
|
|
428
|
+
const signals = candidateSignals(candidate);
|
|
429
|
+
return (_jsxs(TableRow, { children: [_jsxs(TableCell, { className: "min-w-0 py-3", children: [_jsx("div", { className: "max-w-[230px] truncate text-sm font-medium text-foreground", children: candidateLabel(candidate) }), _jsx("div", { className: "mt-1 truncate font-mono text-[11px] text-muted-foreground", children: candidate.thread?.id ??
|
|
430
|
+
candidate.threadId ??
|
|
431
|
+
candidate.runId ??
|
|
432
|
+
id }), _jsxs("div", { className: "mt-1 text-[11px] text-muted-foreground", children: [candidateOwner(candidate), " \u00B7", " ", compactDate(candidateUpdatedAt(candidate))] })] }), _jsx(TableCell, { className: "py-3", children: _jsxs("div", { className: "mt-1 flex flex-wrap gap-1", children: [_jsx(Badge, { variant: "outline", children: candidateStatus(candidate) }), signals.slice(0, 2).map((signal) => (_jsx(Badge, { variant: "secondary", children: signal }, signal)))] }) }), _jsx(TableCell, { className: "py-3 text-right text-sm tabular-nums text-muted-foreground", children: candidate.score ?? "n/a" })] }, id));
|
|
433
|
+
}) })] })) : (_jsx(EmptyPanel, { title: "No candidates", description: "No recent runs matched the dream candidate heuristics." }))) : null] })] })] })] }) }));
|
|
434
|
+
}
|
|
435
|
+
//# sourceMappingURL=dreams.js.map
|