@cleanslate/sdk 0.1.0 → 1.0.2

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 (156) hide show
  1. package/README.md +11 -3
  2. package/VENDOR.md +15 -4
  3. package/dist/agent/cleanSlateAgentSession.d.ts +5 -0
  4. package/dist/agent/cleanSlateAgentSession.d.ts.map +1 -1
  5. package/dist/agent/cleanSlateAgentSession.js +5 -0
  6. package/dist/agent/cleanSlateAgentSession.js.map +1 -1
  7. package/dist/agent/cleanSlateExecutionQuery.d.ts.map +1 -1
  8. package/dist/agent/cleanSlateExecutionQuery.js +2 -1
  9. package/dist/agent/cleanSlateExecutionQuery.js.map +1 -1
  10. package/dist/agent/cleanSlateProviderMessageOrder.d.ts +24 -0
  11. package/dist/agent/cleanSlateProviderMessageOrder.d.ts.map +1 -0
  12. package/dist/agent/cleanSlateProviderMessageOrder.js +37 -0
  13. package/dist/agent/cleanSlateProviderMessageOrder.js.map +1 -0
  14. package/dist/agent/cleanSlateStreamReveal.d.ts +46 -0
  15. package/dist/agent/cleanSlateStreamReveal.d.ts.map +1 -0
  16. package/dist/agent/cleanSlateStreamReveal.js +94 -0
  17. package/dist/agent/cleanSlateStreamReveal.js.map +1 -0
  18. package/dist/composer/instructions/baseInstructions.d.ts +1 -1
  19. package/dist/composer/instructions/baseInstructions.d.ts.map +1 -1
  20. package/dist/composer/instructions/baseInstructions.js +1 -1
  21. package/dist/composer/kernel/coreKernel.d.ts +1 -1
  22. package/dist/composer/kernel/coreKernel.d.ts.map +1 -1
  23. package/dist/composer/kernel/coreKernel.js +1 -1
  24. package/dist/core/buffer.d.ts +19 -15
  25. package/dist/core/buffer.d.ts.map +1 -1
  26. package/dist/core/buffer.js +129 -12
  27. package/dist/core/buffer.js.map +1 -1
  28. package/dist/core/path.d.ts +40 -0
  29. package/dist/core/path.d.ts.map +1 -0
  30. package/dist/core/path.js +1461 -0
  31. package/dist/core/path.js.map +1 -0
  32. package/dist/core/platform.d.ts.map +1 -1
  33. package/dist/core/platform.js +20 -9
  34. package/dist/core/platform.js.map +1 -1
  35. package/dist/core/process.d.ts +13 -0
  36. package/dist/core/process.d.ts.map +1 -0
  37. package/dist/core/process.js +25 -0
  38. package/dist/core/process.js.map +1 -0
  39. package/dist/core/resources.js +3 -3
  40. package/dist/core/uri.js +1 -1
  41. package/dist/host/browserAutomation.d.ts +3 -3
  42. package/dist/host/browserAutomation.d.ts.map +1 -1
  43. package/dist/host/events.d.ts +21 -0
  44. package/dist/host/events.d.ts.map +1 -0
  45. package/dist/host/events.js +6 -0
  46. package/dist/host/events.js.map +1 -0
  47. package/dist/host/files.d.ts +11 -2
  48. package/dist/host/files.d.ts.map +1 -1
  49. package/dist/host/services.d.ts +4 -4
  50. package/dist/host/services.d.ts.map +1 -1
  51. package/dist/host/textModel.d.ts +9 -3
  52. package/dist/host/textModel.d.ts.map +1 -1
  53. package/dist/host/workspace.d.ts +18 -5
  54. package/dist/host/workspace.d.ts.map +1 -1
  55. package/dist/host/workspace.js.map +1 -1
  56. package/dist/index.d.ts +7 -5
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +1 -1
  59. package/dist/index.js.map +1 -1
  60. package/dist/node/cleanSlateHeadlessRunner.d.ts +8 -0
  61. package/dist/node/cleanSlateHeadlessRunner.d.ts.map +1 -1
  62. package/dist/node/cleanSlateHeadlessRunner.js +1 -1
  63. package/dist/node/cleanSlateHeadlessRunner.js.map +1 -1
  64. package/dist/node/cleanSlateMemoryVectorStore.d.ts +19 -0
  65. package/dist/node/cleanSlateMemoryVectorStore.d.ts.map +1 -0
  66. package/dist/node/cleanSlateMemoryVectorStore.js +73 -0
  67. package/dist/node/cleanSlateMemoryVectorStore.js.map +1 -0
  68. package/dist/node/cleanSlateNodeAgentRuntime.d.ts +8 -1
  69. package/dist/node/cleanSlateNodeAgentRuntime.d.ts.map +1 -1
  70. package/dist/node/cleanSlateNodeAgentRuntime.js +41 -2
  71. package/dist/node/cleanSlateNodeAgentRuntime.js.map +1 -1
  72. package/dist/node/cleanSlateNodeHttpTransport.d.ts +33 -0
  73. package/dist/node/cleanSlateNodeHttpTransport.d.ts.map +1 -0
  74. package/dist/node/cleanSlateNodeHttpTransport.js +181 -0
  75. package/dist/node/cleanSlateNodeHttpTransport.js.map +1 -0
  76. package/dist/node/cleanSlateNodeIndexService.d.ts +88 -10
  77. package/dist/node/cleanSlateNodeIndexService.d.ts.map +1 -1
  78. package/dist/node/cleanSlateNodeIndexService.js +447 -93
  79. package/dist/node/cleanSlateNodeIndexService.js.map +1 -1
  80. package/dist/node/cleanSlateNodeMainService.d.ts +18 -10
  81. package/dist/node/cleanSlateNodeMainService.d.ts.map +1 -1
  82. package/dist/node/cleanSlateNodeMainService.js +169 -121
  83. package/dist/node/cleanSlateNodeMainService.js.map +1 -1
  84. package/dist/node/cleanSlateNodeSearchService.d.ts +7 -1
  85. package/dist/node/cleanSlateNodeSearchService.d.ts.map +1 -1
  86. package/dist/node/cleanSlateNodeSearchService.js +11 -11
  87. package/dist/node/cleanSlateNodeSearchService.js.map +1 -1
  88. package/dist/node/cleanSlateNodeToolContext.d.ts +2 -0
  89. package/dist/node/cleanSlateNodeToolContext.d.ts.map +1 -1
  90. package/dist/node/cleanSlateNodeToolContext.js +20 -1
  91. package/dist/node/cleanSlateNodeToolContext.js.map +1 -1
  92. package/dist/node/cleanSlateNodeWebRetrieval.d.ts +3 -0
  93. package/dist/node/cleanSlateNodeWebRetrieval.d.ts.map +1 -1
  94. package/dist/node/cleanSlateNodeWebRetrieval.js +6 -1
  95. package/dist/node/cleanSlateNodeWebRetrieval.js.map +1 -1
  96. package/dist/node/cleanSlateOpenAIMessageAdapter.d.ts.map +1 -1
  97. package/dist/node/cleanSlateOpenAIMessageAdapter.js +4 -0
  98. package/dist/node/cleanSlateOpenAIMessageAdapter.js.map +1 -1
  99. package/dist/node/index.d.ts +4 -0
  100. package/dist/node/index.d.ts.map +1 -1
  101. package/dist/node/index.js +2 -0
  102. package/dist/node/index.js.map +1 -1
  103. package/dist/protocol/cleanSlateAI.d.ts +13 -13
  104. package/dist/protocol/cleanSlateAI.d.ts.map +1 -1
  105. package/dist/protocol/cleanSlateCodeParser.d.ts +13 -0
  106. package/dist/protocol/cleanSlateCodeParser.d.ts.map +1 -0
  107. package/dist/protocol/cleanSlateCodeParser.js +102 -0
  108. package/dist/protocol/cleanSlateCodeParser.js.map +1 -0
  109. package/dist/protocol/cleanSlateModelsDevCatalog.d.ts +27 -0
  110. package/dist/protocol/cleanSlateModelsDevCatalog.d.ts.map +1 -0
  111. package/dist/protocol/cleanSlateModelsDevCatalog.js +87 -0
  112. package/dist/protocol/cleanSlateModelsDevCatalog.js.map +1 -0
  113. package/dist/protocol/cleanSlateProviderTranscript.d.ts +25 -0
  114. package/dist/protocol/cleanSlateProviderTranscript.d.ts.map +1 -0
  115. package/dist/protocol/cleanSlateProviderTranscript.js +125 -0
  116. package/dist/protocol/cleanSlateProviderTranscript.js.map +1 -0
  117. package/dist/protocol/cleanSlateRuntimeConfig.d.ts +33 -0
  118. package/dist/protocol/cleanSlateRuntimeConfig.d.ts.map +1 -0
  119. package/dist/protocol/cleanSlateRuntimeConfig.js +63 -0
  120. package/dist/protocol/cleanSlateRuntimeConfig.js.map +1 -0
  121. package/dist/protocol/cleanSlateService.js.map +1 -1
  122. package/dist/protocol/cleanSlateThreadSession.d.ts +17 -0
  123. package/dist/protocol/cleanSlateThreadSession.d.ts.map +1 -0
  124. package/dist/protocol/cleanSlateThreadSession.js +34 -0
  125. package/dist/protocol/cleanSlateThreadSession.js.map +1 -0
  126. package/dist/services/cleanSlateCommandExecutionService.d.ts +3 -3
  127. package/dist/services/cleanSlateCommandExecutionService.d.ts.map +1 -1
  128. package/dist/services/cleanSlateFileHistory.js +3 -4
  129. package/dist/services/cleanSlateFileHistory.js.map +1 -1
  130. package/dist/tools/FindByNameTool.js +2 -2
  131. package/dist/tools/FindByNameTool.js.map +1 -1
  132. package/dist/tools/FindReferencesTool.js +2 -2
  133. package/dist/tools/FindReferencesTool.js.map +1 -1
  134. package/dist/tools/GetDefinitionsTool.js +2 -2
  135. package/dist/tools/GetDefinitionsTool.js.map +1 -1
  136. package/dist/tools/GrepSearchTool.d.ts.map +1 -1
  137. package/dist/tools/GrepSearchTool.js +16 -10
  138. package/dist/tools/GrepSearchTool.js.map +1 -1
  139. package/dist/tools/ListDirTool.js +2 -2
  140. package/dist/tools/ListDirTool.js.map +1 -1
  141. package/dist/tools/ReadFileRangeTool.js +2 -2
  142. package/dist/tools/ReadFileRangeTool.js.map +1 -1
  143. package/dist/tools/ReadFileTool.js +2 -2
  144. package/dist/tools/ReadFileTool.js.map +1 -1
  145. package/dist/tools/ReadLintsTool.js +3 -3
  146. package/dist/tools/ReadLintsTool.js.map +1 -1
  147. package/dist/tools/ReadSymbolsTool.js +2 -2
  148. package/dist/tools/ReadSymbolsTool.js.map +1 -1
  149. package/dist/tools/SubmitArtifactTool.d.ts.map +1 -1
  150. package/dist/tools/SubmitArtifactTool.js +4 -6
  151. package/dist/tools/SubmitArtifactTool.js.map +1 -1
  152. package/dist/tools/utils.d.ts +19 -1
  153. package/dist/tools/utils.d.ts.map +1 -1
  154. package/dist/tools/utils.js +64 -16
  155. package/dist/tools/utils.js.map +1 -1
  156. package/package.json +14 -2
