rackmind-cli 0.1.5 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +67 -181
  3. package/bin/rackmind.js +5 -1
  4. package/dist/ai/models.d.ts +40 -0
  5. package/dist/ai/models.d.ts.map +1 -0
  6. package/dist/ai/models.js +90 -0
  7. package/dist/ai/models.js.map +1 -0
  8. package/dist/ai/providers/anthropic-provider.d.ts +22 -0
  9. package/dist/ai/providers/anthropic-provider.d.ts.map +1 -0
  10. package/dist/ai/{client.js → providers/anthropic-provider.js} +41 -59
  11. package/dist/ai/providers/anthropic-provider.js.map +1 -0
  12. package/dist/ai/providers/base.d.ts +82 -0
  13. package/dist/ai/providers/base.d.ts.map +1 -0
  14. package/dist/ai/providers/base.js +9 -0
  15. package/dist/ai/providers/base.js.map +1 -0
  16. package/dist/ai/providers/claude-code-bridge.d.ts +51 -0
  17. package/dist/ai/providers/claude-code-bridge.d.ts.map +1 -0
  18. package/dist/ai/providers/claude-code-bridge.js +371 -0
  19. package/dist/ai/providers/claude-code-bridge.js.map +1 -0
  20. package/dist/ai/providers/claude-code-provider.d.ts +24 -0
  21. package/dist/ai/providers/claude-code-provider.d.ts.map +1 -0
  22. package/dist/ai/providers/claude-code-provider.js +246 -0
  23. package/dist/ai/providers/claude-code-provider.js.map +1 -0
  24. package/dist/ai/providers/claude-code-runner.d.ts +51 -0
  25. package/dist/ai/providers/claude-code-runner.d.ts.map +1 -0
  26. package/dist/ai/providers/claude-code-runner.js +325 -0
  27. package/dist/ai/providers/claude-code-runner.js.map +1 -0
  28. package/dist/ai/providers/index.d.ts +8 -0
  29. package/dist/ai/providers/index.d.ts.map +1 -0
  30. package/dist/ai/providers/index.js +28 -0
  31. package/dist/ai/providers/index.js.map +1 -0
  32. package/dist/ai/system-prompt.d.ts.map +1 -1
  33. package/dist/ai/system-prompt.js +1 -26
  34. package/dist/ai/system-prompt.js.map +1 -1
  35. package/dist/ai/tool-executor.d.ts +29 -1
  36. package/dist/ai/tool-executor.d.ts.map +1 -1
  37. package/dist/ai/tool-executor.js +85 -1
  38. package/dist/ai/tool-executor.js.map +1 -1
  39. package/dist/commands/auth.d.ts.map +1 -1
  40. package/dist/commands/auth.js +21 -15
  41. package/dist/commands/auth.js.map +1 -1
  42. package/dist/commands/containers.d.ts.map +1 -1
  43. package/dist/commands/containers.js +10 -3
  44. package/dist/commands/containers.js.map +1 -1
  45. package/dist/commands/exec.d.ts.map +1 -1
  46. package/dist/commands/exec.js +19 -7
  47. package/dist/commands/exec.js.map +1 -1
  48. package/dist/commands/lifecycle.d.ts.map +1 -1
  49. package/dist/commands/lifecycle.js +133 -105
  50. package/dist/commands/lifecycle.js.map +1 -1
  51. package/dist/commands/logs.d.ts.map +1 -1
  52. package/dist/commands/logs.js +10 -4
  53. package/dist/commands/logs.js.map +1 -1
  54. package/dist/commands/report.d.ts.map +1 -1
  55. package/dist/commands/report.js +20 -12
  56. package/dist/commands/report.js.map +1 -1
  57. package/dist/commands/servers.d.ts.map +1 -1
  58. package/dist/commands/servers.js +29 -2
  59. package/dist/commands/servers.js.map +1 -1
  60. package/dist/commands/status.d.ts +5 -0
  61. package/dist/commands/status.d.ts.map +1 -1
  62. package/dist/commands/status.js +66 -50
  63. package/dist/commands/status.js.map +1 -1
  64. package/dist/commands/vms.d.ts.map +1 -1
  65. package/dist/commands/vms.js +9 -3
  66. package/dist/commands/vms.js.map +1 -1
  67. package/dist/config/index.d.ts +10 -0
  68. package/dist/config/index.d.ts.map +1 -1
  69. package/dist/config/index.js +21 -0
  70. package/dist/config/index.js.map +1 -1
  71. package/dist/globals.d.ts +21 -3
  72. package/dist/globals.d.ts.map +1 -1
  73. package/dist/globals.js +30 -4
  74. package/dist/globals.js.map +1 -1
  75. package/dist/index.js +22 -6
  76. package/dist/index.js.map +1 -1
  77. package/dist/interactive/App.d.ts.map +1 -1
  78. package/dist/interactive/App.js +11 -5
  79. package/dist/interactive/App.js.map +1 -1
  80. package/dist/interactive/components/ConfirmDialog.d.ts +9 -0
  81. package/dist/interactive/components/ConfirmDialog.d.ts.map +1 -0
  82. package/dist/interactive/components/ConfirmDialog.js +26 -0
  83. package/dist/interactive/components/ConfirmDialog.js.map +1 -0
  84. package/dist/interactive/components/InputBar.d.ts.map +1 -1
  85. package/dist/interactive/components/InputBar.js +10 -1
  86. package/dist/interactive/components/InputBar.js.map +1 -1
  87. package/dist/interactive/components/ToolOutput.d.ts +1 -1
  88. package/dist/interactive/components/ToolOutput.d.ts.map +1 -1
  89. package/dist/interactive/launch.d.ts +5 -0
  90. package/dist/interactive/launch.d.ts.map +1 -1
  91. package/dist/interactive/launch.js +16 -0
  92. package/dist/interactive/launch.js.map +1 -1
  93. package/dist/interactive/slashCommands.d.ts +1 -0
  94. package/dist/interactive/slashCommands.d.ts.map +1 -1
  95. package/dist/interactive/slashCommands.js +13 -0
  96. package/dist/interactive/slashCommands.js.map +1 -1
  97. package/dist/interactive/useRackMind.d.ts +9 -1
  98. package/dist/interactive/useRackMind.d.ts.map +1 -1
  99. package/dist/interactive/useRackMind.js +81 -8
  100. package/dist/interactive/useRackMind.js.map +1 -1
  101. package/dist/oneshot/run.d.ts.map +1 -1
  102. package/dist/oneshot/run.js +65 -14
  103. package/dist/oneshot/run.js.map +1 -1
  104. package/dist/server/client.d.ts +4 -2
  105. package/dist/server/client.d.ts.map +1 -1
  106. package/dist/server/client.js +6 -4
  107. package/dist/server/client.js.map +1 -1
  108. package/dist/server/ssh.d.ts.map +1 -1
  109. package/dist/server/ssh.js +1 -1
  110. package/dist/server/ssh.js.map +1 -1
  111. package/dist/utils/prompt.d.ts.map +1 -1
  112. package/dist/utils/prompt.js +52 -49
  113. package/dist/utils/prompt.js.map +1 -1
  114. package/dist/utils/table.d.ts +3 -0
  115. package/dist/utils/table.d.ts.map +1 -1
  116. package/dist/utils/table.js +4 -1
  117. package/dist/utils/table.js.map +1 -1
  118. package/package.json +44 -12
  119. package/dist/ai/client.d.ts +0 -71
  120. package/dist/ai/client.d.ts.map +0 -1
  121. package/dist/ai/client.js.map +0 -1
