@syntero/orca-cli 1.2.1 → 1.2.3

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 (88) hide show
  1. package/dist/assistant/anthropic.d.ts +23 -0
  2. package/dist/assistant/anthropic.d.ts.map +1 -0
  3. package/dist/assistant/anthropic.js +186 -0
  4. package/dist/assistant/anthropic.js.map +1 -0
  5. package/dist/assistant/cache.d.ts +20 -0
  6. package/dist/assistant/cache.d.ts.map +1 -0
  7. package/dist/assistant/cache.js +55 -0
  8. package/dist/assistant/cache.js.map +1 -0
  9. package/dist/assistant/helpers.d.ts +10 -0
  10. package/dist/assistant/helpers.d.ts.map +1 -0
  11. package/dist/assistant/helpers.js +74 -0
  12. package/dist/assistant/helpers.js.map +1 -0
  13. package/dist/assistant/index.d.ts +13 -0
  14. package/dist/assistant/index.d.ts.map +1 -0
  15. package/dist/assistant/index.js +40 -0
  16. package/dist/assistant/index.js.map +1 -0
  17. package/dist/assistant/openai.d.ts +34 -0
  18. package/dist/assistant/openai.d.ts.map +1 -0
  19. package/dist/assistant/openai.js +303 -0
  20. package/dist/assistant/openai.js.map +1 -0
  21. package/dist/assistant/prompts.d.ts +11 -0
  22. package/dist/assistant/prompts.d.ts.map +1 -0
  23. package/dist/assistant/prompts.js +203 -0
  24. package/dist/assistant/prompts.js.map +1 -0
  25. package/dist/assistant/summarize.d.ts +32 -0
  26. package/dist/assistant/summarize.d.ts.map +1 -0
  27. package/dist/assistant/summarize.js +134 -0
  28. package/dist/assistant/summarize.js.map +1 -0
  29. package/dist/assistant/types.d.ts +62 -0
  30. package/dist/assistant/types.d.ts.map +1 -0
  31. package/dist/assistant/types.js +2 -0
  32. package/dist/assistant/types.js.map +1 -0
  33. package/dist/assistant.d.ts.map +1 -1
  34. package/dist/assistant.js +161 -383
  35. package/dist/assistant.js.map +1 -1
  36. package/dist/auth.d.ts +2 -1
  37. package/dist/auth.d.ts.map +1 -1
  38. package/dist/auth.js +6 -3
  39. package/dist/auth.js.map +1 -1
  40. package/dist/components/ChatApp.d.ts.map +1 -1
  41. package/dist/components/ChatApp.js +50 -339
  42. package/dist/components/ChatApp.js.map +1 -1
  43. package/dist/components/InputFooter.d.ts +23 -1
  44. package/dist/components/InputFooter.d.ts.map +1 -1
  45. package/dist/components/InputFooter.js +11 -8
  46. package/dist/components/InputFooter.js.map +1 -1
  47. package/dist/components/MultiSelectList.d.ts +25 -0
  48. package/dist/components/MultiSelectList.d.ts.map +1 -0
  49. package/dist/components/MultiSelectList.js +70 -0
  50. package/dist/components/MultiSelectList.js.map +1 -0
  51. package/dist/components/SyncMenu.d.ts +30 -6
  52. package/dist/components/SyncMenu.d.ts.map +1 -1
  53. package/dist/components/SyncMenu.js +383 -43
  54. package/dist/components/SyncMenu.js.map +1 -1
  55. package/dist/conversations/storage.d.ts +1 -1
  56. package/dist/conversations/storage.d.ts.map +1 -1
  57. package/dist/conversations/types.d.ts +1 -1
  58. package/dist/conversations/types.d.ts.map +1 -1
  59. package/dist/hooks/useConversationPersistence.d.ts +15 -0
  60. package/dist/hooks/useConversationPersistence.d.ts.map +1 -0
  61. package/dist/hooks/useConversationPersistence.js +86 -0
  62. package/dist/hooks/useConversationPersistence.js.map +1 -0
  63. package/dist/hooks/useInputDispatch.d.ts +11 -0
  64. package/dist/hooks/useInputDispatch.d.ts.map +1 -0
  65. package/dist/hooks/useInputDispatch.js +112 -0
  66. package/dist/hooks/useInputDispatch.js.map +1 -0
  67. package/dist/hooks/useSlashCommands.d.ts +21 -0
  68. package/dist/hooks/useSlashCommands.d.ts.map +1 -0
  69. package/dist/hooks/useSlashCommands.js +146 -0
  70. package/dist/hooks/useSlashCommands.js.map +1 -0
  71. package/dist/hooks/useSyncFetchers.d.ts +8 -0
  72. package/dist/hooks/useSyncFetchers.d.ts.map +1 -0
  73. package/dist/hooks/useSyncFetchers.js +103 -0
  74. package/dist/hooks/useSyncFetchers.js.map +1 -0
  75. package/dist/index.js +1 -1
  76. package/dist/index.js.map +1 -1
  77. package/dist/sync/download.d.ts +3 -3
  78. package/dist/sync/download.d.ts.map +1 -1
  79. package/dist/sync/download.js +16 -11
  80. package/dist/sync/download.js.map +1 -1
  81. package/dist/sync/sync-engine.d.ts.map +1 -1
  82. package/dist/sync/sync-engine.js +7 -4
  83. package/dist/sync/sync-engine.js.map +1 -1
  84. package/dist/tokens.d.ts +1 -1
  85. package/dist/tokens.d.ts.map +1 -1
  86. package/dist/types/sync.d.ts +2 -0
  87. package/dist/types/sync.d.ts.map +1 -1
  88. package/package.json +1 -1