@@ -3,6 +3,7 @@ import { CancellationToken } from '../core/cancellation.js';
3
3
  import { Event } from '../core/event.js';
4
4
  import { IRequestOptions } from '../host/services.js';
5
5
  import { AIProvider, ICleanSlateAnthropicListModelsOptions, ICleanSlateAnthropicMessagesOptions, ICleanSlateBackgroundCommandOptions, ICleanSlateBackgroundCommandResult, ICleanSlateBedrockConverseStreamOptions, ICleanSlateBedrockListModelsOptions, ICleanSlateBufferedRequestResponse, ICleanSlateCommandExecutionOptions, ICleanSlateCommandExecutionResult, ICleanSlateCommandOutputEvent, ICleanSlateGeminiGenerateContentOptions, ICleanSlateGeminiListModelsOptions, ICleanSlateLocalEmbeddingOptions, ICleanSlateLocalEmbeddingResponse, ICleanSlateMainService, ICleanSlateModelsDevModelMetadata, ICleanSlateOpenAICompatibleChatOptions, ICleanSlateOpenAICompatibleListModelsOptions, ICleanSlateOpenAIResponsesOptions, ICleanSlatePersistedSession, ICleanSlatePlaywrightBrowserRequest, ICleanSlateRuntimeConfig, ICleanSlateStopBackgroundCommandResult, ICleanSlateThreadSessionUpdate, ICleanSlateWebFetchOptions, ICleanSlateWebFetchResponse, ICleanSlateWebSearchOptions, ICleanSlateWebSearchResponse } from '../protocol/cleanSlateAI.js';
