@defai.digital/automatosx 11.2.8 → 11.3.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.
- package/README.md +4 -5
- package/dist/index.js +3192 -297
- package/dist/mcp/index.js +111 -67
- package/examples/abilities/our-architecture-decisions.md +1 -1
- package/examples/abilities/our-project-structure.md +1 -1
- package/package.json +1 -1
package/dist/mcp/index.js
CHANGED
|
@@ -7,13 +7,13 @@ import { existsSync, readFileSync, promises, mkdirSync, createWriteStream, write
|
|
|
7
7
|
import Database2 from 'better-sqlite3';
|
|
8
8
|
import { glob } from 'glob';
|
|
9
9
|
import { spawn, spawnSync } from 'child_process';
|
|
10
|
-
import { z } from 'zod';
|
|
10
|
+
import { z, ZodError } from 'zod';
|
|
11
11
|
import chalk4 from 'chalk';
|
|
12
12
|
import ora2 from 'ora';
|
|
13
13
|
import readline, { createInterface } from 'readline';
|
|
14
|
+
import { Mutex } from 'async-mutex';
|
|
14
15
|
import Ajv from 'ajv';
|
|
15
16
|
import addFormats from 'ajv-formats';
|
|
16
|
-
import { Mutex } from 'async-mutex';
|
|
17
17
|
import os2, { cpus } from 'os';
|
|
18
18
|
import { load } from 'js-yaml';
|
|
19
19
|
import { EventEmitter } from 'events';
|
|
@@ -2277,6 +2277,15 @@ var init_base_provider = __esm({
|
|
|
2277
2277
|
"test-provider"
|
|
2278
2278
|
// For unit tests
|
|
2279
2279
|
];
|
|
2280
|
+
/** Environment variables to force non-interactive CLI mode */
|
|
2281
|
+
static NON_INTERACTIVE_ENV = {
|
|
2282
|
+
TERM: "dumb",
|
|
2283
|
+
NO_COLOR: "1",
|
|
2284
|
+
FORCE_COLOR: "0",
|
|
2285
|
+
CI: "true",
|
|
2286
|
+
NO_UPDATE_NOTIFIER: "1",
|
|
2287
|
+
DEBIAN_FRONTEND: "noninteractive"
|
|
2288
|
+
};
|
|
2280
2289
|
config;
|
|
2281
2290
|
logger = logger;
|
|
2282
2291
|
health;
|
|
@@ -2369,19 +2378,7 @@ var init_base_provider = __esm({
|
|
|
2369
2378
|
shell: true,
|
|
2370
2379
|
// Auto-detects: cmd.exe on Windows, /bin/sh on Unix
|
|
2371
2380
|
timeout: this.config.timeout || 12e4,
|
|
2372
|
-
env: {
|
|
2373
|
-
...process.env,
|
|
2374
|
-
// Force non-interactive mode for CLIs
|
|
2375
|
-
TERM: "dumb",
|
|
2376
|
-
NO_COLOR: "1",
|
|
2377
|
-
// Disable TTY checks for codex and other CLIs
|
|
2378
|
-
FORCE_COLOR: "0",
|
|
2379
|
-
CI: "true",
|
|
2380
|
-
// Many CLIs disable TTY checks in CI mode
|
|
2381
|
-
NO_UPDATE_NOTIFIER: "1",
|
|
2382
|
-
// Disable interactive prompts
|
|
2383
|
-
DEBIAN_FRONTEND: "noninteractive"
|
|
2384
|
-
}
|
|
2381
|
+
env: { ...process.env, ..._BaseProvider.NON_INTERACTIVE_ENV }
|
|
2385
2382
|
});
|
|
2386
2383
|
let stdout = "";
|
|
2387
2384
|
let stderr = "";
|
|
@@ -2531,22 +2528,14 @@ var init_base_provider = __esm({
|
|
|
2531
2528
|
});
|
|
2532
2529
|
const child = spawn(cliCommand, commandArgs, {
|
|
2533
2530
|
timeout: this.config.timeout || 12e4,
|
|
2534
|
-
env: {
|
|
2535
|
-
...process.env,
|
|
2536
|
-
// Force non-interactive mode for CLIs
|
|
2537
|
-
TERM: "dumb",
|
|
2538
|
-
NO_COLOR: "1",
|
|
2539
|
-
FORCE_COLOR: "0",
|
|
2540
|
-
CI: "true",
|
|
2541
|
-
NO_UPDATE_NOTIFIER: "1",
|
|
2542
|
-
DEBIAN_FRONTEND: "noninteractive"
|
|
2543
|
-
}
|
|
2531
|
+
env: { ...process.env, ..._BaseProvider.NON_INTERACTIVE_ENV }
|
|
2544
2532
|
});
|
|
2545
2533
|
let stdout = "";
|
|
2546
2534
|
let stderr = "";
|
|
2547
2535
|
let timeoutId = null;
|
|
2548
2536
|
let forceKillTimer = null;
|
|
2549
2537
|
let readlineInterface = null;
|
|
2538
|
+
let stderrInterface = null;
|
|
2550
2539
|
const streamingEnabled = process.env.AUTOMATOSX_SHOW_PROVIDER_OUTPUT === "true";
|
|
2551
2540
|
const debugMode = process.env.AUTOMATOSX_DEBUG === "true";
|
|
2552
2541
|
const verbosity = VerbosityManager.getInstance();
|
|
@@ -2591,7 +2580,7 @@ var init_base_provider = __esm({
|
|
|
2591
2580
|
});
|
|
2592
2581
|
}
|
|
2593
2582
|
if (child.stderr) {
|
|
2594
|
-
|
|
2583
|
+
stderrInterface = readline.createInterface({
|
|
2595
2584
|
input: child.stderr,
|
|
2596
2585
|
crlfDelay: Infinity
|
|
2597
2586
|
});
|
|
@@ -2607,6 +2596,13 @@ var init_base_provider = __esm({
|
|
|
2607
2596
|
}
|
|
2608
2597
|
}
|
|
2609
2598
|
});
|
|
2599
|
+
stderrInterface.on("error", (error) => {
|
|
2600
|
+
if (error.message !== "Readable stream already read") {
|
|
2601
|
+
logger.debug("Stderr readline error (non-fatal)", {
|
|
2602
|
+
error: error.message
|
|
2603
|
+
});
|
|
2604
|
+
}
|
|
2605
|
+
});
|
|
2610
2606
|
}
|
|
2611
2607
|
const cleanup = () => {
|
|
2612
2608
|
if (timeoutId) {
|
|
@@ -2625,22 +2621,35 @@ var init_base_provider = __esm({
|
|
|
2625
2621
|
readlineInterface = null;
|
|
2626
2622
|
}
|
|
2627
2623
|
}
|
|
2624
|
+
if (stderrInterface) {
|
|
2625
|
+
try {
|
|
2626
|
+
stderrInterface.close();
|
|
2627
|
+
} catch (error) {
|
|
2628
|
+
} finally {
|
|
2629
|
+
stderrInterface = null;
|
|
2630
|
+
}
|
|
2631
|
+
}
|
|
2628
2632
|
};
|
|
2629
2633
|
child.on("close", (code, signal) => {
|
|
2630
2634
|
cleanup();
|
|
2631
2635
|
if (stderr) {
|
|
2632
2636
|
logger.debug(`${cliCommand} CLI stderr output`, { stderr: stderr.trim() });
|
|
2633
2637
|
}
|
|
2634
|
-
if (code === 0) {
|
|
2638
|
+
if ((code === 0 || code === null) && !signal) {
|
|
2635
2639
|
if (progressParser) {
|
|
2636
2640
|
progressParser.succeed(`${cliCommand} completed successfully`);
|
|
2637
2641
|
}
|
|
2638
2642
|
resolve5({ stdout, stderr });
|
|
2643
|
+
} else if (signal) {
|
|
2644
|
+
if (progressParser) {
|
|
2645
|
+
progressParser.fail(`${cliCommand} killed by signal ${signal}`);
|
|
2646
|
+
}
|
|
2647
|
+
reject(new Error(`${cliCommand} CLI killed by signal ${signal}. stderr: ${stderr || "none"}`));
|
|
2639
2648
|
} else {
|
|
2640
2649
|
if (progressParser) {
|
|
2641
2650
|
progressParser.fail(`${cliCommand} failed with code ${code}`);
|
|
2642
2651
|
}
|
|
2643
|
-
reject(new Error(`${cliCommand} CLI exited with code ${code}
|
|
2652
|
+
reject(new Error(`${cliCommand} CLI exited with code ${code}. stderr: ${stderr || "none"}`));
|
|
2644
2653
|
}
|
|
2645
2654
|
});
|
|
2646
2655
|
child.on("error", (error) => {
|
|
@@ -2676,8 +2685,18 @@ var init_base_provider = __esm({
|
|
|
2676
2685
|
/**
|
|
2677
2686
|
* Check if CLI is available - Template method pattern
|
|
2678
2687
|
* Uses getCLICommand() to determine which CLI to check
|
|
2688
|
+
*
|
|
2689
|
+
* v11.2.9 Fix: Always return true in mock mode (AX_MOCK_PROVIDERS=true)
|
|
2690
|
+
* This allows integration tests in CI to run without installing actual provider CLIs
|
|
2679
2691
|
*/
|
|
2680
2692
|
async checkCLIAvailable() {
|
|
2693
|
+
if (process.env.AX_MOCK_PROVIDERS === "true") {
|
|
2694
|
+
logger.debug(`${this.getCLICommand()} CLI availability check (mock mode)`, {
|
|
2695
|
+
available: true,
|
|
2696
|
+
mockMode: true
|
|
2697
|
+
});
|
|
2698
|
+
return true;
|
|
2699
|
+
}
|
|
2681
2700
|
try {
|
|
2682
2701
|
const cliCommand = this.getCLICommand();
|
|
2683
2702
|
const result = findOnPath(cliCommand);
|
|
@@ -3596,8 +3615,6 @@ var init_cli_wrapper = __esm({
|
|
|
3596
3615
|
};
|
|
3597
3616
|
}
|
|
3598
3617
|
});
|
|
3599
|
-
|
|
3600
|
-
// src/integrations/openai-codex/sdk-adapter.ts
|
|
3601
3618
|
var CodexSdkAdapter;
|
|
3602
3619
|
var init_sdk_adapter = __esm({
|
|
3603
3620
|
"src/integrations/openai-codex/sdk-adapter.ts"() {
|
|
@@ -3610,6 +3627,8 @@ var init_sdk_adapter = __esm({
|
|
|
3610
3627
|
sdkModule = null;
|
|
3611
3628
|
options;
|
|
3612
3629
|
initialized = false;
|
|
3630
|
+
initMutex = new Mutex();
|
|
3631
|
+
// v11.2.8: Prevent race condition in ensureInitialized
|
|
3613
3632
|
constructor(options = {}) {
|
|
3614
3633
|
this.options = {
|
|
3615
3634
|
streamingEnabled: true,
|
|
@@ -3704,18 +3723,20 @@ var init_sdk_adapter = __esm({
|
|
|
3704
3723
|
return this.activeThread;
|
|
3705
3724
|
}
|
|
3706
3725
|
async ensureInitialized() {
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
|
|
3726
|
+
return this.initMutex.runExclusive(async () => {
|
|
3727
|
+
if (this.initialized) return;
|
|
3728
|
+
try {
|
|
3729
|
+
this.sdkModule = await import('@openai/codex-sdk');
|
|
3730
|
+
this.codex = new this.sdkModule.Codex();
|
|
3731
|
+
this.initialized = true;
|
|
3732
|
+
logger.info("Codex SDK initialized");
|
|
3733
|
+
} catch (error) {
|
|
3734
|
+
throw new CodexError(
|
|
3735
|
+
"CLI_NOT_FOUND" /* CLI_NOT_FOUND */,
|
|
3736
|
+
"Codex SDK not available. Install with: npm install @openai/codex-sdk"
|
|
3737
|
+
);
|
|
3738
|
+
}
|
|
3739
|
+
});
|
|
3719
3740
|
}
|
|
3720
3741
|
async destroy() {
|
|
3721
3742
|
this.activeThread = null;
|
|
@@ -5229,7 +5250,7 @@ var PRECOMPILED_CONFIG = {
|
|
|
5229
5250
|
"enableFreeTierPrioritization": true,
|
|
5230
5251
|
"enableWorkloadAwareRouting": true
|
|
5231
5252
|
},
|
|
5232
|
-
"version": "11.
|
|
5253
|
+
"version": "11.3.0"
|
|
5233
5254
|
};
|
|
5234
5255
|
|
|
5235
5256
|
// src/core/config/schemas.ts
|
|
@@ -6478,6 +6499,8 @@ var ProviderLimitManager = class _ProviderLimitManager extends EventEmitter {
|
|
|
6478
6499
|
getManualOverride() {
|
|
6479
6500
|
if (this.manualOverride && this.manualOverride.expiresAtMs) {
|
|
6480
6501
|
if (Date.now() >= this.manualOverride.expiresAtMs) {
|
|
6502
|
+
this.manualOverride;
|
|
6503
|
+
this.manualOverride = void 0;
|
|
6481
6504
|
void this.clearManualOverride();
|
|
6482
6505
|
return void 0;
|
|
6483
6506
|
}
|
|
@@ -6972,19 +6995,33 @@ var ProviderMetricsTracker = class extends EventEmitter {
|
|
|
6972
6995
|
const p50 = getPercentile(latencies, 50);
|
|
6973
6996
|
const p95 = getPercentile(latencies, 95);
|
|
6974
6997
|
const p99 = getPercentile(latencies, 99);
|
|
6975
|
-
|
|
6976
|
-
|
|
6977
|
-
|
|
6978
|
-
|
|
6979
|
-
|
|
6980
|
-
|
|
6981
|
-
|
|
6998
|
+
let successCount = 0;
|
|
6999
|
+
let failCount = 0;
|
|
7000
|
+
let stopFinishCount = 0;
|
|
7001
|
+
let lengthFinishCount = 0;
|
|
7002
|
+
let errorFinishCount = 0;
|
|
7003
|
+
let lastSuccessTimestamp = 0;
|
|
7004
|
+
let lastFailureTimestamp = 0;
|
|
7005
|
+
for (const r of records) {
|
|
7006
|
+
if (r.success) {
|
|
7007
|
+
successCount++;
|
|
7008
|
+
lastSuccessTimestamp = r.timestamp;
|
|
7009
|
+
if (r.finishReason === "stop") stopFinishCount++;
|
|
7010
|
+
else if (r.finishReason === "length") lengthFinishCount++;
|
|
7011
|
+
} else {
|
|
7012
|
+
failCount++;
|
|
7013
|
+
lastFailureTimestamp = r.timestamp;
|
|
7014
|
+
}
|
|
7015
|
+
if (r.finishReason === "error") errorFinishCount++;
|
|
7016
|
+
}
|
|
7017
|
+
const successRate = successCount / records.length;
|
|
7018
|
+
const properStopRate = successCount > 0 ? stopFinishCount / successCount : 0;
|
|
6982
7019
|
const totalCost = records.reduce((sum, r) => sum + r.costUsd, 0);
|
|
6983
7020
|
const avgCostPerRequest = totalCost / records.length;
|
|
6984
7021
|
const totalTokens = records.reduce((sum, r) => sum + r.totalTokens, 0);
|
|
6985
7022
|
const avgCostPer1M = totalTokens > 0 ? totalCost / totalTokens * 1e6 : 0;
|
|
6986
|
-
const lastSuccess =
|
|
6987
|
-
const lastFailure =
|
|
7023
|
+
const lastSuccess = lastSuccessTimestamp;
|
|
7024
|
+
const lastFailure = lastFailureTimestamp;
|
|
6988
7025
|
let consecutiveFailures = 0;
|
|
6989
7026
|
for (let i = records.length - 1; i >= 0; i--) {
|
|
6990
7027
|
if (!records[i].success) {
|
|
@@ -7007,12 +7044,12 @@ var ProviderMetricsTracker = class extends EventEmitter {
|
|
|
7007
7044
|
},
|
|
7008
7045
|
quality: {
|
|
7009
7046
|
totalRequests: records.length,
|
|
7010
|
-
successfulRequests:
|
|
7011
|
-
failedRequests:
|
|
7047
|
+
successfulRequests: successCount,
|
|
7048
|
+
failedRequests: failCount,
|
|
7012
7049
|
successRate,
|
|
7013
|
-
stopFinishes:
|
|
7014
|
-
lengthFinishes:
|
|
7015
|
-
errorFinishes:
|
|
7050
|
+
stopFinishes: stopFinishCount,
|
|
7051
|
+
lengthFinishes: lengthFinishCount,
|
|
7052
|
+
errorFinishes: errorFinishCount,
|
|
7016
7053
|
properStopRate
|
|
7017
7054
|
},
|
|
7018
7055
|
cost: {
|
|
@@ -7121,7 +7158,7 @@ var ProviderMetricsTracker = class extends EventEmitter {
|
|
|
7121
7158
|
* v9.0.2: Added score caching to reduce redundant calculations
|
|
7122
7159
|
*/
|
|
7123
7160
|
async calculateScore(provider, weights, allProviders, healthMultiplier = 1) {
|
|
7124
|
-
const cacheKey = `${provider}-${
|
|
7161
|
+
const cacheKey = `${provider}-${weights.cost}-${weights.latency}-${weights.quality}-${weights.availability}-${healthMultiplier}`;
|
|
7125
7162
|
const cached = this.scoreCache.get(cacheKey);
|
|
7126
7163
|
const currentRequestCount = this.getRequestCount(provider);
|
|
7127
7164
|
if (cached) {
|
|
@@ -8285,8 +8322,7 @@ var Router = class {
|
|
|
8285
8322
|
}
|
|
8286
8323
|
}
|
|
8287
8324
|
if (limitedProviders2.length === allProviders2.length && limitedProviders2.length > 0) {
|
|
8288
|
-
|
|
8289
|
-
throw ProviderError.allProvidersLimited(limitedProviders2, soonestReset);
|
|
8325
|
+
throw ProviderError.allProvidersLimited(limitedProviders2, this.getSoonestLimitReset(limitedProviders2));
|
|
8290
8326
|
}
|
|
8291
8327
|
throw ProviderError.noAvailableProviders();
|
|
8292
8328
|
}
|
|
@@ -8692,8 +8728,7 @@ var Router = class {
|
|
|
8692
8728
|
}
|
|
8693
8729
|
}
|
|
8694
8730
|
if (limitedProviders.length === allProviders.length && limitedProviders.length > 0) {
|
|
8695
|
-
|
|
8696
|
-
throw ProviderError.allProvidersLimited(limitedProviders, soonestReset);
|
|
8731
|
+
throw ProviderError.allProvidersLimited(limitedProviders, this.getSoonestLimitReset(limitedProviders));
|
|
8697
8732
|
}
|
|
8698
8733
|
const errorDetails = {
|
|
8699
8734
|
lastError: lastError?.message,
|
|
@@ -8927,6 +8962,16 @@ Run 'ax doctor' to diagnose provider setup.` : "";
|
|
|
8927
8962
|
})
|
|
8928
8963
|
};
|
|
8929
8964
|
}
|
|
8965
|
+
/**
|
|
8966
|
+
* Calculate the soonest reset time from limited providers
|
|
8967
|
+
* v11.2.8: Added guard against empty array (Math.min on empty array returns Infinity)
|
|
8968
|
+
*/
|
|
8969
|
+
getSoonestLimitReset(limitedProviders) {
|
|
8970
|
+
if (limitedProviders.length === 0) {
|
|
8971
|
+
return Date.now() + 6e4;
|
|
8972
|
+
}
|
|
8973
|
+
return Math.min(...limitedProviders.map((p) => p.resetAtMs));
|
|
8974
|
+
}
|
|
8930
8975
|
};
|
|
8931
8976
|
|
|
8932
8977
|
// src/core/memory/lazy-manager.ts
|
|
@@ -10760,8 +10805,6 @@ z.object({
|
|
|
10760
10805
|
limit: z.number().int().positive().max(1e4).optional(),
|
|
10761
10806
|
offset: z.number().int().nonnegative().optional()
|
|
10762
10807
|
}).strict();
|
|
10763
|
-
|
|
10764
|
-
// src/core/session/manager.ts
|
|
10765
10808
|
var SessionManager = class _SessionManager {
|
|
10766
10809
|
/** Active sessions (in-memory, keyed by session ID) */
|
|
10767
10810
|
activeSessions = /* @__PURE__ */ new Map();
|
|
@@ -10834,8 +10877,9 @@ var SessionManager = class _SessionManager {
|
|
|
10834
10877
|
try {
|
|
10835
10878
|
SessionManagerConfigSchema.parse(config);
|
|
10836
10879
|
} catch (error) {
|
|
10880
|
+
const message = error instanceof ZodError ? error.message : String(error);
|
|
10837
10881
|
throw new SessionError(
|
|
10838
|
-
`Invalid session manager config: ${
|
|
10882
|
+
`Invalid session manager config: ${message}`,
|
|
10839
10883
|
void 0,
|
|
10840
10884
|
"invalid_configuration"
|
|
10841
10885
|
);
|
|
@@ -12236,8 +12280,8 @@ var ProjectContextLoader = class {
|
|
|
12236
12280
|
const projectMatch = markdown.match(/>\s*Project:\s*(.+?)$/im);
|
|
12237
12281
|
if (projectMatch && projectMatch[1]) {
|
|
12238
12282
|
const parts = projectMatch[1].trim().split(/\s+v/);
|
|
12239
|
-
metadata.name = parts[0];
|
|
12240
|
-
if (parts[1]) {
|
|
12283
|
+
metadata.name = parts[0] || "";
|
|
12284
|
+
if (parts.length > 1 && parts[1]) {
|
|
12241
12285
|
metadata.version = parts[1];
|
|
12242
12286
|
}
|
|
12243
12287
|
}
|
|
@@ -137,7 +137,7 @@ import type { Provider } from '../types/provider.js';
|
|
|
137
137
|
- `index.js.map` - Source map
|
|
138
138
|
- `index.d.ts` - Type definitions
|
|
139
139
|
|
|
140
|
-
**Bundle target:** ESM, Node
|
|
140
|
+
**Bundle target:** ESM, Node 24+, <250KB target
|
|
141
141
|
|
|
142
142
|
## Workspace Structure
|
|
143
143
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@defai.digital/automatosx",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.3.0",
|
|
4
4
|
"description": "Provider-agnostic AI orchestration platform with 20+ specialized agents, persistent memory, and multi-provider routing for Claude Code, Gemini CLI, Codex CLI, and ax-cli",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|