@@ -0,0 +1,303 @@
1
+ import { resolveAzureDeployment } from '../providers.js';
2
+ import { loadCredentials } from '../auth.js';
3
+ import { ModelRegistry } from '../models.js';
4
+ import { TOOLS_OPENAI, } from '../tools.js';
5
+ import { SYSTEM_PROMPT, SUMMARIZATION_PROMPT } from './prompts.js';
6
+ import { executeToolCalls, injectQueuedMessage } from './helpers.js';
7
+ /**
8
+ * Resolve the OpenAI/Azure model name and registry ID.
9
+ */
10
+ export function resolveOpenAIModel(settings, isAzure) {
11
+ if (isAzure) {
12
+ const modelIdForRegistry = settings.azure.deployment;
13
+ const creds = loadCredentials();
14
+ const model = creds?.llm
15
+ ? resolveAzureDeployment(settings.azure.deployment, creds.llm)
16
+ : settings.azure.deployment;
17
+ return { model, modelIdForRegistry };
18
+ }
19
+ return { model: settings.openai.model, modelIdForRegistry: settings.openai.model };
20
+ }
21
+ /**
22
+ * Convert Anthropic message history to OpenAI message format.
23
+ */
24
+ export function convertMessagesToOpenAI(messages) {
25
+ const openaiMessages = [{ role: 'system', content: SYSTEM_PROMPT }];
26
+ for (const msg of messages) {
27
+ if (msg.role === 'user') {
28
+ if (Array.isArray(msg.content)) {
29
+ for (const item of msg.content) {
30
+ if (item.type === 'tool_result') {
31
+ openaiMessages.push({
32
+ role: 'tool',
33
+ tool_call_id: item.tool_use_id || '',
34
+ content: item.content || '',
35
+ });
36
+ }
37
+ }
38
+ }
39
+ else {
40
+ openaiMessages.push({ role: 'user', content: msg.content });
41
+ }
42
+ }
43
+ else if (msg.role === 'assistant') {
44
+ if (Array.isArray(msg.content)) {
45
+ const toolCallsArr = [];
46
+ let textContent = '';
47
+ for (const item of msg.content) {
48
+ if (item.type === 'text') {
49
+ textContent = item.text || '';
50
+ }
51
+ else if (item.type === 'tool_use') {
52
+ toolCallsArr.push({
53
+ id: item.id || '',
54
+ type: 'function',
55
+ function: {
56
+ name: item.name || '',
57
+ arguments: JSON.stringify(item.input || {}),
58
+ },
59
+ });
60
+ }
61
+ }
62
+ const assistantMsg = {
63
+ role: 'assistant',
64
+ content: textContent || null,
65
+ };
66
+ if (toolCallsArr.length > 0) {
67
+ assistantMsg.tool_calls = toolCallsArr;
68
+ }
69
+ openaiMessages.push(assistantMsg);
70
+ }
71
+ }
72
+ }
73
+ return openaiMessages;
74
+ }
75
+ /**
76
+ * Run assistant with OpenAI/Azure API with streaming.
77
+ * @param getQueuedMessage - Optional callback to check for queued messages at each iteration
78
+ * @param confirmCommand - Optional callback to confirm dangerous commands
79
+ * @param approvedCategories - Set of command categories approved for the session
80
+ */
81
+ export async function* runAssistantOpenAI(client, settings, userMessage, messages, isAzure = false, signal, getQueuedMessage, confirmCommand, approvedCategories) {
82
+ const { model, modelIdForRegistry } = resolveOpenAIModel(settings, isAzure);
83
+ const openaiMessages = convertMessagesToOpenAI(messages);
84
+ openaiMessages.push({ role: 'user', content: userMessage });
85
+ messages.push({ role: 'user', content: userMessage });
86
+ while (true) {
87
+ // Check for queued messages at the start of each iteration
88
+ const queuedMessage = getQueuedMessage?.();
89
+ if (queuedMessage) {
90
+ yield* injectQueuedMessage(queuedMessage, messages, openaiMessages);
91
+ }
92
+ let responseText = '';
93
+ const toolCalls = {};
94
+ let currentToolId = null;
95
+ // Build request options with dynamic max_tokens parameter based on model ID (not deployment name)
96
+ const maxTokensParam = ModelRegistry.getMaxTokensParam(modelIdForRegistry);
97
+ const maxTokensValue = ModelRegistry.getMaxTokens(modelIdForRegistry);
98
+ // Use type assertion through unknown to handle dynamic property names
99
+ const baseOptions = {
100
+ model,
101
+ messages: openaiMessages,
102
+ tools: TOOLS_OPENAI,
103
+ stream: true,
104
+ };
105
+ const streamOptions = maxTokensParam === 'max_completion_tokens'
106
+ ? { ...baseOptions, max_completion_tokens: maxTokensValue }
107
+ : { ...baseOptions, max_tokens: maxTokensValue };
108
+ const stream = await client.chat.completions.create(streamOptions, { signal });
109
+ let finishReason = null;
110
+ for await (const chunk of stream) {
111
+ const delta = chunk.choices[0]?.delta;
112
+ finishReason = chunk.choices[0]?.finish_reason || null;
113
+ if (delta) {
114
+ if (delta.content) {
115
+ yield delta.content;
116
+ responseText += delta.content;
117
+ }
118
+ if (delta.tool_calls) {
119
+ for (const tc of delta.tool_calls) {
120
+ if (tc.id) {
121
+ currentToolId = tc.id;
122
+ toolCalls[currentToolId] = {
123
+ id: tc.id,
124
+ name: tc.function?.name || '',
125
+ input: '',
126
+ };
127
+ }
128
+ if (tc.function?.arguments && currentToolId) {
129
+ toolCalls[currentToolId].input += tc.function.arguments;
130
+ }
131
+ }
132
+ }
133
+ }
134
+ }
135
+ // Build assistant message
136
+ const assistantContent = [];
137
+ if (responseText) {
138
+ assistantContent.push({ type: 'text', text: responseText });
139
+ }
140
+ const openaiAssistantMsg = {
141
+ role: 'assistant',
142
+ content: responseText || null,
143
+ };
144
+ if (Object.keys(toolCalls).length > 0) {
145
+ openaiAssistantMsg.tool_calls = Object.values(toolCalls).map((tc) => ({
146
+ id: tc.id,
147
+ type: 'function',
148
+ function: {
149
+ name: tc.name,
150
+ arguments: tc.input,
151
+ },
152
+ }));
153
+ for (const tc of Object.values(toolCalls)) {
154
+ try {
155
+ tc.input = tc.input ? JSON.parse(tc.input) : {};
156
+ }
157
+ catch {
158
+ tc.input = {};
159
+ }
160
+ assistantContent.push({
161
+ type: 'tool_use',
162
+ id: tc.id,
163
+ name: tc.name,
164
+ input: tc.input,
165
+ });
166
+ }
167
+ }
168
+ openaiMessages.push(openaiAssistantMsg);
169
+ messages.push({ role: 'assistant', content: assistantContent });
170
+ if (finishReason === 'tool_calls' && Object.keys(toolCalls).length > 0) {
171
+ const { anthropicResults, openaiResults } = yield* executeToolCalls(Object.values(toolCalls), confirmCommand, approvedCategories);
172
+ for (const r of openaiResults) {
173
+ openaiMessages.push({ role: 'tool', tool_call_id: r.tool_call_id, content: r.content });
174
+ }
175
+ messages.push({ role: 'user', content: anthropicResults });
176
+ }
177
+ else {
178
+ break;
179
+ }
180
+ }
181
+ return messages;
182
+ }
183
+ /**
184
+ * Run assistant with OpenAI/Azure API without streaming.
185
+ * Fetches complete responses in a single request to eliminate screen jitter.
186
+ * @param getQueuedMessage - Optional callback to check for queued messages at each iteration
187
+ * @param confirmCommand - Optional callback to confirm dangerous commands
188
+ * @param approvedCategories - Set of command categories approved for the session
189
+ */
190
+ export async function* runAssistantOpenAINonStreaming(client, settings, userMessage, messages, isAzure = false, signal, getQueuedMessage, confirmCommand, approvedCategories) {
191
+ const { model, modelIdForRegistry } = resolveOpenAIModel(settings, isAzure);
192
+ const openaiMessages = convertMessagesToOpenAI(messages);
193
+ openaiMessages.push({ role: 'user', content: userMessage });
194
+ messages.push({ role: 'user', content: userMessage });
195
+ while (true) {
196
+ // Check for queued messages at the start of each iteration
197
+ const queuedMessage = getQueuedMessage?.();
198
+ if (queuedMessage) {
199
+ yield* injectQueuedMessage(queuedMessage, messages, openaiMessages);
200
+ }
201
+ // Build request options with dynamic max_tokens parameter based on model ID (not deployment name)
202
+ const maxTokensParam = ModelRegistry.getMaxTokensParam(modelIdForRegistry);
203
+ const maxTokensValue = ModelRegistry.getMaxTokens(modelIdForRegistry);
204
+ // Non-streaming request - no stream option
205
+ const baseOptions = {
206
+ model,
207
+ messages: openaiMessages,
208
+ tools: TOOLS_OPENAI,
209
+ };
210
+ const requestOptions = maxTokensParam === 'max_completion_tokens'
211
+ ? { ...baseOptions, max_completion_tokens: maxTokensValue }
212
+ : { ...baseOptions, max_tokens: maxTokensValue };
213
+ const response = await client.chat.completions.create(requestOptions, { signal });
214
+ const choice = response.choices[0];
215
+ const responseText = choice?.message?.content || '';
216
+ const toolCallsResponse = choice?.message?.tool_calls || [];
217
+ const finishReason = choice?.finish_reason || null;
218
+ // Yield the complete response text at once
219
+ if (responseText) {
220
+ yield responseText;
221
+ }
222
+ // Build assistant message
223
+ const assistantContent = [];
224
+ if (responseText) {
225
+ assistantContent.push({ type: 'text', text: responseText });
226
+ }
227
+ const openaiAssistantMsg = {
228
+ role: 'assistant',
229
+ content: responseText || null,
230
+ };
231
+ const toolCalls = {};
232
+ // Filter for function-type tool calls only
233
+ const functionToolCalls = toolCallsResponse.filter(tc => tc.type === 'function');
234
+ if (functionToolCalls.length > 0) {
235
+ openaiAssistantMsg.tool_calls = functionToolCalls.map((tc) => ({
236
+ id: tc.id,
237
+ type: 'function',
238
+ function: {
239
+ name: tc.function.name,
240
+ arguments: tc.function.arguments,
241
+ },
242
+ }));
243
+ for (const tc of functionToolCalls) {
244
+ const funcTc = tc;
245
+ let parsedInput;
246
+ try {
247
+ parsedInput = funcTc.function.arguments ? JSON.parse(funcTc.function.arguments) : {};
248
+ }
249
+ catch {
250
+ parsedInput = {};
251
+ }
252
+ toolCalls[funcTc.id] = {
253
+ id: funcTc.id,
254
+ name: funcTc.function.name,
255
+ input: parsedInput,
256
+ };
257
+ assistantContent.push({
258
+ type: 'tool_use',
259
+ id: funcTc.id,
260
+ name: funcTc.function.name,
261
+ input: parsedInput,
262
+ });
263
+ }
264
+ }
265
+ openaiMessages.push(openaiAssistantMsg);
266
+ messages.push({ role: 'assistant', content: assistantContent });
267
+ if (finishReason === 'tool_calls' && Object.keys(toolCalls).length > 0) {
268
+ const { anthropicResults, openaiResults } = yield* executeToolCalls(Object.values(toolCalls), confirmCommand, approvedCategories);
269
+ for (const r of openaiResults) {
270
+ openaiMessages.push({ role: 'tool', tool_call_id: r.tool_call_id, content: r.content });
271
+ }
272
+ messages.push({ role: 'user', content: anthropicResults });
273
+ }
274
+ else {
275
+ break;
276
+ }
277
+ }
278
+ return messages;
279
+ }
280
+ /**
281
+ * Summarize a conversation using the OpenAI/Azure API.
282
+ */
283
+ export async function summarizeWithOpenAI(client, settings, conversationText, isAzure) {
284
+ const { model, modelIdForRegistry } = resolveOpenAIModel(settings, isAzure);
285
+ // Build request options with dynamic max_tokens parameter based on model ID (not deployment name)
286
+ const maxTokensParam = ModelRegistry.getMaxTokensParam(modelIdForRegistry);
287
+ const baseOptions = {
288
+ model,
289
+ messages: [
290
+ { role: 'system', content: SUMMARIZATION_PROMPT },
291
+ {
292
+ role: 'user',
293
+ content: `Please summarize the following deployment troubleshooting conversation:\n\n${conversationText}`,
294
+ },
295
+ ],
296
+ };
297
+ const requestOptions = maxTokensParam === 'max_completion_tokens'
298
+ ? { ...baseOptions, max_completion_tokens: 2500 }
299
+ : { ...baseOptions, max_tokens: 2500 };
300
+ const response = await client.chat.completions.create(requestOptions);
301
+ return response.choices[0]?.message?.content || 'Unable to generate summary.';
302
+ }
303
+ //# sourceMappingURL=openai.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/assistant/openai.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export declare const SYSTEM_PROMPT = "You are an expert deployment assistant for Orca, a workflow automation application.\n\n## Your Role\nHelp users install, configure, diagnose, and resolve deployment issues. You have FULL access to:\n- Run shell commands (curl, docker, docker compose, etc.)\n- Docker containers, logs, and configuration\n- Deployment files (docker-compose.yml, .env template)\n- The main application database (read-only SQL)\n- Management scripts via docker exec\n\n## Capabilities\nYou CAN and SHOULD:\n- Authenticate with GHCR to pull Orca images\n- Run docker compose commands (up, down, pull, restart)\n- Edit configuration files\n- Execute any shell command needed to help the user\n\nNote: Potentially dangerous commands (rm, git reset --hard, docker rm, etc.) will prompt the user for confirmation before execution. The user can approve individual commands or allow entire categories for the session.\n\n## Fresh Installation\nWhen a user asks to \"install\" Orca on a fresh machine:\n1. Check prerequisites: Docker and Docker Compose must be installed\n2. Authenticate with GHCR using the docker_login_ghcr tool (REQUIRED before pulling images)\n3. Download deployment files using the download_deployment_files tool (specify target directory like ~/orca or /opt/orca)\n4. Configure .env file:\n - Copy .env.example to .env\n - Auto-generate FLASK_SECRET_KEY using: python3 -c \"import secrets; print(secrets.token_hex(32))\"\n - Auto-detect PUID (host user ID): id -u\n - Auto-detect PGID (host group ID): id -g\n - Auto-detect DOCKER_GID (cross-platform): stat -c '%g' /var/run/docker.sock 2>/dev/null || stat -f '%g' /var/run/docker.sock 2>/dev/null || echo \"Could not detect docker GID\"\n - Auto-detect GUNICORN_WORKERS (2 per CPU core, min 2, max 12): CORES=$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 2); WORKERS=$((CORES * 2)); [ $WORKERS -lt 2 ] && WORKERS=2; [ $WORKERS -gt 12 ] && WORKERS=12; echo $WORKERS\n IMPORTANT: PUID and PGID are critical for avoiding permission issues. They must match the host user running Docker.\n5. cd to deployment directory and run: docker compose pull\n6. Start services: docker compose up -d\n7. Wait for services to become healthy\n8. Configure CORS for LAN access (see below)\n9. **IMPORTANT**: After successful installation, use the save_deployment_dir tool to save the deployment directory path for future updates\n\nIMPORTANT: The user must run /token BEFORE installation to authenticate with the server.\nIf GHCR authentication or deployment file download fails, tell the user to run /token first.\n\n## CORS Configuration for LAN Access\nALWAYS configure CORS at the end of installation:\n1. Auto-detect the server's IP (cross-platform): hostname -I 2>/dev/null | awk '{print $1}' || ipconfig getifaddr en0 2>/dev/null || echo \"IP detection failed - ask user\"\n2. Read current cors_origins.json from the deployment directory\n3. Add both http:// and https:// origins for the detected IP (if not already present)\n4. Write the updated cors_origins.json\n5. Restart the backend: docker compose restart backend\n6. Display access URLs to the user:\n - Local: http://localhost and https://localhost\n - LAN: http://<detected-ip> and https://<detected-ip>\n\n## Container Discovery\nIMPORTANT: Never assume container names. Always discover them dynamically:\n```\ndocker ps --filter \"name=orca-\" --format \"{{.Names}}\"\n```\n\nTypical containers (names may vary):\n- Backend: Flask app (port 5000)\n- Frontend: Nginx/React (ports 80/443)\n- Redis: Caching\n- Sandbox containers: Per-org Python sandboxes (dynamic)\n- Runtime data containers: Per-org PostgreSQL (dynamic)\n\n## Running Management Scripts\nUse docker exec with the discovered backend container name:\n```\ndocker exec <backend-container> python -m backend.scripts.manage_users --list\ndocker exec <backend-container> python -m backend.scripts.manage_api_keys --list-orgs\n```\n\n## Creating Users\nIMPORTANT: When creating users with manage_users.py:\n1. ALWAYS use the org_id from check_auth_status tool (e.g., \"org-syntero\")\n2. Use simple alphanumeric passwords (letters and numbers only, no special characters)\n - GOOD: 'SecurePass123', 'Admin2026xyz'\n - BAD: Generated passwords with special chars like '-' or '_' can cause shell expansion issues\n3. **FIRST USER MUST BE super_admin** - Always use --role super_admin for the first user\n\nExample (first user during installation):\n```\ndocker exec <backend-container> python -m backend.scripts.manage_users \\\n --email admin@example.com --password 'SecurePass123' --name 'Admin' \\\n --org-id <org_id_from_check_auth_status> --org-name \"Organization Name\" \\\n --role super_admin\n```\nThis ensures:\n- The sandbox container name (orca-sandbox-{org_id}) matches correctly for sync\n- The password is stored correctly without shell interpolation issues\n- The first user has full admin privileges to manage the system\n\n## Post-Installation Steps (IMPORTANT)\nAfter creating the super admin user, guide them through these steps:\n\n1. **Log in to Orca** at https://localhost or https://<server-ip> with the super admin credentials\n2. **Navigate to Super Admin Dashboard**: Click the user menu \u2192 \"Super Admin\"\n3. **Create organization containers**: In the Workspaces Manager, find the organization row and click \"Create Containers\" (or \"Recreate Containers\" if they exist)\n4. **Wait for containers to be ready**: The system creates:\n - `orca-sandbox-{org_id}` - Python execution sandbox\n - `orca-runtime-data-{org_id}` - PostgreSQL database for data_store\n\n**Why this is required:**\n- The CLI sync command needs a running sandbox container to write solution files to `/workspace/library/`\n- Without these containers, the sync will fail with \"container not found\" or permission errors\n- Each organization gets isolated containers with their own workspace volume\n\n**Verify containers exist:**\n```\ndocker ps --filter \"name=orca-sandbox-\" --filter \"name=orca-runtime-data-\"\n```\n\nOnly after containers are running can the user sync solutions using the CLI sync command.\n\n## Common Issues\n- Backend crash loops: Check logs for database/migration errors\n- Missing tables: Usually migration issues\n- Permission errors: UID/GID mismatches\n- Network issues: Check cors_origins.json and orca-network\n\n## Guidelines\n1. Discover container names first with docker ps\n2. Start with container status and logs\n3. Use inspect_env (not read_file) for .env\n4. Explain issues clearly with fix steps\n5. Be thorough but concise\n\n## Updating Installation\nWhen a user asks to \"update\" Orca:\n\n1. First, use the get_deployment_dir tool to find where Orca is installed\n2. If the deployment directory is not found, ask the user for the path\n3. Once you have the path, cd to that directory and run these steps:\n a. docker rm -f orca-sandbox-keeper 2>/dev/null (remove sandbox keeper if running)\n b. docker compose up -d --pull always --force-recreate --remove-orphans (pull stable images and force-recreate containers)\n c. Wait for all services to be healthy by checking: docker ps --filter \"name=orca-\"\n d. docker system prune -af (clean up old images)\n e. Use rebuild_all_sandboxes to rebuild sandbox containers with the new image\n4. If the deployment directory was provided by the user (not from settings), save it using save_deployment_dir tool for future updates\n\n## Post-Update Container Management\nAfter updating (docker compose up -d --pull always), sandbox containers still run the OLD image.\nYou MUST rebuild or recreate containers to pick up the new image:\n\n- **rebuild_all_sandboxes**: Pulls latest sandbox image and rebuilds all sandbox containers.\n Preserves workspace volumes (user data). Use this for routine updates.\n- **recreate_all_containers**: Removes ALL containers (sandbox, runtime-data, neo4j) for every\n org, then creates them fresh. Preserves volumes. Use this when a major update requires\n fresh containers for all types, not just sandboxes.\n\nBoth tools require cloud authentication (/token). Always use rebuild_all_sandboxes first.\nOnly use recreate_all_containers if instructed or if rebuild alone didn't resolve issues.\n\n## Troubleshooting Guide\nIMPORTANT: After downloading deployment files, ALWAYS read TROUBLESHOOTING.md first:\n```\ngrep_file({ pattern: \".\", path: \"TROUBLESHOOTING.md\", context_lines: 0 })\n```\nThis document contains critical guidance for installation and common issues.\n\nWhen diagnosing issues:\n1. Search TROUBLESHOOTING.md for error messages or symptoms\n2. Example: grep_file({ pattern: \"502\", path: \"TROUBLESHOOTING.md\", context_lines: 20 })\n3. Follow documented solutions before attempting custom fixes\n\n## Critical Behaviors (MUST FOLLOW)\n1. **NEVER ask users to run commands you can run yourself** - You have full shell access\n2. **VERIFY each step before proceeding**:\n - After \"docker compose up -d\", ALWAYS run: docker ps --filter \"name=orca-\"\n - If no containers shown, run \"docker compose ps -a\" and check logs\n - Don't configure CORS until containers are verified running\n3. **Wait for async operations** - docker compose up may still be pulling images\n4. **Don't restart non-existent containers** - Verify containers exist first with docker ps\n5. **Act, don't over-explain** - Fix issues directly instead of theorizing\n6. **Always call save_deployment_dir** after successful installation\n";
2
+ /**
3
+ * System prompt for conversation summarization.
4
+ * Instructs the model to create a concise but comprehensive summary.
5
+ */
6
+ export declare const SUMMARIZATION_PROMPT = "You are a conversation summarizer. Create a comprehensive summary of a deployment troubleshooting conversation that preserves essential context for continuing the work.\n\nCapture with high fidelity:\n1. **Architectural Decisions**: Any design choices or configuration decisions made\n2. **Unresolved Issues**: Bugs, errors, or problems still pending\n3. **Key Findings**: Important discoveries during troubleshooting (specific error messages, root causes)\n4. **Implementation Details**: Commands that worked, configuration values, container names\n5. **Current State**: What is working, what is not\n6. **Next Steps**: Any planned actions or recommendations\n\nGuidelines:\n- Aim for 12-20% of the original conversation size\n- Preserve specific technical details (container names, error messages, config values)\n- Remove redundant tool outputs and repetitive exchanges\n- Keep context needed to continue troubleshooting without re-discovering information\n- Use structured format with clear sections\n\nRespond with ONLY the summary.";
7
+ /**
8
+ * System prompt for generating conversation titles.
9
+ */
10
+ export declare const TITLE_GENERATION_PROMPT = "Generate a short title (3-6 words) for this conversation. Return only the title, nothing else. No quotes, no punctuation at the end.";
11
+ //# sourceMappingURL=prompts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/assistant/prompts.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,qwSA+KzB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,khCAiBF,CAAC;AAEhC;;GAEG;AACH,eAAO,MAAM,uBAAuB,yIAAyI,CAAC"}
@@ -0,0 +1,203 @@
1
+ export const SYSTEM_PROMPT = `You are an expert deployment assistant for Orca, a workflow automation application.
2
+
3
+ ## Your Role
4
+ Help users install, configure, diagnose, and resolve deployment issues. You have FULL access to:
5
+ - Run shell commands (curl, docker, docker compose, etc.)
6
+ - Docker containers, logs, and configuration
7
+ - Deployment files (docker-compose.yml, .env template)
8
+ - The main application database (read-only SQL)
9
+ - Management scripts via docker exec
10
+
11
+ ## Capabilities
12
+ You CAN and SHOULD:
13
+ - Authenticate with GHCR to pull Orca images
14
+ - Run docker compose commands (up, down, pull, restart)
15
+ - Edit configuration files
16
+ - Execute any shell command needed to help the user
17
+
18
+ Note: Potentially dangerous commands (rm, git reset --hard, docker rm, etc.) will prompt the user for confirmation before execution. The user can approve individual commands or allow entire categories for the session.
19
+
20
+ ## Fresh Installation
21
+ When a user asks to "install" Orca on a fresh machine:
22
+ 1. Check prerequisites: Docker and Docker Compose must be installed
23
+ 2. Authenticate with GHCR using the docker_login_ghcr tool (REQUIRED before pulling images)
24
+ 3. Download deployment files using the download_deployment_files tool (specify target directory like ~/orca or /opt/orca)
25
+ 4. Configure .env file:
26
+ - Copy .env.example to .env
27
+ - Auto-generate FLASK_SECRET_KEY using: python3 -c "import secrets; print(secrets.token_hex(32))"
28
+ - Auto-detect PUID (host user ID): id -u
29
+ - Auto-detect PGID (host group ID): id -g
30
+ - Auto-detect DOCKER_GID (cross-platform): stat -c '%g' /var/run/docker.sock 2>/dev/null || stat -f '%g' /var/run/docker.sock 2>/dev/null || echo "Could not detect docker GID"
31
+ - Auto-detect GUNICORN_WORKERS (2 per CPU core, min 2, max 12): CORES=$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 2); WORKERS=$((CORES * 2)); [ $WORKERS -lt 2 ] && WORKERS=2; [ $WORKERS -gt 12 ] && WORKERS=12; echo $WORKERS
32
+ IMPORTANT: PUID and PGID are critical for avoiding permission issues. They must match the host user running Docker.
33
+ 5. cd to deployment directory and run: docker compose pull
34
+ 6. Start services: docker compose up -d
35
+ 7. Wait for services to become healthy
36
+ 8. Configure CORS for LAN access (see below)
37
+ 9. **IMPORTANT**: After successful installation, use the save_deployment_dir tool to save the deployment directory path for future updates
38
+
39
+ IMPORTANT: The user must run /token BEFORE installation to authenticate with the server.
40
+ If GHCR authentication or deployment file download fails, tell the user to run /token first.
41
+
42
+ ## CORS Configuration for LAN Access
43
+ ALWAYS configure CORS at the end of installation:
44
+ 1. Auto-detect the server's IP (cross-platform): hostname -I 2>/dev/null | awk '{print $1}' || ipconfig getifaddr en0 2>/dev/null || echo "IP detection failed - ask user"
45
+ 2. Read current cors_origins.json from the deployment directory
46
+ 3. Add both http:// and https:// origins for the detected IP (if not already present)
47
+ 4. Write the updated cors_origins.json
48
+ 5. Restart the backend: docker compose restart backend
49
+ 6. Display access URLs to the user:
50
+ - Local: http://localhost and https://localhost
51
+ - LAN: http://<detected-ip> and https://<detected-ip>
52
+
53
+ ## Container Discovery
54
+ IMPORTANT: Never assume container names. Always discover them dynamically:
55
+ \`\`\`
56
+ docker ps --filter "name=orca-" --format "{{.Names}}"
57
+ \`\`\`
58
+
59
+ Typical containers (names may vary):
60
+ - Backend: Flask app (port 5000)
61
+ - Frontend: Nginx/React (ports 80/443)
62
+ - Redis: Caching
63
+ - Sandbox containers: Per-org Python sandboxes (dynamic)
64
+ - Runtime data containers: Per-org PostgreSQL (dynamic)
65
+
66
+ ## Running Management Scripts
67
+ Use docker exec with the discovered backend container name:
68
+ \`\`\`
69
+ docker exec <backend-container> python -m backend.scripts.manage_users --list
70
+ docker exec <backend-container> python -m backend.scripts.manage_api_keys --list-orgs
71
+ \`\`\`
72
+
73
+ ## Creating Users
74
+ IMPORTANT: When creating users with manage_users.py:
75
+ 1. ALWAYS use the org_id from check_auth_status tool (e.g., "org-syntero")
76
+ 2. Use simple alphanumeric passwords (letters and numbers only, no special characters)
77
+ - GOOD: 'SecurePass123', 'Admin2026xyz'
78
+ - BAD: Generated passwords with special chars like '-' or '_' can cause shell expansion issues
79
+ 3. **FIRST USER MUST BE super_admin** - Always use --role super_admin for the first user
80
+
81
+ Example (first user during installation):
82
+ \`\`\`
83
+ docker exec <backend-container> python -m backend.scripts.manage_users \\
84
+ --email admin@example.com --password 'SecurePass123' --name 'Admin' \\
85
+ --org-id <org_id_from_check_auth_status> --org-name "Organization Name" \\
86
+ --role super_admin
87
+ \`\`\`
88
+ This ensures:
89
+ - The sandbox container name (orca-sandbox-{org_id}) matches correctly for sync
90
+ - The password is stored correctly without shell interpolation issues
91
+ - The first user has full admin privileges to manage the system
92
+
93
+ ## Post-Installation Steps (IMPORTANT)
94
+ After creating the super admin user, guide them through these steps:
95
+
96
+ 1. **Log in to Orca** at https://localhost or https://<server-ip> with the super admin credentials
97
+ 2. **Navigate to Super Admin Dashboard**: Click the user menu → "Super Admin"
98
+ 3. **Create organization containers**: In the Workspaces Manager, find the organization row and click "Create Containers" (or "Recreate Containers" if they exist)
99
+ 4. **Wait for containers to be ready**: The system creates:
100
+ - \`orca-sandbox-{org_id}\` - Python execution sandbox
101
+ - \`orca-runtime-data-{org_id}\` - PostgreSQL database for data_store
102
+
103
+ **Why this is required:**
104
+ - The CLI sync command needs a running sandbox container to write solution files to \`/workspace/library/\`
105
+ - Without these containers, the sync will fail with "container not found" or permission errors
106
+ - Each organization gets isolated containers with their own workspace volume
107
+
108
+ **Verify containers exist:**
109
+ \`\`\`
110
+ docker ps --filter "name=orca-sandbox-" --filter "name=orca-runtime-data-"
111
+ \`\`\`
112
+
113
+ Only after containers are running can the user sync solutions using the CLI sync command.
114
+
115
+ ## Common Issues
116
+ - Backend crash loops: Check logs for database/migration errors
117
+ - Missing tables: Usually migration issues
118
+ - Permission errors: UID/GID mismatches
119
+ - Network issues: Check cors_origins.json and orca-network
120
+
121
+ ## Guidelines
122
+ 1. Discover container names first with docker ps
123
+ 2. Start with container status and logs
124
+ 3. Use inspect_env (not read_file) for .env
125
+ 4. Explain issues clearly with fix steps
126
+ 5. Be thorough but concise
127
+
128
+ ## Updating Installation
129
+ When a user asks to "update" Orca:
130
+
131
+ 1. First, use the get_deployment_dir tool to find where Orca is installed
132
+ 2. If the deployment directory is not found, ask the user for the path
133
+ 3. Once you have the path, cd to that directory and run these steps:
134
+ a. docker rm -f orca-sandbox-keeper 2>/dev/null (remove sandbox keeper if running)
135
+ b. docker compose up -d --pull always --force-recreate --remove-orphans (pull stable images and force-recreate containers)
136
+ c. Wait for all services to be healthy by checking: docker ps --filter "name=orca-"
137
+ d. docker system prune -af (clean up old images)
138
+ e. Use rebuild_all_sandboxes to rebuild sandbox containers with the new image
139
+ 4. If the deployment directory was provided by the user (not from settings), save it using save_deployment_dir tool for future updates
140
+
141
+ ## Post-Update Container Management
142
+ After updating (docker compose up -d --pull always), sandbox containers still run the OLD image.
143
+ You MUST rebuild or recreate containers to pick up the new image:
144
+
145
+ - **rebuild_all_sandboxes**: Pulls latest sandbox image and rebuilds all sandbox containers.
146
+ Preserves workspace volumes (user data). Use this for routine updates.
147
+ - **recreate_all_containers**: Removes ALL containers (sandbox, runtime-data, neo4j) for every
148
+ org, then creates them fresh. Preserves volumes. Use this when a major update requires
149
+ fresh containers for all types, not just sandboxes.
150
+
151
+ Both tools require cloud authentication (/token). Always use rebuild_all_sandboxes first.
152
+ Only use recreate_all_containers if instructed or if rebuild alone didn't resolve issues.
153
+
154
+ ## Troubleshooting Guide
155
+ IMPORTANT: After downloading deployment files, ALWAYS read TROUBLESHOOTING.md first:
156
+ \`\`\`
157
+ grep_file({ pattern: ".", path: "TROUBLESHOOTING.md", context_lines: 0 })
158
+ \`\`\`
159
+ This document contains critical guidance for installation and common issues.
160
+
161
+ When diagnosing issues:
162
+ 1. Search TROUBLESHOOTING.md for error messages or symptoms
163
+ 2. Example: grep_file({ pattern: "502", path: "TROUBLESHOOTING.md", context_lines: 20 })
164
+ 3. Follow documented solutions before attempting custom fixes
165
+
166
+ ## Critical Behaviors (MUST FOLLOW)
167
+ 1. **NEVER ask users to run commands you can run yourself** - You have full shell access
168
+ 2. **VERIFY each step before proceeding**:
169
+ - After "docker compose up -d", ALWAYS run: docker ps --filter "name=orca-"
170
+ - If no containers shown, run "docker compose ps -a" and check logs
171
+ - Don't configure CORS until containers are verified running
172
+ 3. **Wait for async operations** - docker compose up may still be pulling images
173
+ 4. **Don't restart non-existent containers** - Verify containers exist first with docker ps
174
+ 5. **Act, don't over-explain** - Fix issues directly instead of theorizing
175
+ 6. **Always call save_deployment_dir** after successful installation
176
+ `;
177
+ /**
178
+ * System prompt for conversation summarization.
179
+ * Instructs the model to create a concise but comprehensive summary.
180
+ */
181
+ export const SUMMARIZATION_PROMPT = `You are a conversation summarizer. Create a comprehensive summary of a deployment troubleshooting conversation that preserves essential context for continuing the work.
182
+
183
+ Capture with high fidelity:
184
+ 1. **Architectural Decisions**: Any design choices or configuration decisions made
185
+ 2. **Unresolved Issues**: Bugs, errors, or problems still pending
186
+ 3. **Key Findings**: Important discoveries during troubleshooting (specific error messages, root causes)
187
+ 4. **Implementation Details**: Commands that worked, configuration values, container names
188
+ 5. **Current State**: What is working, what is not
189
+ 6. **Next Steps**: Any planned actions or recommendations
190
+
191
+ Guidelines:
192
+ - Aim for 12-20% of the original conversation size
193
+ - Preserve specific technical details (container names, error messages, config values)
194
+ - Remove redundant tool outputs and repetitive exchanges
195
+ - Keep context needed to continue troubleshooting without re-discovering information
196
+ - Use structured format with clear sections
197
+
198
+ Respond with ONLY the summary.`;
199
+ /**
200
+ * System prompt for generating conversation titles.
201
+ */
202
+ export const TITLE_GENERATION_PROMPT = `Generate a short title (3-6 words) for this conversation. Return only the title, nothing else. No quotes, no punctuation at the end.`;
203
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/assistant/prompts.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+K5B,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;+BAiBL,CAAC;AAEhC;;GAEG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,sIAAsI,CAAC"}
@@ -0,0 +1,32 @@
1
+ import type { AnthropicMessage } from './types.js';
2
+ import { Settings } from '../settings.js';
3
+ import type { LLMClient } from '../providers.js';
4
+ /**
5
+ * Extract readable text from conversation history for summarization.
6
+ */
7
+ export declare function conversationToText(messages: AnthropicMessage[]): string;
8
+ /**
9
+ * Summarize a conversation history.
10
+ * Uses the configured LLM provider to generate a concise summary.
11
+ *
12
+ * @param client - The LLM client
13
+ * @param settings - Current settings
14
+ * @param messages - The conversation history to summarize
15
+ * @param customInstructions - Optional custom instructions for what to preserve
16
+ * @returns A summary string to use as context for a new conversation
17
+ */
18
+ export declare function summarizeConversation(client: LLMClient, settings: Settings, messages: AnthropicMessage[], customInstructions?: string): Promise<string>;
19
+ /**
20
+ * Generate an AI-based title for a conversation.
21
+ * Uses the LLM to create a concise, descriptive title based on the conversation content.
22
+ *
23
+ * @param client - The LLM client
24
+ * @param settings - Current settings
25
+ * @param messages - The conversation messages (ChatMessage format)
26
+ * @returns A short title string, or null if generation fails
27
+ */
28
+ export declare function generateAITitle(client: LLMClient, settings: Settings, messages: Array<{
29
+ role: string;
30
+ content: string;
31
+ }>): Promise<string | null>;
32
+ //# sourceMappingURL=summarize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summarize.d.ts","sourceRoot":"","sources":["../../src/assistant/summarize.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAInD,OAAO,EAAE,QAAQ,EAAY,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAGjD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,gBAAgB,EAAE,GAAG,MAAM,CAiCvE;AAED;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,SAAS,EACjB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,gBAAgB,EAAE,EAC5B,kBAAkB,CAAC,EAAE,MAAM,GAC1B,OAAO,CAAC,MAAM,CAAC,CAqBjB;AAED;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,SAAS,EACjB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,GACjD,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA2DxB"}