6
+ import { CleanSlateEnvLookup } from '../protocol/cleanSlateRuntimeConfig.js';
6
7
  /**
7
8
  * Node implementation of the provider-facing service used by CleanSlateService.
8
9
  *
@@ -17,19 +18,30 @@ export declare class NodeCleanSlateMainService implements ICleanSlateMainService
17
18
  private readonly openAIMessageAdapter;
18
19
  private readonly anthropicMessageAdapter;
19
20
  private readonly commandService;
21
+ private readonly envLookup;
22
+ private readonly httpTransport;
20
23
  private readonly webRetrieval;
24
+ private modelsDevCatalogCache;
25
+ private modelsDevCatalogRequest;
21
26
  readonly onDidPublishThreadSession: Event<ICleanSlateThreadSessionUpdate>;
22
- constructor(rootPath?: string);
27
+ constructor(rootPath?: string, envLookup?: CleanSlateEnvLookup);
23
28
  getRuntimeConfig(): Promise<ICleanSlateRuntimeConfig>;
24
- getModelsDevModelMetadata(_provider: AIProvider, _model: string, _token: CancellationToken): Promise<ICleanSlateModelsDevModelMetadata | undefined>;
29
+ /**
30
+ * Per-model facts from models.dev — notably which reasoning efforts the model accepts, which
31
+ * `resolveCleanSlateModelCapabilities` turns into `supportedReasoningEfforts`. This used to
32
+ * return `undefined`, so the terminal host reported every model as having no reasoning
33
+ * options and fell back to local limit guesses.
34
+ */
35
+ getModelsDevModelMetadata(provider: AIProvider, model: string, token: CancellationToken): Promise<ICleanSlateModelsDevModelMetadata | undefined>;
36
+ private getModelsDevCatalog;
25
37
  listOpenAICompatibleModels(options: ICleanSlateOpenAICompatibleListModelsOptions, token: CancellationToken): Promise<string[]>;
26
38
  openAICompatibleChatStream(options: ICleanSlateOpenAICompatibleChatOptions, token: CancellationToken): Event<VSBuffer | string | null>;
27
39
  openAIResponsesStream(options: ICleanSlateOpenAIResponsesOptions, token: CancellationToken): Event<VSBuffer | string | null>;
