rivet-design 0.13.4 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-variants/SessionStore.d.ts +14 -3
- package/dist/agent-variants/SessionStore.d.ts.map +1 -1
- package/dist/agent-variants/SessionStore.js +9 -1
- package/dist/agent-variants/SessionStore.js.map +1 -1
- package/dist/agent-variants/WorkerExecutorService.d.ts +140 -0
- package/dist/agent-variants/WorkerExecutorService.d.ts.map +1 -0
- package/dist/agent-variants/WorkerExecutorService.js +496 -0
- package/dist/agent-variants/WorkerExecutorService.js.map +1 -0
- package/dist/agent-variants/WorktreeOrchestrator.d.ts +24 -1
- package/dist/agent-variants/WorktreeOrchestrator.d.ts.map +1 -1
- package/dist/agent-variants/WorktreeOrchestrator.js +82 -3
- package/dist/agent-variants/WorktreeOrchestrator.js.map +1 -1
- package/dist/agent-variants/contracts.d.ts +30 -13
- package/dist/agent-variants/contracts.d.ts.map +1 -1
- package/dist/agent-variants/contracts.js +11 -4
- package/dist/agent-variants/contracts.js.map +1 -1
- package/dist/agent-variants/directionAuthoring.d.ts +36 -0
- package/dist/agent-variants/directionAuthoring.d.ts.map +1 -0
- package/dist/agent-variants/directionAuthoring.js +348 -0
- package/dist/agent-variants/directionAuthoring.js.map +1 -0
- package/dist/agent-variants/runLabel.d.ts +5 -4
- package/dist/agent-variants/runLabel.d.ts.map +1 -1
- package/dist/agent-variants/runLabel.js +16 -8
- package/dist/agent-variants/runLabel.js.map +1 -1
- package/dist/agent-variants/videoKeyframes.d.ts +19 -0
- package/dist/agent-variants/videoKeyframes.d.ts.map +1 -0
- package/dist/agent-variants/videoKeyframes.js +109 -0
- package/dist/agent-variants/videoKeyframes.js.map +1 -0
- package/dist/agent-variants/workItemBriefing.d.ts +3 -1
- package/dist/agent-variants/workItemBriefing.d.ts.map +1 -1
- package/dist/agent-variants/workItemBriefing.js +34 -2
- package/dist/agent-variants/workItemBriefing.js.map +1 -1
- package/dist/cli/commands/mcpServe.d.ts.map +1 -1
- package/dist/cli/commands/mcpServe.js +57 -25
- package/dist/cli/commands/mcpServe.js.map +1 -1
- package/dist/cli/commands/variants.d.ts.map +1 -1
- package/dist/cli/commands/variants.js +294 -4
- package/dist/cli/commands/variants.js.map +1 -1
- package/dist/cli/hostWorkNextAction.d.ts.map +1 -1
- package/dist/cli/hostWorkNextAction.js +6 -1
- package/dist/cli/hostWorkNextAction.js.map +1 -1
- package/dist/cli/router.js +2 -2
- package/dist/cli/router.js.map +1 -1
- package/dist/hosts/workerDefaults.d.ts +42 -0
- package/dist/hosts/workerDefaults.d.ts.map +1 -1
- package/dist/hosts/workerDefaults.js +40 -1
- package/dist/hosts/workerDefaults.js.map +1 -1
- package/dist/mcp/changeBatchClassification.d.ts +2 -0
- package/dist/mcp/changeBatchClassification.d.ts.map +1 -1
- package/dist/mcp/changeBatchClassification.js +5 -0
- package/dist/mcp/changeBatchClassification.js.map +1 -1
- package/dist/routes/agentVariants.d.ts.map +1 -1
- package/dist/routes/agentVariants.js +34 -2
- package/dist/routes/agentVariants.js.map +1 -1
- package/dist/routes/emptyStatePage.d.ts +14 -0
- package/dist/routes/emptyStatePage.d.ts.map +1 -0
- package/dist/routes/emptyStatePage.js +601 -0
- package/dist/routes/emptyStatePage.js.map +1 -0
- package/dist/routes/static.d.ts.map +1 -1
- package/dist/routes/static.js +2 -73
- package/dist/routes/static.js.map +1 -1
- package/dist/services/VariantGenerationService.d.ts +36 -1
- package/dist/services/VariantGenerationService.d.ts.map +1 -1
- package/dist/services/VariantGenerationService.js +334 -13
- package/dist/services/VariantGenerationService.js.map +1 -1
- package/dist/services/VariantRunService.d.ts +8 -0
- package/dist/services/VariantRunService.d.ts.map +1 -1
- package/dist/services/VariantRunService.js +31 -6
- package/dist/services/VariantRunService.js.map +1 -1
- package/dist/services/VariantsRuntime.d.ts.map +1 -1
- package/dist/services/VariantsRuntime.js +9 -0
- package/dist/services/VariantsRuntime.js.map +1 -1
- package/dist/types/change-request-types.d.ts +19 -0
- package/dist/types/change-request-types.d.ts.map +1 -1
- package/dist/utils/skills/claude-skill.d.ts +2 -2
- package/dist/utils/skills/claude-skill.d.ts.map +1 -1
- package/dist/utils/skills/claude-skill.js +1 -1
- package/dist/utils/skills/cli-guidance.d.ts +2 -2
- package/dist/utils/skills/cli-guidance.d.ts.map +1 -1
- package/dist/utils/skills/cli-guidance.js +11 -8
- package/dist/utils/skills/cli-guidance.js.map +1 -1
- package/dist/utils/skills/cursor-rules.d.ts +2 -2
- package/dist/utils/skills/cursor-rules.d.ts.map +1 -1
- package/dist/utils/skills/cursor-rules.js +1 -1
- package/package.json +1 -1
- package/src/ui/dist/assets/main-CobdEReL.css +1 -0
- package/src/ui/dist/assets/main-DJjaeK_0.js +422 -0
- package/src/ui/dist/index.html +2 -2
- package/src/ui/dist/assets/main-Dyos9I29.css +0 -1
- package/src/ui/dist/assets/main-T3U4Gt16.js +0 -419
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emptyStatePage.js","sourceRoot":"","sources":["../../src/routes/emptyStatePage.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;GAWG;AACI,MAAM,gBAAgB,GAAG,GAAW,EAAE,CAAC,gBAAgB,CAAC;AAAlD,QAAA,gBAAgB,oBAAkC;AAE/D,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAskBxB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"static.d.ts","sourceRoot":"","sources":["../../src/routes/static.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAqB,MAAM,EAAE,MAAM,SAAS,CAAC;AAG7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"static.d.ts","sourceRoot":"","sources":["../../src/routes/static.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAqB,MAAM,EAAE,MAAM,SAAS,CAAC;AAG7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAOlE,KAAK,mBAAmB,GAAG;IACzB,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,2BAA2B,CAAC,EAAE,MAAM,CAAC;CACtC,CAAC;AAGF;;GAEG;AACH,eAAO,MAAM,kBAAkB,GAC7B,eAAe,iBAAiB,EAChC,cAAc,MAAM,EACpB,UAAS,mBAAwB,KAChC,MAqDF,CAAC"}
|
package/dist/routes/static.js
CHANGED
|
@@ -42,79 +42,8 @@ const path_1 = __importDefault(require("path"));
|
|
|
42
42
|
const fs_1 = __importDefault(require("fs"));
|
|
43
43
|
const logger_1 = require("../utils/logger");
|
|
44
44
|
const preview_bridge_1 = require("../proxy-middleware/preview-bridge");
|
|
45
|
+
const emptyStatePage_1 = require("./emptyStatePage");
|
|
45
46
|
const log = (0, logger_1.createLogger)('StaticRoutes');
|
|
46
|
-
/** Renders a friendly HTML page when the project has no entry file yet. */
|
|
47
|
-
const renderEmptyState = (entryFileName) => `<!DOCTYPE html>
|
|
48
|
-
<html lang="en">
|
|
49
|
-
<head>
|
|
50
|
-
<meta charset="UTF-8" />
|
|
51
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
52
|
-
<title>No entry file</title>
|
|
53
|
-
<style>
|
|
54
|
-
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
55
|
-
body {
|
|
56
|
-
min-height: 100vh;
|
|
57
|
-
display: flex;
|
|
58
|
-
align-items: center;
|
|
59
|
-
justify-content: center;
|
|
60
|
-
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
61
|
-
background: #0a0a0b;
|
|
62
|
-
color: #e4e4e7;
|
|
63
|
-
}
|
|
64
|
-
.container {
|
|
65
|
-
text-align: center;
|
|
66
|
-
max-width: 420px;
|
|
67
|
-
padding: 2rem;
|
|
68
|
-
}
|
|
69
|
-
.icon {
|
|
70
|
-
width: 48px;
|
|
71
|
-
height: 48px;
|
|
72
|
-
margin: 0 auto 1.25rem;
|
|
73
|
-
border-radius: 12px;
|
|
74
|
-
background: #18181b;
|
|
75
|
-
border: 1px solid #27272a;
|
|
76
|
-
display: flex;
|
|
77
|
-
align-items: center;
|
|
78
|
-
justify-content: center;
|
|
79
|
-
}
|
|
80
|
-
.icon svg { width: 24px; height: 24px; color: #71717a; }
|
|
81
|
-
h1 {
|
|
82
|
-
font-size: 1.125rem;
|
|
83
|
-
font-weight: 600;
|
|
84
|
-
margin-bottom: 0.5rem;
|
|
85
|
-
color: #fafafa;
|
|
86
|
-
}
|
|
87
|
-
p {
|
|
88
|
-
font-size: 0.875rem;
|
|
89
|
-
line-height: 1.5;
|
|
90
|
-
color: #a1a1aa;
|
|
91
|
-
}
|
|
92
|
-
code {
|
|
93
|
-
display: inline-block;
|
|
94
|
-
margin-top: 0.75rem;
|
|
95
|
-
padding: 0.25rem 0.625rem;
|
|
96
|
-
background: #18181b;
|
|
97
|
-
border: 1px solid #27272a;
|
|
98
|
-
border-radius: 6px;
|
|
99
|
-
font-family: "SF Mono", "Fira Code", monospace;
|
|
100
|
-
font-size: 0.8125rem;
|
|
101
|
-
color: #d4d4d8;
|
|
102
|
-
}
|
|
103
|
-
</style>
|
|
104
|
-
</head>
|
|
105
|
-
<body>
|
|
106
|
-
<div class="container">
|
|
107
|
-
<div class="icon">
|
|
108
|
-
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
109
|
-
<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m2.25 0H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z" />
|
|
110
|
-
</svg>
|
|
111
|
-
</div>
|
|
112
|
-
<h1>No entry file found</h1>
|
|
113
|
-
<p>This project doesn\u2019t have an entry file yet. Create one to get started.</p>
|
|
114
|
-
<code>${entryFileName}</code>
|
|
115
|
-
</div>
|
|
116
|
-
</body>
|
|
117
|
-
</html>`;
|
|
118
47
|
/**
|
|
119
48
|
* Create routes for serving static files
|
|
120
49
|
*/
|
|
@@ -137,7 +66,7 @@ const createStaticRoutes = (staticService, _projectPath, options = {}) => {
|
|
|
137
66
|
res.sendFile(entryFileName, { root: basePath });
|
|
138
67
|
};
|
|
139
68
|
const sendEmptyState = (res) => {
|
|
140
|
-
res.status(200).type('html').send(renderEmptyState(
|
|
69
|
+
res.status(200).type('html').send((0, emptyStatePage_1.renderEmptyState)());
|
|
141
70
|
};
|
|
142
71
|
// Serve the entry point at /static/ (root of static site)
|
|
143
72
|
router.get('/static', (_req, res) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"static.js","sourceRoot":"","sources":["../../src/routes/static.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,mDAA6D;AAC7D,gDAAwB;AACxB,4CAAoB;AAEpB,4CAA+C;AAC/C,uEAAyE;
|
|
1
|
+
{"version":3,"file":"static.js","sourceRoot":"","sources":["../../src/routes/static.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,mDAA6D;AAC7D,gDAAwB;AACxB,4CAAoB;AAEpB,4CAA+C;AAC/C,uEAAyE;AACzE,qDAAoD;AAEpD,MAAM,GAAG,GAAG,IAAA,qBAAY,EAAC,cAAc,CAAC,CAAC;AAQzC;;GAEG;AACI,MAAM,kBAAkB,GAAG,CAChC,aAAgC,EAChC,YAAoB,EACpB,UAA+B,EAAE,EACzB,EAAE;IACV,MAAM,MAAM,GAAG,IAAA,gBAAM,GAAE,CAAC;IAExB,4CAA4C;IAC5C,MAAM,QAAQ,GAAG,aAAa,CAAC,WAAW,EAAE,CAAC;IAC7C,MAAM,aAAa,GAAG,aAAa,CAAC,gBAAgB,EAAE,CAAC;IAEvD,GAAG,CAAC,IAAI,CAAC,8BAA8B,QAAQ,EAAE,CAAC,CAAC;IACnD,GAAG,CAAC,IAAI,CAAC,eAAe,aAAa,EAAE,CAAC,CAAC;IAEzC,MAAM,SAAS,GAAG,CAAC,GAAa,EAAE,SAAiB,EAAE,EAAE;QACrD,IAAI,OAAO,CAAC,sBAAsB,EAAE,CAAC;YACnC,GAAG;iBACA,IAAI,CAAC,MAAM,CAAC;iBACZ,IAAI,CACH,IAAA,oCAAmB,EAAC,YAAE,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE;gBACtD,oBAAoB,EAAE,OAAO,CAAC,2BAA2B;aAC1D,CAAC,CACH,CAAC;YACJ,OAAO;QACT,CAAC;QACD,GAAG,CAAC,QAAQ,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;IAClD,CAAC,CAAC;IAEF,MAAM,cAAc,GAAG,CAAC,GAAa,EAAE,EAAE;QACvC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAA,iCAAgB,GAAE,CAAC,CAAC;IACxD,CAAC,CAAC;IAEF,0DAA0D;IAC1D,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,IAAa,EAAE,GAAa,EAAE,EAAE;QACrD,MAAM,SAAS,GAAG,cAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;QACrD,GAAG,CAAC,KAAK,CAAC,wBAAwB,SAAS,EAAE,CAAC,CAAC;QAC/C,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC9B,cAAc,CAAC,GAAG,CAAC,CAAC;YACpB,OAAO;QACT,CAAC;QACD,SAAS,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,IAAa,EAAE,GAAa,EAAE,EAAE;QACtD,MAAM,SAAS,GAAG,cAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;QACrD,GAAG,CAAC,KAAK,CAAC,wBAAwB,SAAS,EAAE,CAAC,CAAC;QAC/C,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC9B,cAAc,CAAC,GAAG,CAAC,CAAC;YACpB,OAAO;QACT,CAAC;QACD,SAAS,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,+BAA+B;IAC/B,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,iBAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEhD,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAzDW,QAAA,kBAAkB,sBAyD7B"}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { AgentVariantsOrchestrator } from '../agent-variants';
|
|
2
2
|
import type { ChangeRequest } from '../types/change-request-types';
|
|
3
|
+
import { BrowserAgentClient } from './BrowserAgentClient';
|
|
4
|
+
import { GatewayClient } from './GatewayClient';
|
|
3
5
|
import { SessionBridgeService } from './SessionBridgeService';
|
|
6
|
+
import { type WorkerExecutorService } from '../agent-variants/WorkerExecutorService';
|
|
4
7
|
export type StaticPreviewWorkItemRunner = {
|
|
5
8
|
runWorkItems: (args: {
|
|
6
9
|
sessionId: string;
|
|
@@ -16,6 +19,15 @@ export type VariantGenerationServiceOptions = {
|
|
|
16
19
|
staticPreviewRunner?: StaticPreviewWorkItemRunner;
|
|
17
20
|
projectPath?: string;
|
|
18
21
|
createSessionId?: () => string;
|
|
22
|
+
/** Server-side worker executor (RIVET_EXECUTOR=1). */
|
|
23
|
+
executor?: WorkerExecutorService;
|
|
24
|
+
/** LLM gateway for server-side direction authoring (tests inject a fake). */
|
|
25
|
+
gateway?: Pick<GatewayClient, 'sendToolUse'>;
|
|
26
|
+
/** Browser agent for server-side reference-page evidence capture. */
|
|
27
|
+
browserAgent?: Pick<BrowserAgentClient, 'captureDesignEvidence'>;
|
|
28
|
+
telemetry?: {
|
|
29
|
+
track(event: string, props?: Record<string, unknown>): void;
|
|
30
|
+
};
|
|
19
31
|
};
|
|
20
32
|
export type VariantRequestResult = {
|
|
21
33
|
success: boolean;
|
|
@@ -34,12 +46,35 @@ export declare class VariantGenerationService {
|
|
|
34
46
|
private staticPreviewRunner;
|
|
35
47
|
private projectPath;
|
|
36
48
|
private createSessionId;
|
|
49
|
+
private executor?;
|
|
50
|
+
private gateway;
|
|
51
|
+
private browserAgent;
|
|
52
|
+
private telemetry?;
|
|
37
53
|
constructor(options: VariantGenerationServiceOptions);
|
|
38
54
|
/**
|
|
39
55
|
* @effect Starts an inline variants session and leases each work item to the host agent session.
|
|
40
56
|
*/
|
|
41
57
|
processVariantRequest(request: ChangeRequest): Promise<VariantRequestResult>;
|
|
42
|
-
/**
|
|
58
|
+
/**
|
|
59
|
+
* Instant slice of fresh reference prep: uploaded images pass straight
|
|
60
|
+
* through to both the context bundle and the direction author.
|
|
61
|
+
*/
|
|
62
|
+
private prepareUploadedImages;
|
|
63
|
+
/**
|
|
64
|
+
* Slow slice of fresh reference prep, run CONCURRENTLY with direction
|
|
65
|
+
* authoring: reference pages render for design evidence + a screenshot,
|
|
66
|
+
* reference videos sample into keyframes. All of it lands in the context
|
|
67
|
+
* bundle the implementation workers Read natively; the direction author
|
|
68
|
+
* only sees lightweight notes (it steers, the workers look). Every
|
|
69
|
+
* failure degrades to a textual note — prep never blocks the run.
|
|
70
|
+
*/
|
|
71
|
+
private prepareRemoteReferences;
|
|
72
|
+
/** Lightweight reference notes the direction author sees immediately —
|
|
73
|
+
* the rendered evidence itself goes to the workers, not the author. */
|
|
74
|
+
private static referenceNotesFor;
|
|
75
|
+
/** @effect Starts a fresh-project variants session; when the host sends no
|
|
76
|
+
* briefs, Rivet prepares reference context and authors the directions
|
|
77
|
+
* server-side so workers spawn without any host deliberation. */
|
|
43
78
|
private processFreshVariantRequest;
|
|
44
79
|
}
|
|
45
80
|
//# sourceMappingURL=VariantGenerationService.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VariantGenerationService.d.ts","sourceRoot":"","sources":["../../src/services/VariantGenerationService.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"VariantGenerationService.d.ts","sourceRoot":"","sources":["../../src/services/VariantGenerationService.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,yBAAyB,EAAU,MAAM,mBAAmB,CAAC;AAU3E,OAAO,KAAK,EACV,aAAa,EAId,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,kBAAkB,EAEnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,aAAa,EAGd,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,yCAAyC,CAAC;AAKjD,MAAM,MAAM,2BAA2B,GAAG;IACxC,YAAY,EAAE,CAAC,IAAI,EAAE;QACnB,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,EAAE,CAAC;KACvB,KAAK,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACtD,CAAC;AAEF,MAAM,MAAM,+BAA+B,GAAG;IAC5C,MAAM,EAAE,oBAAoB,CAAC;IAC7B,YAAY,EAAE,yBAAyB,CAAC;IACxC,mBAAmB,CAAC,EAAE,2BAA2B,CAAC;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,MAAM,CAAC;IAC/B,sDAAsD;IACtD,QAAQ,CAAC,EAAE,qBAAqB,CAAC;IACjC,6EAA6E;IAC7E,OAAO,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;IAC7C,qEAAqE;IACrE,YAAY,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,uBAAuB,CAAC,CAAC;IACjE,SAAS,CAAC,EAAE;QAAE,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;KAAE,CAAC;CAC7E,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAsJF;;;;;;GAMG;AACH,qBAAa,wBAAwB;IACnC,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,YAAY,CAA4B;IAChD,OAAO,CAAC,mBAAmB,CAA0C;IACrE,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,eAAe,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,CAAwB;IACzC,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,YAAY,CAAoD;IACxE,OAAO,CAAC,SAAS,CAAC,CAA+C;gBAErD,OAAO,EAAE,+BAA+B;IAYpD;;OAEG;IACG,qBAAqB,CACzB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,oBAAoB,CAAC;IAmIhC;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAkB7B;;;;;;;OAOG;YACW,uBAAuB;IA0FrC;4EACwE;IACxE,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAehC;;sEAEkE;YACpD,0BAA0B;CA+IzC"}
|
|
@@ -1,11 +1,54 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
36
|
exports.VariantGenerationService = void 0;
|
|
37
|
+
const child_process_1 = require("child_process");
|
|
4
38
|
const crypto_1 = require("crypto");
|
|
39
|
+
const fs = __importStar(require("fs"));
|
|
40
|
+
const os = __importStar(require("os"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
5
42
|
const index_core_1 = require("../index-core");
|
|
6
43
|
const changeBatchClassification_1 = require("../mcp/changeBatchClassification");
|
|
44
|
+
const directionAuthoring_1 = require("../agent-variants/directionAuthoring");
|
|
7
45
|
const generatedDestination_1 = require("../agent-variants/generatedDestination");
|
|
46
|
+
const runPlan_1 = require("../agent-variants/runPlan");
|
|
8
47
|
const variantContext_1 = require("../agent-variants/variantContext");
|
|
48
|
+
const videoKeyframes_1 = require("../agent-variants/videoKeyframes");
|
|
49
|
+
const BrowserAgentClient_1 = require("./BrowserAgentClient");
|
|
50
|
+
const GatewayClient_1 = require("./GatewayClient");
|
|
51
|
+
const WorkerExecutorService_1 = require("../agent-variants/WorkerExecutorService");
|
|
9
52
|
const log = (0, index_core_1.createLogger)('VariantGenerationService');
|
|
10
53
|
const MAX_RELEVANT_FILES = 12;
|
|
11
54
|
const hasWhitespace = (value) => /\s/.test(value);
|
|
@@ -55,6 +98,77 @@ const buildInlineVariantImageContextInputs = (images) => (images ?? []).map((dat
|
|
|
55
98
|
userIntent: 'Inline variant visual reference',
|
|
56
99
|
}));
|
|
57
100
|
const isZeroToOneRequest = (comment) => comment.variantRequest?.mode === 'zero_to_one';
|
|
101
|
+
const MAX_REFERENCE_PAGES = 3;
|
|
102
|
+
const MAX_REFERENCE_VIDEOS = 2;
|
|
103
|
+
const MAX_AUTHOR_IMAGES = 4;
|
|
104
|
+
/** Skip oversized payloads on the direction-author call — the workers still
|
|
105
|
+
* see the full file via the context bundle. */
|
|
106
|
+
const MAX_AUTHOR_IMAGE_BASE64_LENGTH = 5 * 1024 * 1024;
|
|
107
|
+
const MAX_EVIDENCE_ROOT_VARIABLES = 24;
|
|
108
|
+
const DATA_URL_PATTERN = /^data:(image\/(?:png|jpeg|webp|gif));base64,(.+)$/s;
|
|
109
|
+
const parseDataUrlImage = (dataUrl) => {
|
|
110
|
+
const match = DATA_URL_PATTERN.exec(dataUrl);
|
|
111
|
+
if (!match)
|
|
112
|
+
return undefined;
|
|
113
|
+
return {
|
|
114
|
+
mediaType: match[1],
|
|
115
|
+
data: match[2],
|
|
116
|
+
};
|
|
117
|
+
};
|
|
118
|
+
/** Above this, direction-author images get downscaled — the author only
|
|
119
|
+
* steers (palette/type/energy read fine at 1000px) and multi-MB payloads
|
|
120
|
+
* add seconds of upload + vision latency to the intake critical path. */
|
|
121
|
+
const AUTHOR_IMAGE_DOWNSCALE_THRESHOLD = 700_000;
|
|
122
|
+
/** Best-effort downscale via macOS `sips` (no image dependency in the
|
|
123
|
+
* server). Any failure returns the original — never blocks intake. */
|
|
124
|
+
const downscaleAuthorImage = (image) => {
|
|
125
|
+
if (image.data.length <= AUTHOR_IMAGE_DOWNSCALE_THRESHOLD)
|
|
126
|
+
return image;
|
|
127
|
+
const ext = image.mediaType === 'image/png' ? '.png' : '.jpg';
|
|
128
|
+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'rivet-author-img-'));
|
|
129
|
+
const filePath = path.join(dir, `ref${ext}`);
|
|
130
|
+
try {
|
|
131
|
+
fs.writeFileSync(filePath, Buffer.from(image.data, 'base64'));
|
|
132
|
+
(0, child_process_1.execFileSync)('sips', ['-Z', '1000', filePath], {
|
|
133
|
+
stdio: 'ignore',
|
|
134
|
+
timeout: 10_000,
|
|
135
|
+
});
|
|
136
|
+
const resized = fs.readFileSync(filePath).toString('base64');
|
|
137
|
+
return resized.length < image.data.length
|
|
138
|
+
? { ...image, data: resized }
|
|
139
|
+
: image;
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
return image;
|
|
143
|
+
}
|
|
144
|
+
finally {
|
|
145
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
/** Compact design-token summary of rendered page evidence: one line for the
|
|
149
|
+
* direction author, a fuller block for the workers' context bundle. */
|
|
150
|
+
const summarizeEvidence = (url, evidence) => {
|
|
151
|
+
const fonts = evidence.fonts.slice(0, 6).join(', ') || 'none observed';
|
|
152
|
+
const rootVariables = Object.entries(evidence.rootVariables).slice(0, MAX_EVIDENCE_ROOT_VARIABLES);
|
|
153
|
+
const tokens = rootVariables
|
|
154
|
+
.map(([name, value]) => `${name}: ${value}`)
|
|
155
|
+
.join('; ');
|
|
156
|
+
const note = `Page ${url} (rendered, ${evidence.evidenceStatus}) — fonts: ${fonts}${tokens ? `; :root tokens: ${tokens}` : ''}`;
|
|
157
|
+
const bundleText = [
|
|
158
|
+
`# Rendered design evidence — ${url}`,
|
|
159
|
+
`status: ${evidence.evidenceStatus}`,
|
|
160
|
+
`fonts: ${fonts}`,
|
|
161
|
+
rootVariables.length
|
|
162
|
+
? `:root variables:\n${rootVariables.map(([name, value]) => ` ${name}: ${value}`).join('\n')}`
|
|
163
|
+
: ':root variables: none observed',
|
|
164
|
+
Object.keys(evidence.elementStyles).length
|
|
165
|
+
? `element styles:\n${JSON.stringify(evidence.elementStyles, null, 2).slice(0, 6000)}`
|
|
166
|
+
: '',
|
|
167
|
+
]
|
|
168
|
+
.filter(Boolean)
|
|
169
|
+
.join('\n\n');
|
|
170
|
+
return { note, bundleText };
|
|
171
|
+
};
|
|
58
172
|
/**
|
|
59
173
|
* Server-owned variant generation engine. One service, every initiation path:
|
|
60
174
|
* element Vary requests from the editor, agent-initiated instruction-only
|
|
@@ -68,12 +182,20 @@ class VariantGenerationService {
|
|
|
68
182
|
staticPreviewRunner;
|
|
69
183
|
projectPath;
|
|
70
184
|
createSessionId;
|
|
185
|
+
executor;
|
|
186
|
+
gateway;
|
|
187
|
+
browserAgent;
|
|
188
|
+
telemetry;
|
|
71
189
|
constructor(options) {
|
|
72
190
|
this.bridge = options.bridge;
|
|
73
191
|
this.orchestrator = options.orchestrator;
|
|
74
192
|
this.staticPreviewRunner = options.staticPreviewRunner;
|
|
75
193
|
this.projectPath = options.projectPath;
|
|
76
194
|
this.createSessionId = options.createSessionId ?? crypto_1.randomUUID;
|
|
195
|
+
this.executor = options.executor;
|
|
196
|
+
this.gateway = options.gateway ?? new GatewayClient_1.GatewayClient();
|
|
197
|
+
this.browserAgent = options.browserAgent ?? new BrowserAgentClient_1.BrowserAgentClient();
|
|
198
|
+
this.telemetry = options.telemetry;
|
|
77
199
|
}
|
|
78
200
|
/**
|
|
79
201
|
* @effect Starts an inline variants session and leases each work item to the host agent session.
|
|
@@ -127,6 +249,12 @@ class VariantGenerationService {
|
|
|
127
249
|
const startResult = await this.orchestrator.startUnified({
|
|
128
250
|
prompt: comment.instruction,
|
|
129
251
|
count,
|
|
252
|
+
...(comment.variantRequest?.runLabel
|
|
253
|
+
? { runLabel: comment.variantRequest.runLabel }
|
|
254
|
+
: {}),
|
|
255
|
+
...(comment.variantRequest?.fidelity
|
|
256
|
+
? { fidelity: comment.variantRequest.fidelity }
|
|
257
|
+
: {}),
|
|
130
258
|
...(briefs ? { briefs } : {}),
|
|
131
259
|
target: deriveTarget(comment.element),
|
|
132
260
|
...(sessionId ? { sessionId } : {}),
|
|
@@ -137,7 +265,9 @@ class VariantGenerationService {
|
|
|
137
265
|
...(variantContext ? { variantContext } : {}),
|
|
138
266
|
},
|
|
139
267
|
...(relevantFiles.length > 0 ? { relevantFiles } : {}),
|
|
140
|
-
leaseOwner:
|
|
268
|
+
leaseOwner: this.executor?.isRuntimeAvailable()
|
|
269
|
+
? WorkerExecutorService_1.EXECUTOR_LEASE_OWNER
|
|
270
|
+
: 'rivet-host-agent',
|
|
141
271
|
allowAccumulate: true,
|
|
142
272
|
...(sourceVariantId ? { sourceVariantId } : {}),
|
|
143
273
|
});
|
|
@@ -157,7 +287,17 @@ class VariantGenerationService {
|
|
|
157
287
|
this.bridge.setStatus('READY');
|
|
158
288
|
return { success: false, error };
|
|
159
289
|
}
|
|
160
|
-
this.
|
|
290
|
+
if (this.executor?.isRuntimeAvailable()) {
|
|
291
|
+
this.bridge.reportFeedback(`Rivet is building ${leasedItems.length} direction(s) with its own workers — watch status for progress.`);
|
|
292
|
+
void this.executor
|
|
293
|
+
.run(startResult.sessionId, leasedItems.map((item) => item.id), startResult.leaseId
|
|
294
|
+
? { leaseId: startResult.leaseId, items: leasedItems }
|
|
295
|
+
: undefined)
|
|
296
|
+
.catch((error) => log.warn('worker executor run failed', error));
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
this.bridge.reportFeedback(`Host agent work is ready for ${leasedItems.length} inline variants.`);
|
|
300
|
+
}
|
|
161
301
|
this.bridge.setStatus('READY');
|
|
162
302
|
return { success: true };
|
|
163
303
|
}
|
|
@@ -170,7 +310,115 @@ class VariantGenerationService {
|
|
|
170
310
|
return { success: false, error: message };
|
|
171
311
|
}
|
|
172
312
|
}
|
|
173
|
-
/**
|
|
313
|
+
/**
|
|
314
|
+
* Instant slice of fresh reference prep: uploaded images pass straight
|
|
315
|
+
* through to both the context bundle and the direction author.
|
|
316
|
+
*/
|
|
317
|
+
prepareUploadedImages(comment) {
|
|
318
|
+
const userContextInputs = [];
|
|
319
|
+
const authorImages = [];
|
|
320
|
+
for (const input of buildInlineVariantImageContextInputs(comment.images)) {
|
|
321
|
+
userContextInputs.push(input);
|
|
322
|
+
if (input.transport !== 'upload')
|
|
323
|
+
continue;
|
|
324
|
+
if (authorImages.length >= MAX_AUTHOR_IMAGES)
|
|
325
|
+
continue;
|
|
326
|
+
const parsed = parseDataUrlImage(input.dataUrl);
|
|
327
|
+
if (parsed && parsed.data.length <= MAX_AUTHOR_IMAGE_BASE64_LENGTH) {
|
|
328
|
+
authorImages.push(downscaleAuthorImage(parsed));
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
return { userContextInputs, authorImages };
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Slow slice of fresh reference prep, run CONCURRENTLY with direction
|
|
335
|
+
* authoring: reference pages render for design evidence + a screenshot,
|
|
336
|
+
* reference videos sample into keyframes. All of it lands in the context
|
|
337
|
+
* bundle the implementation workers Read natively; the direction author
|
|
338
|
+
* only sees lightweight notes (it steers, the workers look). Every
|
|
339
|
+
* failure degrades to a textual note — prep never blocks the run.
|
|
340
|
+
*/
|
|
341
|
+
async prepareRemoteReferences(comment) {
|
|
342
|
+
const userContextInputs = [];
|
|
343
|
+
const clipLabel = (label) => label.length <= 80 ? label : `${label.slice(0, 77)}...`;
|
|
344
|
+
const pages = (comment.variantRequest?.referencePages ?? []).slice(0, MAX_REFERENCE_PAGES);
|
|
345
|
+
const videos = (comment.variantRequest?.referenceVideos ?? []).slice(0, MAX_REFERENCE_VIDEOS);
|
|
346
|
+
const [pageResults, videoResults] = await Promise.all([
|
|
347
|
+
Promise.all(pages.map(async (page) => ({
|
|
348
|
+
page,
|
|
349
|
+
result: await this.browserAgent
|
|
350
|
+
.captureDesignEvidence(page.url, { screenshot: true })
|
|
351
|
+
.catch((error) => ({
|
|
352
|
+
ok: false,
|
|
353
|
+
available: true,
|
|
354
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
355
|
+
})),
|
|
356
|
+
}))),
|
|
357
|
+
Promise.all(videos.map(async (video) => ({
|
|
358
|
+
video,
|
|
359
|
+
result: await (0, videoKeyframes_1.extractVideoKeyframes)(video.path),
|
|
360
|
+
}))),
|
|
361
|
+
]);
|
|
362
|
+
for (const { page, result } of pageResults) {
|
|
363
|
+
if (!result.ok) {
|
|
364
|
+
log.warn(`reference page ${page.url} could not be rendered (${result.reason})`);
|
|
365
|
+
continue;
|
|
366
|
+
}
|
|
367
|
+
const { bundleText } = summarizeEvidence(page.url, result.evidence);
|
|
368
|
+
userContextInputs.push({
|
|
369
|
+
transport: 'text',
|
|
370
|
+
content: bundleText.slice(0, 49_000),
|
|
371
|
+
label: clipLabel(`Design evidence — ${page.url}`),
|
|
372
|
+
userIntent: 'rendered page design evidence',
|
|
373
|
+
});
|
|
374
|
+
if (result.evidence.screenshotBase64) {
|
|
375
|
+
userContextInputs.push({
|
|
376
|
+
transport: 'upload',
|
|
377
|
+
dataUrl: `data:image/png;base64,${result.evidence.screenshotBase64}`,
|
|
378
|
+
label: clipLabel(`Reference page screenshot — ${page.url}`),
|
|
379
|
+
userIntent: 'page reference',
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
for (const { video, result } of videoResults) {
|
|
384
|
+
if (!result.ok) {
|
|
385
|
+
log.warn(`video reference ${video.path} could not be sampled (${result.reason})`);
|
|
386
|
+
continue;
|
|
387
|
+
}
|
|
388
|
+
result.framePaths.forEach((framePath, index) => {
|
|
389
|
+
try {
|
|
390
|
+
const dataUrl = `data:image/png;base64,${fs
|
|
391
|
+
.readFileSync(framePath)
|
|
392
|
+
.toString('base64')}`;
|
|
393
|
+
userContextInputs.push({
|
|
394
|
+
transport: 'upload',
|
|
395
|
+
dataUrl,
|
|
396
|
+
label: clipLabel(`Video keyframe ${index + 1} of ${result.framePaths.length}${video.note ? ` — ${video.note}` : ''}`),
|
|
397
|
+
userIntent: 'motion reference keyframe (chronological)',
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
catch {
|
|
401
|
+
// Frame unreadable — the remaining frames still carry the motion.
|
|
402
|
+
}
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
return { userContextInputs };
|
|
406
|
+
}
|
|
407
|
+
/** Lightweight reference notes the direction author sees immediately —
|
|
408
|
+
* the rendered evidence itself goes to the workers, not the author. */
|
|
409
|
+
static referenceNotesFor(comment) {
|
|
410
|
+
const notes = [];
|
|
411
|
+
for (const page of comment.variantRequest?.referencePages ?? []) {
|
|
412
|
+
notes.push(`Reference page ${page.url}${page.note ? ` (${page.note})` : ''} — being rendered for the implementers, who will see its full design evidence and screenshot. Direct each direction to derive concrete tokens (palette, type, spacing, motion) from that rendered evidence.`);
|
|
413
|
+
}
|
|
414
|
+
for (const video of comment.variantRequest?.referenceVideos ?? []) {
|
|
415
|
+
notes.push(`Reference video${video.note ? ` (${video.note})` : ''} — being sampled into chronological keyframes for the implementers. Direct each direction to derive motion timing and choreography from those keyframes.`);
|
|
416
|
+
}
|
|
417
|
+
return notes;
|
|
418
|
+
}
|
|
419
|
+
/** @effect Starts a fresh-project variants session; when the host sends no
|
|
420
|
+
* briefs, Rivet prepares reference context and authors the directions
|
|
421
|
+
* server-side so workers spawn without any host deliberation. */
|
|
174
422
|
async processFreshVariantRequest(args) {
|
|
175
423
|
const contextProjectPath = this.projectPath ?? this.bridge.getProjectPath();
|
|
176
424
|
if (!contextProjectPath) {
|
|
@@ -188,24 +436,97 @@ class VariantGenerationService {
|
|
|
188
436
|
this.bridge.setStatus('READY');
|
|
189
437
|
return { success: false, error: destination.message };
|
|
190
438
|
}
|
|
439
|
+
// Reference media rides the same context-bundle machinery as inline
|
|
440
|
+
// existing-project variants: copied into the bundle, surfaced to every
|
|
441
|
+
// worker (host or executor) as briefing contextFiles they Read natively.
|
|
442
|
+
// The slow prep (page render, video keyframes) runs CONCURRENTLY with
|
|
443
|
+
// direction authoring — the author steers from uploaded images + notes;
|
|
444
|
+
// the workers get the full rendered evidence.
|
|
445
|
+
const uploaded = this.prepareUploadedImages(args.comment);
|
|
446
|
+
const remotePrepPromise = this.prepareRemoteReferences(args.comment);
|
|
447
|
+
let briefs = args.comment.variantRequest?.briefs;
|
|
448
|
+
let runLabel = args.comment.variantRequest?.runLabel;
|
|
449
|
+
let authorPromise;
|
|
450
|
+
if (!briefs?.length) {
|
|
451
|
+
const referenceNotes = VariantGenerationService.referenceNotesFor(args.comment);
|
|
452
|
+
authorPromise = (0, directionAuthoring_1.authorDirections)(this.gateway, {
|
|
453
|
+
prompt: args.comment.instruction,
|
|
454
|
+
count: args.count,
|
|
455
|
+
...(uploaded.authorImages.length
|
|
456
|
+
? { images: uploaded.authorImages }
|
|
457
|
+
: {}),
|
|
458
|
+
...(referenceNotes.length ? { referenceNotes } : {}),
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
const [remotePrep, authored] = await Promise.all([
|
|
462
|
+
remotePrepPromise,
|
|
463
|
+
authorPromise,
|
|
464
|
+
]);
|
|
465
|
+
if (authored) {
|
|
466
|
+
briefs = authored.briefs;
|
|
467
|
+
runLabel = runLabel ?? authored.runLabel;
|
|
468
|
+
this.telemetry?.track('agent_variants.directions_authored', {
|
|
469
|
+
source: 'server',
|
|
470
|
+
authorSource: authored.source,
|
|
471
|
+
durationMs: authored.durationMs,
|
|
472
|
+
count: authored.briefs.length,
|
|
473
|
+
referenceImages: uploaded.authorImages.length,
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
const userContextInputs = [
|
|
477
|
+
...uploaded.userContextInputs,
|
|
478
|
+
...remotePrep.userContextInputs,
|
|
479
|
+
];
|
|
480
|
+
let sessionId;
|
|
481
|
+
let variantContext;
|
|
482
|
+
if (userContextInputs.length > 0) {
|
|
483
|
+
sessionId = this.createSessionId();
|
|
484
|
+
variantContext = (0, variantContext_1.createVariantContextBundle)({
|
|
485
|
+
sessionId,
|
|
486
|
+
prompt: args.comment.instruction,
|
|
487
|
+
workspaceRoot: destination.workspaceRoot,
|
|
488
|
+
userContextInputs,
|
|
489
|
+
allowedRoots: [destination.workspaceRoot],
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
const projectContext = {
|
|
493
|
+
kind: 'fresh',
|
|
494
|
+
workspacePath: destination.destinationPath,
|
|
495
|
+
workspaceRoot: destination.workspaceRoot,
|
|
496
|
+
framework: 'vite',
|
|
497
|
+
...(variantContext ? { variantContext } : {}),
|
|
498
|
+
};
|
|
499
|
+
// The executor owns the fresh-static lane (HTML artifacts, no scaffold).
|
|
500
|
+
// The vite lane needs scaffold_base host work, so it stays on the host
|
|
501
|
+
// path until scaffolding becomes server provisioning. Topology is read
|
|
502
|
+
// off the same policy the store uses when spawning work items.
|
|
503
|
+
const useExecutor = Boolean(this.executor?.isRuntimeAvailable() &&
|
|
504
|
+
(0, runPlan_1.resolveRunPlanPolicy)(projectContext).topology === 'static_preview');
|
|
191
505
|
try {
|
|
192
506
|
const startResult = await this.orchestrator.startUnified({
|
|
193
507
|
prompt: args.comment.instruction,
|
|
194
508
|
count: args.count,
|
|
195
|
-
...(
|
|
196
|
-
|
|
509
|
+
...(runLabel ? { runLabel } : {}),
|
|
510
|
+
...(args.comment.variantRequest?.fidelity
|
|
511
|
+
? { fidelity: args.comment.variantRequest.fidelity }
|
|
197
512
|
: {}),
|
|
513
|
+
...(briefs?.length ? { briefs } : {}),
|
|
514
|
+
...(sessionId ? { sessionId } : {}),
|
|
198
515
|
requestId: args.requestId,
|
|
199
|
-
projectContext
|
|
200
|
-
|
|
201
|
-
workspacePath: destination.destinationPath,
|
|
202
|
-
workspaceRoot: destination.workspaceRoot,
|
|
203
|
-
framework: 'vite',
|
|
204
|
-
},
|
|
205
|
-
leaseOwner: 'rivet-host-agent',
|
|
516
|
+
projectContext,
|
|
517
|
+
leaseOwner: useExecutor ? WorkerExecutorService_1.EXECUTOR_LEASE_OWNER : 'rivet-host-agent',
|
|
206
518
|
allowAccumulate: true,
|
|
207
519
|
});
|
|
208
|
-
|
|
520
|
+
const leasedItems = startResult.leasedWorkItems ?? [];
|
|
521
|
+
if (useExecutor && leasedItems.length > 0) {
|
|
522
|
+
this.bridge.reportFeedback(`Rivet is building ${leasedItems.length} direction(s) with its own workers — watch status for progress.`);
|
|
523
|
+
void this.executor.run(startResult.sessionId, leasedItems.map((item) => item.id), startResult.leaseId
|
|
524
|
+
? { leaseId: startResult.leaseId, items: leasedItems }
|
|
525
|
+
: undefined).catch((error) => log.warn('worker executor run failed', error));
|
|
526
|
+
}
|
|
527
|
+
else {
|
|
528
|
+
this.bridge.reportFeedback(`Host agent work is ready for ${startResult.variants.length} fresh variants.`);
|
|
529
|
+
}
|
|
209
530
|
this.bridge.setStatus('READY');
|
|
210
531
|
return { success: true };
|
|
211
532
|
}
|