@@ -1,56 +1,55 @@
1
1
  // ---------------------------------------------------------------------------
2
- // AI clientClaude API integration with tool use loop
2
+ // Anthropic provideroriginal AIClient logic, now behind AIProvider
3
3
  // ---------------------------------------------------------------------------
4
- // Wraps @anthropic-ai/sdk to handle:
5
- // 1. Sending messages with system prompt + tools
6
- // 2. Streaming text responses to a callback
7
- // 3. Executing tool calls and feeding results back until a final text response
4
+ // Wraps @anthropic-ai/sdk with the CLI's tool-use loop. This is the default
5
+ // provider every unknown/missing model id falls back here via
6
+ // providers/index.ts::getAIProvider().
8
7
  // ---------------------------------------------------------------------------
9
8
  import Anthropic from '@anthropic-ai/sdk';
10
- import { getToolDefinitions } from './tools.js';
11
- import { fetchServerContext, buildSystemPrompt } from './system-prompt.js';
12
- import { executeTool } from './tool-executor.js';
13
- import { logger } from '../utils/logger.js';
14
- import { withRetry, isTransientError, isRateLimitError } from '../utils/retry.js';
15
- // Max iterations for the tool use loop to prevent infinite loops
9
+ import { getToolDefinitions } from '../tools.js';
10
+ import { fetchServerContext, buildSystemPrompt } from '../system-prompt.js';
11
+ import { executeTool } from '../tool-executor.js';
12
+ import { logger } from '../../utils/logger.js';
13
+ import { withRetry, isTransientError, isRateLimitError } from '../../utils/retry.js';
14
+ import { DEFAULT_ANTHROPIC_MODEL_ID } from '../models.js';
15
+ /** Max iterations of the tool use loop — hard guard against runaway chains. */
16
16
  const MAX_TOOL_ITERATIONS = 20;
