@cleanslate/sdk 1.0.7 → 1.0.9

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 (84) hide show
  1. package/README.md +81 -5
  2. package/VENDOR.md +7 -8
  3. package/dist/agent/cleanSlateAgentExecutionPhase.d.ts.map +1 -1
  4. package/dist/agent/cleanSlateAgentExecutionPhase.js +7 -1
  5. package/dist/agent/cleanSlateAgentExecutionPhase.js.map +1 -1
  6. package/dist/agent/cleanSlateExecutionQuery.d.ts +1 -0
  7. package/dist/agent/cleanSlateExecutionQuery.d.ts.map +1 -1
  8. package/dist/agent/cleanSlateExecutionQuery.js +135 -89
  9. package/dist/agent/cleanSlateExecutionQuery.js.map +1 -1
  10. package/dist/agent/cleanSlateToolResultPromptSerializer.js +27 -5
  11. package/dist/agent/cleanSlateToolResultPromptSerializer.js.map +1 -1
  12. package/dist/index.d.ts +4 -0
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +2 -0
  15. package/dist/index.js.map +1 -1
  16. package/dist/node/cleanSlateHostedAgentRuntime.d.ts +41 -0
  17. package/dist/node/cleanSlateHostedAgentRuntime.d.ts.map +1 -0
  18. package/dist/node/cleanSlateHostedAgentRuntime.js +525 -0
  19. package/dist/node/cleanSlateHostedAgentRuntime.js.map +1 -0
  20. package/dist/node/cleanSlateManagedAuth.d.ts +19 -0
  21. package/dist/node/cleanSlateManagedAuth.d.ts.map +1 -0
  22. package/dist/node/cleanSlateManagedAuth.js +123 -0
  23. package/dist/node/cleanSlateManagedAuth.js.map +1 -0
  24. package/dist/node/cleanSlateNodeAgentRuntime.d.ts +51 -1
  25. package/dist/node/cleanSlateNodeAgentRuntime.d.ts.map +1 -1
  26. package/dist/node/cleanSlateNodeAgentRuntime.js +188 -17
  27. package/dist/node/cleanSlateNodeAgentRuntime.js.map +1 -1
  28. package/dist/node/cleanSlateNodeBrowserAutomation.d.ts +12 -0
  29. package/dist/node/cleanSlateNodeBrowserAutomation.d.ts.map +1 -1
  30. package/dist/node/cleanSlateNodeBrowserAutomation.js +73 -14
  31. package/dist/node/cleanSlateNodeBrowserAutomation.js.map +1 -1
  32. package/dist/node/cleanSlateNodeCommandService.d.ts.map +1 -1
  33. package/dist/node/cleanSlateNodeCommandService.js +4 -0
  34. package/dist/node/cleanSlateNodeCommandService.js.map +1 -1
  35. package/dist/node/cleanSlateNodeMainService.d.ts +2 -1
  36. package/dist/node/cleanSlateNodeMainService.d.ts.map +1 -1
  37. package/dist/node/cleanSlateNodeMainService.js +1 -0
  38. package/dist/node/cleanSlateNodeMainService.js.map +1 -1
  39. package/dist/node/cleanSlateNodeToolContext.d.ts +2 -0
  40. package/dist/node/cleanSlateNodeToolContext.d.ts.map +1 -1
  41. package/dist/node/cleanSlateNodeToolContext.js +1 -1
  42. package/dist/node/cleanSlateNodeToolContext.js.map +1 -1
  43. package/dist/node/index.d.ts +6 -1
  44. package/dist/node/index.d.ts.map +1 -1
  45. package/dist/node/index.js +3 -0
  46. package/dist/node/index.js.map +1 -1
  47. package/dist/protocol/cleanSlateAI.d.ts +63 -6
  48. package/dist/protocol/cleanSlateAI.d.ts.map +1 -1
  49. package/dist/protocol/cleanSlateAI.js +1 -0
  50. package/dist/protocol/cleanSlateAI.js.map +1 -1
  51. package/dist/protocol/cleanSlateManagedTokenCoordinator.d.ts +16 -0
  52. package/dist/protocol/cleanSlateManagedTokenCoordinator.d.ts.map +1 -0
  53. package/dist/protocol/cleanSlateManagedTokenCoordinator.js +66 -0
  54. package/dist/protocol/cleanSlateManagedTokenCoordinator.js.map +1 -0
  55. package/dist/protocol/cleanSlateService.d.ts.map +1 -1
  56. package/dist/protocol/cleanSlateService.js +3 -5
  57. package/dist/protocol/cleanSlateService.js.map +1 -1
  58. package/dist/services/cleanSlateAgentCoordinator.d.ts +81 -0
  59. package/dist/services/cleanSlateAgentCoordinator.d.ts.map +1 -0
  60. package/dist/services/cleanSlateAgentCoordinator.js +243 -0
  61. package/dist/services/cleanSlateAgentCoordinator.js.map +1 -0
  62. package/dist/services/cleanSlateConversationBranchService.d.ts +34 -0
  63. package/dist/services/cleanSlateConversationBranchService.d.ts.map +1 -0
  64. package/dist/services/cleanSlateConversationBranchService.js +70 -0
  65. package/dist/services/cleanSlateConversationBranchService.js.map +1 -0
  66. package/dist/services/cleanSlateTools.d.ts +2 -0
  67. package/dist/services/cleanSlateTools.d.ts.map +1 -1
  68. package/dist/services/cleanSlateTools.js +2 -0
  69. package/dist/services/cleanSlateTools.js.map +1 -1
  70. package/dist/tools/BrowserAutomationTools.d.ts.map +1 -1
  71. package/dist/tools/BrowserAutomationTools.js +6 -3
  72. package/dist/tools/BrowserAutomationTools.js.map +1 -1
  73. package/dist/tools/ExecuteCommandTool.js +2 -2
  74. package/dist/tools/ExecuteCommandTool.js.map +1 -1
  75. package/dist/tools/SpawnWorkerTool.d.ts +3 -0
  76. package/dist/tools/SpawnWorkerTool.d.ts.map +1 -1
  77. package/dist/tools/SpawnWorkerTool.js +101 -10
  78. package/dist/tools/SpawnWorkerTool.js.map +1 -1
  79. package/dist/tools/registry.d.ts.map +1 -1
  80. package/dist/tools/registry.js +4 -1
  81. package/dist/tools/registry.js.map +1 -1
  82. package/dist/tools/types.d.ts +3 -0
  83. package/dist/tools/types.d.ts.map +1 -1
  84. package/package.json +1 -1
