@codingame/monaco-vscode-chat-cloud-service-override 0.0.0-stage → 38.0.7

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.
Files changed (29) hide show
  1. package/common.d.ts +2 -0
  2. package/common.js +29 -0
  3. package/index.d.ts +3 -0
  4. package/index.js +9 -0
  5. package/package.json +52 -3
  6. package/session.d.ts +3 -0
  7. package/session.js +11 -0
  8. package/vscode/src/vs/sessions/contrib/chat/browser/newSession.d.ts +9 -0
  9. package/vscode/src/vs/sessions/contrib/providers/copilotChatSessions/browser/cloudAutomationStore.d.ts +67 -0
  10. package/vscode/src/vs/sessions/contrib/providers/copilotChatSessions/browser/cloudAutomationStore.js +695 -0
  11. package/vscode/src/vs/sessions/contrib/providers/copilotChatSessions/browser/cloudSandboxSessionConfig.d.ts +4 -0
  12. package/vscode/src/vs/sessions/contrib/providers/copilotChatSessions/browser/cloudSandboxSessionConfig.js +39 -0
  13. package/vscode/src/vs/sessions/contrib/providers/copilotChatSessions/browser/copilotChatSessions.contribution.d.ts +1 -0
  14. package/vscode/src/vs/sessions/contrib/providers/copilotChatSessions/browser/copilotChatSessions.contribution.js +59 -0
  15. package/vscode/src/vs/sessions/contrib/providers/copilotChatSessions/browser/copilotChatSessionsActions.d.ts +1 -0
  16. package/vscode/src/vs/sessions/contrib/providers/copilotChatSessions/browser/copilotChatSessionsActions.js +83 -0
  17. package/vscode/src/vs/sessions/contrib/providers/copilotChatSessions/browser/copilotChatSessionsChangesets.d.ts +87 -0
  18. package/vscode/src/vs/sessions/contrib/providers/copilotChatSessions/browser/copilotChatSessionsChangesets.js +176 -0
  19. package/vscode/src/vs/sessions/contrib/providers/copilotChatSessions/browser/copilotChatSessionsProvider.d.ts +422 -0
  20. package/vscode/src/vs/sessions/contrib/providers/copilotChatSessions/browser/copilotChatSessionsProvider.js +2444 -0
  21. package/vscode/src/vs/sessions/contrib/providers/copilotChatSessions/browser/githubCloudAutomationStore.d.ts +91 -0
  22. package/vscode/src/vs/sessions/contrib/providers/copilotChatSessions/browser/githubCloudAutomationStore.js +620 -0
  23. package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/cloudSandboxAgentHost.contribution.d.ts +1 -0
  24. package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/cloudSandboxAgentHost.contribution.js +5 -0
  25. package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/cloudSandboxAgentHostContribution.d.ts +46 -0
  26. package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/cloudSandboxAgentHostContribution.js +321 -0
  27. package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/cloudSandboxSessionsProvider.d.ts +104 -0
  28. package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/cloudSandboxSessionsProvider.js +345 -0
  29. package/README.md +0 -3