28
40
  listAnthropicModels(options: ICleanSlateAnthropicListModelsOptions, token: CancellationToken): Promise<string[]>;
29
41
  anthropicMessagesStream(options: ICleanSlateAnthropicMessagesOptions, token: CancellationToken): Event<VSBuffer | string | null>;
30
42
  executeCommand(options: ICleanSlateCommandExecutionOptions): Promise<ICleanSlateCommandExecutionResult>;
31
- proxyRequest(_options: IRequestOptions, _token: CancellationToken): Promise<ICleanSlateBufferedRequestResponse>;
32
- proxyStream(_options: IRequestOptions, _token: CancellationToken): Event<VSBuffer | string | null>;
43
+ proxyRequest(options: IRequestOptions, token: CancellationToken): Promise<ICleanSlateBufferedRequestResponse>;
44
+ proxyStream(options: IRequestOptions, token: CancellationToken): Event<VSBuffer | string | null>;
33
45
  listGeminiModels(options: ICleanSlateGeminiListModelsOptions, token: CancellationToken): Promise<string[]>;
34
46
  geminiGenerateContentStream(options: ICleanSlateGeminiGenerateContentOptions, token: CancellationToken): Event<VSBuffer | string | null>;
35
47
  listBedrockFoundationModels(options: ICleanSlateBedrockListModelsOptions, token: CancellationToken): Promise<string[]>;
@@ -54,13 +66,9 @@ export declare class NodeCleanSlateMainService implements ICleanSlateMainService
54
66
  removeThreadSession(_sessionId: string): Promise<void>;
55
67
  removeArchivedThreadSession(_workspaceId: string, _sessionId: string): Promise<void>;
56
68
  private createGeminiClient;
57
- private toGeminiContents;
58
- private toGeminiToolResultTranscriptText;
59
- private safeStringifyForTranscript;
60
69
  private extractGeminiThoughtText;
61
70
  private extractGeminiFunctionCallParts;
62
71
  private collectGeminiPendingToolCall;
63
- private toGeminiParts;
64
72
  private createBedrockClientConfig;
65
73
  private toProviderConverseRequest;
66
74
  private createOpenAICompatibleClient;
@@ -70,11 +78,11 @@ export declare class NodeCleanSlateMainService implements ICleanSlateMainService
70
78
  private isOpenRouterProviderName;
71
79
  private isCustomProviderName;
72
80
  private isCleanSlateManagedProviderName;
73
- private normalizeEnvValue;
81
+ private createProxyFetchRequest;
82
+ private responseHeaders;
74
83
  private importExternalModule;
75
84
  private createProviderAbortController;
76
85
  private toProviderErrorMessage;
77
- private messageContentToText;
78
86
  private parseToolInput;
79
87
  private emitProviderPart;
80
88
  private toProviderUsage;