@@ -0,0 +1,123 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) CleanSlate. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { spawnSync } from 'node:child_process';
6
+ const DEFAULT_API_BASE_URL = 'https://api.thewariend.com/api';
7
+ function resolveApiBaseUrl(value) {
8
+ const baseUrl = (value?.trim() || process.env['CLEANSLATE_API_BASE_URL']?.trim() || DEFAULT_API_BASE_URL).replace(/\/+$/, '');
9
+ const parsed = new URL(baseUrl);
10
+ const localDevelopment = isLocalHostname(parsed.hostname);
11
+ if (parsed.protocol !== 'https:' && !(parsed.protocol === 'http:' && localDevelopment)) {
12
+ throw new Error('CleanSlate authentication requires HTTPS (HTTP is allowed only for local development).');
13
+ }
14
+ if (parsed.username || parsed.password || parsed.search || parsed.hash) {
15
+ throw new Error('CleanSlate authentication API URLs cannot contain credentials, query parameters, or fragments.');
16
+ }
17
+ return baseUrl;
18
+ }
19
+ function isLocalHostname(hostname) {
20
+ return hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '[::1]';
21
+ }
22
+ function seconds(value, fallback, minimum, maximum) {
23
+ return typeof value === 'number' && Number.isFinite(value)
24
+ ? Math.min(maximum, Math.max(minimum, value))
25
+ : fallback;
26
+ }
27
+ async function responseError(response) {
28
+ const body = await response.json().catch(() => ({}));
29
+ const validation = body.errors ? Object.values(body.errors)[0]?.[0] : undefined;
30
+ return new Error(validation || body.message || body.error || `CleanSlate authentication failed (${response.status}).`);
31
+ }
32
+ async function loadEntitlements(baseUrl, token, fetcher, signal) {
33
+ const response = await fetcher(`${baseUrl}/cleanslate/entitlements`, {
34
+ headers: { Accept: 'application/json', Authorization: `Bearer ${token}`, 'Cache-Control': 'no-store' },
35
+ signal
36
+ });
37
+ if (!response.ok) {
38
+ throw await responseError(response);
39
+ }
40
+ const body = await response.json();
41
+ if (!body.data) {
42
+ throw new Error('CleanSlate authentication succeeded, but no managed-model entitlements were returned.');
43
+ }
44
+ return body.data;
45
+ }
46
+ function openSystemBrowser(url) {
47
+ const command = process.platform === 'darwin' ? '/usr/bin/open' : process.platform === 'win32' ? 'rundll32.exe' : 'xdg-open';
48
+ const args = process.platform === 'win32' ? ['url.dll,FileProtocolHandler', url] : [url];
49
+ const result = spawnSync(command, args, { stdio: 'ignore' });
50
+ if (result.status !== 0) {
51
+ throw new Error(`Could not open the system browser. Open this URL manually: ${url}`);
52
+ }
53
+ }
54
+ function wait(milliseconds, signal) {
55
+ return new Promise((resolve, reject) => {
56
+ if (signal?.aborted) {
57
+ reject(new Error('CleanSlate sign-in was cancelled.'));
58
+ return;
59
+ }
60
+ const finish = () => {
61
+ signal?.removeEventListener('abort', cancel);
62
+ resolve();
63
+ };
64
+ const timeout = setTimeout(finish, milliseconds);
65
+ const cancel = () => {
66
+ clearTimeout(timeout);
67
+ signal?.removeEventListener('abort', cancel);
68
+ reject(new Error('CleanSlate sign-in was cancelled.'));
69
+ };
70
+ signal?.addEventListener('abort', cancel, { once: true });
71
+ });
72
+ }
73
+ /** Open the browser-based device flow and return a token usable by provider `cleanslate`. */
74
+ export async function authenticateCleanSlateInBrowser(options = {}) {
75
+ const baseUrl = resolveApiBaseUrl(options.apiBaseUrl);
76
+ const fetcher = options.fetcher ?? fetch;
77
+ const startResponse = await fetcher(`${baseUrl}/auth/device`, {
78
+ method: 'POST',
79
+ headers: { Accept: 'application/json', 'Content-Type': 'application/json' },
80
+ body: JSON.stringify({
81
+ device_name: options.deviceName?.trim() || `CleanSlate SDK (${process.platform})`
82
+ }),
83
+ signal: options.signal
84
+ });
85
+ if (!startResponse.ok) {
86
+ throw await responseError(startResponse);
87
+ }
88
+ const authorization = await startResponse.json();
89
+ if (!authorization.device_code || !authorization.verification_uri_complete) {
90
+ throw new Error('The server did not return a valid CleanSlate device authorization.');
91
+ }
92
+ const verificationUrl = new URL(authorization.verification_uri_complete);
93
+ const localVerificationUrl = verificationUrl.protocol === 'http:' && isLocalHostname(verificationUrl.hostname);
94
+ if ((verificationUrl.protocol !== 'https:' && !localVerificationUrl) || verificationUrl.username || verificationUrl.password) {
95
+ throw new Error('CleanSlate returned an insecure device authorization URL.');
96
+ }
97
+ options.onReady?.(verificationUrl.href);
98
+ await (options.openBrowser ?? openSystemBrowser)(verificationUrl.href);
99
+ const deadline = Date.now() + seconds(authorization.expires_in, 600, 1, 3_600) * 1_000;
100
+ const interval = seconds(authorization.interval, 2, 1, 60) * 1_000;
101
+ const sleep = options.sleep ?? wait;
102
+ while (Date.now() < deadline) {
103
+ if (options.signal?.aborted) {
104
+ throw new Error('CleanSlate sign-in was cancelled.');
105
+ }
106
+ const tokenResponse = await fetcher(`${baseUrl}/auth/device/token`, {
107
+ method: 'POST',
108
+ headers: { Accept: 'application/json', 'Content-Type': 'application/json' },
109
+ body: JSON.stringify({ device_code: authorization.device_code }),
110
+ signal: options.signal
111
+ });
112
+ const tokenBody = await tokenResponse.json().catch(() => ({}));
113
+ if (tokenResponse.ok && tokenBody.token) {
114
+ return { token: tokenBody.token, entitlements: await loadEntitlements(baseUrl, tokenBody.token, fetcher, options.signal) };
115
+ }
116
+ if (tokenBody.error !== 'authorization_pending') {
117
+ throw new Error(tokenBody.error || `CleanSlate authentication failed (${tokenResponse.status}).`);
118
+ }
119
+ await sleep(interval, options.signal);
120
+ }
121
+ throw new Error('CleanSlate browser sign-in timed out.');
122
+ }
123
+ //# sourceMappingURL=cleanSlateManagedAuth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cleanSlateManagedAuth.js","sourceRoot":"","sources":["../../src/node/cleanSlateManagedAuth.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { CleanSlateStreamPart } from '../agent/cleanSlateAgentTypes.js';
2
- import { AIProvider, CleanSlateEmbeddingProvider, ICleanSlateConfiguration, ICleanSlateAgentRuntimeSnapshot, ICleanSlateLogger, ICleanSlatePendingAgentInteraction, IChatMessagePart } from '../protocol/cleanSlateAI.js';
2
+ import { AIProvider, CleanSlateEmbeddingProvider, ICleanSlateConfiguration, ICleanSlateAgentRuntimeSnapshot, ICleanSlateLogger, ICleanSlateMainService, ICleanSlateManagedEntitlements, ICleanSlatePendingAgentInteraction, IChatMessagePart } from '../protocol/cleanSlateAI.js';
3
+ import { CleanSlateManagedTokenCoordinator } from '../protocol/cleanSlateManagedTokenCoordinator.js';
3
4
  import { ICleanSlateTaskSessionSnapshot } from '../services/cleanSlateTaskSessionService.js';