@@ -0,0 +1,695 @@
1
+
2
+ import { __decorate, __param } from '@codingame/monaco-vscode-api/external/tslib/tslib.es6';
3
+ import { RunOnceScheduler } from '@codingame/monaco-vscode-api/vscode/vs/base/common/async';
4
+ import { CancellationToken } from '@codingame/monaco-vscode-api/vscode/vs/base/common/cancellation';
5
+ import { Codicon } from '@codingame/monaco-vscode-api/vscode/vs/base/common/codicons';
6
+ import { isCancellationError, CancellationError } from '@codingame/monaco-vscode-api/vscode/vs/base/common/errors';
7
+ import { Disposable, DisposableStore } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
8
+ import { Schemas } from '@codingame/monaco-vscode-api/vscode/vs/base/common/network';
9
+ import '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/index';
10
+ import { isEqual } from '@codingame/monaco-vscode-api/vscode/vs/base/common/resources';
11
+ import { isStringArray } from '@codingame/monaco-vscode-api/vscode/vs/base/common/types';
12
+ import { URI } from '@codingame/monaco-vscode-api/vscode/vs/base/common/uri';
13
+ import { localize } from '@codingame/monaco-vscode-api/vscode/vs/nls';
14
+ import { ChatAIDisabledSettingId } from '@codingame/monaco-vscode-api/vscode/vs/platform/chat/common/chatSettings';
15
+ import { IConfigurationService } from '@codingame/monaco-vscode-api/vscode/vs/platform/configuration/common/configuration.service';
16
+ import { IDefaultAccountService } from '@codingame/monaco-vscode-api/vscode/vs/platform/defaultAccount/common/defaultAccount.service';
17
+ import { MutationUncertainError, ApiRequestError } from '@codingame/monaco-vscode-api/vscode/vs/platform/github/common/missionControl/missionControlClient';
18
+ import { IInstantiationService } from '@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/instantiation';
19
+ import { ILogService } from '@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log.service';
20
+ import { getGitHubRepositoryId } from '@codingame/monaco-vscode-api/vscode/vs/platform/github/common/githubUrls';
21
+ import { RepositoryPicker } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/browser/agentSessions/repositoryPicker';
22
+ import { IGitHubService } from '@codingame/monaco-vscode-api/vscode/vs/sessions/contrib/github/browser/githubService.service';
23
+ import { AutomationUnavailableError, serializeAutomationEditableState, assertAutomationSessionTemplateAuthority } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/automations/automationService';
24
+ import { CHAT_CLOUD_AUTOMATIONS_ENABLED_SETTING, CHAT_AUTOMATIONS_ENABLED_SETTING } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/automations/automationsEnabled';
25
+ import { IChatEntitlementService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/chat/common/chatEntitlementService.service';
26
+ import { IWorkbenchGitHubService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/github/common/githubService.service';
27
+ import { GITHUB_REMOTE_FILE_SCHEME } from '@codingame/monaco-vscode-api/vscode/vs/sessions/services/sessions/common/session';
28
+ import { GitHubCloudAutomationStore } from './githubCloudAutomationStore.js';
29
+ import { observableValue } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/observables/observableValue';
30
+ import { derived } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/observables/derived';
31
+ import { observableSignalFromEvent } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/observables/observableSignalFromEvent';
32
+ import { autorun } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/reactions/autorun';
33
+ import { transaction } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/transaction';
34
+
35
+ let CloudAutomationStore = class CloudAutomationStore extends Disposable {
36
+ constructor(
37
+ providerId,
38
+ sessionTypeId,
39
+ resolveRepositoryUri,
40
+ configurationService,
41
+ defaultAccountService,
42
+ entitlementService,
43
+ instantiationService,
44
+ logService,
45
+ gitHubService,
46
+ workbenchGitHubService
47
+ ) {
48
+ super();
49
+ this.providerId = providerId;
50
+ this.sessionTypeId = sessionTypeId;
51
+ this.defaultAccountService = defaultAccountService;
52
+ this.instantiationService = instantiationService;
53
+ this.logService = logService;
54
+ this.gitHubService = gitHubService;
55
+ this.store = observableValue(this, undefined);
56
+ this.refreshError = observableValue(this, undefined);
57
+ this.historyState = observableValue(this, "ready");
58
+ this.discoveryAttempts = 0;
59
+ this.historyScheduler = this._register(( new RunOnceScheduler(() => {
60
+ this.discoveryAttempts = Math.max(0, this.discoveryAttempts - 1);
61
+ this.refreshHistoryInBackground();
62
+ }, 15_000)));
63
+ this.catalogueState = derived(
64
+ this,
65
+ reader => this.refreshError.read(reader) ? "error" : this.store.read(reader)?.catalogueState.read(reader) ?? "unavailable"
66
+ );
67
+ this.unavailableReason = this.refreshError;
68
+ this.canCreateAutomation = derived(
69
+ this,
70
+ reader => this.enabled.read(reader) && this.catalogueState.read(reader) === "ready" && this.store.read(reader)?.mutationUncertain.read(reader) === false
71
+ );
72
+ this.automations = derived(
73
+ this,
74
+ reader => (this.store.read(reader)?.entries.read(reader) ?? []).map(entry => this.toAutomation(entry))
75
+ );
76
+ this.runs = derived(
77
+ this,
78
+ reader => (this.store.read(reader)?.history.read(reader) ?? []).map(entry => this.toRun(entry)).filter(run => run !== undefined)
79
+ );
80
+ this.configuration = {
81
+ sessionTypes: [sessionTypeId],
82
+ description: ( localize(5027, "Runs even when your computer is off, triggered on a schedule.")),
83
+ timeZone: "UTC",
84
+ targetChangeDisabledReason: ( localize(
85
+ 5028,
86
+ "The repository and provider cannot be changed for an existing cloud automation. Duplicate this automation to use another target."
87
+ )),
88
+ tools: derived(this, reader => toToolCatalog(
89
+ this.store.read(reader)?.toolCatalog.read(reader),
90
+ !!this.store.read(reader)
91
+ )),
92
+ loadTools: () => this.store.get()?.loadTools(),
93
+ pickWorkspace: token => this.pickWorkspace(token),
94
+ getWorkspaceTarget: workspace => derived(
95
+ reader => this.store.read(reader)?.getWorkspaceTarget(workspace).read(reader) ?? {
96
+ disabledReason: ( localize(5029, "Cloud automations are unavailable."))
97
+ }
98
+ )
99
+ };
100
+ const configurationChanged = observableSignalFromEvent(this, configurationService.onDidChangeConfiguration);
101
+ const sentimentChanged = observableSignalFromEvent(this, entitlementService.onDidChangeSentiment);
102
+ const accountChanged = observableSignalFromEvent(this, defaultAccountService.onDidChangeDefaultAccount);
103
+ const clientChanged = observableSignalFromEvent(this, workbenchGitHubService.onDidChangeDefaultClient);
104
+ this.enabled = derived(this, reader => {
105
+ configurationChanged.read(reader);
106
+ sentimentChanged.read(reader);
107
+ return configurationService.getValue(CHAT_CLOUD_AUTOMATIONS_ENABLED_SETTING) === true && configurationService.getValue(CHAT_AUTOMATIONS_ENABLED_SETTING) === true && configurationService.getValue(ChatAIDisabledSettingId) !== true && !entitlementService.sentiment.hidden;
108
+ });
109
+ this._register(autorun(reader => {
110
+ accountChanged.read(reader);
111
+ clientChanged.read(reader);
112
+ this.historyScheduler.cancel();
113
+ this.discoveryAttempts = 0;
114
+ this.historyRefresh = undefined;
115
+ const account = defaultAccountService.currentDefaultAccount;
116
+ let store;
117
+ if (this.enabled.read(reader) && account && !account.enterprise) {
118
+ store = reader.store.add(
119
+ instantiationService.createInstance(GitHubCloudAutomationStore, resolveRepositoryUri)
120
+ );
121
+ }
122
+ transaction(tx => {
123
+ this.store.set(store, tx);
124
+ this.refreshError.set(undefined, tx);
125
+ this.historyState.set("ready", tx);
126
+ });
127
+ if (store) {
128
+ void (async () => {
129
+ await Promise.resolve();
130
+ this.assertCurrentStore(store);
131
+ await this.refresh();
132
+ })().catch(error => {
133
+ if (!isCancellationError(error)) {
134
+ this.logService.warn("[CloudAutomations] Initial refresh failed", error);
135
+ }
136
+ });
137
+ }
138
+ }));
139
+ }
140
+ async pickWorkspace(token) {
141
+ const store = this.requireStore();
142
+ const resources = ( new DisposableStore());
143
+ const checkAccount = () => {
144
+ this.assertCurrentStore(store);
145
+ if (token.isCancellationRequested) {
146
+ throw ( new CancellationError());
147
+ }
148
+ if (this.gitHubService.enterpriseHost !== undefined) {
149
+ throw ( new Error(( localize(5030, "Select a private repository on GitHub.com."))));
150
+ }
151
+ };
152
+ try {
153
+ checkAccount();
154
+ await this.gitHubService.authenticateForRepositoryAccess(token);
155
+ checkAccount();
156
+ const picker = resources.add(this.instantiationService.createInstance(RepositoryPicker));
157
+ const result = await picker.pickRepository(async (query, requestToken) => {
158
+ checkAccount();
159
+ const repositories = await this.gitHubService.getRepositories(getGitHubRepositoryId(query.trim()) ?? query, requestToken);
160
+ checkAccount();
161
+ return repositories.filter(repository => repository.isPrivate).map(repository => repository.fullName);
162
+ }, {
163
+ allowRepositoryUrl: true,
164
+ placeholder: ( localize(5031, "Search for a private repository or paste a repository URL..."))
165
+ }, token);
166
+ checkAccount();
167
+ if (!result) {
168
+ return undefined;
169
+ }
170
+ const repository = getGitHubRepositoryId(result.repository ?? result.cloneUrl ?? "");
171
+ if (!repository) {
172
+ throw ( new Error(( localize(5030, "Select a private repository on GitHub.com."))));
173
+ }
174
+ return ( URI.from({
175
+ scheme: GITHUB_REMOTE_FILE_SCHEME,
176
+ authority: "github",
177
+ path: `/${repository}/HEAD`
178
+ }));
179
+ } finally {
180
+ resources.dispose();
181
+ }
182
+ }
183
+ async refresh() {
184
+ const store = this.requireStore();
185
+ try {
186
+ await store.refresh();
187
+ if (this.store.get() === store) {
188
+ this.refreshError.set(undefined, undefined);
189
+ }
190
+ } catch (error) {
191
+ if (this.store.get() === store && !isCancellationError(error)) {
192
+ this.refreshError.set(error instanceof Error ? error.message : ( localize(5032, "Cloud automations could not be refreshed.")), undefined);
193
+ }
194
+ throw error;
195
+ }
196
+ this.assertCurrentStore(store);
197
+ await this.refreshHistory();
198
+ }
199
+ refreshHistory() {
200
+ if (this.historyRefresh) {
201
+ return this.historyRefresh;
202
+ }
203
+ const store = this.requireStore();
204
+ this.historyScheduler.cancel();
205
+ this.historyState.set("loading", undefined);
206
+ this.historyRefresh = (async () => {
207
+ try {
208
+ await store.refreshHistory();
209
+ this.assertCurrentStore(store);
210
+ this.historyState.set("ready", undefined);
211
+ } catch (error) {
212
+ if (this.store.get() === store && !isCancellationError(error)) {
213
+ this.historyState.set("error", undefined);
214
+ }
215
+ throw error;
216
+ } finally {
217
+ if (this.store.get() === store && !this._store.isDisposed) {
218
+ this.historyRefresh = undefined;
219
+ if (this.historyState.get() === "ready" && (this.discoveryAttempts > 0 || ( this.runs.get().some(run => run.status === "pending" || run.status === "running")))) {
220
+ this.historyScheduler.schedule();
221
+ }
222
+ }
223
+ }
224
+ })();
225
+ return this.historyRefresh;
226
+ }
227
+ refreshHistoryInBackground() {
228
+ void this.refreshHistory().catch(error => {
229
+ if (!isCancellationError(error)) {
230
+ this.logService.warn("[CloudAutomations] History refresh failed", error);
231
+ }
232
+ });
233
+ }
234
+ getAutomation(id) {
235
+ return this.automations.get().find(automation => automation.id === id);
236
+ }
237
+ runsFor(id) {
238
+ return derived(
239
+ this,
240
+ reader => this.runs.read(reader).filter(run => run.automationId === id)
241
+ );
242
+ }
243
+ getActiveRunFor(id) {
244
+ return this.runs.get().filter(
245
+ run => run.automationId === id && (run.status === "pending" || run.status === "running")
246
+ ).sort((a, b) => b.startedAt.localeCompare(a.startedAt))[0];
247
+ }
248
+ canRunAutomation(id) {
249
+ return this.canCreateAutomation.get() && this.getAutomation(id) !== undefined;
250
+ }
251
+ canUpdateAutomation(id) {
252
+ return this.canRunAutomation(id) && !this.getAutomation(id)?.readOnlyReason;
253
+ }
254
+ canDeleteAutomation(id) {
255
+ return this.canRunAutomation(id);
256
+ }
257
+ async createAutomation(options, guard) {
258
+ const store = this.requireWritableStore();
259
+ this.validateTarget(options.target);
260
+ validateLocalOptions(options);
261
+ const value = {
262
+ name: options.name,
263
+ description: "",
264
+ prompt: options.prompt,
265
+ disabled: !(options.enabled ?? true),
266
+ triggers: cloudAutomationTriggers(options.schedule),
267
+ ...templateMutation(options.sessionTemplate),
268
+ ...(options.modelId !== undefined && options.sessionTemplate === undefined ? {
269
+ model: options.modelId
270
+ } : {})
271
+ };
272
+ const entry = await store.create(options.target.folderUri, value, guard);
273
+ this.assertCurrentStore(store);
274
+ return this.toAutomation(entry);
275
+ }
276
+ async updateAutomation(id, patch) {
277
+ const store = this.requireWritableStore();
278
+ const {
279
+ entry
280
+ } = await store.update(this.requireEntry(id), current => this.updateValue(current, id, patch));
281
+ this.assertCurrentStore(store);
282
+ if (!entry) {
283
+ throw ( new AutomationUnavailableError(( localize(
284
+ 5033,
285
+ "This cloud automation is no longer available. Refresh the catalogue."
286
+ ))));
287
+ }
288
+ return this.toAutomation(entry);
289
+ }
290
+ async updateAutomationIfUnchanged(id, patch, expected, guard) {
291
+ const store = this.requireWritableStore();
292
+ const entry = this.requireEntry(id);
293
+ const result = await store.update(entry, current => {
294
+ const latest = this.toAutomation({
295
+ repository: entry.repository,
296
+ definition: current
297
+ });
298
+ return serializeAutomationEditableState(latest) === serializeAutomationEditableState(expected) ? this.updateValue(current, id, patch) : undefined;
299
+ }, guard);
300
+ this.assertCurrentStore(store);
301
+ if (!result.entry) {
302
+ return {
303
+ kind: "conflict",
304
+ current: undefined
305
+ };
306
+ }
307
+ const automation = this.toAutomation(result.entry);
308
+ return result.updated ? {
309
+ kind: "updated",
310
+ automation
311
+ } : {
312
+ kind: "conflict",
313
+ current: automation
314
+ };
315
+ }
316
+ async deleteAutomation(id, guard) {
317
+ await this.requireWritableStore().delete(this.requireEntry(id), guard);
318
+ }
319
+ async runAutomation(id, token = CancellationToken.None) {
320
+ const store = this.requireWritableStore();
321
+ try {
322
+ await store.run(this.requireEntry(id), token);
323
+ } catch (error) {
324
+ if ((error instanceof MutationUncertainError || error instanceof ApiRequestError && error.outcome === "indeterminate") && this.store.get() === store) {
325
+ this.discoveryAttempts = 4;
326
+ this.refreshHistoryInBackground();
327
+ }
328
+ throw error;
329
+ }
330
+ this.assertCurrentStore(store);
331
+ this.discoveryAttempts = 4;
332
+ this.refreshHistoryInBackground();
333
+ return {
334
+ kind: "accepted"
335
+ };
336
+ }
337
+ canStopRun(run) {
338
+ return this.canRunAutomation(run.automationId) && ( this.runs.get().some(
339
+ current => current.id === run.id && (current.status === "pending" || current.status === "running")
340
+ ));
341
+ }
342
+ async stopRun(run) {
343
+ const store = this.requireWritableStore();
344
+ const entry = store.history.get().find(entry => this.toRun(entry)?.id === run.id);
345
+ if (!entry || !this.canStopRun(run)) {
346
+ throw ( new AutomationUnavailableError(( localize(5034, "Unable to stop this cloud automation run."))));
347
+ }
348
+ await store.stop(entry);
349
+ this.assertCurrentStore(store);
350
+ this.discoveryAttempts = 4;
351
+ this.refreshHistoryInBackground();
352
+ }
353
+ updateValue(definition, id, patch) {
354
+ validateLocalOptions(patch);
355
+ if (patch.sessionTemplate === null) {
356
+ throw ( new Error(( localize(5035, "Resetting cloud automation configuration is not supported."))));
357
+ }
358
+ const current = this.getAutomation(id);
359
+ assertAutomationSessionTemplateAuthority(current, patch);
360
+ if (cloudAutomationSchedule(definition.triggers).interval === "custom") {
361
+ throw ( new Error(( localize(5036, "This automation uses triggers that cannot be edited in VS Code."))));
362
+ }
363
+ if (patch.target) {
364
+ this.validateTarget(patch.target);
365
+ if (current.target.kind !== "workspace" || !isEqual(current.target.folderUri, patch.target.folderUri)) {
366
+ throw ( new Error(( localize(5037, "Duplicate this automation to use another repository."))));
367
+ }
368
+ }
369
+ let triggers = patch.schedule ? cloudAutomationTriggers(patch.schedule) : undefined;
370
+ if (triggers?.interval && definition.triggers?.interval) {
371
+ const {
372
+ types: _types,
373
+ hour_utc: _hour,
374
+ minute_utc: _minute,
375
+ day_of_week: _day,
376
+ ...otherFields
377
+ } = definition.triggers.interval;
378
+ triggers = {
379
+ interval: {
380
+ ...otherFields,
381
+ ...triggers.interval
382
+ }
383
+ };
384
+ }
385
+ return {
386
+ ...(patch.name !== undefined ? {
387
+ name: patch.name
388
+ } : {}),
389
+ ...(patch.prompt !== undefined ? {
390
+ prompt: patch.prompt
391
+ } : {}),
392
+ ...(patch.enabled !== undefined ? {
393
+ disabled: !patch.enabled
394
+ } : {}),
395
+ ...(triggers !== undefined ? {
396
+ triggers
397
+ } : {}),
398
+ ...(patch.sessionTemplate !== undefined ? templateMutation(patch.sessionTemplate) : {}),
399
+ ...(patch.modelId !== undefined ? {
400
+ model: patch.modelId ?? ""
401
+ } : {})
402
+ };
403
+ }
404
+ validateTarget(target) {
405
+ if (target.providerId !== this.providerId || target.sessionTypeId !== this.sessionTypeId || target.kind !== "workspace" || target.isolation.kind !== "default") {
406
+ throw ( new Error(( localize(
407
+ 5038,
408
+ "Select a GitHub repository with default isolation for this cloud automation."
409
+ ))));
410
+ }
411
+ }
412
+ requireStore() {
413
+ const store = this.store.get();
414
+ if (!store || !this.enabled.get() || this._store.isDisposed) {
415
+ throw ( new AutomationUnavailableError(( localize(
416
+ 5039,
417
+ "Sign in to GitHub.com and enable cloud automations before continuing."
418
+ ))));
419
+ }
420
+ return store;
421
+ }
422
+ assertCurrentStore(store) {
423
+ if (this.store.get() !== store || this._store.isDisposed) {
424
+ throw ( new CancellationError());
425
+ }
426
+ }
427
+ requireWritableStore() {
428
+ const store = this.requireStore();
429
+ if (!this.canCreateAutomation.get()) {
430
+ throw ( new AutomationUnavailableError(( localize(5040, "Refresh cloud automations before submitting another request."))));
431
+ }
432
+ return store;
433
+ }
434
+ requireEntry(id) {
435
+ const entry = this.requireStore().entries.get().find(entry => this.toAutomation(entry).id === id);
436
+ if (!entry) {
437
+ throw ( new AutomationUnavailableError(( localize(
438
+ 5033,
439
+ "This cloud automation is no longer available. Refresh the catalogue."
440
+ ))));
441
+ }
442
+ return entry;
443
+ }
444
+ toAutomation(entry) {
445
+ const {
446
+ definition,
447
+ repository
448
+ } = entry;
449
+ const schedule = cloudAutomationSchedule(definition.triggers);
450
+ return {
451
+ id: JSON.stringify([
452
+ this.providerId,
453
+ this.defaultAccountService.currentDefaultAccount?.accountName,
454
+ repository.owner.toLowerCase(),
455
+ repository.name.toLowerCase(),
456
+ definition.id
457
+ ]),
458
+ name: definition.name,
459
+ prompt: definition.prompt,
460
+ schedule,
461
+ targetDisplay: {
462
+ label: `${repository.owner}/${repository.name}`,
463
+ icon: Codicon.cloud
464
+ },
465
+ externalResource: ( URI.from({
466
+ scheme: Schemas.https,
467
+ authority: "github.com",
468
+ path: `/${repository.owner}/${repository.name}/agents/automations/${definition.id}`
469
+ })),
470
+ target: {
471
+ kind: "workspace",
472
+ providerId: this.providerId,
473
+ sessionTypeId: this.sessionTypeId,
474
+ isolation: {
475
+ kind: "default"
476
+ },
477
+ folderUri: ( URI.from({
478
+ scheme: GITHUB_REMOTE_FILE_SCHEME,
479
+ authority: "github",
480
+ path: `/${repository.owner}/${repository.name}/HEAD`
481
+ }))
482
+ },
483
+ sessionTemplate: {
484
+ ...(definition.model ? {
485
+ modelId: definition.model
486
+ } : {}),
487
+ config: {
488
+ ...(definition.tools ? {
489
+ tools: definition.tools
490
+ } : {}),
491
+ ...(definition.reasoning_effort ? {
492
+ reasoningEffort: definition.reasoning_effort
493
+ } : {})
494
+ }
495
+ },
496
+ enabled: definition.disabled !== true,
497
+ createdAt: definition.created_at,
498
+ updatedAt: definition.updated_at,
499
+ ...(schedule.interval === "custom" ? {
500
+ readOnlyReason: ( localize(5041, "This automation uses triggers that cannot be edited in VS Code."))
501
+ } : {})
502
+ };
503
+ }
504
+ toRun(
505
+ {
506
+ entry,
507
+ task
508
+ }
509
+ ) {
510
+ const status = cloudTaskStatus(task);
511
+ if (status === undefined) {
512
+ this.logService.warn(
513
+ `[CloudAutomations] Skipping run ${task.id} with unsupported state: ${task.state}`
514
+ );
515
+ return undefined;
516
+ }
517
+ const automationId = this.toAutomation(entry).id;
518
+ return {
519
+ id: JSON.stringify([automationId, task.id]),
520
+ automationId,
521
+ status,
522
+ trigger: "external",
523
+ startedAt: task.created_at,
524
+ updatedAt: task.updated_at,
525
+ ...(status === "completed" || status === "failed" ? {
526
+ completedAt: task.updated_at
527
+ } : {}),
528
+ ...(status === "failed" ? {
529
+ errorMessage: task.status || task.state
530
+ } : {}),
531
+ ...(task.state === "waiting_for_user" ? {
532
+ needsInput: true,
533
+ statusDescription: ( localize(5042, "Needs input on GitHub"))
534
+ } : {}),
535
+ externalResource: ( URI.from({
536
+ scheme: Schemas.https,
537
+ authority: "github.com",
538
+ path: `/${entry.repository.owner}/${entry.repository.name}/tasks/${task.id}`
539
+ }))
540
+ };
541
+ }
542
+ };
543
+ CloudAutomationStore = ( __decorate([( __param(3, IConfigurationService)), ( __param(4, IDefaultAccountService)), ( __param(5, IChatEntitlementService)), ( __param(6, IInstantiationService)), ( __param(7, ILogService)), ( __param(8, IGitHubService)), ( __param(9, IWorkbenchGitHubService))], CloudAutomationStore));
544
+ function toToolCatalog(catalog, available) {
545
+ if (!available) {
546
+ return {
547
+ kind: "error",
548
+ message: ( localize(5043, "Cloud automations are unavailable."))
549
+ };
550
+ }
551
+ if (catalog?.kind === "error") {
552
+ return {
553
+ kind: "error",
554
+ message: ( localize(5044, "Available tools could not be loaded."))
555
+ };
556
+ }
557
+ if (catalog?.kind !== "ready") {
558
+ return {
559
+ kind: "loading"
560
+ };
561
+ }
562
+ return {
563
+ kind: "ready",
564
+ groups: catalog.groups.map(group => ({
565
+ id: group.id,
566
+ label: group.name || group.title || group.id,
567
+ tools: group.tools.map(tool => ({
568
+ id: tool.id,
569
+ label: tool.name || tool.title || tool.id,
570
+ description: tool.description || undefined
571
+ }))
572
+ }))
573
+ };
574
+ }
575
+ function validateLocalOptions(options) {
576
+ if (options.mode !== undefined || options.permissionLevel !== undefined) {
577
+ throw ( new Error(( localize(5045, "Cloud automations do not support local mode or approval settings."))));
578
+ }
579
+ if ((options.name !== undefined && !options.name.trim()) || (options.prompt !== undefined && !options.prompt.trim())) {
580
+ throw ( new Error(( localize(5046, "An automation name and prompt are required."))));
581
+ }
582
+ }
583
+ function templateMutation(template) {
584
+ const tools = template?.config?.tools;
585
+ const reasoning = template?.config?.reasoningEffort;
586
+ if (template?.agent || template?.modelConfiguration || ( ( Object.keys(template?.config ?? {})).some(key => key !== "tools" && key !== "reasoningEffort")) || (tools !== undefined && !isStringArray(tools)) || (reasoning !== undefined && typeof reasoning !== "string")) {
587
+ throw ( new Error(( localize(5047, "This session configuration is not supported by cloud automations."))));
588
+ }
589
+ return {
590
+ model: template?.modelId ?? "",
591
+ ...(isStringArray(tools) ? {
592
+ tools
593
+ } : {}),
594
+ ...(typeof reasoning === "string" ? {
595
+ reasoning_effort: reasoning
596
+ } : {})
597
+ };
598
+ }
599
+ function cloudAutomationSchedule(triggers) {
600
+ const base = {
601
+ scheduleHour: 0,
602
+ scheduleMinute: 0,
603
+ scheduleDay: 0,
604
+ timeZone: "UTC"
605
+ };
606
+ if (( Object.keys(triggers ?? {})).length === 0) {
607
+ return {
608
+ ...base,
609
+ interval: "manual"
610
+ };
611
+ }
612
+ const trigger = triggers?.interval;
613
+ if (( Object.keys(triggers ?? {})).length !== 1 || !trigger || trigger.types?.length !== 1) {
614
+ return {
615
+ ...base,
616
+ interval: "custom"
617
+ };
618
+ }
619
+ const interval = trigger.types[0];
620
+ if (interval === "hourly") {
621
+ return {
622
+ ...base,
623
+ interval
624
+ };
625
+ }
626
+ const hour = trigger.hour_utc;
627
+ const minute = trigger.minute_utc ?? 0;
628
+ const day = trigger.day_of_week ?? 0;
629
+ if ((interval === "daily" || interval === "weekly") && typeof hour === "number" && Number.isInteger(hour) && hour >= 0 && hour < 24 && typeof minute === "number" && [0, 15, 30, 45].includes(minute) && typeof day === "number" && Number.isInteger(day) && day >= 0 && day < 7) {
630
+ return {
631
+ ...base,
632
+ interval,
633
+ scheduleHour: hour,
634
+ scheduleMinute: minute,
635
+ scheduleDay: day
636
+ };
637
+ }
638
+ return {
639
+ ...base,
640
+ interval: "custom"
641
+ };
642
+ }
643
+ function cloudAutomationTriggers(schedule) {
644
+ if (schedule.interval === "manual") {
645
+ return {};
646
+ }
647
+ if (schedule.interval === "hourly") {
648
+ return {
649
+ interval: {
650
+ types: ["hourly"]
651
+ }
652
+ };
653
+ }
654
+ const minute = schedule.scheduleMinute;
655
+ if (schedule.timeZone !== "UTC" || (schedule.interval !== "daily" && schedule.interval !== "weekly") || !Number.isInteger(schedule.scheduleHour) || schedule.scheduleHour < 0 || schedule.scheduleHour > 23 || (minute !== 0 && minute !== 15 && minute !== 30 && minute !== 45) || !Number.isInteger(schedule.scheduleDay) || schedule.scheduleDay < 0 || schedule.scheduleDay > 6) {
656
+ throw ( new Error(( localize(
657
+ 5048,
658
+ "Choose a daily or weekly UTC schedule with minutes 00, 15, 30, or 45."
659
+ ))));
660
+ }
661
+ return {
662
+ interval: {
663
+ types: [schedule.interval],
664
+ hour_utc: schedule.scheduleHour,
665
+ minute_utc: minute,
666
+ ...(schedule.interval === "weekly" ? {
667
+ day_of_week: schedule.scheduleDay
668
+ } : {})
669
+ }
670
+ };
671
+ }
672
+ function cloudTaskStatus(task) {
673
+ const state = task.state;
674
+ switch (state) {
675
+ case "queued":
676
+ return "pending";
677
+ case "in_progress":
678
+ case "running":
679
+ case "waiting_for_user":
680
+ return "running";
681
+ case "completed":
682
+ case "idle":
683
+ return "completed";
684
+ case "failed":
685
+ case "timed_out":
686
+ case "cancelled":
687
+ case "canceled":
688
+ case "error":
689
+ return "failed";
690
+ default:
691
+ return undefined;
692
+ }
693
+ }
694
+
695
+ export { CloudAutomationStore, cloudAutomationSchedule, cloudAutomationTriggers };