@rtrvr-ai/rover 3.0.0 → 4.0.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/README.md +291 -12
- package/dist/agentDiscovery.d.ts +304 -0
- package/dist/agentDiscovery.js +1040 -0
- package/dist/embed.js +3706 -1562
- package/dist/index.d.ts +18 -1
- package/dist/ownerInstall.d.ts +150 -0
- package/dist/ownerInstall.js +340 -0
- package/dist/previewBootstrap.d.ts +36 -0
- package/dist/previewBootstrap.js +273 -0
- package/dist/rolls-cli.mjs +312 -0
- package/dist/rover.js +3706 -1562
- package/dist/worker/rover-worker.js +11 -11
- package/package.json +23 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import type { RoverPageCaptureConfig } from '@rover/shared/lib/types/index.js';
|
|
2
2
|
import { type RoverAskUserQuestion, type RoverShortcut, type RoverVoiceConfig } from '@rover/ui';
|
|
3
|
+
import { normalizePendingRunResumeReason } from './resumeReasons.js';
|
|
4
|
+
import { createRoverBookmarklet, createRoverConsoleSnippet, createRoverScriptTagSnippet, readRoverScriptDataAttributes, type RoverPreviewAttachLaunch } from './previewBootstrap.js';
|
|
5
|
+
import { createRoverOwnerInstallBundle, type RoverOwnerInstallBootConfig, type RoverOwnerInstallBundle, type RoverOwnerInstallBundleInput, type RoverOwnerInstallRoverBookConfig } from './ownerInstall.js';
|
|
6
|
+
import { createRoverAgentCard, createRoverAgentCardJson, createRoverAgentDiscoveryTags, createRoverSiteProfile, createRoverSiteProfileJson, createRoverServiceDescLinkHeader, createRoverWellKnownAgentCard, createRoverWellKnownSiteProfile, type RoverAgentCard, type RoverAgentDiscoveryRuntimeConfig } from './agentDiscovery.js';
|
|
3
7
|
import { type RoverCloudCheckpointState } from './cloudCheckpoint.js';
|
|
4
8
|
import type { PersistedRuntimeState, PersistedWorkerState } from './runtimeTypes.js';
|
|
9
|
+
import { type RoverLaunchAttachResponse, type RoverServerExperienceConfig } from './serverRuntime.js';
|
|
5
10
|
import { type FollowupChatEntry } from './followupChatHeuristics.js';
|
|
6
11
|
export type RoverWebToolsConfig = {
|
|
7
12
|
enableExternalWebContext?: boolean;
|
|
@@ -73,6 +78,7 @@ export type RoverInit = {
|
|
|
73
78
|
activation?: 'on_demand';
|
|
74
79
|
idleCloseMs?: number;
|
|
75
80
|
};
|
|
81
|
+
agentDiscovery?: RoverAgentDiscoveryRuntimeConfig;
|
|
76
82
|
stability?: {
|
|
77
83
|
maxPersistBytes?: number;
|
|
78
84
|
maxSnapshotBytes?: number;
|
|
@@ -161,6 +167,7 @@ export type RoverInit = {
|
|
|
161
167
|
disabled?: boolean;
|
|
162
168
|
mp4Url?: string;
|
|
163
169
|
webmUrl?: string;
|
|
170
|
+
soundEnabled?: boolean;
|
|
164
171
|
};
|
|
165
172
|
shortcuts?: RoverShortcut[];
|
|
166
173
|
muted?: boolean;
|
|
@@ -169,6 +176,7 @@ export type RoverInit = {
|
|
|
169
176
|
resizable?: boolean;
|
|
170
177
|
};
|
|
171
178
|
showTaskControls?: boolean;
|
|
179
|
+
experience?: RoverServerExperienceConfig;
|
|
172
180
|
greeting?: {
|
|
173
181
|
text?: string;
|
|
174
182
|
delay?: number;
|
|
@@ -193,10 +201,13 @@ export type RoverInit = {
|
|
|
193
201
|
};
|
|
194
202
|
export type ClientToolDefinition = {
|
|
195
203
|
name: string;
|
|
204
|
+
title?: string;
|
|
196
205
|
description?: string;
|
|
197
206
|
parameters?: Record<string, any>;
|
|
198
207
|
required?: string[];
|
|
199
208
|
schema?: any;
|
|
209
|
+
outputSchema?: any;
|
|
210
|
+
annotations?: Record<string, any>;
|
|
200
211
|
llmCallable?: boolean;
|
|
201
212
|
};
|
|
202
213
|
export type RoverEventName = 'ready' | 'updated' | 'status' | 'run_started' | 'run_state_transition' | 'run_completed' | 'tool_start' | 'tool_result' | 'error' | 'auth_required' | 'navigation_guardrail' | 'mode_change' | 'task_started' | 'task_ended' | 'task_suggested_reset' | 'context_restored' | 'checkpoint_state' | 'checkpoint_error' | 'tab_event_conflict_retry' | 'tab_event_conflict_exhausted' | 'checkpoint_token_missing' | 'open' | 'close';
|
|
@@ -238,7 +249,9 @@ export type RoverInstance = {
|
|
|
238
249
|
reason?: string;
|
|
239
250
|
}) => void;
|
|
240
251
|
getState: () => any;
|
|
252
|
+
getAgentCard: () => RoverAgentCard | null;
|
|
241
253
|
requestSigned: (input: string | URL, init?: RequestInit) => Promise<Response>;
|
|
254
|
+
attachLaunch: (params: RoverPreviewAttachLaunch) => Promise<RoverLaunchAttachResponse | null>;
|
|
242
255
|
registerPromptContextProvider: (provider: RoverPromptContextProvider) => () => void;
|
|
243
256
|
registerTool: (nameOrDef: string | ClientToolDefinition, handler: (args: any) => any | Promise<any>) => void;
|
|
244
257
|
identify: (visitor: {
|
|
@@ -251,6 +264,7 @@ type TelemetryEventName = RoverEventName | RoverVoiceTelemetryEventName;
|
|
|
251
264
|
declare function normalizePromptContextEntry(input: string | RoverPromptContextEntry): FollowupChatEntry | null;
|
|
252
265
|
declare function buildPublicRunStartedPayload(msg: any): Record<string, unknown>;
|
|
253
266
|
declare function buildPublicRunLifecyclePayload(msg: any, completionState: ReturnType<typeof normalizeRunCompletionState>): Record<string, unknown>;
|
|
267
|
+
export declare function getAgentCard(): RoverAgentCard | null;
|
|
254
268
|
declare function normalizeRunCompletionState(msg: any): {
|
|
255
269
|
taskComplete: boolean;
|
|
256
270
|
needsUserInput: boolean;
|
|
@@ -274,6 +288,7 @@ export declare function close(): void;
|
|
|
274
288
|
export declare function show(): void;
|
|
275
289
|
export declare function hide(): void;
|
|
276
290
|
export declare function send(text: string): void;
|
|
291
|
+
export declare function attachLaunch(params: RoverPreviewAttachLaunch): Promise<RoverLaunchAttachResponse | null>;
|
|
277
292
|
export declare function requestSigned(input: string | URL, init?: RequestInit): Promise<Response>;
|
|
278
293
|
export declare function registerPromptContextProvider(provider: RoverPromptContextProvider): () => void;
|
|
279
294
|
export declare function newTask(options?: {
|
|
@@ -286,6 +301,7 @@ export declare function endTask(options?: {
|
|
|
286
301
|
export declare function getState(): any;
|
|
287
302
|
export declare function registerTool(nameOrDef: string | ClientToolDefinition, handler: (args: any) => any | Promise<any>): void;
|
|
288
303
|
export declare const __roverInternalsForTests: {
|
|
304
|
+
normalizePendingRunResumeReason: typeof normalizePendingRunResumeReason;
|
|
289
305
|
sanitizeWorkerState: typeof sanitizeWorkerState;
|
|
290
306
|
cloneRuntimeStateForCheckpoint: typeof cloneRuntimeStateForCheckpoint;
|
|
291
307
|
getPersistGovernorConfig: () => {
|
|
@@ -297,5 +313,6 @@ export declare const __roverInternalsForTests: {
|
|
|
297
313
|
buildPublicRunStartedPayload: typeof buildPublicRunStartedPayload;
|
|
298
314
|
buildPublicRunLifecyclePayload: typeof buildPublicRunLifecyclePayload;
|
|
299
315
|
};
|
|
316
|
+
export { createRoverAgentCard, createRoverAgentCardJson, createRoverAgentDiscoveryTags, createRoverBookmarklet, createRoverConsoleSnippet, createRoverOwnerInstallBundle, createRoverSiteProfile, createRoverSiteProfileJson, createRoverServiceDescLinkHeader, createRoverScriptTagSnippet, createRoverWellKnownAgentCard, createRoverWellKnownSiteProfile, readRoverScriptDataAttributes, };
|
|
317
|
+
export type { RoverOwnerInstallBootConfig, RoverOwnerInstallBundle, RoverOwnerInstallBundleInput, RoverOwnerInstallRoverBookConfig, };
|
|
300
318
|
export declare function installGlobal(): void;
|
|
301
|
-
export {};
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import type { RoverPageCaptureConfig } from '@rover/shared/lib/types/index.js';
|
|
2
|
+
import type { RoverShortcut, RoverVoiceConfig } from '@rover/ui';
|
|
3
|
+
import { type RoverAgentCard, type RoverAgentDiscoveryConfig, type RoverAgentDiscoveryRuntimeConfig, type RoverSiteProfile } from './agentDiscovery.js';
|
|
4
|
+
type JsonRecord = Record<string, unknown>;
|
|
5
|
+
export type RoverOwnerInstallBootConfig = {
|
|
6
|
+
siteId: string;
|
|
7
|
+
publicKey?: string;
|
|
8
|
+
sessionToken?: string;
|
|
9
|
+
sessionId?: string;
|
|
10
|
+
siteKeyId?: string;
|
|
11
|
+
apiBase?: string;
|
|
12
|
+
visitorId?: string;
|
|
13
|
+
workerUrl?: string;
|
|
14
|
+
allowedDomains?: string[];
|
|
15
|
+
domainScopeMode?: 'host_only' | 'registrable_domain';
|
|
16
|
+
externalNavigationPolicy?: 'open_new_tab_notice' | 'block' | 'allow';
|
|
17
|
+
sessionScope?: 'shared_site' | 'tab';
|
|
18
|
+
openOnInit?: boolean;
|
|
19
|
+
mode?: 'safe' | 'full';
|
|
20
|
+
allowActions?: boolean;
|
|
21
|
+
deepLink?: {
|
|
22
|
+
enabled?: boolean;
|
|
23
|
+
promptParam?: string;
|
|
24
|
+
shortcutParam?: string;
|
|
25
|
+
consume?: boolean;
|
|
26
|
+
};
|
|
27
|
+
pageConfig?: RoverPageCaptureConfig | null;
|
|
28
|
+
navigation?: {
|
|
29
|
+
crossHostPolicy?: 'open_new_tab' | 'same_tab';
|
|
30
|
+
};
|
|
31
|
+
tabPolicy?: {
|
|
32
|
+
observerByDefault?: boolean;
|
|
33
|
+
actionLeaseMs?: number;
|
|
34
|
+
};
|
|
35
|
+
taskRouting?: {
|
|
36
|
+
mode?: 'auto' | 'act' | 'planner';
|
|
37
|
+
actHeuristicThreshold?: number;
|
|
38
|
+
plannerOnActError?: boolean;
|
|
39
|
+
};
|
|
40
|
+
taskContext?: {
|
|
41
|
+
resetMode?: 'auto' | 'ask' | 'off';
|
|
42
|
+
inactivityMs?: number;
|
|
43
|
+
suggestReset?: boolean;
|
|
44
|
+
semanticSimilarityThreshold?: number;
|
|
45
|
+
};
|
|
46
|
+
checkpointing?: {
|
|
47
|
+
enabled?: boolean;
|
|
48
|
+
autoVisitorId?: boolean;
|
|
49
|
+
flushIntervalMs?: number;
|
|
50
|
+
pullIntervalMs?: number;
|
|
51
|
+
minFlushIntervalMs?: number;
|
|
52
|
+
ttlHours?: number;
|
|
53
|
+
};
|
|
54
|
+
apiMode?: boolean;
|
|
55
|
+
apiToolsConfig?: {
|
|
56
|
+
mode?: 'allowlist' | 'profile' | 'none';
|
|
57
|
+
enableAdditionalTools?: string[];
|
|
58
|
+
userDefined?: string[];
|
|
59
|
+
};
|
|
60
|
+
telemetry?: {
|
|
61
|
+
enabled?: boolean;
|
|
62
|
+
sampleRate?: number;
|
|
63
|
+
flushIntervalMs?: number;
|
|
64
|
+
maxBatchSize?: number;
|
|
65
|
+
includePayloads?: boolean;
|
|
66
|
+
};
|
|
67
|
+
ui?: {
|
|
68
|
+
agent?: {
|
|
69
|
+
name?: string;
|
|
70
|
+
};
|
|
71
|
+
mascot?: {
|
|
72
|
+
disabled?: boolean;
|
|
73
|
+
mp4Url?: string;
|
|
74
|
+
webmUrl?: string;
|
|
75
|
+
soundEnabled?: boolean;
|
|
76
|
+
};
|
|
77
|
+
shortcuts?: RoverShortcut[];
|
|
78
|
+
greeting?: {
|
|
79
|
+
text?: string;
|
|
80
|
+
delay?: number;
|
|
81
|
+
duration?: number;
|
|
82
|
+
disabled?: boolean;
|
|
83
|
+
};
|
|
84
|
+
voice?: RoverVoiceConfig | JsonRecord | null;
|
|
85
|
+
experience?: JsonRecord | null;
|
|
86
|
+
muted?: boolean;
|
|
87
|
+
thoughtStyle?: 'concise_cards' | 'minimal';
|
|
88
|
+
panel?: {
|
|
89
|
+
resizable?: boolean;
|
|
90
|
+
};
|
|
91
|
+
showTaskControls?: boolean;
|
|
92
|
+
};
|
|
93
|
+
tools?: {
|
|
94
|
+
web?: {
|
|
95
|
+
enableExternalWebContext?: boolean;
|
|
96
|
+
allowDomains?: string[];
|
|
97
|
+
denyDomains?: string[];
|
|
98
|
+
scrapeMode?: 'off' | 'on_demand';
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
agentDiscovery?: RoverAgentDiscoveryRuntimeConfig;
|
|
102
|
+
siteMode?: 'agent' | 'analytics_only' | string;
|
|
103
|
+
};
|
|
104
|
+
export type RoverOwnerInstallRoverBookConfig = {
|
|
105
|
+
enabled?: boolean;
|
|
106
|
+
scriptUrl?: string;
|
|
107
|
+
config?: JsonRecord | null;
|
|
108
|
+
attachPollIntervalMs?: number;
|
|
109
|
+
attachMaxAttempts?: number;
|
|
110
|
+
};
|
|
111
|
+
export type RoverOwnerInstallBundleInput = {
|
|
112
|
+
bootConfig: RoverOwnerInstallBootConfig;
|
|
113
|
+
discovery?: RoverAgentDiscoveryConfig | null;
|
|
114
|
+
embedScriptUrl?: string;
|
|
115
|
+
roverBook?: RoverOwnerInstallRoverBookConfig | null;
|
|
116
|
+
emitLlmsTxt?: boolean;
|
|
117
|
+
llmsTxt?: string;
|
|
118
|
+
};
|
|
119
|
+
export type RoverOwnerInstallBundleMetadata = {
|
|
120
|
+
discoveryEnabled: boolean;
|
|
121
|
+
llmsPublished: boolean;
|
|
122
|
+
embedScriptUrl: string;
|
|
123
|
+
roverBookEnabled: boolean;
|
|
124
|
+
roverBookScriptUrl?: string;
|
|
125
|
+
publishedAgentCardUrl?: string;
|
|
126
|
+
publishedRoverSiteUrl?: string;
|
|
127
|
+
publishedLlmsUrl?: string;
|
|
128
|
+
serviceDescLinkTag?: string;
|
|
129
|
+
serviceDocLinkTag?: string;
|
|
130
|
+
markerJson?: string;
|
|
131
|
+
markerScript?: string;
|
|
132
|
+
inlineAgentCardScript?: string;
|
|
133
|
+
roverSiteJson?: string;
|
|
134
|
+
inlineRoverSiteScript?: string;
|
|
135
|
+
pageManifestJson?: string;
|
|
136
|
+
pageManifestScript?: string;
|
|
137
|
+
};
|
|
138
|
+
export type RoverOwnerInstallBundle = {
|
|
139
|
+
bodyInstallHtml: string;
|
|
140
|
+
headDiscoveryHtml: string;
|
|
141
|
+
agentCard?: RoverAgentCard;
|
|
142
|
+
agentCardJson?: string;
|
|
143
|
+
roverSite?: RoverSiteProfile;
|
|
144
|
+
roverSiteJson?: string;
|
|
145
|
+
serviceDescLinkHeader?: string;
|
|
146
|
+
llmsTxt?: string;
|
|
147
|
+
metadata: RoverOwnerInstallBundleMetadata;
|
|
148
|
+
};
|
|
149
|
+
export declare function createRoverOwnerInstallBundle(input: RoverOwnerInstallBundleInput): RoverOwnerInstallBundle;
|
|
150
|
+
export {};
|
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
import { DEFAULT_AGENT_CARD_PATH, DEFAULT_ROVER_SITE_PATH, createRoverAgentCard, createRoverAgentCardJson, createRoverSiteProfile, createRoverSiteProfileJson, createRoverServiceDescLinkHeader, } from './agentDiscovery.js';
|
|
2
|
+
const DEFAULT_EMBED_SCRIPT_URL = 'https://rover.rtrvr.ai/embed.js';
|
|
3
|
+
const DEFAULT_ROVERBOOK_SCRIPT_URL = 'https://rover.rtrvr.ai/roverbook.js';
|
|
4
|
+
function text(value) {
|
|
5
|
+
return String(value || '').trim();
|
|
6
|
+
}
|
|
7
|
+
function escapeHtmlAttr(value) {
|
|
8
|
+
return String(value || '')
|
|
9
|
+
.replace(/&/g, '&')
|
|
10
|
+
.replace(/"/g, '"')
|
|
11
|
+
.replace(/</g, '<')
|
|
12
|
+
.replace(/>/g, '>');
|
|
13
|
+
}
|
|
14
|
+
function escapeScriptJson(value) {
|
|
15
|
+
return String(value || '')
|
|
16
|
+
.replace(/</g, '\\u003c')
|
|
17
|
+
.replace(/>/g, '\\u003e')
|
|
18
|
+
.replace(/&/g, '\\u0026');
|
|
19
|
+
}
|
|
20
|
+
function replaceInlineDiscoveryScript(html, marker, script) {
|
|
21
|
+
if (!script)
|
|
22
|
+
return html;
|
|
23
|
+
const pattern = new RegExp(`<script[^>]+data-rover-agent-discovery="${marker}"[^>]*>[\\s\\S]*?<\\/script>`);
|
|
24
|
+
if (pattern.test(html)) {
|
|
25
|
+
return html.replace(pattern, script);
|
|
26
|
+
}
|
|
27
|
+
return [html, script].filter(Boolean).join('\n');
|
|
28
|
+
}
|
|
29
|
+
function decorateBundleWithExperience(bundle, bootConfig) {
|
|
30
|
+
const experience = isObject(bootConfig.ui?.experience) ? bootConfig.ui?.experience : null;
|
|
31
|
+
if (!experience)
|
|
32
|
+
return bundle;
|
|
33
|
+
const presence = isObject(experience.presence) ? experience.presence : {};
|
|
34
|
+
const inputs = isObject(experience.inputs) ? experience.inputs : {};
|
|
35
|
+
const shell = isObject(experience.shell) ? experience.shell : {};
|
|
36
|
+
const stream = isObject(experience.stream) ? experience.stream : {};
|
|
37
|
+
const ctaText = text(presence.ctaText) || `Do it with ${text(bootConfig.ui?.agent?.name) || 'Rover'}`;
|
|
38
|
+
const assistantName = text(presence.assistantName) || text(bootConfig.ui?.agent?.name) || 'Rover';
|
|
39
|
+
const agentCard = bundle.agentCard ? JSON.parse(JSON.stringify(bundle.agentCard)) : undefined;
|
|
40
|
+
if (agentCard?.extensions?.rover) {
|
|
41
|
+
agentCard.extensions.rover.discoverySurface = {
|
|
42
|
+
...(agentCard.extensions.rover.discoverySurface || {}),
|
|
43
|
+
mode: 'beacon',
|
|
44
|
+
hostSurface: 'floating-corner',
|
|
45
|
+
actionReveal: 'click',
|
|
46
|
+
beaconLabel: ctaText,
|
|
47
|
+
};
|
|
48
|
+
agentCard.extensions.rover.presence = {
|
|
49
|
+
assistantName,
|
|
50
|
+
ctaText,
|
|
51
|
+
draggable: presence.draggable !== false,
|
|
52
|
+
};
|
|
53
|
+
agentCard.extensions.rover.experience = experience;
|
|
54
|
+
agentCard.extensions.rover.inputs = {
|
|
55
|
+
filesEnabled: inputs.files !== false,
|
|
56
|
+
acceptedMimeGroups: Array.isArray(inputs.acceptedMimeGroups) ? inputs.acceptedMimeGroups : ['images', 'pdfs', 'office', 'text'],
|
|
57
|
+
allowMultipleFiles: inputs.allowMultipleFiles !== false,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
const roverSite = bundle.roverSite ? JSON.parse(JSON.stringify(bundle.roverSite)) : undefined;
|
|
61
|
+
if (roverSite) {
|
|
62
|
+
roverSite.display = {
|
|
63
|
+
...(roverSite.display || {}),
|
|
64
|
+
mode: 'beacon',
|
|
65
|
+
hostSurface: 'floating-corner',
|
|
66
|
+
actionReveal: 'click',
|
|
67
|
+
beaconLabel: ctaText,
|
|
68
|
+
presence: 'draggable_pill',
|
|
69
|
+
openMode: text(shell.openMode) || 'center_stage',
|
|
70
|
+
mobileMode: text(shell.mobileMode) || 'fullscreen_sheet',
|
|
71
|
+
streamMode: text(stream.layout) || 'single_column',
|
|
72
|
+
focusView: 'focus_stream',
|
|
73
|
+
};
|
|
74
|
+
roverSite.experience = experience;
|
|
75
|
+
roverSite.inputs = {
|
|
76
|
+
...(roverSite.inputs || {}),
|
|
77
|
+
filesEnabled: inputs.files !== false,
|
|
78
|
+
acceptedMimeGroups: Array.isArray(inputs.acceptedMimeGroups) ? inputs.acceptedMimeGroups : ['images', 'pdfs', 'office', 'text'],
|
|
79
|
+
allowMultipleFiles: inputs.allowMultipleFiles !== false,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
const agentCardJson = agentCard ? JSON.stringify(agentCard, null, 2) : bundle.agentCardJson;
|
|
83
|
+
const roverSiteJson = roverSite ? JSON.stringify(roverSite, null, 2) : bundle.roverSiteJson;
|
|
84
|
+
const inlineAgentCardScript = agentCardJson
|
|
85
|
+
? `<script type="application/agent-card+json" data-rover-agent-discovery="agent-card">${escapeScriptJson(agentCardJson)}</script>`
|
|
86
|
+
: bundle.metadata.inlineAgentCardScript;
|
|
87
|
+
const inlineRoverSiteScript = roverSiteJson
|
|
88
|
+
? `<script type="application/rover-site+json" data-rover-agent-discovery="rover-site">${escapeScriptJson(roverSiteJson)}</script>`
|
|
89
|
+
: bundle.metadata.inlineRoverSiteScript;
|
|
90
|
+
return {
|
|
91
|
+
...bundle,
|
|
92
|
+
agentCard,
|
|
93
|
+
agentCardJson,
|
|
94
|
+
roverSite,
|
|
95
|
+
roverSiteJson,
|
|
96
|
+
bodyInstallHtml: replaceInlineDiscoveryScript(replaceInlineDiscoveryScript(bundle.bodyInstallHtml, 'agent-card', inlineAgentCardScript), 'rover-site', inlineRoverSiteScript),
|
|
97
|
+
metadata: {
|
|
98
|
+
...bundle.metadata,
|
|
99
|
+
roverSiteJson,
|
|
100
|
+
inlineAgentCardScript,
|
|
101
|
+
inlineRoverSiteScript,
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
function indentJson(value) {
|
|
106
|
+
return JSON.stringify(value, null, 2)
|
|
107
|
+
.split('\n')
|
|
108
|
+
.map(line => ` ${line}`)
|
|
109
|
+
.join('\n');
|
|
110
|
+
}
|
|
111
|
+
function isObject(value) {
|
|
112
|
+
return !!value && typeof value === 'object' && !Array.isArray(value);
|
|
113
|
+
}
|
|
114
|
+
function hasObjectEntries(value) {
|
|
115
|
+
return isObject(value) && Object.keys(value).length > 0;
|
|
116
|
+
}
|
|
117
|
+
function normalizeAttachPollIntervalMs(value) {
|
|
118
|
+
const parsed = Number(value);
|
|
119
|
+
if (!Number.isFinite(parsed) || parsed < 10)
|
|
120
|
+
return 50;
|
|
121
|
+
return Math.round(parsed);
|
|
122
|
+
}
|
|
123
|
+
function normalizeAttachMaxAttempts(value) {
|
|
124
|
+
const parsed = Number(value);
|
|
125
|
+
if (!Number.isFinite(parsed) || parsed < 1)
|
|
126
|
+
return 300;
|
|
127
|
+
return Math.round(parsed);
|
|
128
|
+
}
|
|
129
|
+
function discoveryEnabled(config) {
|
|
130
|
+
return !!config && config.enabled !== false && config.aiAccess?.enabled !== false;
|
|
131
|
+
}
|
|
132
|
+
function llmsEnabled(input, config) {
|
|
133
|
+
if (!discoveryEnabled(config))
|
|
134
|
+
return false;
|
|
135
|
+
return input.emitLlmsTxt === true || !!text(config.llmsUrl);
|
|
136
|
+
}
|
|
137
|
+
function buildOwnerMarker(card, publishedAgentCardUrl) {
|
|
138
|
+
return {
|
|
139
|
+
task: card.extensions?.rover.taskEndpoint,
|
|
140
|
+
card: publishedAgentCardUrl,
|
|
141
|
+
roverSite: card.extensions?.rover.roverSiteUrl,
|
|
142
|
+
site: card.extensions?.rover.siteUrl,
|
|
143
|
+
workflow: card.extensions?.rover.workflowEndpoint,
|
|
144
|
+
page: card.extensions?.rover.currentPage?.pageId,
|
|
145
|
+
preferExecution: card.extensions?.rover.preferredExecution,
|
|
146
|
+
display: card.extensions?.rover.discoverySurface
|
|
147
|
+
? {
|
|
148
|
+
mode: card.extensions.rover.discoverySurface.mode,
|
|
149
|
+
hostSurface: card.extensions.rover.discoverySurface.hostSurface,
|
|
150
|
+
actionReveal: card.extensions.rover.discoverySurface.actionReveal,
|
|
151
|
+
beaconLabel: card.extensions.rover.discoverySurface.beaconLabel,
|
|
152
|
+
}
|
|
153
|
+
: undefined,
|
|
154
|
+
skills: card.skills.slice(0, 24).map(skill => ({
|
|
155
|
+
id: skill.id,
|
|
156
|
+
name: skill.name,
|
|
157
|
+
})),
|
|
158
|
+
capabilities: (card.extensions?.rover.capabilitiesGraph || []).slice(0, 24).map(capability => ({
|
|
159
|
+
capabilityId: capability.capabilityId,
|
|
160
|
+
label: capability.label,
|
|
161
|
+
})),
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
function buildDefaultLlmsTxt(card, options) {
|
|
165
|
+
const lines = [
|
|
166
|
+
`# ${card.name}`,
|
|
167
|
+
'',
|
|
168
|
+
card.description,
|
|
169
|
+
'',
|
|
170
|
+
'Prefer Rover shortcuts, explicit site tools, and public task flows over raw DOM automation when they match the requested outcome.',
|
|
171
|
+
`Primary task endpoint: ${text(card.extensions?.rover.taskEndpoint || card.url)}`,
|
|
172
|
+
`Workflow endpoint: ${text(card.extensions?.rover.workflowEndpoint)}`,
|
|
173
|
+
`Capability card: ${options.agentCardUrl}`,
|
|
174
|
+
];
|
|
175
|
+
const skills = card.skills
|
|
176
|
+
.map(skill => ({
|
|
177
|
+
id: text(skill.id),
|
|
178
|
+
name: text(skill.name),
|
|
179
|
+
description: text(skill.description),
|
|
180
|
+
interface: text(skill.preferredInterface || skill.rover?.source || 'task'),
|
|
181
|
+
}))
|
|
182
|
+
.filter(skill => skill.id && skill.name);
|
|
183
|
+
if (skills.length > 0) {
|
|
184
|
+
lines.push('', 'Published skills:');
|
|
185
|
+
for (const skill of skills) {
|
|
186
|
+
const description = skill.description ? ` - ${skill.description}` : '';
|
|
187
|
+
lines.push(`- ${skill.id}: ${skill.name} [${skill.interface}]${description}`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
const shortcuts = (card.extensions?.rover.shortcuts || [])
|
|
191
|
+
.map(shortcut => `${text(shortcut.id)}: ${text(shortcut.label)}`)
|
|
192
|
+
.filter(Boolean);
|
|
193
|
+
if (shortcuts.length > 0) {
|
|
194
|
+
lines.push('', 'Shortcut IDs:');
|
|
195
|
+
for (const shortcut of shortcuts) {
|
|
196
|
+
lines.push(`- ${shortcut}`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return lines.join('\n');
|
|
200
|
+
}
|
|
201
|
+
function buildQueueStubLines() {
|
|
202
|
+
return [
|
|
203
|
+
'(function(){ var r = window.rover = window.rover || function(){ (r.q = r.q || []).push(arguments); }; r.l = +new Date(); })();',
|
|
204
|
+
];
|
|
205
|
+
}
|
|
206
|
+
function buildBootScript(bootConfig) {
|
|
207
|
+
const lines = [
|
|
208
|
+
'<script>',
|
|
209
|
+
...buildQueueStubLines().map(line => ` ${line}`),
|
|
210
|
+
` rover('boot', ${indentJson(bootConfig)});`,
|
|
211
|
+
'</script>',
|
|
212
|
+
];
|
|
213
|
+
return lines.join('\n');
|
|
214
|
+
}
|
|
215
|
+
function buildRoverBookAttachScript(config, options) {
|
|
216
|
+
const pollIntervalMs = normalizeAttachPollIntervalMs(options?.pollIntervalMs);
|
|
217
|
+
const maxAttempts = normalizeAttachMaxAttempts(options?.maxAttempts);
|
|
218
|
+
return [
|
|
219
|
+
'<script>',
|
|
220
|
+
' (function(){',
|
|
221
|
+
` var roverBookConfig = ${indentJson(config)};`,
|
|
222
|
+
' function attachRoverBook(){',
|
|
223
|
+
' if (window.__ROVERBOOK_INSTANCE__) return true;',
|
|
224
|
+
' var roverApi = window.rover;',
|
|
225
|
+
' var roverBook = window.RoverBook;',
|
|
226
|
+
" if (!roverApi || typeof roverApi.on !== 'function' || typeof roverApi.requestSigned !== 'function') return false;",
|
|
227
|
+
" if (!roverBook || typeof roverBook.enableRoverBook !== 'function') return false;",
|
|
228
|
+
' window.__ROVERBOOK_INSTANCE__ = roverBook.enableRoverBook(roverApi, roverBookConfig);',
|
|
229
|
+
' return true;',
|
|
230
|
+
' }',
|
|
231
|
+
' if (attachRoverBook()) return;',
|
|
232
|
+
' var attempts = 0;',
|
|
233
|
+
' var timer = setInterval(function(){',
|
|
234
|
+
' attempts += 1;',
|
|
235
|
+
` if (attachRoverBook() || attempts >= ${maxAttempts}) clearInterval(timer);`,
|
|
236
|
+
` }, ${pollIntervalMs});`,
|
|
237
|
+
' })();',
|
|
238
|
+
'</script>',
|
|
239
|
+
].join('\n');
|
|
240
|
+
}
|
|
241
|
+
export function createRoverOwnerInstallBundle(input) {
|
|
242
|
+
const bootConfig = input.bootConfig;
|
|
243
|
+
const discoveryConfig = discoveryEnabled(input.discovery) ? input.discovery : null;
|
|
244
|
+
const publishedAgentCardUrl = discoveryConfig ? text(discoveryConfig.agentCardUrl) || DEFAULT_AGENT_CARD_PATH : '';
|
|
245
|
+
const publishedRoverSiteUrl = discoveryConfig ? text(discoveryConfig.roverSiteUrl) || DEFAULT_ROVER_SITE_PATH : '';
|
|
246
|
+
const publishLlmsTxt = llmsEnabled(input, discoveryConfig);
|
|
247
|
+
const publishedLlmsUrl = discoveryConfig ? text(discoveryConfig.llmsUrl) : '';
|
|
248
|
+
const embedScriptUrl = text(input.embedScriptUrl) || DEFAULT_EMBED_SCRIPT_URL;
|
|
249
|
+
const roverBookEnabled = input.roverBook?.enabled !== false && hasObjectEntries(input.roverBook?.config);
|
|
250
|
+
const roverBookScriptUrl = roverBookEnabled
|
|
251
|
+
? (text(input.roverBook?.scriptUrl) || DEFAULT_ROVERBOOK_SCRIPT_URL)
|
|
252
|
+
: '';
|
|
253
|
+
const agentCard = discoveryConfig ? createRoverAgentCard(discoveryConfig) : undefined;
|
|
254
|
+
const agentCardJson = discoveryConfig ? createRoverAgentCardJson(discoveryConfig) : undefined;
|
|
255
|
+
const roverSite = discoveryConfig ? createRoverSiteProfile(discoveryConfig) : undefined;
|
|
256
|
+
const roverSiteJson = discoveryConfig ? createRoverSiteProfileJson(discoveryConfig) : undefined;
|
|
257
|
+
const pageManifestJson = discoveryConfig
|
|
258
|
+
? JSON.stringify(agentCard?.extensions?.rover.currentPage || null, null, 2)
|
|
259
|
+
: undefined;
|
|
260
|
+
const marker = agentCard && publishedAgentCardUrl
|
|
261
|
+
? buildOwnerMarker(agentCard, publishedAgentCardUrl)
|
|
262
|
+
: undefined;
|
|
263
|
+
const markerJson = marker ? escapeScriptJson(JSON.stringify(marker)) : undefined;
|
|
264
|
+
const escapedAgentCardJson = agentCardJson ? escapeScriptJson(agentCardJson) : undefined;
|
|
265
|
+
const escapedRoverSiteJson = roverSiteJson ? escapeScriptJson(roverSiteJson) : undefined;
|
|
266
|
+
const escapedPageManifestJson = pageManifestJson ? escapeScriptJson(pageManifestJson) : undefined;
|
|
267
|
+
const serviceDescLinkTag = discoveryConfig && publishedAgentCardUrl
|
|
268
|
+
? `<link rel="service-desc" href="${escapeHtmlAttr(publishedAgentCardUrl)}" type="application/json" />`
|
|
269
|
+
: undefined;
|
|
270
|
+
const serviceDocLinkTag = discoveryConfig && publishedLlmsUrl
|
|
271
|
+
? `<link rel="service-doc" href="${escapeHtmlAttr(publishedLlmsUrl)}" type="text/markdown" />`
|
|
272
|
+
: undefined;
|
|
273
|
+
const bodyLines = [];
|
|
274
|
+
if (markerJson) {
|
|
275
|
+
bodyLines.push(`<script type="application/agent+json" data-rover-agent-discovery="marker">${markerJson}</script>`);
|
|
276
|
+
}
|
|
277
|
+
if (escapedRoverSiteJson) {
|
|
278
|
+
bodyLines.push(`<script type="application/rover-site+json" data-rover-agent-discovery="rover-site">${escapedRoverSiteJson}</script>`);
|
|
279
|
+
}
|
|
280
|
+
if (escapedPageManifestJson) {
|
|
281
|
+
bodyLines.push(`<script type="application/rover-page+json" data-rover-agent-discovery="page">${escapedPageManifestJson}</script>`);
|
|
282
|
+
}
|
|
283
|
+
if (escapedAgentCardJson) {
|
|
284
|
+
bodyLines.push(`<script type="application/agent-card+json" data-rover-agent-discovery="agent-card">${escapedAgentCardJson}</script>`);
|
|
285
|
+
}
|
|
286
|
+
bodyLines.push(buildBootScript(bootConfig));
|
|
287
|
+
bodyLines.push(`<script src="${escapeHtmlAttr(embedScriptUrl)}" async></script>`);
|
|
288
|
+
if (roverBookEnabled && roverBookScriptUrl) {
|
|
289
|
+
bodyLines.push(`<script src="${escapeHtmlAttr(roverBookScriptUrl)}" async></script>`);
|
|
290
|
+
bodyLines.push(buildRoverBookAttachScript(input.roverBook?.config || {}, {
|
|
291
|
+
pollIntervalMs: input.roverBook?.attachPollIntervalMs,
|
|
292
|
+
maxAttempts: input.roverBook?.attachMaxAttempts,
|
|
293
|
+
}));
|
|
294
|
+
}
|
|
295
|
+
const llmsTxt = publishLlmsTxt && agentCard
|
|
296
|
+
? (text(input.llmsTxt) ? input.llmsTxt : buildDefaultLlmsTxt(agentCard, { agentCardUrl: publishedAgentCardUrl || DEFAULT_AGENT_CARD_PATH }))
|
|
297
|
+
: undefined;
|
|
298
|
+
return decorateBundleWithExperience({
|
|
299
|
+
bodyInstallHtml: bodyLines.join('\n'),
|
|
300
|
+
headDiscoveryHtml: [serviceDescLinkTag, serviceDocLinkTag].filter(Boolean).join('\n'),
|
|
301
|
+
agentCard,
|
|
302
|
+
agentCardJson,
|
|
303
|
+
roverSite,
|
|
304
|
+
roverSiteJson,
|
|
305
|
+
serviceDescLinkHeader: discoveryConfig
|
|
306
|
+
? createRoverServiceDescLinkHeader({
|
|
307
|
+
agentCardUrl: publishedAgentCardUrl || DEFAULT_AGENT_CARD_PATH,
|
|
308
|
+
...(publishedLlmsUrl ? { llmsUrl: publishedLlmsUrl } : {}),
|
|
309
|
+
})
|
|
310
|
+
: undefined,
|
|
311
|
+
llmsTxt,
|
|
312
|
+
metadata: {
|
|
313
|
+
discoveryEnabled: !!discoveryConfig,
|
|
314
|
+
llmsPublished: !!serviceDocLinkTag,
|
|
315
|
+
embedScriptUrl,
|
|
316
|
+
roverBookEnabled,
|
|
317
|
+
roverBookScriptUrl: roverBookScriptUrl || undefined,
|
|
318
|
+
publishedAgentCardUrl: publishedAgentCardUrl || undefined,
|
|
319
|
+
publishedRoverSiteUrl: publishedRoverSiteUrl || undefined,
|
|
320
|
+
publishedLlmsUrl: publishedLlmsUrl || undefined,
|
|
321
|
+
serviceDescLinkTag,
|
|
322
|
+
serviceDocLinkTag,
|
|
323
|
+
markerJson,
|
|
324
|
+
markerScript: markerJson
|
|
325
|
+
? `<script type="application/agent+json" data-rover-agent-discovery="marker">${markerJson}</script>`
|
|
326
|
+
: undefined,
|
|
327
|
+
inlineAgentCardScript: escapedAgentCardJson
|
|
328
|
+
? `<script type="application/agent-card+json" data-rover-agent-discovery="agent-card">${escapedAgentCardJson}</script>`
|
|
329
|
+
: undefined,
|
|
330
|
+
roverSiteJson,
|
|
331
|
+
inlineRoverSiteScript: escapedRoverSiteJson
|
|
332
|
+
? `<script type="application/rover-site+json" data-rover-agent-discovery="rover-site">${escapedRoverSiteJson}</script>`
|
|
333
|
+
: undefined,
|
|
334
|
+
pageManifestJson,
|
|
335
|
+
pageManifestScript: escapedPageManifestJson
|
|
336
|
+
? `<script type="application/rover-page+json" data-rover-agent-discovery="page">${escapedPageManifestJson}</script>`
|
|
337
|
+
: undefined,
|
|
338
|
+
},
|
|
339
|
+
}, input.bootConfig);
|
|
340
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export type RoverPreviewAttachLaunch = {
|
|
2
|
+
requestId: string;
|
|
3
|
+
attachToken: string;
|
|
4
|
+
};
|
|
5
|
+
export type RoverPreviewBootstrapVoiceConfig = {
|
|
6
|
+
enabled?: boolean;
|
|
7
|
+
language?: string;
|
|
8
|
+
autoStopMs?: number;
|
|
9
|
+
};
|
|
10
|
+
export type RoverPreviewBootstrapUiConfig = {
|
|
11
|
+
voice?: RoverPreviewBootstrapVoiceConfig;
|
|
12
|
+
};
|
|
13
|
+
export type RoverPreviewBootstrapConfig = {
|
|
14
|
+
scriptUrl?: string;
|
|
15
|
+
siteId: string;
|
|
16
|
+
publicKey?: string;
|
|
17
|
+
sessionToken?: string;
|
|
18
|
+
sessionId?: string;
|
|
19
|
+
siteKeyId?: string;
|
|
20
|
+
apiBase?: string;
|
|
21
|
+
workerUrl?: string;
|
|
22
|
+
allowedDomains?: string[];
|
|
23
|
+
domainScopeMode?: 'host_only' | 'registrable_domain';
|
|
24
|
+
externalNavigationPolicy?: 'open_new_tab_notice' | 'block' | 'allow';
|
|
25
|
+
sessionScope?: 'shared_site' | 'tab';
|
|
26
|
+
openOnInit?: boolean;
|
|
27
|
+
mode?: 'safe' | 'full';
|
|
28
|
+
allowActions?: boolean;
|
|
29
|
+
ui?: RoverPreviewBootstrapUiConfig;
|
|
30
|
+
attachLaunch?: RoverPreviewAttachLaunch;
|
|
31
|
+
};
|
|
32
|
+
export type RoverScriptAttributeSource = Pick<HTMLScriptElement, 'getAttribute'>;
|
|
33
|
+
export declare function createRoverConsoleSnippet(config: RoverPreviewBootstrapConfig): string;
|
|
34
|
+
export declare function createRoverBookmarklet(config: RoverPreviewBootstrapConfig): string;
|
|
35
|
+
export declare function createRoverScriptTagSnippet(config: RoverPreviewBootstrapConfig): string;
|
|
36
|
+
export declare function readRoverScriptDataAttributes(scriptEl: RoverScriptAttributeSource): RoverPreviewBootstrapConfig | null;
|