4
5
  import { ICleanSlateThreadMessage } from '../services/cleanSlateThreadService.js';
5
6
  import type { CleanSlateTool } from '../tools/types.js';
@@ -7,6 +8,8 @@ import type { ICleanSlateDomainProfile } from '../agent/cleanSlateDomainProfile.
7
8
  import type { AgentDefinition } from '../composer/registry/agentSchema.js';
8
9
  export interface ICleanSlateNodeAgentRuntimeOptions {
9
10
  rootPath: string;
11
+ /** A desktop host can reuse its authenticated transport and runtime endpoints. */
12
+ mainService?: ICleanSlateMainService;
10
13
  /** Private host directory for per-workspace state such as edit recovery history. */
11
14
  workspaceStorageHome?: string;
12
15
  configuration: ICleanSlateConfiguration;
@@ -20,6 +23,9 @@ export interface ICleanSlateNodeAgentRuntimeOptions {
20
23
  instructions?: string | ((task: string) => string | Promise<string>);
21
24
  /** Whether browser automation should run without a visible browser window. */
22
25
  browserHeadless?: boolean;
26
+ browserAutomationService?: import('../host/browserAutomation.js').ICleanSlateBrowserAutomationService;
27
+ /** Child runtimes share the parent's desktop browser without owning its lifetime. */
28
+ disposeBrowserAutomationService?: boolean;
23
29
  approveCommand?: (request: {
24
30
  command: string;
25
31
  cwd?: string;
@@ -29,7 +35,18 @@ export interface ICleanSlateNodeAgentRuntimeOptions {
29
35
  type: string;
30
36
  [key: string]: any;
31
37
  }) => void;
38
+ /** Desktop hosts present artifacts in their own views instead of an external viewer. */
39
+ onArtifact?: (artifact: {
40
+ id: string;
41
+ type: string;
42
+ content: string;
43
+ metadata?: any;
44
+ }) => void;
32
45
  onManagedTokenRefresh?: (token: string) => void | Promise<void>;
46
+ /** Shared authority for hosted conversations, workers and account settings. */
47
+ managedTokenCoordinator?: CleanSlateManagedTokenCoordinator;
48
+ /** Surface-specific recovery copy. CLI hosts default to the setup command. */
49
+ managedSessionExpiredMessage?: string;
33
50
  fetcher?: typeof fetch;
34
51
  logger?: Partial<ICleanSlateLogger>;
35
52
  sessionId?: string;
@@ -43,6 +60,15 @@ export interface ICleanSlateNodeAgentRuntimeOptions {
43
60
  }) => boolean | Promise<boolean>;
44
61
  /** Multimodal parts explicitly attached by the host for a user turn. */
45
62
  resolveAttachments?: (task: string) => IChatMessagePart[] | Promise<IChatMessagePart[]>;
63
+ /** Maximum child agents owned by this runtime at once. */
64
+ maxConcurrentAgents?: number;
65
+ /** Receives portable child-agent lifecycle events for a host UI or logger. */
66
+ onAgentEvent?: (event: {
67
+ type: string;
68
+ [key: string]: any;
69
+ }) => void;
70
+ /** @internal Prevents recursive worker trees. */
71
+ workerDepth?: number;
46
72
  }
47
73
  export interface ICleanSlateNodeAgentSessionSnapshot {
48
74
  version: 1;
@@ -51,6 +77,12 @@ export interface ICleanSlateNodeAgentSessionSnapshot {
51
77
  task?: ICleanSlateTaskSessionSnapshot;
52
78
  threadHistory: ICleanSlateThreadMessage[];
53
79
  }
80
+ export interface ICleanSlateNodeSideChat {
81
+ id: string;
82
+ title: string;
83
+ createdAt: number;
84
+ runtime: CleanSlateNodeAgentRuntime;
85
+ }
54
86
  /**
55
87
  * Wires CleanSlate's existing execution loop to the Node host and complete tool registry.
56
88
  */
@@ -59,29 +91,47 @@ export declare class CleanSlateNodeAgentRuntime {
59
91
  private readonly rootPath;
60
92
  private readonly mainService;
61
93
  private readonly configService;
94
+ private readonly managedTokenCoordinator;
62
95
  private readonly headlessRuntime;
63
96
  private readonly queryRunner;
64
97
  private readonly cleanSlateService;
65
98
  private readonly agentSession;
66
99
  private readonly threadService;
67
100
  private readonly taskSessionService;
101
+ private readonly agentCoordinator;
102
+ private readonly sideChats;
68
103
  private readonly sessionId;
69
104
  private readonly contextService;
70
105
  constructor(options: ICleanSlateNodeAgentRuntimeOptions);
71
106
  run(task: string, signal?: AbortSignal): AsyncIterable<CleanSlateStreamPart>;
107
+ configureRun(configuration: ICleanSlateConfiguration, agentDefinition?: AgentDefinition): Promise<void>;
72
108
  plan(task: string, signal?: AbortSignal): AsyncIterable<CleanSlateStreamPart>;
73
109
  private runInPhase;
74
110
  resumePendingQuestion(answer: string, signal?: AbortSignal): AsyncIterable<CleanSlateStreamPart>;
75
111
  approvePlan(signal?: AbortSignal): AsyncIterable<CleanSlateStreamPart>;
76
112
  getPendingQuestion(): ICleanSlatePendingAgentInteraction | undefined;
113
+ rejectPlan(): void;
77
114
  getSessionSnapshot(): ICleanSlateNodeAgentSessionSnapshot;
78
115
  restoreSessionSnapshot(snapshot: ICleanSlateNodeAgentSessionSnapshot | undefined): void;
79
116
  clearConversation(): void;
117
+ /** Creates an independent conversational runtime attached to this session. */
118
+ createSideChat(options?: {
119
+ id?: string;
120
+ title?: string;
121
+ inheritContext?: boolean;
122
+ }): ICleanSlateNodeSideChat;
123
+ listSideChats(): Array<Omit<ICleanSlateNodeSideChat, 'runtime'>>;
124
+ getSideChat(id: string): ICleanSlateNodeSideChat | undefined;
125
+ closeSideChat(id: string): boolean;
80
126
  getModels(): Promise<string[]>;
127
+ getManagedEntitlements(): Promise<ICleanSlateManagedEntitlements>;
81
128
  private runMessages;
82
129
  getAvailableToolCount(): number;
83
130
  getResult(): import("./cleanSlateHeadlessRunner.js").ICleanSlateHeadlessRunResult;
84
131
  dispose(): void;
132
+ listChildAgents(): import("../services/cleanSlateAgentCoordinator.js").ICleanSlateChildAgentSnapshot[];
133
+ cancelChildAgent(agentId: string): boolean;
134
+ private runChildAgent;
85
135
  private buildPromptContext;
86
136
  private workspaceIsEmpty;
87
137
  private getToolDescriptions;
@@ -1 +1 @@
1
- {"version":3,"file":"cleanSlateNodeAgentRuntime.d.ts","sourceRoot":"","sources":["../../src/node/cleanSlateNodeAgentRuntime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cleanSlateNodeAgentRuntime.d.ts","sourceRoot":"","sources":["../../src/node/cleanSlateNodeAgentRuntime.ts"],"names":[],"mappings":"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"}
@@ -13,38 +13,68 @@ import { CleanSlateQueryRunner } from '../agent/cleanSlateQueryRunner.js';
13
13
  import { Event } from '../core/event.js';
14
14
  import { getCleanSlateContextDefaults } from '../protocol/cleanSlateModelCapabilities.js';
15
15
  import { CleanSlateService } from '../protocol/cleanSlateService.js';
16
+ import { CleanSlateManagedTokenCoordinator } from '../protocol/cleanSlateManagedTokenCoordinator.js';
16
17
  import { CleanSlateTaskSessionService } from '../services/cleanSlateTaskSessionService.js';
17
18
  import { CleanSlateTaskKind, CleanSlateWorkspaceShape } from '../services/cleanSlateTaskState.js';
18
19
  import { CleanSlateThreadService } from '../services/cleanSlateThreadService.js';
20
+ import { CleanSlateAgentCoordinator, formatCleanSlateChildAgentNotification } from '../services/cleanSlateAgentCoordinator.js';
19
21
  import { ALL_TOOLS } from '../tools/registry.js';
20
22
  import { CleanSlateHeadlessRuntime } from './cleanSlateHeadlessRunner.js';
21
23
  import { NodeCleanSlateMainService } from './cleanSlateNodeMainService.js';
22
24
  class NodeConfigurationService {
23
- constructor(configuration, mainService, onManagedTokenRefresh, fetcher = fetch) {
25
+ constructor(configuration, mainService, onManagedTokenRefresh, managedSessionExpiredMessage = 'Your CleanSlate session expired. Run cleanslate --setup to sign in again.', fetcher = fetch, managedTokenCoordinator) {
24
26
  this.configuration = configuration;
25
27
  this.mainService = mainService;
26
28
  this.onManagedTokenRefresh = onManagedTokenRefresh;
29
+ this.managedSessionExpiredMessage = managedSessionExpiredMessage;
27
30
  this.fetcher = fetcher;
28
31
  this.onDidChangeConfiguration = Event.None;
32
+ this.managedTokenCoordinator = managedTokenCoordinator ?? new CleanSlateManagedTokenCoordinator(token => this.rotateManagedToken(token));
29
33
  }
30
34
  getConfiguration() {
35
+ const token = this.configuration.providers?.cleanslate?.apiKey;
36
+ const resolved = token ? this.managedTokenCoordinator.resolve(token) : token;
37
+ if (resolved !== token) {
38
+ this.configuration = {
39
+ ...this.configuration,
40
+ providers: {
41
+ ...this.configuration.providers,
42
+ cleanslate: { ...this.configuration.providers?.cleanslate, apiKey: resolved }
43
+ }
44
+ };
45
+ }
31
46
  return this.configuration;
32
47
  }
33
48
  getResolvedConfiguration() {
34
- return Promise.resolve(this.configuration);
49
+ return Promise.resolve(this.getConfiguration());
35
50
  }
36
51
  updateConfiguration(config) {
37
- this.configuration = { ...this.configuration, ...config };
52
+ const incomingManagedToken = config.providers?.cleanslate?.apiKey;
53
+ this.configuration = {
54
+ ...this.configuration,
55
+ ...config,
56
+ providers: config.providers ? {
57
+ ...config.providers,
58
+ cleanslate: config.providers.cleanslate ? {
59
+ ...config.providers.cleanslate,
60
+ apiKey: incomingManagedToken ? this.managedTokenCoordinator.resolve(incomingManagedToken) : incomingManagedToken
61
+ } : config.providers.cleanslate
62
+ } : this.configuration.providers
63
+ };
38
64
  return Promise.resolve();
39
65
  }
40
66
  async refreshManagedToken(rejectedToken) {
41
- const current = this.configuration.providers?.cleanslate?.apiKey;
67
+ const current = this.getConfiguration().providers?.cleanslate?.apiKey;
42
68
  if (!current) {
43
69
  throw new Error('Sign in to CleanSlate again.');
44
70
  }
45
71
  if (rejectedToken && current !== rejectedToken) {
46
72
  return current;
47
73
  }
74
+ const response = await this.managedTokenCoordinator.refresh(current);
75
+ return response.token;
76
+ }
77
+ async rotateManagedToken(current) {
48
78
  const runtimeConfig = await this.mainService.getRuntimeConfig();
49
79
  const response = await this.fetcher(`${runtimeConfig.apiBaseUrl}/auth/refresh`, {
50
80
  method: 'POST',
@@ -52,24 +82,21 @@ class NodeConfigurationService {
52
82
  });
53
83
  const body = await this.readJson(response);
54
84
  if (response.status === 401) {
55
- throw new Error('Your CleanSlate session expired. Run cleanslate --setup to sign in again.');
85
+ throw new Error(this.managedSessionExpiredMessage);
56
86
  }
57
87
  if (!response.ok || typeof body?.token !== 'string' || !body.token) {
58
88
  throw new Error(body?.message || `Unable to refresh the CleanSlate session (${response.status}).`);
59
89
  }
60
90
  const token = body.token;
61
- this.configuration = {
62
- ...this.configuration,
63
- providers: {
64
- ...this.configuration.providers,
65
- cleanslate: { ...this.configuration.providers?.cleanslate, apiKey: token }
66
- }
67
- };
68
91
  await this.onManagedTokenRefresh?.(token);
69
- return token;
92
+ return {
93
+ token,
94
+ expires_at: typeof body.expires_at === 'string' ? body.expires_at : undefined,
95
+ expires_in: typeof body.expires_in === 'number' || typeof body.expires_in === 'string' ? body.expires_in : undefined
96
+ };
70
97
  }
71
98
  async getManagedEntitlements() {
72
- let token = this.configuration.providers?.cleanslate?.apiKey;
99
+ let token = this.getConfiguration().providers?.cleanslate?.apiKey;
73
100
  if (!token) {
74
101
  throw new Error('Sign in to CleanSlate to view your managed models.');
75
102
  }
@@ -128,21 +155,38 @@ export class CleanSlateNodeAgentRuntime {
128
155
  this.agentSession = new CleanSlateAgentSession();
129
156
  this.threadService = new CleanSlateThreadService();
130
157
  this.taskSessionService = new CleanSlateTaskSessionService();
158
+ this.sideChats = new Map();
131
159
  this.contextService = {
132
160
  _serviceBrand: undefined,
133
161
  getContext: async () => ({ activeFile: undefined, openFiles: [] })
134
162
  };
135
163
  this.rootPath = path.resolve(options.rootPath);
136
164
  this.sessionId = options.sessionId?.trim() || `cli-${process.pid}-${Date.now()}`;
137
- this.mainService = new NodeCleanSlateMainService(this.rootPath);
138
- this.configService = new NodeConfigurationService(options.configuration, this.mainService, options.onManagedTokenRefresh, options.fetcher);
165
+ this.mainService = options.mainService ?? new NodeCleanSlateMainService(this.rootPath);
166
+ this.configService = new NodeConfigurationService(options.configuration, this.mainService, options.onManagedTokenRefresh, options.managedSessionExpiredMessage, options.fetcher, options.managedTokenCoordinator);
167
+ this.managedTokenCoordinator = this.configService.managedTokenCoordinator;
139
168
  const cleanSlateService = new CleanSlateService(this.configService, this.mainService, createLogger(options.logger));
140
169
  this.cleanSlateService = cleanSlateService;
170
+ this.agentCoordinator = new CleanSlateAgentCoordinator((request, context) => this.runChildAgent(request, context.id, context.signal, context.emitStreamPart), { maxConcurrentAgents: options.maxConcurrentAgents });
171
+ this.agentCoordinator.onDidChangeAgent(event => {
172
+ options.onAgentEvent?.({
173
+ type: 'child_agent',
174
+ eventType: event.type,
175
+ agent: event.agent,
176
+ delta: event.delta,
177
+ streamPart: event.streamPart
178
+ });
179
+ if (event.agent.parentAgentId === this.sessionId
180
+ && (event.agent.status === 'completed' || event.agent.status === 'failed' || event.agent.status === 'cancelled')) {
181
+ this.agentSession.appendMessage({ role: 'system', content: formatCleanSlateChildAgentNotification(event.agent) });
182
+ }
183
+ });
141
184
  this.headlessRuntime = new CleanSlateHeadlessRuntime({
142
185
  rootPath: this.rootPath,
143
186
  workspaceStorageHome: options.workspaceStorageHome,
144
187
  configuration: options.configuration,
145
188
  browserHeadless: options.browserHeadless,
189
+ browserAutomationService: options.browserAutomationService,
146
190
  fetcher: options.fetcher,
147
191
  tools: options.tools ?? ALL_TOOLS,
148
192
  cleanSlateService,
@@ -152,8 +196,15 @@ export class CleanSlateNodeAgentRuntime {
152
196
  onProgress: options.onProgress
153
197
  });
154
198
  const toolContext = this.headlessRuntime.getToolContext();
199
+ // Tools (including spawn_worker) must use the same owner as model calls.
200
+ toolContext.sessionId = this.sessionId;
201
+ if (options.onArtifact) {
202
+ toolContext.artifactPresentationHost = { openArtifact: async () => { } };
203
+ toolContext.artifactService.onDidArtifactChange(options.onArtifact);
204
+ }
155
205
  toolContext.cleanSlateMainService = this.mainService;
156
206
  toolContext.contextService = this.contextService;
207
+ toolContext.agentCoordinator = this.agentCoordinator;
157
208
  const parsingSupport = new CleanSlateAgentParsingSupport(this.configService);
158
209
  const executionSupport = new CleanSlateAgentExecutionSupport(toolContext.workspaceContextService, toolContext.markerService, this.contextService);
159
210
  this.queryRunner = new CleanSlateQueryRunner({
@@ -179,6 +230,11 @@ export class CleanSlateNodeAgentRuntime {
179
230
  async *run(task, signal) {
180
231
  yield* this.runInPhase(task, AgentPhase.EXECUTION, signal);
181
232
  }
233
+ async configureRun(configuration, agentDefinition) {
234
+ this.options.agentDefinition = agentDefinition;
235
+ await this.configService.updateConfiguration(configuration);
236
+ this.options.configuration = this.configService.getConfiguration();
237
+ }
182
238
  async *plan(task, signal) {
183
239
  yield* this.runInPhase(task, AgentPhase.PLANNING, signal);
184
240
  }
@@ -236,6 +292,10 @@ export class CleanSlateNodeAgentRuntime {
236
292
  getPendingQuestion() {
237
293
  return this.agentSession.getSnapshot()?.pendingInteraction;
238
294
  }
295
+ rejectPlan() {
296
+ this.taskSessionService.setAwaitingApproval(false);
297
+ this.taskSessionService.setPhase(AgentPhase.PLANNING);
298
+ }
239
299
  getSessionSnapshot() {
240
300
  return {
241
301
  version: 1,
@@ -258,9 +318,61 @@ export class CleanSlateNodeAgentRuntime {
258
318
  this.taskSessionService.reset();
259
319
  this.threadService.clearHistory();
260
320
  }
321
+ /** Creates an independent conversational runtime attached to this session. */
322
+ createSideChat(options = {}) {
323
+ const id = options.id?.trim() || `${this.sessionId}-side-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
324
+ if (this.sideChats.has(id)) {
325
+ throw new Error(`Side chat already exists: ${id}`);
326
+ }
327
+ const inheritedHistory = options.inheritContext === false
328
+ ? ''
329
+ : this.threadService.getActiveTaskHistory()
330
+ .filter(message => !message.isInternalState && (message.role === 'user' || message.role === 'assistant'))
331
+ .slice(-8)
332
+ .map(message => `${message.role}: ${message.content}`)
333
+ .join('\n\n');
334
+ const parentAdditionalContext = this.options.additionalContext;
335
+ const runtime = new CleanSlateNodeAgentRuntime({
336
+ ...this.options,
337
+ configuration: this.configService.getConfiguration(),
338
+ managedTokenCoordinator: this.managedTokenCoordinator,
339
+ sessionId: id,
340
+ disposeBrowserAutomationService: !this.options.browserAutomationService,
341
+ additionalContext: async (task) => {
342
+ const base = typeof parentAdditionalContext === 'function'
343
+ ? await parentAdditionalContext(task)
344
+ : parentAdditionalContext;
345
+ return [
346
+ base?.trim(),
347
+ inheritedHistory ? `Parent conversation context (read-only):\n${inheritedHistory}` : ''
348
+ ].filter(Boolean).join('\n\n');
349
+ }
350
+ });
351
+ const sideChat = { id, title: options.title?.trim() || 'Side chat', createdAt: Date.now(), runtime };
352
+ this.sideChats.set(id, sideChat);
353
+ return sideChat;
354
+ }
355
+ listSideChats() {
356
+ return Array.from(this.sideChats.values()).map(({ id, title, createdAt }) => ({ id, title, createdAt }));
357
+ }
358
+ getSideChat(id) {
359
+ return this.sideChats.get(id);
360
+ }
361
+ closeSideChat(id) {
362
+ const sideChat = this.sideChats.get(id);
363
+ if (!sideChat) {
364
+ return false;
365
+ }
366
+ sideChat.runtime.dispose();
367
+ this.sideChats.delete(id);
368
+ return true;
369
+ }
261
370
  getModels() {
262
371
  return this.cleanSlateService.getModels();
263
372
  }
373
+ getManagedEntitlements() {
374
+ return this.configService.getManagedEntitlements();
375
+ }
264
376
  async *runMessages(messages, objective, phase, signal) {
265
377
  const parsingSupport = new CleanSlateAgentParsingSupport(this.configService);
266
378
  const budget = new CleanSlateExecutionBudget(parsingSupport.getExecutionLoopSettings().maxTurns);
@@ -285,10 +397,69 @@ export class CleanSlateNodeAgentRuntime {
285
397
  return this.headlessRuntime.getResult();
286
398
  }
287
399
  dispose() {
400
+ for (const sideChat of this.sideChats.values()) {
401
+ sideChat.runtime.dispose();
402
+ }
403
+ this.sideChats.clear();
288
404
  const context = this.headlessRuntime.getToolContext();
289
405
  context.commandExecutionService.dispose?.();
290
- void context.browserAutomationService.dispose?.();
406
+ if (this.options.disposeBrowserAutomationService !== false) {
407
+ void context.browserAutomationService.dispose?.();
408
+ }
291
409
  void context.mcpClientService.dispose?.();
410
+ if (!this.options.managedTokenCoordinator) {
411
+ this.managedTokenCoordinator.clear();
412
+ }
413
+ }
414
+ listChildAgents() {
415
+ return this.agentCoordinator.listAgents(this.sessionId);
416
+ }
417
+ cancelChildAgent(agentId) {
418
+ return this.agentCoordinator.cancelAgent(agentId);
419
+ }
420
+ async runChildAgent(request, agentId, signal, emitStreamPart) {
421
+ const workerDepth = this.options.workerDepth ?? 0;
422
+ if (workerDepth >= 1) {
423
+ throw new Error('Nested child agents are disabled. Return the work to the parent agent instead.');
424
+ }
425
+ const child = new CleanSlateNodeAgentRuntime({
426
+ ...this.options,
427
+ configuration: this.configService.getConfiguration(),
428
+ managedTokenCoordinator: this.managedTokenCoordinator,
429
+ sessionId: agentId,
430
+ workerDepth: workerDepth + 1,
431
+ disposeBrowserAutomationService: !this.options.browserAutomationService,
432
+ // A child receives the same capabilities, but not delegation authority.
433
+ tools: (this.options.tools ?? ALL_TOOLS).filter(tool => tool.name !== 'spawn_worker'
434
+ && tool.name !== 'wait_worker'
435
+ && tool.name !== 'list_workers'
436
+ && tool.name !== 'cancel_worker'),
437
+ instructions: async (task) => {
438
+ const base = typeof this.options.instructions === 'function'
439
+ ? await this.options.instructions(task)
440
+ : this.options.instructions;
441
+ return [
442
+ base?.trim(),
443
+ `You are a ${request.kind ?? 'worker'} child agent. Complete only this bounded assignment and return a concise, evidence-backed result to the parent.`,
444
+ `Assignment label: ${request.description}`
445
+ ].filter(Boolean).join('\n\n');
446
+ },
447
+ onProgress: event => this.options.onProgress?.({ ...event, agentId }),
448
+ onAgentEvent: event => this.options.onAgentEvent?.(event)
449
+ });
450
+ let output = '';
451
+ try {
452
+ for await (const part of child.run(request.prompt, signal)) {
453
+ emitStreamPart(part);
454
+ if ((part.type === 'chat_text' || part.type === 'text') && part.content) {
455
+ output += part.content;
456
+ }
457
+ }
458
+ return output.trim();
459
+ }
460
+ finally {
461
+ child.dispose();
462
+ }
292
463
  }
293
464
  async buildPromptContext(task = '') {
294
465
  const instructions = typeof this.options.instructions === 'function'