17
- // ---------------------------------------------------------------------------
18
- // AI Client
19
- // ---------------------------------------------------------------------------
20
- export class AIClient {
17
+ export class AnthropicProvider {
21
18
  anthropic;
22
19
  model;
23
20
  maxTokens;
21
+ /** Cached server context — fetched once per session, cleared by /refresh */
22
+ cachedContext = null;
24
23
  constructor(options) {
24
+ if (!options.apiKey) {
25
+ throw new Error('Anthropic provider requires an API key.');
26
+ }
25
27
  this.anthropic = new Anthropic({
26
28
  apiKey: options.apiKey,
27
- timeout: options.timeoutMs ?? 120_000, // 2 minutes default
29
+ timeout: options.timeoutMs ?? 120_000,
28
30
  });
29
- this.model = options.model ?? 'claude-sonnet-4-5';
31
+ this.model = options.model || DEFAULT_ANTHROPIC_MODEL_ID;
30
32
  this.maxTokens = options.maxTokens ?? 4096;
31
33
  }
32
- /**
33
- * Send a one-shot query to Claude with full server context and tool use.
34
- *
35
- * This method:
36
- * 1. Fetches live server context from the Proxmox API
37
- * 2. Builds a system prompt with the context
38
- * 3. Sends the user's query to Claude with tool definitions
39
- * 4. Streams the response, executing any tool calls in a loop
40
- * 5. Returns when Claude produces a final text response (stop_reason = "end_turn")
41
- */
34
+ getModel() {
35
+ return this.model;
36
+ }
37
+ /** Clear cached server context so next turn re-fetches from Proxmox API. */
38
+ invalidateContextCache() {
39
+ this.cachedContext = null;
40
+ logger.info('Server context cache cleared will re-fetch on next turn');
41
+ }
42
42
  async chat(query, serverClient, serverAlias, callbacks) {
43
- // Fetch live server context
44
- const context = await fetchServerContext(serverClient);
43
+ if (!this.cachedContext) {
44
+ this.cachedContext = await fetchServerContext(serverClient);
45
+ }
46
+ const context = this.cachedContext;
45
47
  const systemPrompt = buildSystemPrompt(context, serverAlias);
46
48
  const tools = getToolDefinitions();
47
- // Build initial messages
48
49
  const messages = [{ role: 'user', content: query }];
49
- // Tool use loop — keep going until Claude gives a final text response
50
50
  for (let iteration = 0; iteration < MAX_TOOL_ITERATIONS; iteration++) {
51
51
  logger.debug('AI request iteration', { iteration, messageCount: messages.length });
52
52
  const response = await this.createWithRetry(systemPrompt, tools, messages, callbacks);
53
- // Process the response content blocks
54
53
  const assistantContent = [];
55
54
  const toolUseBlocks = [];
56
55
  for (const block of response.content) {
@@ -62,9 +61,7 @@ export class AIClient {
62
61
  toolUseBlocks.push(block);
63
62
  }
64
63
  }
65
- // Add the assistant's response to the conversation
66
64
  messages.push({ role: 'assistant', content: assistantContent });
67
- // If Claude is done (no more tool calls), we're finished
68
65
  if (response.stop_reason === 'end_turn' || toolUseBlocks.length === 0) {
69
66
  logger.debug('AI conversation complete', {
70
67
  iterations: iteration + 1,
@@ -72,12 +69,11 @@ export class AIClient {
72
69
  });
73
70
  return;
74
71
  }
75
- // Execute all tool calls and collect results
76
72
  const toolResults = [];
77
73
  for (const toolBlock of toolUseBlocks) {
78
74
  const toolInput = toolBlock.input;
79
75
  callbacks.onToolStart(toolBlock.name, toolBlock.name);
80
- const result = await executeTool(toolBlock.name, toolInput, serverClient);
76
+ const result = await executeTool(toolBlock.name, toolInput, serverClient, { confirm: callbacks.confirmDestructive });
81
77
  callbacks.onToolEnd(toolBlock.name, result.label, result.isError);
82
78
  toolResults.push({
83
79
  type: 'tool_result',
@@ -86,38 +82,27 @@ export class AIClient {
86
82
  is_error: result.isError,
87
83
  });
88
84
  }
89
- // Add tool results to the conversation and loop back
90
85
  messages.push({ role: 'user', content: toolResults });
91
86
  }
92
87
  callbacks.onError('Reached maximum tool iterations. The AI may be stuck in a loop.');
93
88
  }
94
- /**
95
- * Multi-turn conversation method for the interactive REPL.
96
- *
97
- * Unlike `chat()`, this accepts the full conversation history so far
98
- * and appends the new user query. It returns the updated history
99
- * (including the assistant's response) for the caller to persist.
100
- *
101
- * The caller is responsible for building up `history` across turns.
102
- */
103
89
  async chatMultiTurn(query, history, serverClient, serverAlias, callbacks) {
104
- // Fetch live server context
105
- const context = await fetchServerContext(serverClient);
90
+ if (!this.cachedContext) {
91
+ this.cachedContext = await fetchServerContext(serverClient);
92
+ }
93
+ const context = this.cachedContext;
106
94
  const systemPrompt = buildSystemPrompt(context, serverAlias);
107
95
  const tools = getToolDefinitions();
108
- // Clone history and append the new user message
109
96
  const messages = [
110
97
  ...history,
111
98
  { role: 'user', content: query },
112
99
  ];
113
- // Tool use loop
114
100
  for (let iteration = 0; iteration < MAX_TOOL_ITERATIONS; iteration++) {
115
101
  logger.debug('AI multi-turn request iteration', {
116
102
  iteration,
117
103
  messageCount: messages.length,
118
104
  });
119
105
  const response = await this.createWithRetry(systemPrompt, tools, messages, callbacks);
120
- // Process content blocks
121
106
  const assistantContent = [];
122
107
  const toolUseBlocks = [];
123
108
  for (const block of response.content) {
@@ -130,7 +115,6 @@ export class AIClient {
130
115
  }
131
116
  }
132
117
  messages.push({ role: 'assistant', content: assistantContent });
133
- // If done, return the full updated history
134
118
  if (response.stop_reason === 'end_turn' || toolUseBlocks.length === 0) {
135
119
  logger.debug('AI multi-turn conversation turn complete', {
136
120
  iterations: iteration + 1,
@@ -138,12 +122,11 @@ export class AIClient {
138
122
  });
139
123
  return messages;
140
124
  }
141
- // Execute tool calls
142
125
  const toolResults = [];
143
126
  for (const toolBlock of toolUseBlocks) {
144
127
  const toolInput = toolBlock.input;
145
128
  callbacks.onToolStart(toolBlock.name, toolBlock.name);
146
- const result = await executeTool(toolBlock.name, toolInput, serverClient);
129
+ const result = await executeTool(toolBlock.name, toolInput, serverClient, { confirm: callbacks.confirmDestructive });
147
130
  callbacks.onToolEnd(toolBlock.name, result.label, result.isError);
148
131
  if (callbacks.onToolResult) {
149
132
  callbacks.onToolResult({
@@ -165,6 +148,9 @@ export class AIClient {
165
148
  callbacks.onError('Reached maximum tool iterations. The AI may be stuck in a loop.');
166
149
  return messages;
167
150
  }
151
+ async dispose() {
152
+ // Anthropic SDK has no persistent resources to release.
153
+ }
168
154
  /**
169
155
  * Create a message with retry logic for transient errors.
170
156
  * Rate limits and overload errors trigger exponential backoff.
@@ -190,9 +176,5 @@ export class AIClient {
190
176
  },
191
177
  });
192
178
  }
193
- /** Get the current model name */
194
- getModel() {
195
- return this.model;
196
- }
197
179
  }
198
- //# sourceMappingURL=client.js.map
180
+ //# sourceMappingURL=anthropic-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic-provider.js","sourceRoot":"","sources":["../../../src/ai/providers/anthropic-provider.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,sEAAsE;AACtE,8EAA8E;AAC9E,4EAA4E;AAC5E,gEAAgE;AAChE,uCAAuC;AACvC,8EAA8E;AAE9E,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAE1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAsB,MAAM,qBAAqB,CAAC;AAChG,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACrF,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAS1D,+EAA+E;AAC/E,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAE/B,MAAM,OAAO,iBAAiB;IACT,SAAS,CAAY;IACrB,KAAK,CAAS;IACd,SAAS,CAAS;IACnC,4EAA4E;IACpE,aAAa,GAAyB,IAAI,CAAC;IAEnD,YAAY,OAAwB;QAChC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;QAC/D,CAAC;QACD,IAAI,CAAC,SAAS,GAAG,IAAI,SAAS,CAAC;YAC3B,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,OAAO,EAAE,OAAO,CAAC,SAAS,IAAI,OAAO;SACxC,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,0BAA0B,CAAC;QACzD,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC;IAC/C,CAAC;IAED,QAAQ;QACJ,OAAO,IAAI,CAAC,KAAK,CAAC;IACtB,CAAC;IAED,4EAA4E;IAC5E,sBAAsB;QAClB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,MAAM,CAAC,IAAI,CAAC,2DAA2D,CAAC,CAAC;IAC7E,CAAC;IAED,KAAK,CAAC,IAAI,CACN,KAAa,EACb,YAA0B,EAC1B,WAAmB,EACnB,SAA0B;QAE1B,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACtB,IAAI,CAAC,aAAa,GAAG,MAAM,kBAAkB,CAAC,YAAY,CAAC,CAAC;QAChE,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC;QACnC,MAAM,YAAY,GAAG,iBAAiB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QAC7D,MAAM,KAAK,GAAG,kBAAkB,EAAE,CAAC;QAEnC,MAAM,QAAQ,GAAsC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QAEvF,KAAK,IAAI,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,mBAAmB,EAAE,SAAS,EAAE,EAAE,CAAC;YACnE,MAAM,CAAC,KAAK,CAAC,sBAAsB,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YAEnF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;YAEtF,MAAM,gBAAgB,GAAsC,EAAE,CAAC;YAC/D,MAAM,aAAa,GAAsC,EAAE,CAAC;YAE5D,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACnC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC7B,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;oBACxB,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACjC,CAAC;qBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;oBACnC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC9B,CAAC;YACL,CAAC;YAED,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC,CAAC;YAEhE,IAAI,QAAQ,CAAC,WAAW,KAAK,UAAU,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACpE,MAAM,CAAC,KAAK,CAAC,0BAA0B,EAAE;oBACrC,UAAU,EAAE,SAAS,GAAG,CAAC;oBACzB,UAAU,EAAE,QAAQ,CAAC,WAAW;iBACnC,CAAC,CAAC;gBACH,OAAO;YACX,CAAC;YAED,MAAM,WAAW,GAA8C,EAAE,CAAC;YAClE,KAAK,MAAM,SAAS,IAAI,aAAa,EAAE,CAAC;gBACpC,MAAM,SAAS,GAAG,SAAS,CAAC,KAAgC,CAAC;gBAC7D,SAAS,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;gBACtD,MAAM,MAAM,GAAG,MAAM,WAAW,CAC5B,SAAS,CAAC,IAAI,EACd,SAA8C,EAC9C,YAAY,EACZ,EAAE,OAAO,EAAE,SAAS,CAAC,kBAAkB,EAAE,CAC5C,CAAC;gBACF,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;gBAClE,WAAW,CAAC,IAAI,CAAC;oBACb,IAAI,EAAE,aAAa;oBACnB,WAAW,EAAE,SAAS,CAAC,EAAE;oBACzB,OAAO,EAAE,MAAM,CAAC,OAAO;oBACvB,QAAQ,EAAE,MAAM,CAAC,OAAO;iBAC3B,CAAC,CAAC;YACP,CAAC;YACD,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;QAC1D,CAAC;QAED,SAAS,CAAC,OAAO,CAAC,iEAAiE,CAAC,CAAC;IACzF,CAAC;IAED,KAAK,CAAC,aAAa,CACf,KAAa,EACb,OAAoB,EACpB,YAA0B,EAC1B,WAAmB,EACnB,SAA6B;QAE7B,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACtB,IAAI,CAAC,aAAa,GAAG,MAAM,kBAAkB,CAAC,YAAY,CAAC,CAAC;QAChE,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC;QACnC,MAAM,YAAY,GAAG,iBAAiB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QAC7D,MAAM,KAAK,GAAG,kBAAkB,EAAE,CAAC;QAEnC,MAAM,QAAQ,GAAsC;YAChD,GAAG,OAAO;YACV,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE;SACnC,CAAC;QAEF,KAAK,IAAI,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,mBAAmB,EAAE,SAAS,EAAE,EAAE,CAAC;YACnE,MAAM,CAAC,KAAK,CAAC,iCAAiC,EAAE;gBAC5C,SAAS;gBACT,YAAY,EAAE,QAAQ,CAAC,MAAM;aAChC,CAAC,CAAC;YAEH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;YAEtF,MAAM,gBAAgB,GAAsC,EAAE,CAAC;YAC/D,MAAM,aAAa,GAAsC,EAAE,CAAC;YAE5D,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACnC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC7B,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;oBACxB,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACjC,CAAC;qBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;oBACnC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC9B,CAAC;YACL,CAAC;YAED,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC,CAAC;YAEhE,IAAI,QAAQ,CAAC,WAAW,KAAK,UAAU,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACpE,MAAM,CAAC,KAAK,CAAC,0CAA0C,EAAE;oBACrD,UAAU,EAAE,SAAS,GAAG,CAAC;oBACzB,UAAU,EAAE,QAAQ,CAAC,WAAW;iBACnC,CAAC,CAAC;gBACH,OAAO,QAAQ,CAAC;YACpB,CAAC;YAED,MAAM,WAAW,GAA8C,EAAE,CAAC;YAClE,KAAK,MAAM,SAAS,IAAI,aAAa,EAAE,CAAC;gBACpC,MAAM,SAAS,GAAG,SAAS,CAAC,KAAgC,CAAC;gBAC7D,SAAS,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;gBACtD,MAAM,MAAM,GAAG,MAAM,WAAW,CAC5B,SAAS,CAAC,IAAI,EACd,SAA8C,EAC9C,YAAY,EACZ,EAAE,OAAO,EAAE,SAAS,CAAC,kBAAkB,EAAE,CAC5C,CAAC;gBACF,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;gBAClE,IAAI,SAAS,CAAC,YAAY,EAAE,CAAC;oBACzB,SAAS,CAAC,YAAY,CAAC;wBACnB,QAAQ,EAAE,SAAS,CAAC,IAAI;wBACxB,KAAK,EAAE,MAAM,CAAC,KAAK;wBACnB,OAAO,EAAE,MAAM,CAAC,OAAO;wBACvB,OAAO,EAAE,MAAM,CAAC,OAAO;qBAC1B,CAAC,CAAC;gBACP,CAAC;gBACD,WAAW,CAAC,IAAI,CAAC;oBACb,IAAI,EAAE,aAAa;oBACnB,WAAW,EAAE,SAAS,CAAC,EAAE;oBACzB,OAAO,EAAE,MAAM,CAAC,OAAO;oBACvB,QAAQ,EAAE,MAAM,CAAC,OAAO;iBAC3B,CAAC,CAAC;YACP,CAAC;YACD,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;QAC1D,CAAC;QAED,SAAS,CAAC,OAAO,CAAC,iEAAiE,CAAC,CAAC;QACrF,OAAO,QAAQ,CAAC;IACpB,CAAC;IAED,KAAK,CAAC,OAAO;QACT,wDAAwD;IAC5D,CAAC;IAED;;;OAGG;IACK,eAAe,CACnB,MAAc,EACd,KAAgC,EAChC,QAA2C,EAC3C,SAA0B;QAE1B,OAAO,SAAS,CACZ,GAAG,EAAE,CACD,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC;YAC3B,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,UAAU,EAAE,IAAI,CAAC,SAAS;YAC1B,MAAM;YACN,KAAK;YACL,QAAQ;SACX,CAAC,EACN;YACI,WAAW,EAAE,CAAC;YACd,cAAc,EAAE,IAAI;YACpB,UAAU,EAAE,MAAM;YAClB,WAAW,EAAE,gBAAgB;YAC7B,OAAO,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;gBACjC,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBACnE,MAAM,WAAW,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;gBAC5C,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,WAAW,CAAC;gBACzD,SAAS,CAAC,OAAO,CACb,GAAG,KAAK,iBAAiB,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,cAAc,OAAO,GAAG,CAAC,QAAQ,CACvF,CAAC;gBACF,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;YACpE,CAAC;SACJ,CACJ,CAAC;IACN,CAAC;CACJ"}
@@ -0,0 +1,82 @@
1
+ import type Anthropic from '@anthropic-ai/sdk';
2
+ import type { ServerClient } from '../../server/client.js';
3
+ import type { ConfirmDestructiveFn } from '../tool-executor.js';
4
+ export type { ConfirmDestructiveFn, PendingDestructiveAction } from '../tool-executor.js';
5
+ /** Callbacks the provider invokes while a chat turn is in flight. */
6
+ export interface StreamCallbacks {
7
+ /** Streaming text chunk from the assistant. */
8
+ onText: (text: string) => void;
9
+ /** A tool call is about to run (or has started). */
10
+ onToolStart: (toolName: string, label: string) => void;
11
+ /** A tool call finished (success or error). */
12
+ onToolEnd: (toolName: string, label: string, isError: boolean) => void;
13
+ /** A non-fatal error occurred (rate limit retries, warnings, etc.). */
14
+ onError: (error: string) => void;
15
+ /**
16
+ * Optional: asked before a destructive tool runs. Return true to proceed,
17
+ * false to cancel. If omitted, the provider may execute without prompting
18
+ * (only intended for non-interactive surfaces that have already validated
19
+ * the user opted into auto-confirm).
20
+ */
21
+ confirmDestructive?: ConfirmDestructiveFn;
22
+ }
23
+ /** A single tool execution observed during a turn (shown in REPL history). */
24
+ export interface ToolExecution {
25
+ toolName: string;
26
+ label: string;
27
+ isError: boolean;
28
+ content: string;
29
+ }
30
+ /** Extended callbacks for multi-turn mode (captures full tool result for UI). */
31
+ export interface MultiTurnCallbacks extends StreamCallbacks {
32
+ onToolResult?: (execution: ToolExecution) => void;
33
+ }
34
+ /**
35
+ * Conversation history shape used by multi-turn mode. We reuse Anthropic's
36
+ * MessageParam for wire compatibility with the anthropic provider and for
37
+ * easy mirroring when the user switches providers mid-conversation.
38
+ */
39
+ export type ChatHistory = Anthropic.Messages.MessageParam[];
40
+ /**
41
+ * Every provider implements this. `chat` is one-shot (no history);
42
+ * `chatMultiTurn` takes the prior history, appends the new turn, and
43
+ * returns the updated history for the caller to persist.
44
+ */
45
+ export interface AIProvider {
46
+ /** The model id this provider instance was constructed for. */
47
+ getModel(): string;
48
+ /**
49
+ * Send a single query with no prior history. Streams results via
50
+ * callbacks. Throws on fatal errors.
51
+ */
52
+ chat(query: string, serverClient: ServerClient, serverAlias: string, callbacks: StreamCallbacks): Promise<void>;
53
+ /**
54
+ * Send a new user message given the prior conversation history.
55
+ * Returns the updated history (with the new user turn and the
56
+ * assistant's response appended).
57
+ */
58
+ chatMultiTurn(query: string, history: ChatHistory, serverClient: ServerClient, serverAlias: string, callbacks: MultiTurnCallbacks): Promise<ChatHistory>;
59
+ /**
60
+ * Release any resources this provider holds (HTTP bridge, child
61
+ * processes, etc.). Safe to call multiple times.
62
+ */
63
+ dispose(): Promise<void>;
64
+ /**
65
+ * Optional: clear any cached server context so the next chat turn
66
+ * re-fetches fresh data from the Proxmox API.
67
+ * Not all providers cache context — callers should treat as a no-op if absent.
68
+ */
69
+ invalidateContextCache?(): void;
70
+ }
71
+ /** Construction options common to every provider. */
72
+ export interface ProviderOptions {
73
+ /** Anthropic API key (required for the anthropic provider, ignored otherwise). */
74
+ apiKey?: string;
75
+ /** Model id to route with. */
76
+ model: string;
77
+ /** Max tokens per response (anthropic only). */
78
+ maxTokens?: number;
79
+ /** Request timeout (anthropic only), ms. */
80
+ timeoutMs?: number;
81
+ }
82
+ //# sourceMappingURL=base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/ai/providers/base.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,SAAS,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAEhE,YAAY,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAE1F,qEAAqE;AACrE,MAAM,WAAW,eAAe;IAC5B,+CAA+C;IAC/C,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,oDAAoD;IACpD,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvD,+CAA+C;IAC/C,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACvE,uEAAuE;IACvE,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,oBAAoB,CAAC;CAC7C;AAED,8EAA8E;AAC9E,MAAM,WAAW,aAAa;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,iFAAiF;AACjF,MAAM,WAAW,kBAAmB,SAAQ,eAAe;IACvD,YAAY,CAAC,EAAE,CAAC,SAAS,EAAE,aAAa,KAAK,IAAI,CAAC;CACrD;AAED;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC;AAE5D;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACvB,+DAA+D;IAC/D,QAAQ,IAAI,MAAM,CAAC;IAEnB;;;OAGG;IACH,IAAI,CACA,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,eAAe,GAC3B,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB;;;;OAIG;IACH,aAAa,CACT,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,WAAW,EACpB,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,kBAAkB,GAC9B,OAAO,CAAC,WAAW,CAAC,CAAC;IAExB;;;OAGG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzB;;;;OAIG;IACH,sBAAsB,CAAC,IAAI,IAAI,CAAC;CACnC;AAED,qDAAqD;AACrD,MAAM,WAAW,eAAe;IAC5B,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8BAA8B;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB"}
@@ -0,0 +1,9 @@
1
+ // ---------------------------------------------------------------------------
2
+ // AIProvider interface — minimum surface every provider must implement
3
+ // ---------------------------------------------------------------------------
4
+ // Callers (oneshot/run.ts, interactive/useRackMind.ts) depend ONLY on this
5
+ // interface. Concrete providers (anthropic, claude-code) live in sibling
6
+ // files and are wired up by providers/index.ts via getAIProvider(modelId).
7
+ // ---------------------------------------------------------------------------
8
+ export {};
9
+ //# sourceMappingURL=base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/ai/providers/base.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,uEAAuE;AACvE,8EAA8E;AAC9E,2EAA2E;AAC3E,yEAAyE;AACzE,2EAA2E;AAC3E,8EAA8E"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * ClaudeCodeBridge — loopback HTTP tool bridge for the spawned `claude`
3
+ * CLI child. Ported from the desktop app's bridge with one adaptation:
4
+ * the executor here runs the CLI's in-process tools (src/ai/tool-executor.ts)
5
+ * instead of delegating to Electron IPC. The security model (loopback bind,
6
+ * random shared secret, Host header check, body cap, request timeout) is
7
+ * identical to the desktop version.
8
+ */
9
+ import type Anthropic from '@anthropic-ai/sdk';
10
+ import type { ServerClient } from '../../server/client.js';
11
+ import { type ConfirmDestructiveFn } from '../tool-executor.js';
12
+ export interface BridgeToolCallback {
13
+ (toolName: string, label: string, isError: boolean, content: string): void;
14
+ }
15
+ export interface BridgeHandle {
16
+ bridgeDir: string;
17
+ port: number;
18
+ secret: string;
19
+ stop(): Promise<void>;
20
+ }
21
+ /**
22
+ * Build a concise manifest of RackMind tools for injection into the Claude
23
+ * Code system prompt. Lists every available tool with its description,
24
+ * input schema, and an example invocation so the model knows what to call
25
+ * via `rackmind-bridge`.
26
+ */
27
+ export declare function buildToolManifest(tools: Anthropic.Messages.Tool[]): string;
28
+ export interface StartBridgeOptions {
29
+ /** Server client the in-process tool executor dispatches to. */
30
+ serverClient: ServerClient;
31
+ /**
32
+ * Optional observer called for every bridge tool invocation — lets the
33
+ * caller forward a display label into the REPL's tool-event stream.
34
+ */
35
+ onToolCall?: BridgeToolCallback;
36
+ /** Signal that aborts pending/future tool calls (returns `cancelled`). */
37
+ signal?: AbortSignal;
38
+ /**
39
+ * Confirmation callback for destructive tools (stop/restart/start of guests).
40
+ * Returning false from this callback cancels the action — the bridge returns
41
+ * a non-error result describing the cancellation so the model can react.
42
+ */
43
+ confirmDestructive?: ConfirmDestructiveFn;
44
+ }
45
+ /**
46
+ * Start the local HTTP bridge and write the `rackmind-bridge` helper
47
+ * script. Returns a handle with the PATH dir and port the child should
48
+ * see in its env.
49
+ */
50
+ export declare function startClaudeCodeBridge(opts: StartBridgeOptions): Promise<BridgeHandle>;
51
+ //# sourceMappingURL=claude-code-bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code-bridge.d.ts","sourceRoot":"","sources":["../../../src/ai/providers/claude-code-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,KAAK,SAAS,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAe,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAa7E,MAAM,WAAW,kBAAkB;IAC/B,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9E;AAED,MAAM,WAAW,YAAY;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB;AAwCD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,MAAM,CA+C1E;AA6CD,MAAM,WAAW,kBAAkB;IAC/B,gEAAgE;IAChE,YAAY,EAAE,YAAY,CAAC;IAC3B;;;OAGG;IACH,UAAU,CAAC,EAAE,kBAAkB,CAAC;IAChC,0EAA0E;IAC1E,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,oBAAoB,CAAC;CAC7C;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,YAAY,CAAC,CAmP3F"}