@@ -1 +1 @@
1
- {"version":3,"file":"cleanSlateNodeMainService.d.ts","sourceRoot":"","sources":["../../src/node/cleanSlateNodeMainService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cleanSlateNodeMainService.d.ts","sourceRoot":"","sources":["../../src/node/cleanSlateNodeMainService.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@
2
2
  * Copyright (c) CleanSlate. All rights reserved.
3
3
  * Licensed under the MIT License. See License.txt in the project root for license information.
4
4
  *--------------------------------------------------------------------------------------------*/
5
+ import { VSBuffer } from '../core/buffer.js';
5
6
  import { Emitter, Event } from '../core/event.js';
6
7
  import { CleanSlateNodeCommandService } from './cleanSlateNodeCommandService.js';
7
8
  import { CleanSlateAnthropicMessageAdapter } from './cleanSlateAnthropicMessageAdapter.js';
@@ -9,6 +10,10 @@ import { CleanSlateOpenAIMessageAdapter } from './cleanSlateOpenAIMessageAdapter
9
10
  import { CleanSlateProviderSchemaNormalizer } from './cleanSlateProviderSchemaNormalizer.js';
10
11
  import { normalizeToolName } from '../protocol/cleanSlateProviderMessageTransforms.js';
11
12
  import { CleanSlateNodeWebRetrieval } from './cleanSlateNodeWebRetrieval.js';
13
+ import { CleanSlateNodeHttpTransport } from './cleanSlateNodeHttpTransport.js';
14
+ import { messageContentToText, toGeminiContents } from '../protocol/cleanSlateProviderTranscript.js';
15
+ import { buildCleanSlateRuntimeConfig, normalizeBaseUrlValue, normalizeEnvValue, resolveCleanSlateManagedBaseUrl } from '../protocol/cleanSlateRuntimeConfig.js';
16
+ import { findModelsDevMetadata, isValidModelsDevCatalog, MODELS_DEV_CACHE_TTL_MS, MODELS_DEV_CATALOG_URL } from '../protocol/cleanSlateModelsDevCatalog.js';
12
17
  const LEADING_REASONING_HOLD_CAP_CHARS = 8_000;
13
18
  /**
14
19
  * Node implementation of the provider-facing service used by CleanSlateService.
@@ -19,26 +24,62 @@ const LEADING_REASONING_HOLD_CAP_CHARS = 8_000;
19
24
  export class NodeCleanSlateMainService {
20
25
  static { this.MODEL_LIST_TIMEOUT_MS = 30_000; }
21
26
  static { this.PROVIDER_STREAM_IDLE_TIMEOUT_MS = 120_000; }
22
- constructor(rootPath = process.cwd()) {
27
+ constructor(rootPath = process.cwd(), envLookup = name => normalizeEnvValue(process.env[name])) {
23
28
  this.providerSchemaNormalizer = new CleanSlateProviderSchemaNormalizer();
24
29
  this.openAIMessageAdapter = new CleanSlateOpenAIMessageAdapter();
25
30
  this.anthropicMessageAdapter = new CleanSlateAnthropicMessageAdapter(this.providerSchemaNormalizer);
26
- this.webRetrieval = new CleanSlateNodeWebRetrieval();
27
31
  this.onDidPublishThreadSession = Event.None;
28
32
  this.commandService = new CleanSlateNodeCommandService(rootPath);
33
+ this.envLookup = envLookup;
34
+ this.httpTransport = new CleanSlateNodeHttpTransport(envLookup);
35
+ this.webRetrieval = new CleanSlateNodeWebRetrieval(this.httpTransport);
29
36
  }
30
37
  getRuntimeConfig() {
31
- const apiBaseUrl = this.normalizeEnvValue(process.env['CLEANSLATE_API_BASE_URL']) ?? 'https://api.thewariend.com/api';
32
- const authWebUrl = this.normalizeEnvValue(process.env['CLEANSLATE_AUTH_WEB_URL']) ?? 'https://thewariend.com/auth';
33
- return Promise.resolve({
34
- authWebUrl,
35
- apiBaseUrl,
36
- managedAIBaseUrl: `${apiBaseUrl}/cleanslate`,
37
- proCheckoutUrl: 'https://api.thewariend.com/checkout/cleanslate/pro'
38
- });
38
+ return Promise.resolve(buildCleanSlateRuntimeConfig(this.envLookup));
39
+ }
40
+ /**
41
+ * Per-model facts from models.dev — notably which reasoning efforts the model accepts, which
42
+ * `resolveCleanSlateModelCapabilities` turns into `supportedReasoningEfforts`. This used to
43
+ * return `undefined`, so the terminal host reported every model as having no reasoning
44
+ * options and fell back to local limit guesses.
45
+ */
46
+ async getModelsDevModelMetadata(provider, model, token) {
47
+ if (!model.trim()) {
48
+ return undefined;
49
+ }
50
+ return findModelsDevMetadata(await this.getModelsDevCatalog(token), provider, model);
39
51
  }
40
- getModelsDevModelMetadata(_provider, _model, _token) {
41
- return Promise.resolve(undefined);
52
+ async getModelsDevCatalog(token) {
53
+ if (this.modelsDevCatalogCache && this.modelsDevCatalogCache.expiresAt > Date.now()) {
54
+ return this.modelsDevCatalogCache.value;
55
+ }
56
+ // One in-flight request shared by concurrent callers; the catalog is a single document.
57
+ this.modelsDevCatalogRequest ??= (async () => {
58
+ const abort = this.createProviderAbortController(token, NodeCleanSlateMainService.MODEL_LIST_TIMEOUT_MS);
59
+ try {
60
+ const response = await this.httpTransport.fetch(MODELS_DEV_CATALOG_URL, { signal: abort.signal });
61
+ if (!response.ok) {
62
+ throw new Error(`HTTP ${response.status}`);
63
+ }
64
+ const parsed = await response.json();
65
+ if (!isValidModelsDevCatalog(parsed)) {
66
+ throw new Error('invalid catalog shape');
67
+ }
68
+ this.modelsDevCatalogCache = { expiresAt: Date.now() + MODELS_DEV_CACHE_TTL_MS, value: parsed };
69
+ return parsed;
70
+ }
71
+ catch (error) {
72
+ // Non-fatal: capability resolution falls back to the local tables, so offline and
73
+ // air-gapped installs keep working without catalog-derived facts.
74
+ console.warn(`[CleanSlateService] models.dev capability catalog unavailable; using local fallbacks: ${String(error)}`);
75
+ return undefined;
76
+ }
77
+ finally {
78
+ abort.dispose();
79
+ this.modelsDevCatalogRequest = undefined;
80
+ }
81
+ })();
82
+ return this.modelsDevCatalogRequest;
42
83
  }
43
84
  async listOpenAICompatibleModels(options, token) {
44
85
  if (!options.apiKey && !this.isCustomProviderName(options.providerName)) {
@@ -516,11 +557,50 @@ export class NodeCleanSlateMainService {
516
557
  executeCommand(options) {
517
558
  return this.commandService.executeCommand(options);
518
559
  }
519
- proxyRequest(_options, _token) {
520
- return this.unsupported('proxy requests');
560
+ async proxyRequest(options, token) {
561
+ const request = this.createProxyFetchRequest(options, token);
562
+ try {
563
+ const response = await this.httpTransport.fetch(request.url, request.init);
564
+ return {
565
+ res: { statusCode: response.status, headers: this.responseHeaders(response.headers) },
566
+ data: await response.text()
567
+ };
568
+ }
569
+ finally {
570
+ request.dispose();
571
+ }
521
572
  }
522
- proxyStream(_options, _token) {
523
- return this.unsupportedEvent('proxy streams');
573
+ proxyStream(options, token) {
574
+ const emitter = new Emitter();
575
+ (async () => {
576
+ let request;
577
+ try {
578
+ // Let callers subscribe before validation or setup can emit an error.
579
+ await Promise.resolve();
580
+ request = this.createProxyFetchRequest(options, token);
581
+ const response = await this.httpTransport.fetch(request.url, request.init);
582
+ if (!response.ok) {
583
+ emitter.fire(`ERROR: HTTP ${response.status}: ${await response.text() || response.statusText}`);
584
+ return;
585
+ }
586
+ const reader = response.body?.getReader();
587
+ while (reader) {
588
+ const next = await reader.read();
589
+ if (next.done) {
590
+ break;
591
+ }
592
+ emitter.fire(VSBuffer.wrap(next.value));
593
+ }
594
+ }
595
+ catch (error) {
596
+ emitter.fire(`ERROR: ${error instanceof Error ? error.message : String(error)}`);
597
+ }
598
+ finally {
599
+ request?.dispose();
600
+ emitter.fire(null);
601
+ }
602
+ })();
603
+ return emitter.event;
524
604
  }
525
605
  async listGeminiModels(options, token) {
526
606
  if (!options.apiKey) {
@@ -557,7 +637,7 @@ export class NodeCleanSlateMainService {
557
637
  }
558
638
  const client = await this.createGeminiClient(options);
559
639
  const googleModule = await this.importExternalModule('@google/genai');
560
- const { contents, systemInstruction } = this.toGeminiContents(options.messages);
640
+ const { contents, systemInstruction } = toGeminiContents(options.messages);
561
641
  abort = this.createProviderAbortController(token, NodeCleanSlateMainService.PROVIDER_STREAM_IDLE_TIMEOUT_MS);
562
642
  const config = {
563
643
  maxOutputTokens: options.maxOutputTokens || 16384,
@@ -808,6 +888,7 @@ export class NodeCleanSlateMainService {
808
888
  return this.unsupported('thread persistence');
809
889
  }
810
890
  async createGeminiClient(options) {
891
+ this.httpTransport.ensureGlobalDispatcher();
811
892
  const googleModule = await this.importExternalModule('@google/genai');
812
893
  const GoogleGenAI = googleModule.GoogleGenAI;
813
894
  if (!GoogleGenAI) {
@@ -815,61 +896,6 @@ export class NodeCleanSlateMainService {
815
896
  }
816
897
  return new GoogleGenAI({ apiKey: options.apiKey });
817
898
  }
818
- toGeminiContents(messages) {
819
- const systemParts = [];
820
- const contents = [];
821
- for (let index = 0; index < messages.length; index++) {
822
- const message = messages[index];
823
- if (message.role === 'system') {
824
- systemParts.push(...this.toGeminiParts(message.content));
825
- continue;
826
- }
827
- if (message.role === 'tool') {
828
- const parts = [];
829
- while (index < messages.length && messages[index].role === 'tool') {
830
- const toolMessage = messages[index];
831
- parts.push({ text: this.toGeminiToolResultTranscriptText(toolMessage) });
832
- index++;
833
- }
834
- index--;
835
- contents.push({ role: 'user', parts });
836
- continue;
837
- }
838
- const parts = this.toGeminiParts(message.content);
839
- if (message.role === 'assistant' && message.toolCalls?.length) {
840
- for (let toolIndex = 0; toolIndex < message.toolCalls.length; toolIndex++) {
841
- const toolCall = message.toolCalls[toolIndex];
842
- parts.push({
843
- text: [
844
- `Tool call (${toolCall.id || `call_${index}_${toolIndex}`}): ${toolCall.toolName || 'tool'}`,
845
- `Arguments: ${this.safeStringifyForTranscript(toolCall.input ?? {})}`
846
- ].join('\n')
847
- });
848
- }
849
- }
850
- if (parts.length) {
851
- contents.push({ role: message.role === 'assistant' ? 'model' : 'user', parts });
852
- }
853
- }
854
- return {
855
- contents,
856
- systemInstruction: systemParts.length ? { role: 'user', parts: systemParts } : undefined
857
- };
858
- }
859
- toGeminiToolResultTranscriptText(toolMessage) {
860
- return [
861
- `Tool result (${toolMessage.toolCallId || 'tool_result'}): ${toolMessage.toolName || 'tool'}`,
862
- this.messageContentToText(toolMessage.content)
863
- ].filter(part => typeof part === 'string' && part.trim().length > 0).join('\n');
864
- }
865
- safeStringifyForTranscript(value) {
866
- try {
867
- return JSON.stringify(value);
868
- }
869
- catch {
870
- return String(value);
871
- }
872
- }
873
899
  extractGeminiThoughtText(chunk) {
874
900
  let thought = '';
875
901
  for (const candidate of Array.isArray(chunk?.candidates) ? chunk.candidates : []) {
@@ -911,28 +937,12 @@ export class NodeCleanSlateMainService {
911
937
  thoughtSignature: call.thoughtSignature || existing?.thoughtSignature
912
938
  });
913
939
  }
914
- toGeminiParts(content) {
915
- if (typeof content === 'string') {
916
- return content.trim() ? [{ text: content }] : [];
917
- }
918
- if (!Array.isArray(content)) {
919
- return [];
920
- }
921
- return content.map(part => {
922
- if (part?.type === 'text') {
923
- return { text: part.text ?? '' };
924
- }
925
- if (part?.type === 'image_url' && part.image_url?.url) {
926
- const match = String(part.image_url.url).match(/^data:(image\/[a-zA-Z0-9.\-+]+);base64,(.*)$/);
927
- if (match) {
928
- return { inlineData: { mimeType: match[1], data: match[2] } };
929
- }
930
- }
931
- return null;
932
- }).filter(Boolean);
933
- }
934
940
  async createBedrockClientConfig(options) {
935
941
  const config = { region: options.region };
942
+ const requestHandler = this.httpTransport.createAwsRequestHandler();
943
+ if (requestHandler) {
944
+ config.requestHandler = requestHandler;
945
+ }
936
946
  if (options.credentialMode === 'accessKey') {
937
947
  if (!options.accessKeyId || !options.secretAccessKey) {
938
948
  throw new Error('Bedrock access key ID and secret access key are required for manual credential mode.');
@@ -948,11 +958,14 @@ export class NodeCleanSlateMainService {
948
958
  throw new Error('AWS profile name is required for Bedrock profile credential mode.');
949
959
  }
950
960
  const { fromIni } = await this.importExternalModule('@aws-sdk/credential-provider-ini');
951
- config.credentials = fromIni({ profile: options.profile });
961
+ config.credentials = fromIni({
962
+ profile: options.profile,
963
+ ...(requestHandler ? { clientConfig: { requestHandler } } : {})
964
+ });
952
965
  }
953
966
  else {
954
967
  const { defaultProvider } = await this.importExternalModule('@aws-sdk/credential-provider-node');
955
- config.credentials = defaultProvider();
968
+ config.credentials = defaultProvider(requestHandler ? { clientConfig: { requestHandler } } : undefined);
956
969
  }
957
970
  return config;
958
971
  }
@@ -961,7 +974,7 @@ export class NodeCleanSlateMainService {
961
974
  const messages = [];
962
975
  for (let index = 0; index < options.messages.length; index++) {
963
976
  const message = options.messages[index];
964
- const text = this.messageContentToText(message.content);
977
+ const text = messageContentToText(message.content);
965
978
  if (message.role === 'system') {
966
979
  if (text) {
967
980
  system.push({ text });
@@ -975,7 +988,7 @@ export class NodeCleanSlateMainService {
975
988
  content.push({
976
989
  toolResult: {
977
990
  toolUseId: toolMessage.toolCallId || `tool_${index}`,
978
- content: [{ text: this.messageContentToText(toolMessage.content) }]
991
+ content: [{ text: messageContentToText(toolMessage.content) }]
979
992
  }
980
993
  });
981
994
  index++;
@@ -1054,7 +1067,8 @@ export class NodeCleanSlateMainService {
1054
1067
  apiKey: options.apiKey,
1055
1068
  endpoint: azure.endpoint,
1056
1069
  deployment: azure.deploymentName,
1057
- apiVersion: azure.apiVersion || '2024-12-01-preview'
1070
+ apiVersion: azure.apiVersion || '2024-12-01-preview',
1071
+ ...(this.httpTransport.usesProxy ? { fetch: this.httpTransport.fetch.bind(this.httpTransport) } : {})
1058
1072
  });
1059
1073
  }
1060
1074
  const OpenAI = openAIModule.OpenAI ?? openAIModule.default;
@@ -1070,7 +1084,8 @@ export class NodeCleanSlateMainService {
1070
1084
  defaultHeaders: managed
1071
1085
  ? { 'User-Agent': 'CleanSlate/1.0' }
1072
1086
  : azureV1 ? { 'api-key': options.apiKey } : undefined,
1073
- ...(managed ? { maxRetries: 0 } : {})
1087
+ ...(managed ? { maxRetries: 0 } : {}),
1088
+ ...(this.httpTransport.usesProxy ? { fetch: this.httpTransport.fetch.bind(this.httpTransport) } : {})
1074
1089
  });
1075
1090
  }
1076
1091
  async createAnthropicClient(options) {
@@ -1081,25 +1096,26 @@ export class NodeCleanSlateMainService {
1081
1096
  }
1082
1097
  return new Anthropic({
1083
1098
  apiKey: options.apiKey,
1084
- baseURL: options.baseUrl || undefined
1099
+ baseURL: options.baseUrl || undefined,
1100
+ ...(this.httpTransport.usesProxy ? { fetch: this.httpTransport.fetch.bind(this.httpTransport) } : {})
1085
1101
  });
1086
1102
  }
1087
1103
  resolveOpenAICompatibleBaseUrl(options) {
1088
1104
  if (this.isCleanSlateManagedProviderName(options.providerName)) {
1089
- return `${this.normalizeEnvValue(process.env['CLEANSLATE_API_BASE_URL']) ?? 'https://api.thewariend.com/api'}/cleanslate`;
1105
+ return resolveCleanSlateManagedBaseUrl(this.envLookup);
1090
1106
  }
1091
- const configured = this.normalizeEnvValue(options.baseUrl);
1107
+ const configured = normalizeBaseUrlValue(options.baseUrl);
1092
1108
  if (configured) {
1093
1109
  return configured;
1094
1110
  }
1095
1111
  if (this.isNvidiaProviderName(options.providerName)) {
1096
- return this.normalizeEnvValue(process.env['CLEANSLATE_NVIDIA_BASE_URL'])
1097
- || this.normalizeEnvValue(process.env['NVIDIA_BASE_URL'])
1112
+ return normalizeBaseUrlValue(this.envLookup('CLEANSLATE_NVIDIA_BASE_URL'))
1113
+ || normalizeBaseUrlValue(this.envLookup('NVIDIA_BASE_URL'))
1098
1114
  || 'https://integrate.api.nvidia.com/v1';
1099
1115
  }
1100
1116
  if (this.isOpenRouterProviderName(options.providerName)) {
1101
- return this.normalizeEnvValue(process.env['CLEANSLATE_OPENROUTER_BASE_URL'])
1102
- || this.normalizeEnvValue(process.env['OPENROUTER_BASE_URL'])
1117
+ return normalizeBaseUrlValue(this.envLookup('CLEANSLATE_OPENROUTER_BASE_URL'))
1118
+ || normalizeBaseUrlValue(this.envLookup('OPENROUTER_BASE_URL'))
1103
1119
  || 'https://openrouter.ai/api/v1';
1104
1120
  }
1105
1121
  return undefined;
@@ -1116,9 +1132,54 @@ export class NodeCleanSlateMainService {
1116
1132
  isCleanSlateManagedProviderName(providerName) {
1117
1133
  return typeof providerName === 'string' && providerName.toLowerCase() === 'cleanslate pro';
1118
1134
  }
1119
- normalizeEnvValue(value) {
1120
- const trimmed = value?.trim();
1121
- return trimmed ? trimmed.replace(/\/+$/, '') : undefined;
1135
+ createProxyFetchRequest(options, token) {
1136
+ if (!options.url) {
1137
+ throw new Error('Request URL is required.');
1138
+ }
1139
+ const url = new URL(options.url);
1140
+ if (url.protocol !== 'http:' && url.protocol !== 'https:') {
1141
+ throw new Error('Request URL must use HTTP or HTTPS.');
1142
+ }
1143
+ const headers = new Headers();
1144
+ for (const [name, value] of Object.entries(options.headers ?? {})) {
1145
+ for (const item of Array.isArray(value) ? value : value === undefined ? [] : [value]) {
1146
+ headers.append(name, item);
1147
+ }
1148
+ }
1149
+ if (options.user && !headers.has('authorization')) {
1150
+ headers.set('authorization', `Basic ${Buffer.from(`${options.user}:${options.password ?? ''}`).toString('base64')}`);
1151
+ }
1152
+ const controller = new AbortController();
1153
+ const cancellation = token.onCancellationRequested(() => controller.abort());
1154
+ if (token.isCancellationRequested) {
1155
+ controller.abort();
1156
+ }
1157
+ const timeout = options.timeout && options.timeout > 0
1158
+ ? setTimeout(() => controller.abort(), options.timeout)
1159
+ : undefined;
1160
+ return {
1161
+ url: url.toString(),
1162
+ init: {
1163
+ method: options.type || 'GET',
1164
+ headers,
1165
+ body: options.data,
1166
+ redirect: options.followRedirects === 0 ? 'manual' : 'follow',
1167
+ signal: controller.signal
1168
+ },
1169
+ dispose: () => {
1170
+ if (timeout) {
1171
+ clearTimeout(timeout);
1172
+ }
1173
+ cancellation.dispose();
1174
+ }
1175
+ };
1176
+ }
1177
+ responseHeaders(headers) {
1178
+ const result = {};
1179
+ for (const [name, value] of headers) {
1180
+ result[name] = value;
1181
+ }
1182
+ return result;
1122
1183
  }
1123
1184
  async importExternalModule(specifier) {
1124
1185
  return import(specifier);
@@ -1166,19 +1227,6 @@ export class NodeCleanSlateMainService {
1166
1227
  }
1167
1228
  return error instanceof Error ? error.message : String(error);
1168
1229
  }
1169
- messageContentToText(content) {
1170
- if (typeof content === 'string') {
1171
- return content;
1172
- }
1173
- if (Array.isArray(content)) {
1174
- return content
1175
- .filter(part => part?.type === 'text')
1176
- .map(part => part.text ?? '')
1177
- .filter(text => text.length > 0)
1178
- .join('\n');
1179
- }
1180
- return '';
1181
- }
1182
1230
  parseToolInput(inputJson) {
1183
1231
  if (!inputJson || inputJson.trim().length === 0) {
1184
1232
  return {};