orquesta-cli 0.2.75 → 0.2.76

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.
@@ -89,6 +89,11 @@ export declare class LLMClient {
89
89
  latency?: number;
90
90
  error?: string;
91
91
  }[]>>;
92
+ static healthCheckCurrent(): Promise<{
93
+ healthy: boolean;
94
+ latency?: number;
95
+ error?: string;
96
+ }>;
92
97
  static testConnection(baseUrl: string, apiKey: string, model: string): Promise<{
93
98
  success: boolean;
94
99
  latency?: number;
@@ -1213,6 +1213,52 @@ export class LLMClient {
1213
1213
  }
1214
1214
  return results;
1215
1215
  }
1216
+ static async healthCheckCurrent() {
1217
+ const endpoint = configManager.getCurrentEndpoint();
1218
+ const model = configManager.getCurrentModel();
1219
+ if (!endpoint || !model) {
1220
+ return { healthy: false, error: 'No endpoint/model configured' };
1221
+ }
1222
+ const startTime = Date.now();
1223
+ try {
1224
+ const axiosInstance = axios.create({
1225
+ baseURL: endpoint.baseUrl,
1226
+ headers: {
1227
+ 'Content-Type': 'application/json',
1228
+ ...(endpoint.apiKey && { Authorization: `Bearer ${endpoint.apiKey}` }),
1229
+ },
1230
+ timeout: 10000,
1231
+ });
1232
+ const response = await axiosInstance.post('/chat/completions', {
1233
+ model: model.id,
1234
+ messages: [{ role: 'user', content: 'ping' }],
1235
+ max_tokens: 1,
1236
+ });
1237
+ const latency = Date.now() - startTime;
1238
+ if (response.status === 200 && response.data.choices?.[0]?.message) {
1239
+ return { healthy: true, latency };
1240
+ }
1241
+ return { healthy: false, latency, error: 'Invalid response' };
1242
+ }
1243
+ catch (error) {
1244
+ const latency = Date.now() - startTime;
1245
+ const axiosError = error;
1246
+ let errorMessage = 'Unknown error';
1247
+ if (axiosError.response) {
1248
+ errorMessage = `HTTP ${axiosError.response.status}`;
1249
+ }
1250
+ else if (axiosError.code === 'ECONNREFUSED') {
1251
+ errorMessage = 'Connection refused';
1252
+ }
1253
+ else if (axiosError.code === 'ETIMEDOUT' || axiosError.code === 'ECONNABORTED') {
1254
+ errorMessage = 'Timeout';
1255
+ }
1256
+ else if (axiosError.request) {
1257
+ errorMessage = 'Network error';
1258
+ }
1259
+ return { healthy: false, latency, error: errorMessage };
1260
+ }
1261
+ }
1216
1262
  static async testConnection(baseUrl, apiKey, model) {
1217
1263
  const startTime = Date.now();
1218
1264
  try {
@@ -470,30 +470,24 @@ export const PlanExecuteApp = ({ llmClient: initialLlmClient, modelInfo, resumeL
470
470
  logger.startTimer('app-init');
471
471
  try {
472
472
  setInitStep('health');
473
- logger.flow('Running health check + docs init in parallel');
473
+ logger.flow('Kicking off background health probe + docs init');
474
474
  setHealthStatus('checking');
475
- const healthPromise = (async () => {
475
+ void (async () => {
476
476
  if (configManager.hasEndpoints()) {
477
- const healthResults = await LLMClient.healthCheckAll();
478
- let hasHealthy = false;
479
- for (const [endpointId, modelResults] of healthResults) {
480
- logger.vars({ name: 'endpointId', value: endpointId }, { name: 'healthyModels', value: modelResults.filter(r => r.healthy).length });
481
- if (modelResults.some((r) => r.healthy)) {
482
- hasHealthy = true;
483
- }
484
- }
485
- logger.state('Health status', 'checking', hasHealthy ? 'healthy' : 'unhealthy');
486
- setHealthStatus(hasHealthy ? 'healthy' : 'unhealthy');
487
- await configManager.updateAllHealthStatus(healthResults);
477
+ const result = await LLMClient.healthCheckCurrent();
478
+ logger.state('Health status', 'checking', result.healthy ? 'healthy' : 'unhealthy');
479
+ setHealthStatus(result.healthy ? 'healthy' : 'unhealthy');
488
480
  }
489
481
  else {
490
482
  setHealthStatus('unknown');
491
483
  }
492
- })();
493
- const docsPromise = initializeDocsDirectory().catch((err) => {
484
+ })().catch((err) => {
485
+ logger.warn('Background health probe failed', { error: err });
486
+ setHealthStatus('unknown');
487
+ });
488
+ await initializeDocsDirectory().catch((err) => {
494
489
  logger.warn('Docs directory initialization warning', { error: err });
495
490
  });
496
- await Promise.all([healthPromise, docsPromise]);
497
491
  setInitStep('config');
498
492
  logger.flow('Checking configuration');
499
493
  if (!configManager.hasEndpoints()) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orquesta-cli",
3
- "version": "0.2.75",
3
+ "version": "0.2.76",
4
4
  "description": "Orquesta CLI - AI-powered coding assistant with team collaboration",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",