@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/index.js
CHANGED
|
@@ -15,14 +15,14 @@ import chalk5 from 'chalk';
|
|
|
15
15
|
import ora8 from 'ora';
|
|
16
16
|
import * as readline2 from 'readline';
|
|
17
17
|
import readline2__default, { createInterface } from 'readline';
|
|
18
|
+
import { Mutex } from 'async-mutex';
|
|
18
19
|
import { promisify } from 'util';
|
|
19
20
|
import yargs from 'yargs';
|
|
20
21
|
import { hideBin } from 'yargs/helpers';
|
|
21
|
-
import { randomUUID, createHash } from 'crypto';
|
|
22
|
+
import crypto2, { randomUUID, createHash } from 'crypto';
|
|
22
23
|
import * as yaml4 from 'js-yaml';
|
|
23
24
|
import yaml4__default, { load, dump } from 'js-yaml';
|
|
24
25
|
import Table from 'cli-table3';
|
|
25
|
-
import { Mutex } from 'async-mutex';
|
|
26
26
|
import inquirer from 'inquirer';
|
|
27
27
|
import Ajv from 'ajv';
|
|
28
28
|
import addFormats from 'ajv-formats';
|
|
@@ -2535,6 +2535,15 @@ var init_base_provider = __esm({
|
|
|
2535
2535
|
"test-provider"
|
|
2536
2536
|
// For unit tests
|
|
2537
2537
|
];
|
|
2538
|
+
/** Environment variables to force non-interactive CLI mode */
|
|
2539
|
+
static NON_INTERACTIVE_ENV = {
|
|
2540
|
+
TERM: "dumb",
|
|
2541
|
+
NO_COLOR: "1",
|
|
2542
|
+
FORCE_COLOR: "0",
|
|
2543
|
+
CI: "true",
|
|
2544
|
+
NO_UPDATE_NOTIFIER: "1",
|
|
2545
|
+
DEBIAN_FRONTEND: "noninteractive"
|
|
2546
|
+
};
|
|
2538
2547
|
config;
|
|
2539
2548
|
logger = logger;
|
|
2540
2549
|
health;
|
|
@@ -2627,19 +2636,7 @@ var init_base_provider = __esm({
|
|
|
2627
2636
|
shell: true,
|
|
2628
2637
|
// Auto-detects: cmd.exe on Windows, /bin/sh on Unix
|
|
2629
2638
|
timeout: this.config.timeout || 12e4,
|
|
2630
|
-
env: {
|
|
2631
|
-
...process.env,
|
|
2632
|
-
// Force non-interactive mode for CLIs
|
|
2633
|
-
TERM: "dumb",
|
|
2634
|
-
NO_COLOR: "1",
|
|
2635
|
-
// Disable TTY checks for codex and other CLIs
|
|
2636
|
-
FORCE_COLOR: "0",
|
|
2637
|
-
CI: "true",
|
|
2638
|
-
// Many CLIs disable TTY checks in CI mode
|
|
2639
|
-
NO_UPDATE_NOTIFIER: "1",
|
|
2640
|
-
// Disable interactive prompts
|
|
2641
|
-
DEBIAN_FRONTEND: "noninteractive"
|
|
2642
|
-
}
|
|
2639
|
+
env: { ...process.env, ..._BaseProvider.NON_INTERACTIVE_ENV }
|
|
2643
2640
|
});
|
|
2644
2641
|
let stdout = "";
|
|
2645
2642
|
let stderr = "";
|
|
@@ -2789,22 +2786,14 @@ var init_base_provider = __esm({
|
|
|
2789
2786
|
});
|
|
2790
2787
|
const child = spawn(cliCommand2, commandArgs, {
|
|
2791
2788
|
timeout: this.config.timeout || 12e4,
|
|
2792
|
-
env: {
|
|
2793
|
-
...process.env,
|
|
2794
|
-
// Force non-interactive mode for CLIs
|
|
2795
|
-
TERM: "dumb",
|
|
2796
|
-
NO_COLOR: "1",
|
|
2797
|
-
FORCE_COLOR: "0",
|
|
2798
|
-
CI: "true",
|
|
2799
|
-
NO_UPDATE_NOTIFIER: "1",
|
|
2800
|
-
DEBIAN_FRONTEND: "noninteractive"
|
|
2801
|
-
}
|
|
2789
|
+
env: { ...process.env, ..._BaseProvider.NON_INTERACTIVE_ENV }
|
|
2802
2790
|
});
|
|
2803
2791
|
let stdout = "";
|
|
2804
2792
|
let stderr = "";
|
|
2805
2793
|
let timeoutId = null;
|
|
2806
2794
|
let forceKillTimer = null;
|
|
2807
2795
|
let readlineInterface = null;
|
|
2796
|
+
let stderrInterface = null;
|
|
2808
2797
|
const streamingEnabled = process.env.AUTOMATOSX_SHOW_PROVIDER_OUTPUT === "true";
|
|
2809
2798
|
const debugMode = process.env.AUTOMATOSX_DEBUG === "true";
|
|
2810
2799
|
const verbosity = VerbosityManager.getInstance();
|
|
@@ -2849,7 +2838,7 @@ var init_base_provider = __esm({
|
|
|
2849
2838
|
});
|
|
2850
2839
|
}
|
|
2851
2840
|
if (child.stderr) {
|
|
2852
|
-
|
|
2841
|
+
stderrInterface = readline2__default.createInterface({
|
|
2853
2842
|
input: child.stderr,
|
|
2854
2843
|
crlfDelay: Infinity
|
|
2855
2844
|
});
|
|
@@ -2865,6 +2854,13 @@ var init_base_provider = __esm({
|
|
|
2865
2854
|
}
|
|
2866
2855
|
}
|
|
2867
2856
|
});
|
|
2857
|
+
stderrInterface.on("error", (error) => {
|
|
2858
|
+
if (error.message !== "Readable stream already read") {
|
|
2859
|
+
logger.debug("Stderr readline error (non-fatal)", {
|
|
2860
|
+
error: error.message
|
|
2861
|
+
});
|
|
2862
|
+
}
|
|
2863
|
+
});
|
|
2868
2864
|
}
|
|
2869
2865
|
const cleanup = () => {
|
|
2870
2866
|
if (timeoutId) {
|
|
@@ -2883,22 +2879,35 @@ var init_base_provider = __esm({
|
|
|
2883
2879
|
readlineInterface = null;
|
|
2884
2880
|
}
|
|
2885
2881
|
}
|
|
2882
|
+
if (stderrInterface) {
|
|
2883
|
+
try {
|
|
2884
|
+
stderrInterface.close();
|
|
2885
|
+
} catch (error) {
|
|
2886
|
+
} finally {
|
|
2887
|
+
stderrInterface = null;
|
|
2888
|
+
}
|
|
2889
|
+
}
|
|
2886
2890
|
};
|
|
2887
2891
|
child.on("close", (code, signal) => {
|
|
2888
2892
|
cleanup();
|
|
2889
2893
|
if (stderr) {
|
|
2890
2894
|
logger.debug(`${cliCommand2} CLI stderr output`, { stderr: stderr.trim() });
|
|
2891
2895
|
}
|
|
2892
|
-
if (code === 0) {
|
|
2896
|
+
if ((code === 0 || code === null) && !signal) {
|
|
2893
2897
|
if (progressParser) {
|
|
2894
2898
|
progressParser.succeed(`${cliCommand2} completed successfully`);
|
|
2895
2899
|
}
|
|
2896
2900
|
resolve13({ stdout, stderr });
|
|
2901
|
+
} else if (signal) {
|
|
2902
|
+
if (progressParser) {
|
|
2903
|
+
progressParser.fail(`${cliCommand2} killed by signal ${signal}`);
|
|
2904
|
+
}
|
|
2905
|
+
reject(new Error(`${cliCommand2} CLI killed by signal ${signal}. stderr: ${stderr || "none"}`));
|
|
2897
2906
|
} else {
|
|
2898
2907
|
if (progressParser) {
|
|
2899
2908
|
progressParser.fail(`${cliCommand2} failed with code ${code}`);
|
|
2900
2909
|
}
|
|
2901
|
-
reject(new Error(`${cliCommand2} CLI exited with code ${code}
|
|
2910
|
+
reject(new Error(`${cliCommand2} CLI exited with code ${code}. stderr: ${stderr || "none"}`));
|
|
2902
2911
|
}
|
|
2903
2912
|
});
|
|
2904
2913
|
child.on("error", (error) => {
|
|
@@ -2934,8 +2943,18 @@ var init_base_provider = __esm({
|
|
|
2934
2943
|
/**
|
|
2935
2944
|
* Check if CLI is available - Template method pattern
|
|
2936
2945
|
* Uses getCLICommand() to determine which CLI to check
|
|
2946
|
+
*
|
|
2947
|
+
* v11.2.9 Fix: Always return true in mock mode (AX_MOCK_PROVIDERS=true)
|
|
2948
|
+
* This allows integration tests in CI to run without installing actual provider CLIs
|
|
2937
2949
|
*/
|
|
2938
2950
|
async checkCLIAvailable() {
|
|
2951
|
+
if (process.env.AX_MOCK_PROVIDERS === "true") {
|
|
2952
|
+
logger.debug(`${this.getCLICommand()} CLI availability check (mock mode)`, {
|
|
2953
|
+
available: true,
|
|
2954
|
+
mockMode: true
|
|
2955
|
+
});
|
|
2956
|
+
return true;
|
|
2957
|
+
}
|
|
2939
2958
|
try {
|
|
2940
2959
|
const cliCommand2 = this.getCLICommand();
|
|
2941
2960
|
const result = findOnPath(cliCommand2);
|
|
@@ -3854,8 +3873,6 @@ var init_cli_wrapper = __esm({
|
|
|
3854
3873
|
};
|
|
3855
3874
|
}
|
|
3856
3875
|
});
|
|
3857
|
-
|
|
3858
|
-
// src/integrations/openai-codex/sdk-adapter.ts
|
|
3859
3876
|
var CodexSdkAdapter;
|
|
3860
3877
|
var init_sdk_adapter = __esm({
|
|
3861
3878
|
"src/integrations/openai-codex/sdk-adapter.ts"() {
|
|
@@ -3868,6 +3885,8 @@ var init_sdk_adapter = __esm({
|
|
|
3868
3885
|
sdkModule = null;
|
|
3869
3886
|
options;
|
|
3870
3887
|
initialized = false;
|
|
3888
|
+
initMutex = new Mutex();
|
|
3889
|
+
// v11.2.8: Prevent race condition in ensureInitialized
|
|
3871
3890
|
constructor(options = {}) {
|
|
3872
3891
|
this.options = {
|
|
3873
3892
|
streamingEnabled: true,
|
|
@@ -3962,18 +3981,20 @@ var init_sdk_adapter = __esm({
|
|
|
3962
3981
|
return this.activeThread;
|
|
3963
3982
|
}
|
|
3964
3983
|
async ensureInitialized() {
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3984
|
+
return this.initMutex.runExclusive(async () => {
|
|
3985
|
+
if (this.initialized) return;
|
|
3986
|
+
try {
|
|
3987
|
+
this.sdkModule = await import('@openai/codex-sdk');
|
|
3988
|
+
this.codex = new this.sdkModule.Codex();
|
|
3989
|
+
this.initialized = true;
|
|
3990
|
+
logger.info("Codex SDK initialized");
|
|
3991
|
+
} catch (error) {
|
|
3992
|
+
throw new CodexError(
|
|
3993
|
+
"CLI_NOT_FOUND" /* CLI_NOT_FOUND */,
|
|
3994
|
+
"Codex SDK not available. Install with: npm install @openai/codex-sdk"
|
|
3995
|
+
);
|
|
3996
|
+
}
|
|
3997
|
+
});
|
|
3977
3998
|
}
|
|
3978
3999
|
async destroy() {
|
|
3979
4000
|
this.activeThread = null;
|
|
@@ -4379,6 +4400,9 @@ var init_command_builder = __esm({
|
|
|
4379
4400
|
* @returns Environment variable object
|
|
4380
4401
|
*/
|
|
4381
4402
|
buildEnv(options) {
|
|
4403
|
+
if (!options.apiKey && !options.baseUrl && !options.model) {
|
|
4404
|
+
return null;
|
|
4405
|
+
}
|
|
4382
4406
|
const env = {};
|
|
4383
4407
|
if (options.apiKey) {
|
|
4384
4408
|
env.YOUR_API_KEY = options.apiKey;
|
|
@@ -4426,6 +4450,27 @@ var init_response_parser = __esm({
|
|
|
4426
4450
|
AxCliResponseParser = class _AxCliResponseParser {
|
|
4427
4451
|
/** Maximum number of assistant messages to prevent memory exhaustion */
|
|
4428
4452
|
static MAX_ASSISTANT_MESSAGES = 1e3;
|
|
4453
|
+
/** Pre-compiled regex patterns for error detection (avoids recompilation per call) */
|
|
4454
|
+
static ERROR_WITH_COLON_REGEX = /Sorry, I encountered an error: (.+?)$/;
|
|
4455
|
+
static ERROR_WITHOUT_COLON_REGEX = /Sorry, I encountered an error(.*?)$/;
|
|
4456
|
+
/**
|
|
4457
|
+
* Extract error message from content if present
|
|
4458
|
+
* @returns Error message or null if no error
|
|
4459
|
+
*/
|
|
4460
|
+
extractErrorFromContent(content) {
|
|
4461
|
+
if (!content.includes("Sorry, I encountered an error")) {
|
|
4462
|
+
return null;
|
|
4463
|
+
}
|
|
4464
|
+
const matchWithColon = content.match(_AxCliResponseParser.ERROR_WITH_COLON_REGEX);
|
|
4465
|
+
if (matchWithColon?.[1]) {
|
|
4466
|
+
return matchWithColon[1];
|
|
4467
|
+
}
|
|
4468
|
+
const matchWithoutColon = content.match(_AxCliResponseParser.ERROR_WITHOUT_COLON_REGEX);
|
|
4469
|
+
if (matchWithoutColon) {
|
|
4470
|
+
return matchWithoutColon[1] ? matchWithoutColon[1].trim() : "API error";
|
|
4471
|
+
}
|
|
4472
|
+
return "API error";
|
|
4473
|
+
}
|
|
4429
4474
|
/**
|
|
4430
4475
|
* Parse JSONL output from ax-cli into ProviderResponse
|
|
4431
4476
|
*
|
|
@@ -4450,17 +4495,9 @@ var init_response_parser = __esm({
|
|
|
4450
4495
|
const parsed = JSON.parse(line);
|
|
4451
4496
|
const validated = AxCliMessageSchema.parse(parsed);
|
|
4452
4497
|
if (validated.role === "assistant") {
|
|
4453
|
-
|
|
4454
|
-
|
|
4455
|
-
|
|
4456
|
-
throw new Error(`ax-cli error: ${matchWithColon[1]}`);
|
|
4457
|
-
}
|
|
4458
|
-
const matchWithoutColon = validated.content.match(/Sorry, I encountered an error(.*?)$/);
|
|
4459
|
-
if (matchWithoutColon) {
|
|
4460
|
-
const errorMsg = matchWithoutColon[1] ? matchWithoutColon[1].trim() : "API error";
|
|
4461
|
-
throw new Error(`ax-cli error: ${errorMsg}`);
|
|
4462
|
-
}
|
|
4463
|
-
throw new Error("ax-cli error: API error");
|
|
4498
|
+
const errorMsg = this.extractErrorFromContent(validated.content);
|
|
4499
|
+
if (errorMsg) {
|
|
4500
|
+
throw new Error(`ax-cli error: ${errorMsg}`);
|
|
4464
4501
|
}
|
|
4465
4502
|
if (assistantMessages.length >= _AxCliResponseParser.MAX_ASSISTANT_MESSAGES) {
|
|
4466
4503
|
throw new Error(
|
|
@@ -4538,16 +4575,9 @@ var init_response_parser = __esm({
|
|
|
4538
4575
|
try {
|
|
4539
4576
|
const parsed = JSON.parse(line);
|
|
4540
4577
|
if (parsed.role === "assistant" && parsed.content) {
|
|
4541
|
-
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
return matchWithColon[1];
|
|
4545
|
-
}
|
|
4546
|
-
const matchWithoutColon = parsed.content.match(/Sorry, I encountered an error(.*?)$/);
|
|
4547
|
-
if (matchWithoutColon) {
|
|
4548
|
-
return matchWithoutColon[1] ? matchWithoutColon[1].trim() : "Sorry, I encountered an error";
|
|
4549
|
-
}
|
|
4550
|
-
return parsed.content;
|
|
4578
|
+
const errorMsg = this.extractErrorFromContent(parsed.content);
|
|
4579
|
+
if (errorMsg) {
|
|
4580
|
+
return errorMsg;
|
|
4551
4581
|
}
|
|
4552
4582
|
}
|
|
4553
4583
|
} catch {
|
|
@@ -4605,7 +4635,7 @@ var init_adapter = __esm({
|
|
|
4605
4635
|
// 10MB
|
|
4606
4636
|
env: {
|
|
4607
4637
|
...process.env,
|
|
4608
|
-
...this.commandBuilder.buildEnv(options)
|
|
4638
|
+
...this.commandBuilder.buildEnv(options) ?? {}
|
|
4609
4639
|
}
|
|
4610
4640
|
});
|
|
4611
4641
|
if (stderr && stderr.trim().length > 0) {
|
|
@@ -4824,11 +4854,12 @@ var init_token_estimator = __esm({
|
|
|
4824
4854
|
});
|
|
4825
4855
|
|
|
4826
4856
|
// src/integrations/ax-cli-sdk/subagent-adapter.ts
|
|
4827
|
-
var SubagentAdapter;
|
|
4857
|
+
var TOKEN_SPLIT, SubagentAdapter;
|
|
4828
4858
|
var init_subagent_adapter = __esm({
|
|
4829
4859
|
"src/integrations/ax-cli-sdk/subagent-adapter.ts"() {
|
|
4830
4860
|
init_esm_shims();
|
|
4831
4861
|
init_logger();
|
|
4862
|
+
TOKEN_SPLIT = { PROMPT: 0.3, COMPLETION: 0.7 };
|
|
4832
4863
|
SubagentAdapter = class {
|
|
4833
4864
|
orchestrator = null;
|
|
4834
4865
|
subagents = /* @__PURE__ */ new Map();
|
|
@@ -5033,9 +5064,8 @@ ${task.task}` : task.task;
|
|
|
5033
5064
|
success: true,
|
|
5034
5065
|
latencyMs,
|
|
5035
5066
|
tokensUsed: totalTokens > 0 ? {
|
|
5036
|
-
prompt: Math.floor(totalTokens *
|
|
5037
|
-
|
|
5038
|
-
completion: Math.floor(totalTokens * 0.7),
|
|
5067
|
+
prompt: Math.floor(totalTokens * TOKEN_SPLIT.PROMPT),
|
|
5068
|
+
completion: Math.floor(totalTokens * TOKEN_SPLIT.COMPLETION),
|
|
5039
5069
|
total: totalTokens
|
|
5040
5070
|
} : void 0
|
|
5041
5071
|
};
|
|
@@ -5198,7 +5228,10 @@ ${task.task}` : task.task;
|
|
|
5198
5228
|
for (const [key, subagent] of this.subagents) {
|
|
5199
5229
|
try {
|
|
5200
5230
|
if (subagent.dispose) {
|
|
5201
|
-
subagent.dispose();
|
|
5231
|
+
const result = subagent.dispose();
|
|
5232
|
+
if (result instanceof Promise) {
|
|
5233
|
+
await result;
|
|
5234
|
+
}
|
|
5202
5235
|
}
|
|
5203
5236
|
logger.debug("Subagent disposed", { key });
|
|
5204
5237
|
} catch (error) {
|
|
@@ -6354,7 +6387,7 @@ var init_adapter2 = __esm({
|
|
|
6354
6387
|
init_instructions_bridge();
|
|
6355
6388
|
init_mcp_manager();
|
|
6356
6389
|
init_mcp_manager();
|
|
6357
|
-
AxCliSdkAdapter = class {
|
|
6390
|
+
AxCliSdkAdapter = class _AxCliSdkAdapter {
|
|
6358
6391
|
agent = null;
|
|
6359
6392
|
// Will type as LLMAgent after import
|
|
6360
6393
|
agentConfig = null;
|
|
@@ -6565,7 +6598,7 @@ var init_adapter2 = __esm({
|
|
|
6565
6598
|
if (!await this.ensureSDKAvailable()) {
|
|
6566
6599
|
throw new Error("ax-cli SDK not available. Install with: npm install @defai.digital/ax-cli");
|
|
6567
6600
|
}
|
|
6568
|
-
if (!this.agent ||
|
|
6601
|
+
if (!this.agent || this.hasConfigChanged(options)) {
|
|
6569
6602
|
await this.initializeAgent(options);
|
|
6570
6603
|
}
|
|
6571
6604
|
logger.debug("Executing via SDK (streaming mode for token tracking)", {
|
|
@@ -6712,8 +6745,9 @@ var init_adapter2 = __esm({
|
|
|
6712
6745
|
* Check if agent config has changed (requires new agent)
|
|
6713
6746
|
*
|
|
6714
6747
|
* Since SDK manages credentials via settings, we only track maxToolRounds
|
|
6748
|
+
* v11.2.8: Removed unnecessary async (no async operations)
|
|
6715
6749
|
*/
|
|
6716
|
-
|
|
6750
|
+
hasConfigChanged(options) {
|
|
6717
6751
|
if (!this.agentConfig) return true;
|
|
6718
6752
|
const changed = this.agentConfig.maxToolRounds !== (options.maxToolRounds || 400);
|
|
6719
6753
|
if (changed) {
|
|
@@ -6797,6 +6831,49 @@ var init_adapter2 = __esm({
|
|
|
6797
6831
|
});
|
|
6798
6832
|
}
|
|
6799
6833
|
}
|
|
6834
|
+
/**
|
|
6835
|
+
* Extract token usage from various sources with priority:
|
|
6836
|
+
* 1. SDK events (token_count emissions) - most accurate
|
|
6837
|
+
* 2. Usage object (ChatEntry.usage or response.usage)
|
|
6838
|
+
* 3. Estimation fallback
|
|
6839
|
+
*/
|
|
6840
|
+
extractTokenUsage(prompt, content, totalTokensFromEvents, usageObject, sourceName) {
|
|
6841
|
+
if (totalTokensFromEvents > 0) {
|
|
6842
|
+
const estimated2 = TokenEstimator.estimateUsage(prompt, content);
|
|
6843
|
+
const tokens = {
|
|
6844
|
+
prompt: estimated2.prompt,
|
|
6845
|
+
completion: estimated2.completion,
|
|
6846
|
+
total: totalTokensFromEvents
|
|
6847
|
+
};
|
|
6848
|
+
logger.info(`Using token count from SDK events${sourceName ? ` (${sourceName})` : ""}`, {
|
|
6849
|
+
tokens: TokenEstimator.format(tokens),
|
|
6850
|
+
accuracy: "100% (total), 80-90% (split)",
|
|
6851
|
+
source: "token_count events"
|
|
6852
|
+
});
|
|
6853
|
+
return tokens;
|
|
6854
|
+
}
|
|
6855
|
+
const usage = usageObject || {};
|
|
6856
|
+
const actualTokens = {
|
|
6857
|
+
prompt: usage.prompt_tokens || usage.prompt || usage.input || usage.promptTokens || 0,
|
|
6858
|
+
completion: usage.completion_tokens || usage.completion || usage.output || usage.completionTokens || 0,
|
|
6859
|
+
total: usage.total_tokens || usage.total || usage.totalTokens || 0
|
|
6860
|
+
};
|
|
6861
|
+
if (actualTokens.total > 0) {
|
|
6862
|
+
logger.info(`Using token counts from ${sourceName || "usage object"}`, {
|
|
6863
|
+
tokens: TokenEstimator.format(actualTokens),
|
|
6864
|
+
accuracy: "100%",
|
|
6865
|
+
source: sourceName || "usage"
|
|
6866
|
+
});
|
|
6867
|
+
return actualTokens;
|
|
6868
|
+
}
|
|
6869
|
+
const estimated = TokenEstimator.estimateUsage(prompt, content);
|
|
6870
|
+
logger.warn(`SDK did not provide token counts${sourceName ? ` (${sourceName})` : ""}, using estimation`, {
|
|
6871
|
+
tokens: TokenEstimator.format(estimated, true),
|
|
6872
|
+
accuracy: "80-90% (estimated)",
|
|
6873
|
+
source: "estimation"
|
|
6874
|
+
});
|
|
6875
|
+
return estimated;
|
|
6876
|
+
}
|
|
6800
6877
|
/**
|
|
6801
6878
|
* Convert SDK response to ExecutionResponse format
|
|
6802
6879
|
*
|
|
@@ -6827,116 +6904,47 @@ var init_adapter2 = __esm({
|
|
|
6827
6904
|
}
|
|
6828
6905
|
const lastAssistant = assistantMessages[assistantMessages.length - 1];
|
|
6829
6906
|
const content2 = lastAssistant.content || "";
|
|
6830
|
-
|
|
6831
|
-
|
|
6832
|
-
|
|
6833
|
-
|
|
6834
|
-
|
|
6835
|
-
|
|
6836
|
-
|
|
6837
|
-
// Estimated split
|
|
6838
|
-
total: totalTokensFromEvents
|
|
6839
|
-
// Actual total from events
|
|
6840
|
-
};
|
|
6841
|
-
logger.info("Using token count from SDK events", {
|
|
6842
|
-
tokens: TokenEstimator.format(finalTokens2),
|
|
6843
|
-
accuracy: "100% (total), 80-90% (split)",
|
|
6844
|
-
source: "token_count events"
|
|
6845
|
-
});
|
|
6846
|
-
} else {
|
|
6847
|
-
const usage = lastAssistant.usage || lastAssistant.tokens || {};
|
|
6848
|
-
const actualTokens = {
|
|
6849
|
-
prompt: usage.prompt_tokens || usage.prompt || usage.input || usage.promptTokens || 0,
|
|
6850
|
-
completion: usage.completion_tokens || usage.completion || usage.output || usage.completionTokens || 0,
|
|
6851
|
-
total: usage.total_tokens || usage.total || usage.totalTokens || 0
|
|
6852
|
-
};
|
|
6853
|
-
const hasActualTokens = actualTokens.total > 0;
|
|
6854
|
-
if (hasActualTokens) {
|
|
6855
|
-
finalTokens2 = {
|
|
6856
|
-
prompt: actualTokens.prompt,
|
|
6857
|
-
completion: actualTokens.completion,
|
|
6858
|
-
total: actualTokens.total
|
|
6859
|
-
};
|
|
6860
|
-
logger.info("Using token counts from ChatEntry.usage", {
|
|
6861
|
-
tokens: TokenEstimator.format(finalTokens2),
|
|
6862
|
-
accuracy: "100%",
|
|
6863
|
-
source: "ChatEntry.usage"
|
|
6864
|
-
});
|
|
6865
|
-
} else {
|
|
6866
|
-
finalTokens2 = TokenEstimator.estimateUsage(prompt, content2);
|
|
6867
|
-
logger.warn("SDK did not provide token counts, using estimation", {
|
|
6868
|
-
tokens: TokenEstimator.format(finalTokens2, true),
|
|
6869
|
-
accuracy: "80-90% (estimated)",
|
|
6870
|
-
source: "estimation"
|
|
6871
|
-
});
|
|
6872
|
-
}
|
|
6873
|
-
}
|
|
6874
|
-
const model2 = this.agent.getCurrentModel();
|
|
6875
|
-
const finishReason2 = "stop";
|
|
6907
|
+
const tokensUsed2 = this.extractTokenUsage(
|
|
6908
|
+
prompt,
|
|
6909
|
+
content2,
|
|
6910
|
+
totalTokensFromEvents,
|
|
6911
|
+
lastAssistant.usage || lastAssistant.tokens,
|
|
6912
|
+
"ChatEntry.usage"
|
|
6913
|
+
);
|
|
6876
6914
|
return {
|
|
6877
6915
|
content: content2,
|
|
6878
|
-
model:
|
|
6879
|
-
tokensUsed:
|
|
6916
|
+
model: this.agent?.getCurrentModel() ?? "unknown",
|
|
6917
|
+
tokensUsed: tokensUsed2,
|
|
6880
6918
|
latencyMs,
|
|
6881
|
-
finishReason:
|
|
6919
|
+
finishReason: "stop",
|
|
6882
6920
|
cached: false
|
|
6883
|
-
// SDK doesn't expose cache status via ChatEntry
|
|
6884
6921
|
};
|
|
6885
6922
|
}
|
|
6886
6923
|
const content = typeof result === "string" ? result : result.content || result.text || "";
|
|
6887
|
-
|
|
6888
|
-
|
|
6889
|
-
|
|
6890
|
-
|
|
6891
|
-
|
|
6892
|
-
|
|
6893
|
-
|
|
6894
|
-
};
|
|
6895
|
-
logger.info("Using token count from SDK events (fallback path)", {
|
|
6896
|
-
tokens: TokenEstimator.format(finalTokens),
|
|
6897
|
-
accuracy: "100% (total), 80-90% (split)",
|
|
6898
|
-
source: "token_count events"
|
|
6899
|
-
});
|
|
6900
|
-
} else {
|
|
6901
|
-
const usage = result.usage || result.tokens || {};
|
|
6902
|
-
const actualTokens = {
|
|
6903
|
-
prompt: usage.prompt_tokens || usage.prompt || usage.input || usage.promptTokens || 0,
|
|
6904
|
-
completion: usage.completion_tokens || usage.completion || usage.output || usage.completionTokens || 0,
|
|
6905
|
-
total: usage.total_tokens || usage.total || usage.totalTokens || 0
|
|
6906
|
-
};
|
|
6907
|
-
const hasActualTokens = actualTokens.total > 0;
|
|
6908
|
-
if (hasActualTokens) {
|
|
6909
|
-
finalTokens = {
|
|
6910
|
-
prompt: actualTokens.prompt,
|
|
6911
|
-
completion: actualTokens.completion,
|
|
6912
|
-
total: actualTokens.total
|
|
6913
|
-
};
|
|
6914
|
-
logger.info("Using token counts from response.usage (fallback path)", {
|
|
6915
|
-
tokens: TokenEstimator.format(finalTokens),
|
|
6916
|
-
accuracy: "100%",
|
|
6917
|
-
source: "response.usage"
|
|
6918
|
-
});
|
|
6919
|
-
} else {
|
|
6920
|
-
finalTokens = TokenEstimator.estimateUsage(prompt, content);
|
|
6921
|
-
logger.warn("SDK did not provide token counts (fallback path), using estimation", {
|
|
6922
|
-
tokens: TokenEstimator.format(finalTokens, true),
|
|
6923
|
-
accuracy: "80-90% (estimated)",
|
|
6924
|
-
source: "estimation"
|
|
6925
|
-
});
|
|
6926
|
-
}
|
|
6927
|
-
}
|
|
6928
|
-
const model = this.agent.getCurrentModel();
|
|
6929
|
-
const finishReason = "stop";
|
|
6924
|
+
const tokensUsed = this.extractTokenUsage(
|
|
6925
|
+
prompt,
|
|
6926
|
+
content,
|
|
6927
|
+
totalTokensFromEvents,
|
|
6928
|
+
result.usage || result.tokens,
|
|
6929
|
+
"response.usage (fallback path)"
|
|
6930
|
+
);
|
|
6930
6931
|
return {
|
|
6931
6932
|
content,
|
|
6932
|
-
model,
|
|
6933
|
-
tokensUsed
|
|
6933
|
+
model: this.agent?.getCurrentModel() ?? "unknown",
|
|
6934
|
+
tokensUsed,
|
|
6934
6935
|
latencyMs,
|
|
6935
|
-
finishReason,
|
|
6936
|
+
finishReason: "stop",
|
|
6936
6937
|
cached: false
|
|
6937
|
-
// SDK doesn't expose cache status
|
|
6938
6938
|
};
|
|
6939
6939
|
}
|
|
6940
|
+
/** Error mapping patterns: [patterns, prefix, code] */
|
|
6941
|
+
static ERROR_MAPPINGS = [
|
|
6942
|
+
[["rate limit", "rate_limit"], "Rate limit exceeded", "RATE_LIMIT_EXCEEDED"],
|
|
6943
|
+
[["context length", "max_tokens"], "Context length exceeded", "CONTEXT_LENGTH_EXCEEDED"],
|
|
6944
|
+
[["timeout", "timed out"], "Request timeout", "TIMEOUT"],
|
|
6945
|
+
[["invalid api key", "authentication"], "Authentication failed", "AUTHENTICATION_FAILED"],
|
|
6946
|
+
[["network", "econnrefused"], "Network error", "NETWORK_ERROR"]
|
|
6947
|
+
];
|
|
6940
6948
|
/**
|
|
6941
6949
|
* Map SDK errors to AutomatosX error types
|
|
6942
6950
|
*/
|
|
@@ -6945,30 +6953,12 @@ var init_adapter2 = __esm({
|
|
|
6945
6953
|
return new Error(`SDK error: ${String(error)}`);
|
|
6946
6954
|
}
|
|
6947
6955
|
const message = error.message.toLowerCase();
|
|
6948
|
-
|
|
6949
|
-
|
|
6950
|
-
|
|
6951
|
-
|
|
6952
|
-
|
|
6953
|
-
|
|
6954
|
-
const mappedError = new Error(`Context length exceeded: ${error.message}`);
|
|
6955
|
-
mappedError.code = "CONTEXT_LENGTH_EXCEEDED";
|
|
6956
|
-
return mappedError;
|
|
6957
|
-
}
|
|
6958
|
-
if (message.includes("timeout") || message.includes("timed out")) {
|
|
6959
|
-
const mappedError = new Error(`Request timeout: ${error.message}`);
|
|
6960
|
-
mappedError.code = "TIMEOUT";
|
|
6961
|
-
return mappedError;
|
|
6962
|
-
}
|
|
6963
|
-
if (message.includes("invalid api key") || message.includes("authentication")) {
|
|
6964
|
-
const mappedError = new Error(`Authentication failed: ${error.message}`);
|
|
6965
|
-
mappedError.code = "AUTHENTICATION_FAILED";
|
|
6966
|
-
return mappedError;
|
|
6967
|
-
}
|
|
6968
|
-
if (message.includes("network") || message.includes("econnrefused")) {
|
|
6969
|
-
const mappedError = new Error(`Network error: ${error.message}`);
|
|
6970
|
-
mappedError.code = "NETWORK_ERROR";
|
|
6971
|
-
return mappedError;
|
|
6956
|
+
for (const [patterns, prefix, code] of _AxCliSdkAdapter.ERROR_MAPPINGS) {
|
|
6957
|
+
if (patterns.some((pattern) => message.includes(pattern))) {
|
|
6958
|
+
const mappedError = new Error(`${prefix}: ${error.message}`);
|
|
6959
|
+
mappedError.code = code;
|
|
6960
|
+
return mappedError;
|
|
6961
|
+
}
|
|
6972
6962
|
}
|
|
6973
6963
|
return error;
|
|
6974
6964
|
}
|
|
@@ -7003,15 +6993,10 @@ var init_adapter2 = __esm({
|
|
|
7003
6993
|
* Get SDK version
|
|
7004
6994
|
*/
|
|
7005
6995
|
async getVersion() {
|
|
7006
|
-
|
|
7007
|
-
await import('@defai.digital/ax-cli/sdk');
|
|
6996
|
+
if (await this.ensureSDKAvailable()) {
|
|
7008
6997
|
return "3.14.5+";
|
|
7009
|
-
} catch (error) {
|
|
7010
|
-
logger.warn("Failed to get SDK version", {
|
|
7011
|
-
error: error instanceof Error ? error.message : String(error)
|
|
7012
|
-
});
|
|
7013
|
-
return "unknown";
|
|
7014
6998
|
}
|
|
6999
|
+
return "unknown";
|
|
7015
7000
|
}
|
|
7016
7001
|
/**
|
|
7017
7002
|
* Get command name (for compatibility with AxCliAdapter interface)
|
|
@@ -7031,7 +7016,10 @@ var init_adapter2 = __esm({
|
|
|
7031
7016
|
async destroy() {
|
|
7032
7017
|
if (this.agent) {
|
|
7033
7018
|
try {
|
|
7034
|
-
this.agent.dispose();
|
|
7019
|
+
const result = this.agent.dispose();
|
|
7020
|
+
if (result instanceof Promise) {
|
|
7021
|
+
await result;
|
|
7022
|
+
}
|
|
7035
7023
|
this.agent = null;
|
|
7036
7024
|
this.agentConfig = null;
|
|
7037
7025
|
logger.debug("SDK agent destroyed");
|
|
@@ -9285,7 +9273,7 @@ var PRECOMPILED_CONFIG = {
|
|
|
9285
9273
|
"enableFreeTierPrioritization": true,
|
|
9286
9274
|
"enableWorkloadAwareRouting": true
|
|
9287
9275
|
},
|
|
9288
|
-
"version": "11.
|
|
9276
|
+
"version": "11.3.0"
|
|
9289
9277
|
};
|
|
9290
9278
|
|
|
9291
9279
|
// src/core/config/schemas.ts
|
|
@@ -15174,7 +15162,7 @@ function parseAXMD(content) {
|
|
|
15174
15162
|
"Useful Links"
|
|
15175
15163
|
];
|
|
15176
15164
|
for (const section of sections) {
|
|
15177
|
-
const sectionName = section.split("\n")[0];
|
|
15165
|
+
const sectionName = section.split("\n")[0] ?? "";
|
|
15178
15166
|
if (sectionName && !standardSections.includes(sectionName)) {
|
|
15179
15167
|
result.customSections.push(sectionName);
|
|
15180
15168
|
}
|
|
@@ -16567,6 +16555,8 @@ var ProviderLimitManager = class _ProviderLimitManager extends EventEmitter {
|
|
|
16567
16555
|
getManualOverride() {
|
|
16568
16556
|
if (this.manualOverride && this.manualOverride.expiresAtMs) {
|
|
16569
16557
|
if (Date.now() >= this.manualOverride.expiresAtMs) {
|
|
16558
|
+
this.manualOverride;
|
|
16559
|
+
this.manualOverride = void 0;
|
|
16570
16560
|
void this.clearManualOverride();
|
|
16571
16561
|
return void 0;
|
|
16572
16562
|
}
|
|
@@ -16907,19 +16897,33 @@ var ProviderMetricsTracker = class extends EventEmitter {
|
|
|
16907
16897
|
const p50 = getPercentile(latencies, 50);
|
|
16908
16898
|
const p95 = getPercentile(latencies, 95);
|
|
16909
16899
|
const p99 = getPercentile(latencies, 99);
|
|
16910
|
-
|
|
16911
|
-
|
|
16912
|
-
|
|
16913
|
-
|
|
16914
|
-
|
|
16915
|
-
|
|
16916
|
-
|
|
16900
|
+
let successCount = 0;
|
|
16901
|
+
let failCount = 0;
|
|
16902
|
+
let stopFinishCount = 0;
|
|
16903
|
+
let lengthFinishCount = 0;
|
|
16904
|
+
let errorFinishCount = 0;
|
|
16905
|
+
let lastSuccessTimestamp = 0;
|
|
16906
|
+
let lastFailureTimestamp = 0;
|
|
16907
|
+
for (const r of records) {
|
|
16908
|
+
if (r.success) {
|
|
16909
|
+
successCount++;
|
|
16910
|
+
lastSuccessTimestamp = r.timestamp;
|
|
16911
|
+
if (r.finishReason === "stop") stopFinishCount++;
|
|
16912
|
+
else if (r.finishReason === "length") lengthFinishCount++;
|
|
16913
|
+
} else {
|
|
16914
|
+
failCount++;
|
|
16915
|
+
lastFailureTimestamp = r.timestamp;
|
|
16916
|
+
}
|
|
16917
|
+
if (r.finishReason === "error") errorFinishCount++;
|
|
16918
|
+
}
|
|
16919
|
+
const successRate = successCount / records.length;
|
|
16920
|
+
const properStopRate = successCount > 0 ? stopFinishCount / successCount : 0;
|
|
16917
16921
|
const totalCost = records.reduce((sum, r) => sum + r.costUsd, 0);
|
|
16918
16922
|
const avgCostPerRequest = totalCost / records.length;
|
|
16919
16923
|
const totalTokens = records.reduce((sum, r) => sum + r.totalTokens, 0);
|
|
16920
16924
|
const avgCostPer1M = totalTokens > 0 ? totalCost / totalTokens * 1e6 : 0;
|
|
16921
|
-
const lastSuccess =
|
|
16922
|
-
const lastFailure =
|
|
16925
|
+
const lastSuccess = lastSuccessTimestamp;
|
|
16926
|
+
const lastFailure = lastFailureTimestamp;
|
|
16923
16927
|
let consecutiveFailures = 0;
|
|
16924
16928
|
for (let i = records.length - 1; i >= 0; i--) {
|
|
16925
16929
|
if (!records[i].success) {
|
|
@@ -16942,12 +16946,12 @@ var ProviderMetricsTracker = class extends EventEmitter {
|
|
|
16942
16946
|
},
|
|
16943
16947
|
quality: {
|
|
16944
16948
|
totalRequests: records.length,
|
|
16945
|
-
successfulRequests:
|
|
16946
|
-
failedRequests:
|
|
16949
|
+
successfulRequests: successCount,
|
|
16950
|
+
failedRequests: failCount,
|
|
16947
16951
|
successRate,
|
|
16948
|
-
stopFinishes:
|
|
16949
|
-
lengthFinishes:
|
|
16950
|
-
errorFinishes:
|
|
16952
|
+
stopFinishes: stopFinishCount,
|
|
16953
|
+
lengthFinishes: lengthFinishCount,
|
|
16954
|
+
errorFinishes: errorFinishCount,
|
|
16951
16955
|
properStopRate
|
|
16952
16956
|
},
|
|
16953
16957
|
cost: {
|
|
@@ -17056,7 +17060,7 @@ var ProviderMetricsTracker = class extends EventEmitter {
|
|
|
17056
17060
|
* v9.0.2: Added score caching to reduce redundant calculations
|
|
17057
17061
|
*/
|
|
17058
17062
|
async calculateScore(provider, weights, allProviders, healthMultiplier = 1) {
|
|
17059
|
-
const cacheKey = `${provider}-${
|
|
17063
|
+
const cacheKey = `${provider}-${weights.cost}-${weights.latency}-${weights.quality}-${weights.availability}-${healthMultiplier}`;
|
|
17060
17064
|
const cached = this.scoreCache.get(cacheKey);
|
|
17061
17065
|
const currentRequestCount = this.getRequestCount(provider);
|
|
17062
17066
|
if (cached) {
|
|
@@ -18221,8 +18225,7 @@ var Router = class {
|
|
|
18221
18225
|
}
|
|
18222
18226
|
}
|
|
18223
18227
|
if (limitedProviders2.length === allProviders2.length && limitedProviders2.length > 0) {
|
|
18224
|
-
|
|
18225
|
-
throw ProviderError.allProvidersLimited(limitedProviders2, soonestReset);
|
|
18228
|
+
throw ProviderError.allProvidersLimited(limitedProviders2, this.getSoonestLimitReset(limitedProviders2));
|
|
18226
18229
|
}
|
|
18227
18230
|
throw ProviderError.noAvailableProviders();
|
|
18228
18231
|
}
|
|
@@ -18628,8 +18631,7 @@ var Router = class {
|
|
|
18628
18631
|
}
|
|
18629
18632
|
}
|
|
18630
18633
|
if (limitedProviders.length === allProviders.length && limitedProviders.length > 0) {
|
|
18631
|
-
|
|
18632
|
-
throw ProviderError.allProvidersLimited(limitedProviders, soonestReset);
|
|
18634
|
+
throw ProviderError.allProvidersLimited(limitedProviders, this.getSoonestLimitReset(limitedProviders));
|
|
18633
18635
|
}
|
|
18634
18636
|
const errorDetails = {
|
|
18635
18637
|
lastError: lastError?.message,
|
|
@@ -18863,6 +18865,16 @@ Run 'ax doctor' to diagnose provider setup.` : "";
|
|
|
18863
18865
|
})
|
|
18864
18866
|
};
|
|
18865
18867
|
}
|
|
18868
|
+
/**
|
|
18869
|
+
* Calculate the soonest reset time from limited providers
|
|
18870
|
+
* v11.2.8: Added guard against empty array (Math.min on empty array returns Infinity)
|
|
18871
|
+
*/
|
|
18872
|
+
getSoonestLimitReset(limitedProviders) {
|
|
18873
|
+
if (limitedProviders.length === 0) {
|
|
18874
|
+
return Date.now() + 6e4;
|
|
18875
|
+
}
|
|
18876
|
+
return Math.min(...limitedProviders.map((p) => p.resetAtMs));
|
|
18877
|
+
}
|
|
18866
18878
|
};
|
|
18867
18879
|
|
|
18868
18880
|
// src/core/memory/lazy-manager.ts
|
|
@@ -20698,8 +20710,6 @@ z.object({
|
|
|
20698
20710
|
limit: z.number().int().positive().max(1e4).optional(),
|
|
20699
20711
|
offset: z.number().int().nonnegative().optional()
|
|
20700
20712
|
}).strict();
|
|
20701
|
-
|
|
20702
|
-
// src/core/session/manager.ts
|
|
20703
20713
|
var SessionManager = class _SessionManager {
|
|
20704
20714
|
/** Active sessions (in-memory, keyed by session ID) */
|
|
20705
20715
|
activeSessions = /* @__PURE__ */ new Map();
|
|
@@ -20772,8 +20782,9 @@ var SessionManager = class _SessionManager {
|
|
|
20772
20782
|
try {
|
|
20773
20783
|
SessionManagerConfigSchema.parse(config);
|
|
20774
20784
|
} catch (error) {
|
|
20785
|
+
const message = error instanceof ZodError ? error.message : String(error);
|
|
20775
20786
|
throw new SessionError(
|
|
20776
|
-
`Invalid session manager config: ${
|
|
20787
|
+
`Invalid session manager config: ${message}`,
|
|
20777
20788
|
void 0,
|
|
20778
20789
|
"invalid_configuration"
|
|
20779
20790
|
);
|
|
@@ -22175,8 +22186,8 @@ var ProjectContextLoader = class {
|
|
|
22175
22186
|
const projectMatch = markdown.match(/>\s*Project:\s*(.+?)$/im);
|
|
22176
22187
|
if (projectMatch && projectMatch[1]) {
|
|
22177
22188
|
const parts = projectMatch[1].trim().split(/\s+v/);
|
|
22178
|
-
metadata.name = parts[0];
|
|
22179
|
-
if (parts[1]) {
|
|
22189
|
+
metadata.name = parts[0] || "";
|
|
22190
|
+
if (parts.length > 1 && parts[1]) {
|
|
22180
22191
|
metadata.version = parts[1];
|
|
22181
22192
|
}
|
|
22182
22193
|
}
|
|
@@ -29880,13 +29891,23 @@ var MetricsCollector = class {
|
|
|
29880
29891
|
*/
|
|
29881
29892
|
getMetricsSummary(serverMetrics) {
|
|
29882
29893
|
const totalServers = serverMetrics.length;
|
|
29883
|
-
|
|
29884
|
-
|
|
29885
|
-
|
|
29886
|
-
|
|
29887
|
-
|
|
29888
|
-
|
|
29889
|
-
|
|
29894
|
+
let healthyServers = 0;
|
|
29895
|
+
let totalCpu = 0;
|
|
29896
|
+
let totalMemory = 0;
|
|
29897
|
+
let totalRequests = 0;
|
|
29898
|
+
let totalFailed = 0;
|
|
29899
|
+
let totalRestarts = 0;
|
|
29900
|
+
let totalResponseTime = 0;
|
|
29901
|
+
for (const m of serverMetrics) {
|
|
29902
|
+
if (m.memoryUsageMB > 0) healthyServers++;
|
|
29903
|
+
totalCpu += m.cpuUsagePercent;
|
|
29904
|
+
totalMemory += m.memoryUsageMB;
|
|
29905
|
+
totalRequests += m.totalRequests;
|
|
29906
|
+
totalFailed += m.failedRequests;
|
|
29907
|
+
totalRestarts += m.restartCount;
|
|
29908
|
+
totalResponseTime += m.avgResponseTimeMs;
|
|
29909
|
+
}
|
|
29910
|
+
const avgResponseTime = totalServers > 0 ? totalResponseTime / totalServers : 0;
|
|
29890
29911
|
const errorRate = totalRequests > 0 ? totalFailed / totalRequests * 100 : 0;
|
|
29891
29912
|
return {
|
|
29892
29913
|
totalServers,
|
|
@@ -31758,7 +31779,7 @@ var addCommand = {
|
|
|
31758
31779
|
throw new Error(`Invalid metadata JSON: ${error.message}`);
|
|
31759
31780
|
}
|
|
31760
31781
|
}
|
|
31761
|
-
const embedding =
|
|
31782
|
+
const embedding = Array(1536).fill(0);
|
|
31762
31783
|
const entry = await manager.add(argv.content, embedding, metadata);
|
|
31763
31784
|
printSuccess("\nMemory entry added successfully\n");
|
|
31764
31785
|
console.log(`${chalk5.bold("ID:")} ${chalk5.white(entry.id)}`);
|
|
@@ -34106,47 +34127,39 @@ ${action.modifications}`;
|
|
|
34106
34127
|
* @param stage - Stage to execute
|
|
34107
34128
|
* @param context - Stage context
|
|
34108
34129
|
* @returns Stage task prompt
|
|
34130
|
+
* v11.2.8: Refactored to use array.join() for better string building performance
|
|
34109
34131
|
*/
|
|
34110
34132
|
buildStageTask(stage, context) {
|
|
34111
|
-
|
|
34112
|
-
|
|
34113
|
-
|
|
34114
|
-
|
|
34133
|
+
const parts = [
|
|
34134
|
+
`# Stage: ${stage.name}
|
|
34135
|
+
`,
|
|
34136
|
+
`## Stage Description
|
|
34115
34137
|
${stage.description}
|
|
34116
|
-
|
|
34117
|
-
|
|
34118
|
-
prompt += `## Original Task
|
|
34138
|
+
`,
|
|
34139
|
+
`## Original Task
|
|
34119
34140
|
${context.task}
|
|
34120
|
-
|
|
34121
|
-
|
|
34141
|
+
`
|
|
34142
|
+
];
|
|
34122
34143
|
if (context.previousOutputs.length > 0) {
|
|
34123
|
-
|
|
34124
|
-
|
|
34125
|
-
|
|
34126
|
-
|
|
34127
|
-
prompt += `### Stage ${index + 1} Output
|
|
34144
|
+
parts.push(`## Previous Stage Outputs
|
|
34145
|
+
`);
|
|
34146
|
+
parts.push(...context.previousOutputs.map(
|
|
34147
|
+
(output, index) => `### Stage ${index + 1} Output
|
|
34128
34148
|
${output}
|
|
34129
|
-
|
|
34130
|
-
|
|
34131
|
-
});
|
|
34149
|
+
`
|
|
34150
|
+
));
|
|
34132
34151
|
}
|
|
34133
34152
|
if (stage.key_questions && stage.key_questions.length > 0) {
|
|
34134
|
-
|
|
34135
|
-
|
|
34136
|
-
|
|
34137
|
-
`);
|
|
34138
|
-
prompt += `
|
|
34139
|
-
`;
|
|
34153
|
+
parts.push(`## Key Questions to Address`);
|
|
34154
|
+
parts.push(...stage.key_questions.map((q) => `- ${q}`));
|
|
34155
|
+
parts.push("");
|
|
34140
34156
|
}
|
|
34141
34157
|
if (stage.outputs && stage.outputs.length > 0) {
|
|
34142
|
-
|
|
34143
|
-
|
|
34144
|
-
|
|
34145
|
-
`);
|
|
34146
|
-
prompt += `
|
|
34147
|
-
`;
|
|
34158
|
+
parts.push(`## Expected Outputs`);
|
|
34159
|
+
parts.push(...stage.outputs.map((o) => `- ${o}`));
|
|
34160
|
+
parts.push("");
|
|
34148
34161
|
}
|
|
34149
|
-
return
|
|
34162
|
+
return parts.join("\n");
|
|
34150
34163
|
}
|
|
34151
34164
|
/**
|
|
34152
34165
|
* Enhance stages with index and defaults
|
|
@@ -36222,10 +36235,10 @@ var runCommand = {
|
|
|
36222
36235
|
}).positional("task", {
|
|
36223
36236
|
describe: "Task to execute",
|
|
36224
36237
|
type: "string"
|
|
36225
|
-
}).option("
|
|
36226
|
-
describe: "
|
|
36238
|
+
}).option("auto-select", {
|
|
36239
|
+
describe: "Enable agent auto-selection when agent not found (v11.1.0+)",
|
|
36227
36240
|
type: "boolean",
|
|
36228
|
-
default:
|
|
36241
|
+
default: true
|
|
36229
36242
|
}).option("provider", {
|
|
36230
36243
|
describe: "Override provider (claude, gemini, openai)",
|
|
36231
36244
|
type: "string"
|
|
@@ -36367,7 +36380,7 @@ var runCommand = {
|
|
|
36367
36380
|
console.log(chalk5.gray(' ax run backend "implement API" # uses specified agent'));
|
|
36368
36381
|
process.exit(1);
|
|
36369
36382
|
}
|
|
36370
|
-
if (!agentProvided && argv.
|
|
36383
|
+
if (!agentProvided && argv.autoSelect === false) {
|
|
36371
36384
|
console.log(chalk5.red.bold("\n\u274C Error: Agent name is required when --no-auto-select is used\n"));
|
|
36372
36385
|
console.log(chalk5.gray("Usage: ax run <agent> <task> --no-auto-select"));
|
|
36373
36386
|
process.exit(1);
|
|
@@ -36502,7 +36515,7 @@ var runCommand = {
|
|
|
36502
36515
|
}
|
|
36503
36516
|
}
|
|
36504
36517
|
} catch (error) {
|
|
36505
|
-
if (argv.
|
|
36518
|
+
if (argv.autoSelect === false) {
|
|
36506
36519
|
console.error(chalk5.red.bold(`
|
|
36507
36520
|
\u274C Agent not found: ${actualAgent}
|
|
36508
36521
|
`));
|
|
@@ -44704,10 +44717,11 @@ function displayPlanSummary(plan) {
|
|
|
44704
44717
|
console.log(chalk5.gray(` Storage: ${plan.resourceRequirements.storage}`));
|
|
44705
44718
|
console.log(chalk5.gray(` Network: ${plan.resourceRequirements.network}
|
|
44706
44719
|
`));
|
|
44720
|
+
const SEVERITY_ICONS = { high: "\u{1F534}", medium: "\u{1F7E1}", low: "\u{1F7E2}" };
|
|
44707
44721
|
if (plan.risks.length > 0) {
|
|
44708
44722
|
console.log(chalk5.blue("Identified Risks:"));
|
|
44709
44723
|
for (const risk of plan.risks) {
|
|
44710
|
-
const icon = risk.severity
|
|
44724
|
+
const icon = SEVERITY_ICONS[risk.severity] ?? "\u{1F7E2}";
|
|
44711
44725
|
console.log(` ${icon} ${risk.severity.toUpperCase()}: ${risk.title}`);
|
|
44712
44726
|
console.log(chalk5.gray(` ${risk.description}`));
|
|
44713
44727
|
console.log(chalk5.gray(` Mitigation: ${risk.mitigation}
|
|
@@ -44863,24 +44877,24 @@ async function handleList(config, argv) {
|
|
|
44863
44877
|
});
|
|
44864
44878
|
}
|
|
44865
44879
|
}
|
|
44866
|
-
let
|
|
44880
|
+
let displayProviders2 = argv.available ? providers.filter((p) => p.enabled && !p.limitInfo?.isBlocked) : providers;
|
|
44867
44881
|
switch (argv.sort) {
|
|
44868
44882
|
case "cost":
|
|
44869
|
-
|
|
44883
|
+
displayProviders2.sort((a, b) => {
|
|
44870
44884
|
const costA = a.metadata ? (a.metadata.costPerToken.input + a.metadata.costPerToken.output) / 2 : Infinity;
|
|
44871
44885
|
const costB = b.metadata ? (b.metadata.costPerToken.input + b.metadata.costPerToken.output) / 2 : Infinity;
|
|
44872
44886
|
return costA - costB;
|
|
44873
44887
|
});
|
|
44874
44888
|
break;
|
|
44875
44889
|
case "latency":
|
|
44876
|
-
|
|
44890
|
+
displayProviders2.sort((a, b) => {
|
|
44877
44891
|
const latA = a.metadata?.latencyEstimate.p95 || Infinity;
|
|
44878
44892
|
const latB = b.metadata?.latencyEstimate.p95 || Infinity;
|
|
44879
44893
|
return latA - latB;
|
|
44880
44894
|
});
|
|
44881
44895
|
break;
|
|
44882
44896
|
case "reliability":
|
|
44883
|
-
|
|
44897
|
+
displayProviders2.sort((a, b) => {
|
|
44884
44898
|
const relA = a.metadata?.reliability.availability || 0;
|
|
44885
44899
|
const relB = b.metadata?.reliability.availability || 0;
|
|
44886
44900
|
return relB - relA;
|
|
@@ -44888,15 +44902,15 @@ async function handleList(config, argv) {
|
|
|
44888
44902
|
break;
|
|
44889
44903
|
case "priority":
|
|
44890
44904
|
default:
|
|
44891
|
-
|
|
44905
|
+
displayProviders2.sort((a, b) => a.priority - b.priority);
|
|
44892
44906
|
break;
|
|
44893
44907
|
}
|
|
44894
44908
|
if (argv.json) {
|
|
44895
|
-
console.log(JSON.stringify({ providers:
|
|
44909
|
+
console.log(JSON.stringify({ providers: displayProviders2 }, null, 2));
|
|
44896
44910
|
return;
|
|
44897
44911
|
}
|
|
44898
44912
|
console.log(chalk5.gray("Provider Status & Metadata:\n"));
|
|
44899
|
-
for (const provider of
|
|
44913
|
+
for (const provider of displayProviders2) {
|
|
44900
44914
|
const status = provider.enabled ? provider.limitInfo?.isBlocked ? chalk5.red("\u25CF BLOCKED") : chalk5.green("\u25CF ENABLED") : chalk5.gray("\u25CB DISABLED");
|
|
44901
44915
|
console.log(`${status} ${chalk5.bold(provider.name)} ${chalk5.gray(`(priority: ${provider.priority})`)}`);
|
|
44902
44916
|
if (provider.metadata && argv.verbose) {
|
|
@@ -46143,9 +46157,11 @@ async function checkDiskSpace(workingDir, verbose) {
|
|
|
46143
46157
|
timeout: 5e3
|
|
46144
46158
|
});
|
|
46145
46159
|
const parts = dfOutput.trim().split(/\s+/);
|
|
46146
|
-
const
|
|
46147
|
-
const
|
|
46148
|
-
const
|
|
46160
|
+
const rawAvailable = parts.length > 3 ? parts[3] : "0";
|
|
46161
|
+
const availableKB = parseInt(rawAvailable || "0", 10);
|
|
46162
|
+
const safeAvailableKB = isNaN(availableKB) ? 0 : availableKB;
|
|
46163
|
+
const availableMB = Math.round(safeAvailableKB / 1024);
|
|
46164
|
+
const availableGB = (safeAvailableKB / (1024 * 1024)).toFixed(2);
|
|
46149
46165
|
const hasEnoughSpace = availableMB > 100;
|
|
46150
46166
|
results.push({
|
|
46151
46167
|
name: "Available Disk Space",
|
|
@@ -46833,37 +46849,38 @@ var TelemetryCollector = class {
|
|
|
46833
46849
|
logger.warn("Query called on closed or uninitialized telemetry collector");
|
|
46834
46850
|
return [];
|
|
46835
46851
|
}
|
|
46836
|
-
|
|
46852
|
+
const conditions = [];
|
|
46837
46853
|
const params = [];
|
|
46838
46854
|
if (filters.provider) {
|
|
46839
|
-
|
|
46855
|
+
conditions.push("provider = ?");
|
|
46840
46856
|
params.push(filters.provider);
|
|
46841
46857
|
}
|
|
46842
46858
|
if (filters.agentName) {
|
|
46843
|
-
|
|
46859
|
+
conditions.push("agent_name = ?");
|
|
46844
46860
|
params.push(filters.agentName);
|
|
46845
46861
|
}
|
|
46846
46862
|
if (filters.sessionId) {
|
|
46847
|
-
|
|
46863
|
+
conditions.push("session_id = ?");
|
|
46848
46864
|
params.push(filters.sessionId);
|
|
46849
46865
|
}
|
|
46850
46866
|
if (filters.type) {
|
|
46851
|
-
|
|
46867
|
+
conditions.push("type = ?");
|
|
46852
46868
|
params.push(filters.type);
|
|
46853
46869
|
}
|
|
46854
46870
|
if (filters.startDate) {
|
|
46855
|
-
|
|
46871
|
+
conditions.push("timestamp >= ?");
|
|
46856
46872
|
params.push(filters.startDate);
|
|
46857
46873
|
}
|
|
46858
46874
|
if (filters.endDate) {
|
|
46859
|
-
|
|
46875
|
+
conditions.push("timestamp <= ?");
|
|
46860
46876
|
params.push(filters.endDate);
|
|
46861
46877
|
}
|
|
46862
46878
|
if (filters.success !== void 0) {
|
|
46863
|
-
|
|
46879
|
+
conditions.push("success = ?");
|
|
46864
46880
|
params.push(filters.success ? 1 : 0);
|
|
46865
46881
|
}
|
|
46866
|
-
|
|
46882
|
+
const whereClause = conditions.length > 0 ? "WHERE " + conditions.join(" AND ") : "";
|
|
46883
|
+
const sql = `SELECT * FROM telemetry_events ${whereClause} ORDER BY timestamp DESC LIMIT ?`;
|
|
46867
46884
|
params.push(filters.limit || 1e3);
|
|
46868
46885
|
const rows = this.db.prepare(sql).all(...params);
|
|
46869
46886
|
return rows.map((row) => this.mapRowToEvent(row));
|
|
@@ -46877,20 +46894,22 @@ var TelemetryCollector = class {
|
|
|
46877
46894
|
if (this.closed || !this.db) {
|
|
46878
46895
|
return 0;
|
|
46879
46896
|
}
|
|
46880
|
-
|
|
46897
|
+
const conditions = [];
|
|
46881
46898
|
const params = [];
|
|
46882
46899
|
if (filters.provider) {
|
|
46883
|
-
|
|
46900
|
+
conditions.push("provider = ?");
|
|
46884
46901
|
params.push(filters.provider);
|
|
46885
46902
|
}
|
|
46886
46903
|
if (filters.startDate) {
|
|
46887
|
-
|
|
46904
|
+
conditions.push("timestamp >= ?");
|
|
46888
46905
|
params.push(filters.startDate);
|
|
46889
46906
|
}
|
|
46890
46907
|
if (filters.endDate) {
|
|
46891
|
-
|
|
46908
|
+
conditions.push("timestamp <= ?");
|
|
46892
46909
|
params.push(filters.endDate);
|
|
46893
46910
|
}
|
|
46911
|
+
const whereClause = conditions.length > 0 ? "WHERE " + conditions.join(" AND ") : "";
|
|
46912
|
+
const sql = `SELECT COUNT(*) as count FROM telemetry_events ${whereClause}`;
|
|
46894
46913
|
const result = this.db.prepare(sql).get(...params);
|
|
46895
46914
|
return result.count;
|
|
46896
46915
|
}
|
|
@@ -47610,9 +47629,11 @@ async function optimizeHandler(argv) {
|
|
|
47610
47629
|
console.log(chalk5.green("\u2705 No optimization opportunities found. You're doing great!\n"));
|
|
47611
47630
|
return;
|
|
47612
47631
|
}
|
|
47632
|
+
const TYPE_ICONS = { cost_saving: "\u{1F4B0}", performance: "\u26A1", security: "\u{1F512}" };
|
|
47633
|
+
const SEVERITY_COLORS = { high: chalk5.red, medium: chalk5.yellow, low: chalk5.gray };
|
|
47613
47634
|
for (const rec of recommendations) {
|
|
47614
|
-
const icon = rec.type
|
|
47615
|
-
const severityColor = rec.severity
|
|
47635
|
+
const icon = TYPE_ICONS[rec.type] ?? "\u{1F512}";
|
|
47636
|
+
const severityColor = SEVERITY_COLORS[rec.severity] ?? chalk5.gray;
|
|
47616
47637
|
console.log(`${icon} ${severityColor(rec.severity.toUpperCase())}: ${chalk5.bold(rec.title)}`);
|
|
47617
47638
|
console.log(` ${rec.description}`);
|
|
47618
47639
|
if (rec.estimatedSavings) {
|
|
@@ -48510,6 +48531,2880 @@ var uninstallCommand = {
|
|
|
48510
48531
|
}
|
|
48511
48532
|
};
|
|
48512
48533
|
|
|
48534
|
+
// src/cli/commands/mode.ts
|
|
48535
|
+
init_esm_shims();
|
|
48536
|
+
init_logger();
|
|
48537
|
+
|
|
48538
|
+
// src/core/workflow/index.ts
|
|
48539
|
+
init_esm_shims();
|
|
48540
|
+
|
|
48541
|
+
// src/core/workflow/workflow-mode.ts
|
|
48542
|
+
init_esm_shims();
|
|
48543
|
+
var WorkflowModeSchema = z.enum(["default", "plan", "iterate", "review"]);
|
|
48544
|
+
z.object({
|
|
48545
|
+
name: WorkflowModeSchema,
|
|
48546
|
+
description: z.string(),
|
|
48547
|
+
displayName: z.string(),
|
|
48548
|
+
allowedTools: z.array(z.string()).optional(),
|
|
48549
|
+
blockedTools: z.array(z.string()).optional(),
|
|
48550
|
+
systemInstructions: z.string(),
|
|
48551
|
+
allowNesting: z.boolean(),
|
|
48552
|
+
maxNestingDepth: z.number().int().positive().optional(),
|
|
48553
|
+
autoExitConditions: z.object({
|
|
48554
|
+
maxTurns: z.number().int().positive().optional(),
|
|
48555
|
+
onToolUse: z.array(z.string()).optional(),
|
|
48556
|
+
onKeywords: z.array(z.string()).optional()
|
|
48557
|
+
}).optional()
|
|
48558
|
+
});
|
|
48559
|
+
var WRITE_TOOLS = [
|
|
48560
|
+
"Write",
|
|
48561
|
+
"Edit",
|
|
48562
|
+
"NotebookEdit",
|
|
48563
|
+
"Bash"
|
|
48564
|
+
];
|
|
48565
|
+
var DEFAULT_MODE_CONFIG = {
|
|
48566
|
+
name: "default",
|
|
48567
|
+
displayName: "Default",
|
|
48568
|
+
description: "Standard operation mode with all tools available",
|
|
48569
|
+
systemInstructions: "",
|
|
48570
|
+
allowNesting: true,
|
|
48571
|
+
maxNestingDepth: 3
|
|
48572
|
+
};
|
|
48573
|
+
var PLAN_MODE_CONFIG = {
|
|
48574
|
+
name: "plan",
|
|
48575
|
+
displayName: "Plan Mode",
|
|
48576
|
+
description: "Planning mode - read-only exploration without code modifications",
|
|
48577
|
+
blockedTools: [...WRITE_TOOLS],
|
|
48578
|
+
systemInstructions: `## Plan Mode Active
|
|
48579
|
+
|
|
48580
|
+
You are in **Plan Mode**. This mode is for exploration and planning only.
|
|
48581
|
+
|
|
48582
|
+
**Restrictions:**
|
|
48583
|
+
- You CANNOT use Write, Edit, or Bash tools that modify files
|
|
48584
|
+
- Focus on reading, searching, and understanding the codebase
|
|
48585
|
+
- Create a comprehensive plan before implementation
|
|
48586
|
+
|
|
48587
|
+
**Your Goals:**
|
|
48588
|
+
1. Explore the codebase to understand existing patterns
|
|
48589
|
+
2. Identify files that need to be modified
|
|
48590
|
+
3. Design an implementation approach
|
|
48591
|
+
4. Document your plan clearly
|
|
48592
|
+
5. Use ExitPlanMode when ready to implement
|
|
48593
|
+
|
|
48594
|
+
**Remember:** No code modifications in this mode. Plan first, implement later.`,
|
|
48595
|
+
allowNesting: false,
|
|
48596
|
+
autoExitConditions: {
|
|
48597
|
+
onToolUse: ["ExitPlanMode"]
|
|
48598
|
+
}
|
|
48599
|
+
};
|
|
48600
|
+
var ITERATE_MODE_CONFIG = {
|
|
48601
|
+
name: "iterate",
|
|
48602
|
+
displayName: "Iterate Mode",
|
|
48603
|
+
description: "Continuous iteration mode for implementation with automatic continuation",
|
|
48604
|
+
systemInstructions: `## Iterate Mode Active
|
|
48605
|
+
|
|
48606
|
+
You are in **Iterate Mode**. This mode enables continuous task execution.
|
|
48607
|
+
|
|
48608
|
+
**Behavior:**
|
|
48609
|
+
- Continue working until the task is complete
|
|
48610
|
+
- After each step, assess progress and continue
|
|
48611
|
+
- Don't stop to ask for confirmation unless critical
|
|
48612
|
+
- Mark todos as completed as you finish them
|
|
48613
|
+
|
|
48614
|
+
**Guidelines:**
|
|
48615
|
+
1. Work through tasks systematically
|
|
48616
|
+
2. Test changes as you go when possible
|
|
48617
|
+
3. Update todo list to track progress
|
|
48618
|
+
4. Only pause for critical decisions or blockers
|
|
48619
|
+
|
|
48620
|
+
**Remember:** Keep iterating until the task is done or you hit a blocker.`,
|
|
48621
|
+
allowNesting: true,
|
|
48622
|
+
maxNestingDepth: 2
|
|
48623
|
+
};
|
|
48624
|
+
var REVIEW_MODE_CONFIG = {
|
|
48625
|
+
name: "review",
|
|
48626
|
+
displayName: "Review Mode",
|
|
48627
|
+
description: "Code review mode - analyze code quality, security, and best practices",
|
|
48628
|
+
blockedTools: [...WRITE_TOOLS],
|
|
48629
|
+
systemInstructions: `## Review Mode Active
|
|
48630
|
+
|
|
48631
|
+
You are in **Review Mode**. This mode is for code review and analysis.
|
|
48632
|
+
|
|
48633
|
+
**Focus Areas:**
|
|
48634
|
+
- Code quality and readability
|
|
48635
|
+
- Security vulnerabilities (OWASP Top 10)
|
|
48636
|
+
- Performance issues
|
|
48637
|
+
- Best practices and patterns
|
|
48638
|
+
- Test coverage gaps
|
|
48639
|
+
|
|
48640
|
+
**Output Format:**
|
|
48641
|
+
Provide structured feedback:
|
|
48642
|
+
1. **Critical Issues** - Must fix before merge
|
|
48643
|
+
2. **Warnings** - Should address
|
|
48644
|
+
3. **Suggestions** - Nice to have improvements
|
|
48645
|
+
4. **Positive Notes** - Good patterns observed
|
|
48646
|
+
|
|
48647
|
+
**Remember:** No code modifications. Provide actionable feedback only.`,
|
|
48648
|
+
allowNesting: false
|
|
48649
|
+
};
|
|
48650
|
+
var WORKFLOW_MODE_CONFIGS = {
|
|
48651
|
+
default: DEFAULT_MODE_CONFIG,
|
|
48652
|
+
plan: PLAN_MODE_CONFIG,
|
|
48653
|
+
iterate: ITERATE_MODE_CONFIG,
|
|
48654
|
+
review: REVIEW_MODE_CONFIG
|
|
48655
|
+
};
|
|
48656
|
+
function getWorkflowModeConfig(mode) {
|
|
48657
|
+
return WORKFLOW_MODE_CONFIGS[mode];
|
|
48658
|
+
}
|
|
48659
|
+
function isToolAllowedInMode(tool, mode) {
|
|
48660
|
+
const config = getWorkflowModeConfig(mode);
|
|
48661
|
+
if (config.allowedTools && config.allowedTools.length > 0) {
|
|
48662
|
+
return config.allowedTools.includes(tool);
|
|
48663
|
+
}
|
|
48664
|
+
if (config.blockedTools && config.blockedTools.length > 0) {
|
|
48665
|
+
return !config.blockedTools.includes(tool);
|
|
48666
|
+
}
|
|
48667
|
+
return true;
|
|
48668
|
+
}
|
|
48669
|
+
function isValidWorkflowMode(mode) {
|
|
48670
|
+
return mode in WORKFLOW_MODE_CONFIGS;
|
|
48671
|
+
}
|
|
48672
|
+
var WORKFLOW_MODES = WORKFLOW_MODE_CONFIGS;
|
|
48673
|
+
|
|
48674
|
+
// src/core/workflow/workflow-mode-manager.ts
|
|
48675
|
+
init_esm_shims();
|
|
48676
|
+
init_logger();
|
|
48677
|
+
var WorkflowModeManager = class {
|
|
48678
|
+
name = "workflow-mode";
|
|
48679
|
+
modeStack = [];
|
|
48680
|
+
transitionListeners = /* @__PURE__ */ new Set();
|
|
48681
|
+
turnCount = 0;
|
|
48682
|
+
constructor(initialMode = "default") {
|
|
48683
|
+
this.modeStack.push({
|
|
48684
|
+
mode: initialMode,
|
|
48685
|
+
enteredAt: Date.now(),
|
|
48686
|
+
enteredAtTurn: 0,
|
|
48687
|
+
reason: "initial"
|
|
48688
|
+
});
|
|
48689
|
+
logger.debug("WorkflowModeManager initialized", {
|
|
48690
|
+
initialMode
|
|
48691
|
+
});
|
|
48692
|
+
}
|
|
48693
|
+
/**
|
|
48694
|
+
* Get the current active mode
|
|
48695
|
+
*/
|
|
48696
|
+
getCurrentMode() {
|
|
48697
|
+
const top = this.modeStack[this.modeStack.length - 1];
|
|
48698
|
+
return top?.mode ?? "default";
|
|
48699
|
+
}
|
|
48700
|
+
/**
|
|
48701
|
+
* Get the current mode configuration
|
|
48702
|
+
*/
|
|
48703
|
+
getCurrentModeConfig() {
|
|
48704
|
+
const mode = this.getCurrentMode();
|
|
48705
|
+
const entry = this.modeStack[this.modeStack.length - 1];
|
|
48706
|
+
const baseConfig = getWorkflowModeConfig(mode);
|
|
48707
|
+
if (entry?.customConfig) {
|
|
48708
|
+
return {
|
|
48709
|
+
...baseConfig,
|
|
48710
|
+
...entry.customConfig,
|
|
48711
|
+
// Deep merge for nested objects
|
|
48712
|
+
autoExitConditions: {
|
|
48713
|
+
...baseConfig.autoExitConditions,
|
|
48714
|
+
...entry.customConfig.autoExitConditions
|
|
48715
|
+
}
|
|
48716
|
+
};
|
|
48717
|
+
}
|
|
48718
|
+
return baseConfig;
|
|
48719
|
+
}
|
|
48720
|
+
/**
|
|
48721
|
+
* Get the full mode stack
|
|
48722
|
+
*/
|
|
48723
|
+
getModeStack() {
|
|
48724
|
+
return [...this.modeStack];
|
|
48725
|
+
}
|
|
48726
|
+
/**
|
|
48727
|
+
* Get the current stack depth
|
|
48728
|
+
*/
|
|
48729
|
+
getStackDepth() {
|
|
48730
|
+
return this.modeStack.length;
|
|
48731
|
+
}
|
|
48732
|
+
/**
|
|
48733
|
+
* Push a new mode onto the stack
|
|
48734
|
+
*/
|
|
48735
|
+
pushMode(mode, options) {
|
|
48736
|
+
const currentConfig = this.getCurrentModeConfig();
|
|
48737
|
+
if (!currentConfig.allowNesting) {
|
|
48738
|
+
logger.warn("Cannot push mode: current mode does not allow nesting", {
|
|
48739
|
+
currentMode: this.getCurrentMode(),
|
|
48740
|
+
attemptedMode: mode
|
|
48741
|
+
});
|
|
48742
|
+
return false;
|
|
48743
|
+
}
|
|
48744
|
+
const maxDepth = currentConfig.maxNestingDepth ?? 3;
|
|
48745
|
+
if (this.modeStack.length >= maxDepth) {
|
|
48746
|
+
logger.warn("Cannot push mode: max nesting depth reached", {
|
|
48747
|
+
currentDepth: this.modeStack.length,
|
|
48748
|
+
maxDepth
|
|
48749
|
+
});
|
|
48750
|
+
return false;
|
|
48751
|
+
}
|
|
48752
|
+
const previousMode = this.getCurrentMode();
|
|
48753
|
+
this.modeStack.push({
|
|
48754
|
+
mode,
|
|
48755
|
+
enteredAt: Date.now(),
|
|
48756
|
+
enteredAtTurn: this.turnCount,
|
|
48757
|
+
customConfig: options?.customConfig,
|
|
48758
|
+
reason: options?.reason
|
|
48759
|
+
});
|
|
48760
|
+
this.emitTransition({
|
|
48761
|
+
from: previousMode,
|
|
48762
|
+
to: mode,
|
|
48763
|
+
type: "push",
|
|
48764
|
+
timestamp: Date.now(),
|
|
48765
|
+
reason: options?.reason
|
|
48766
|
+
});
|
|
48767
|
+
logger.info("Pushed workflow mode", {
|
|
48768
|
+
from: previousMode,
|
|
48769
|
+
to: mode,
|
|
48770
|
+
stackDepth: this.modeStack.length,
|
|
48771
|
+
reason: options?.reason
|
|
48772
|
+
});
|
|
48773
|
+
return true;
|
|
48774
|
+
}
|
|
48775
|
+
/**
|
|
48776
|
+
* Pop the current mode from the stack
|
|
48777
|
+
*/
|
|
48778
|
+
popMode(reason) {
|
|
48779
|
+
if (this.modeStack.length <= 1) {
|
|
48780
|
+
logger.warn("Cannot pop mode: at base level");
|
|
48781
|
+
return null;
|
|
48782
|
+
}
|
|
48783
|
+
const popped = this.modeStack.pop();
|
|
48784
|
+
const newMode = this.getCurrentMode();
|
|
48785
|
+
if (popped) {
|
|
48786
|
+
this.emitTransition({
|
|
48787
|
+
from: popped.mode,
|
|
48788
|
+
to: newMode,
|
|
48789
|
+
type: "pop",
|
|
48790
|
+
timestamp: Date.now(),
|
|
48791
|
+
reason
|
|
48792
|
+
});
|
|
48793
|
+
logger.info("Popped workflow mode", {
|
|
48794
|
+
from: popped.mode,
|
|
48795
|
+
to: newMode,
|
|
48796
|
+
stackDepth: this.modeStack.length,
|
|
48797
|
+
reason
|
|
48798
|
+
});
|
|
48799
|
+
}
|
|
48800
|
+
return popped?.mode ?? null;
|
|
48801
|
+
}
|
|
48802
|
+
/**
|
|
48803
|
+
* Replace the current mode (pop then push)
|
|
48804
|
+
*/
|
|
48805
|
+
replaceMode(mode, options) {
|
|
48806
|
+
const previousMode = this.getCurrentMode();
|
|
48807
|
+
if (this.modeStack.length === 1) {
|
|
48808
|
+
this.modeStack[0] = {
|
|
48809
|
+
mode,
|
|
48810
|
+
enteredAt: Date.now(),
|
|
48811
|
+
enteredAtTurn: this.turnCount,
|
|
48812
|
+
customConfig: options?.customConfig,
|
|
48813
|
+
reason: options?.reason
|
|
48814
|
+
};
|
|
48815
|
+
} else {
|
|
48816
|
+
this.modeStack.pop();
|
|
48817
|
+
this.modeStack.push({
|
|
48818
|
+
mode,
|
|
48819
|
+
enteredAt: Date.now(),
|
|
48820
|
+
enteredAtTurn: this.turnCount,
|
|
48821
|
+
customConfig: options?.customConfig,
|
|
48822
|
+
reason: options?.reason
|
|
48823
|
+
});
|
|
48824
|
+
}
|
|
48825
|
+
this.emitTransition({
|
|
48826
|
+
from: previousMode,
|
|
48827
|
+
to: mode,
|
|
48828
|
+
type: "replace",
|
|
48829
|
+
timestamp: Date.now(),
|
|
48830
|
+
reason: options?.reason
|
|
48831
|
+
});
|
|
48832
|
+
logger.info("Replaced workflow mode", {
|
|
48833
|
+
from: previousMode,
|
|
48834
|
+
to: mode,
|
|
48835
|
+
reason: options?.reason
|
|
48836
|
+
});
|
|
48837
|
+
return true;
|
|
48838
|
+
}
|
|
48839
|
+
/**
|
|
48840
|
+
* Set mode directly (clears stack and sets new base mode)
|
|
48841
|
+
*/
|
|
48842
|
+
setMode(mode, options) {
|
|
48843
|
+
const previousMode = this.getCurrentMode();
|
|
48844
|
+
this.modeStack = [{
|
|
48845
|
+
mode,
|
|
48846
|
+
enteredAt: Date.now(),
|
|
48847
|
+
enteredAtTurn: this.turnCount,
|
|
48848
|
+
customConfig: options?.customConfig,
|
|
48849
|
+
reason: options?.reason
|
|
48850
|
+
}];
|
|
48851
|
+
this.emitTransition({
|
|
48852
|
+
from: previousMode,
|
|
48853
|
+
to: mode,
|
|
48854
|
+
type: "replace",
|
|
48855
|
+
timestamp: Date.now(),
|
|
48856
|
+
reason: options?.reason
|
|
48857
|
+
});
|
|
48858
|
+
logger.info("Set workflow mode", {
|
|
48859
|
+
from: previousMode,
|
|
48860
|
+
to: mode,
|
|
48861
|
+
reason: options?.reason
|
|
48862
|
+
});
|
|
48863
|
+
}
|
|
48864
|
+
/**
|
|
48865
|
+
* Check if a tool is allowed in the current mode
|
|
48866
|
+
*/
|
|
48867
|
+
isToolAllowed(tool) {
|
|
48868
|
+
return isToolAllowedInMode(tool, this.getCurrentMode());
|
|
48869
|
+
}
|
|
48870
|
+
/**
|
|
48871
|
+
* Get list of blocked tools in current mode
|
|
48872
|
+
*/
|
|
48873
|
+
getBlockedTools() {
|
|
48874
|
+
const config = this.getCurrentModeConfig();
|
|
48875
|
+
return config.blockedTools || [];
|
|
48876
|
+
}
|
|
48877
|
+
/**
|
|
48878
|
+
* Filter a list of tools based on current mode
|
|
48879
|
+
*/
|
|
48880
|
+
filterTools(tools) {
|
|
48881
|
+
return tools.filter((tool) => this.isToolAllowed(tool.name));
|
|
48882
|
+
}
|
|
48883
|
+
/**
|
|
48884
|
+
* Update turn count (for auto-exit tracking)
|
|
48885
|
+
*/
|
|
48886
|
+
updateTurnCount(turn) {
|
|
48887
|
+
this.turnCount = turn;
|
|
48888
|
+
this.checkAutoExit();
|
|
48889
|
+
}
|
|
48890
|
+
/**
|
|
48891
|
+
* Check and handle auto-exit conditions
|
|
48892
|
+
*/
|
|
48893
|
+
checkAutoExit() {
|
|
48894
|
+
const config = this.getCurrentModeConfig();
|
|
48895
|
+
const entry = this.modeStack[this.modeStack.length - 1];
|
|
48896
|
+
if (!config.autoExitConditions || !entry) return;
|
|
48897
|
+
if (config.autoExitConditions.maxTurns) {
|
|
48898
|
+
const turnsInMode = this.turnCount - entry.enteredAtTurn;
|
|
48899
|
+
if (turnsInMode >= config.autoExitConditions.maxTurns) {
|
|
48900
|
+
logger.info("Auto-exiting mode due to max turns", {
|
|
48901
|
+
mode: this.getCurrentMode(),
|
|
48902
|
+
turnsInMode,
|
|
48903
|
+
maxTurns: config.autoExitConditions.maxTurns
|
|
48904
|
+
});
|
|
48905
|
+
this.popMode("max_turns_reached");
|
|
48906
|
+
}
|
|
48907
|
+
}
|
|
48908
|
+
}
|
|
48909
|
+
/**
|
|
48910
|
+
* Notify that a tool was used (for auto-exit on tool use)
|
|
48911
|
+
*/
|
|
48912
|
+
notifyToolUsed(tool) {
|
|
48913
|
+
const config = this.getCurrentModeConfig();
|
|
48914
|
+
if (config.autoExitConditions?.onToolUse?.includes(tool)) {
|
|
48915
|
+
logger.info("Auto-exiting mode due to tool use", {
|
|
48916
|
+
mode: this.getCurrentMode(),
|
|
48917
|
+
tool
|
|
48918
|
+
});
|
|
48919
|
+
this.popMode(`tool_used:${tool}`);
|
|
48920
|
+
}
|
|
48921
|
+
}
|
|
48922
|
+
/**
|
|
48923
|
+
* Add a mode transition listener
|
|
48924
|
+
*/
|
|
48925
|
+
onTransition(listener) {
|
|
48926
|
+
this.transitionListeners.add(listener);
|
|
48927
|
+
return () => this.transitionListeners.delete(listener);
|
|
48928
|
+
}
|
|
48929
|
+
/**
|
|
48930
|
+
* Emit a transition event to all listeners
|
|
48931
|
+
*/
|
|
48932
|
+
emitTransition(event) {
|
|
48933
|
+
for (const listener of this.transitionListeners) {
|
|
48934
|
+
try {
|
|
48935
|
+
listener(event);
|
|
48936
|
+
} catch (error) {
|
|
48937
|
+
logger.error("Mode transition listener error", {
|
|
48938
|
+
error: error instanceof Error ? error.message : String(error)
|
|
48939
|
+
});
|
|
48940
|
+
}
|
|
48941
|
+
}
|
|
48942
|
+
}
|
|
48943
|
+
// InstructionProvider implementation
|
|
48944
|
+
/**
|
|
48945
|
+
* Check if mode instructions should be generated
|
|
48946
|
+
*/
|
|
48947
|
+
shouldGenerate(context) {
|
|
48948
|
+
return this.getCurrentMode() !== "default";
|
|
48949
|
+
}
|
|
48950
|
+
/**
|
|
48951
|
+
* Get mode-specific instructions
|
|
48952
|
+
*/
|
|
48953
|
+
async getInstructions(context) {
|
|
48954
|
+
const config = this.getCurrentModeConfig();
|
|
48955
|
+
const instructions = [];
|
|
48956
|
+
if (config.systemInstructions && config.systemInstructions.length > 0) {
|
|
48957
|
+
instructions.push({
|
|
48958
|
+
type: "mode",
|
|
48959
|
+
priority: "high",
|
|
48960
|
+
content: config.systemInstructions,
|
|
48961
|
+
source: "automatosx",
|
|
48962
|
+
createdAt: Date.now(),
|
|
48963
|
+
id: `mode-${config.name}-${Date.now()}`
|
|
48964
|
+
});
|
|
48965
|
+
}
|
|
48966
|
+
if (config.blockedTools && config.blockedTools.length > 0) {
|
|
48967
|
+
instructions.push({
|
|
48968
|
+
type: "mode",
|
|
48969
|
+
priority: "critical",
|
|
48970
|
+
content: `**Tool Restrictions:** The following tools are NOT available in ${config.displayName}: ${config.blockedTools.join(", ")}`,
|
|
48971
|
+
source: "automatosx",
|
|
48972
|
+
createdAt: Date.now(),
|
|
48973
|
+
id: `mode-blocked-tools-${Date.now()}`
|
|
48974
|
+
});
|
|
48975
|
+
}
|
|
48976
|
+
return instructions;
|
|
48977
|
+
}
|
|
48978
|
+
/**
|
|
48979
|
+
* Reset to default state
|
|
48980
|
+
*/
|
|
48981
|
+
reset() {
|
|
48982
|
+
const previousMode = this.getCurrentMode();
|
|
48983
|
+
this.modeStack = [{
|
|
48984
|
+
mode: "default",
|
|
48985
|
+
enteredAt: Date.now(),
|
|
48986
|
+
enteredAtTurn: 0,
|
|
48987
|
+
reason: "reset"
|
|
48988
|
+
}];
|
|
48989
|
+
this.turnCount = 0;
|
|
48990
|
+
if (previousMode !== "default") {
|
|
48991
|
+
this.emitTransition({
|
|
48992
|
+
from: previousMode,
|
|
48993
|
+
to: "default",
|
|
48994
|
+
type: "replace",
|
|
48995
|
+
timestamp: Date.now(),
|
|
48996
|
+
reason: "reset"
|
|
48997
|
+
});
|
|
48998
|
+
}
|
|
48999
|
+
logger.debug("WorkflowModeManager reset");
|
|
49000
|
+
}
|
|
49001
|
+
/**
|
|
49002
|
+
* Get status information for debugging
|
|
49003
|
+
*/
|
|
49004
|
+
getStatus() {
|
|
49005
|
+
return {
|
|
49006
|
+
currentMode: this.getCurrentMode(),
|
|
49007
|
+
stackDepth: this.modeStack.length,
|
|
49008
|
+
stack: this.modeStack.map((entry) => ({
|
|
49009
|
+
mode: entry.mode,
|
|
49010
|
+
enteredAt: entry.enteredAt,
|
|
49011
|
+
reason: entry.reason
|
|
49012
|
+
})),
|
|
49013
|
+
blockedTools: this.getBlockedTools(),
|
|
49014
|
+
turnCount: this.turnCount
|
|
49015
|
+
};
|
|
49016
|
+
}
|
|
49017
|
+
};
|
|
49018
|
+
|
|
49019
|
+
// src/cli/commands/mode.ts
|
|
49020
|
+
var modeCommand = {
|
|
49021
|
+
command: "mode [mode]",
|
|
49022
|
+
describe: "Manage workflow modes for embedded instructions (v11.3.0)",
|
|
49023
|
+
builder: (yargs2) => {
|
|
49024
|
+
return yargs2.positional("mode", {
|
|
49025
|
+
describe: "Workflow mode to set (default, plan, iterate, review)",
|
|
49026
|
+
type: "string"
|
|
49027
|
+
}).option("list", {
|
|
49028
|
+
alias: "l",
|
|
49029
|
+
describe: "List available workflow modes",
|
|
49030
|
+
type: "boolean",
|
|
49031
|
+
default: false
|
|
49032
|
+
}).option("status", {
|
|
49033
|
+
alias: "s",
|
|
49034
|
+
describe: "Show current workflow mode status",
|
|
49035
|
+
type: "boolean",
|
|
49036
|
+
default: false
|
|
49037
|
+
}).example("$0 mode plan", "Enter plan mode (restricts code-modifying tools)").example("$0 mode iterate", "Enter iterate mode (for autonomous execution)").example("$0 mode default", "Return to default mode").example("$0 mode --list", "List all available modes").example("$0 mode --status", "Show current mode status");
|
|
49038
|
+
},
|
|
49039
|
+
handler: async (argv) => {
|
|
49040
|
+
try {
|
|
49041
|
+
if (argv.list) {
|
|
49042
|
+
displayModeList();
|
|
49043
|
+
return;
|
|
49044
|
+
}
|
|
49045
|
+
if (argv.status || !argv.mode) {
|
|
49046
|
+
displayModeStatus();
|
|
49047
|
+
return;
|
|
49048
|
+
}
|
|
49049
|
+
const modeName = argv.mode.toLowerCase();
|
|
49050
|
+
if (!isValidWorkflowMode(modeName)) {
|
|
49051
|
+
console.error(chalk5.red.bold(`
|
|
49052
|
+
\u274C Invalid workflow mode: ${argv.mode}
|
|
49053
|
+
`));
|
|
49054
|
+
console.log(chalk5.gray("Available modes:"));
|
|
49055
|
+
Object.keys(WORKFLOW_MODES).forEach((mode) => {
|
|
49056
|
+
console.log(chalk5.cyan(` \u2022 ${mode}`));
|
|
49057
|
+
});
|
|
49058
|
+
console.log();
|
|
49059
|
+
process.exit(1);
|
|
49060
|
+
}
|
|
49061
|
+
const modeConfig = WORKFLOW_MODES[modeName];
|
|
49062
|
+
console.log(chalk5.green.bold(`
|
|
49063
|
+
\u2705 Workflow mode set to: ${modeName}
|
|
49064
|
+
`));
|
|
49065
|
+
console.log(chalk5.gray(`Description: ${modeConfig.description}`));
|
|
49066
|
+
if (modeConfig.blockedTools && modeConfig.blockedTools.length > 0) {
|
|
49067
|
+
console.log(chalk5.yellow("\nRestricted tools in this mode:"));
|
|
49068
|
+
modeConfig.blockedTools.forEach((tool) => {
|
|
49069
|
+
console.log(chalk5.yellow(` \u2022 ${tool}`));
|
|
49070
|
+
});
|
|
49071
|
+
}
|
|
49072
|
+
if (modeConfig.allowedTools && modeConfig.allowedTools.length > 0) {
|
|
49073
|
+
console.log(chalk5.cyan("\nAllowed tools in this mode:"));
|
|
49074
|
+
modeConfig.allowedTools.forEach((tool) => {
|
|
49075
|
+
console.log(chalk5.cyan(` \u2022 ${tool}`));
|
|
49076
|
+
});
|
|
49077
|
+
}
|
|
49078
|
+
console.log();
|
|
49079
|
+
console.log(chalk5.gray("Note: Mode setting applies to the current session."));
|
|
49080
|
+
console.log(chalk5.gray("Use with --iterate flag in ax run for persistent mode.\n"));
|
|
49081
|
+
logger.info("Workflow mode set", { mode: modeName });
|
|
49082
|
+
} catch (error) {
|
|
49083
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
49084
|
+
console.error(chalk5.red.bold(`
|
|
49085
|
+
\u274C Error: ${err.message}
|
|
49086
|
+
`));
|
|
49087
|
+
logger.error("Mode command failed", { error: err.message });
|
|
49088
|
+
process.exit(1);
|
|
49089
|
+
}
|
|
49090
|
+
}
|
|
49091
|
+
};
|
|
49092
|
+
function displayModeList() {
|
|
49093
|
+
console.log(chalk5.blue.bold("\n\u{1F4CB} Available Workflow Modes\n"));
|
|
49094
|
+
console.log(chalk5.dim("\u2500".repeat(60)));
|
|
49095
|
+
for (const [name, config] of Object.entries(WORKFLOW_MODES)) {
|
|
49096
|
+
console.log();
|
|
49097
|
+
console.log(chalk5.cyan.bold(` ${name}`));
|
|
49098
|
+
console.log(chalk5.gray(` ${config.description}`));
|
|
49099
|
+
if (config.blockedTools && config.blockedTools.length > 0) {
|
|
49100
|
+
console.log(chalk5.yellow(` Blocked: ${config.blockedTools.join(", ")}`));
|
|
49101
|
+
}
|
|
49102
|
+
if (config.maxNestingDepth !== void 0) {
|
|
49103
|
+
console.log(chalk5.gray(` Max nesting depth: ${config.maxNestingDepth}`));
|
|
49104
|
+
}
|
|
49105
|
+
}
|
|
49106
|
+
console.log();
|
|
49107
|
+
console.log(chalk5.dim("\u2500".repeat(60)));
|
|
49108
|
+
console.log(chalk5.gray("\nUsage: ax mode <mode-name>"));
|
|
49109
|
+
console.log(chalk5.gray("Example: ax mode plan\n"));
|
|
49110
|
+
}
|
|
49111
|
+
function displayModeStatus() {
|
|
49112
|
+
const currentMode = "default";
|
|
49113
|
+
const modeConfig = WORKFLOW_MODES[currentMode];
|
|
49114
|
+
console.log(chalk5.blue.bold("\n\u{1F4CA} Workflow Mode Status\n"));
|
|
49115
|
+
console.log(chalk5.dim("\u2500".repeat(50)));
|
|
49116
|
+
console.log(` Current mode: ${chalk5.cyan.bold(currentMode)}`);
|
|
49117
|
+
console.log(` Description: ${chalk5.gray(modeConfig.description)}`);
|
|
49118
|
+
if (modeConfig.blockedTools && modeConfig.blockedTools.length > 0) {
|
|
49119
|
+
console.log(` Blocked tools: ${chalk5.yellow(modeConfig.blockedTools.length)}`);
|
|
49120
|
+
} else {
|
|
49121
|
+
console.log(` Blocked tools: ${chalk5.green("none")}`);
|
|
49122
|
+
}
|
|
49123
|
+
console.log(chalk5.dim("\u2500".repeat(50)));
|
|
49124
|
+
console.log();
|
|
49125
|
+
console.log(chalk5.gray("To change mode: ax mode <mode-name>"));
|
|
49126
|
+
console.log(chalk5.gray("To list modes: ax mode --list\n"));
|
|
49127
|
+
}
|
|
49128
|
+
|
|
49129
|
+
// src/cli/commands/debug-instructions.ts
|
|
49130
|
+
init_esm_shims();
|
|
49131
|
+
init_logger();
|
|
49132
|
+
|
|
49133
|
+
// src/core/orchestration/orchestration-service.ts
|
|
49134
|
+
init_esm_shims();
|
|
49135
|
+
init_logger();
|
|
49136
|
+
|
|
49137
|
+
// src/core/orchestration/types.ts
|
|
49138
|
+
init_esm_shims();
|
|
49139
|
+
z.object({
|
|
49140
|
+
type: z.enum(["task", "memory", "session", "delegation", "mode"]),
|
|
49141
|
+
priority: z.enum(["critical", "high", "normal", "low"]),
|
|
49142
|
+
content: z.string().min(1).max(5e3),
|
|
49143
|
+
source: z.literal("automatosx"),
|
|
49144
|
+
expiresAfter: z.number().int().positive().optional(),
|
|
49145
|
+
createdAt: z.number(),
|
|
49146
|
+
id: z.string().optional()
|
|
49147
|
+
});
|
|
49148
|
+
var TodoItemSchema = z.object({
|
|
49149
|
+
id: z.string(),
|
|
49150
|
+
content: z.string().min(1).max(1e3),
|
|
49151
|
+
status: z.enum(["pending", "in_progress", "completed"]),
|
|
49152
|
+
activeForm: z.string().min(1).max(1e3),
|
|
49153
|
+
createdAt: z.number(),
|
|
49154
|
+
updatedAt: z.number().optional(),
|
|
49155
|
+
metadata: z.record(z.string(), z.unknown()).optional()
|
|
49156
|
+
});
|
|
49157
|
+
z.object({
|
|
49158
|
+
name: z.enum(["default", "plan", "iterate", "review"]),
|
|
49159
|
+
description: z.string(),
|
|
49160
|
+
allowedTools: z.array(z.string()).optional(),
|
|
49161
|
+
blockedTools: z.array(z.string()).optional(),
|
|
49162
|
+
systemInstructions: z.string(),
|
|
49163
|
+
allowNesting: z.boolean()
|
|
49164
|
+
});
|
|
49165
|
+
z.object({
|
|
49166
|
+
todos: z.array(TodoItemSchema),
|
|
49167
|
+
currentTask: z.string().optional(),
|
|
49168
|
+
agentName: z.string().optional(),
|
|
49169
|
+
turnCount: z.number().int().nonnegative(),
|
|
49170
|
+
workflowMode: z.enum(["default", "plan", "iterate", "review"]),
|
|
49171
|
+
sessionId: z.string().optional(),
|
|
49172
|
+
parentAgent: z.string().optional(),
|
|
49173
|
+
memories: z.array(z.object({
|
|
49174
|
+
content: z.string(),
|
|
49175
|
+
relevance: z.number().min(0).max(1),
|
|
49176
|
+
agent: z.string().optional(),
|
|
49177
|
+
timestamp: z.number()
|
|
49178
|
+
})).optional()
|
|
49179
|
+
});
|
|
49180
|
+
var DEFAULT_TOKEN_BUDGET = {
|
|
49181
|
+
maxTotal: 2e3,
|
|
49182
|
+
perType: {
|
|
49183
|
+
task: 500,
|
|
49184
|
+
memory: 600,
|
|
49185
|
+
session: 300,
|
|
49186
|
+
delegation: 200,
|
|
49187
|
+
mode: 400
|
|
49188
|
+
},
|
|
49189
|
+
criticalReserve: 300
|
|
49190
|
+
};
|
|
49191
|
+
var TokenBudgetConfigSchema = z.object({
|
|
49192
|
+
maxTotal: z.number().int().positive().max(1e4),
|
|
49193
|
+
perType: z.record(
|
|
49194
|
+
z.enum(["task", "memory", "session", "delegation", "mode"]),
|
|
49195
|
+
z.number().int().nonnegative()
|
|
49196
|
+
),
|
|
49197
|
+
criticalReserve: z.number().int().nonnegative()
|
|
49198
|
+
});
|
|
49199
|
+
var DEFAULT_ORCHESTRATION_CONFIG = {
|
|
49200
|
+
enabled: true,
|
|
49201
|
+
tokenBudget: DEFAULT_TOKEN_BUDGET,
|
|
49202
|
+
todoIntegration: {
|
|
49203
|
+
enabled: true,
|
|
49204
|
+
reminderFrequency: 3,
|
|
49205
|
+
compactMode: false
|
|
49206
|
+
},
|
|
49207
|
+
memoryIntegration: {
|
|
49208
|
+
enabled: true,
|
|
49209
|
+
maxEntries: 5,
|
|
49210
|
+
minRelevance: 0.5
|
|
49211
|
+
},
|
|
49212
|
+
sessionIntegration: {
|
|
49213
|
+
enabled: true,
|
|
49214
|
+
showCollaboration: true
|
|
49215
|
+
},
|
|
49216
|
+
agentTemplates: {
|
|
49217
|
+
enabled: true,
|
|
49218
|
+
reminderFrequency: 5
|
|
49219
|
+
}
|
|
49220
|
+
};
|
|
49221
|
+
z.object({
|
|
49222
|
+
enabled: z.boolean(),
|
|
49223
|
+
tokenBudget: TokenBudgetConfigSchema,
|
|
49224
|
+
todoIntegration: z.object({
|
|
49225
|
+
enabled: z.boolean(),
|
|
49226
|
+
reminderFrequency: z.number().int().positive(),
|
|
49227
|
+
compactMode: z.boolean()
|
|
49228
|
+
}),
|
|
49229
|
+
memoryIntegration: z.object({
|
|
49230
|
+
enabled: z.boolean(),
|
|
49231
|
+
maxEntries: z.number().int().nonnegative(),
|
|
49232
|
+
minRelevance: z.number().min(0).max(1)
|
|
49233
|
+
}),
|
|
49234
|
+
sessionIntegration: z.object({
|
|
49235
|
+
enabled: z.boolean(),
|
|
49236
|
+
showCollaboration: z.boolean()
|
|
49237
|
+
}),
|
|
49238
|
+
agentTemplates: z.object({
|
|
49239
|
+
enabled: z.boolean(),
|
|
49240
|
+
reminderFrequency: z.number().int().positive()
|
|
49241
|
+
})
|
|
49242
|
+
});
|
|
49243
|
+
|
|
49244
|
+
// src/core/orchestration/instruction-injector.ts
|
|
49245
|
+
init_esm_shims();
|
|
49246
|
+
init_logger();
|
|
49247
|
+
|
|
49248
|
+
// src/core/orchestration/token-budget.ts
|
|
49249
|
+
init_esm_shims();
|
|
49250
|
+
init_logger();
|
|
49251
|
+
var TokenBudgetManager = class _TokenBudgetManager {
|
|
49252
|
+
config;
|
|
49253
|
+
/** Characters per token estimate (conservative) */
|
|
49254
|
+
static CHARS_PER_TOKEN = 4;
|
|
49255
|
+
constructor(config) {
|
|
49256
|
+
this.config = {
|
|
49257
|
+
...DEFAULT_TOKEN_BUDGET,
|
|
49258
|
+
...config,
|
|
49259
|
+
perType: {
|
|
49260
|
+
...DEFAULT_TOKEN_BUDGET.perType,
|
|
49261
|
+
...config?.perType
|
|
49262
|
+
}
|
|
49263
|
+
};
|
|
49264
|
+
logger.debug("TokenBudgetManager initialized", {
|
|
49265
|
+
maxTotal: this.config.maxTotal,
|
|
49266
|
+
criticalReserve: this.config.criticalReserve
|
|
49267
|
+
});
|
|
49268
|
+
}
|
|
49269
|
+
/**
|
|
49270
|
+
* Estimate tokens for a string
|
|
49271
|
+
*/
|
|
49272
|
+
estimateTokens(content) {
|
|
49273
|
+
const characters = content.length;
|
|
49274
|
+
const tokens = Math.ceil(characters / _TokenBudgetManager.CHARS_PER_TOKEN);
|
|
49275
|
+
return {
|
|
49276
|
+
tokens,
|
|
49277
|
+
characters,
|
|
49278
|
+
isEstimate: true
|
|
49279
|
+
};
|
|
49280
|
+
}
|
|
49281
|
+
/**
|
|
49282
|
+
* Estimate tokens for an instruction (including formatting overhead)
|
|
49283
|
+
*/
|
|
49284
|
+
estimateInstructionTokens(instruction) {
|
|
49285
|
+
const overhead = 50;
|
|
49286
|
+
const contentTokens = this.estimateTokens(instruction.content).tokens;
|
|
49287
|
+
return contentTokens + overhead;
|
|
49288
|
+
}
|
|
49289
|
+
/**
|
|
49290
|
+
* Allocate budget for instructions
|
|
49291
|
+
*
|
|
49292
|
+
* Priority order:
|
|
49293
|
+
* 1. Critical instructions (always included, use reserve)
|
|
49294
|
+
* 2. High priority (included if budget allows)
|
|
49295
|
+
* 3. Normal priority (included if budget allows)
|
|
49296
|
+
* 4. Low priority (only if significant budget remains)
|
|
49297
|
+
*/
|
|
49298
|
+
allocateBudget(instructions) {
|
|
49299
|
+
const included = [];
|
|
49300
|
+
const excluded = [];
|
|
49301
|
+
const perTypeUsage = {
|
|
49302
|
+
task: 0,
|
|
49303
|
+
memory: 0,
|
|
49304
|
+
session: 0,
|
|
49305
|
+
delegation: 0,
|
|
49306
|
+
mode: 0
|
|
49307
|
+
};
|
|
49308
|
+
let tokensUsed = 0;
|
|
49309
|
+
const availableBudget = this.config.maxTotal;
|
|
49310
|
+
const priorityOrder = {
|
|
49311
|
+
critical: 0,
|
|
49312
|
+
high: 1,
|
|
49313
|
+
normal: 2,
|
|
49314
|
+
low: 3
|
|
49315
|
+
};
|
|
49316
|
+
const sorted = [...instructions].sort((a, b) => {
|
|
49317
|
+
const aPriority = priorityOrder[a.priority] ?? 2;
|
|
49318
|
+
const bPriority = priorityOrder[b.priority] ?? 2;
|
|
49319
|
+
const priorityDiff = aPriority - bPriority;
|
|
49320
|
+
if (priorityDiff !== 0) return priorityDiff;
|
|
49321
|
+
return a.createdAt - b.createdAt;
|
|
49322
|
+
});
|
|
49323
|
+
for (const instruction of sorted) {
|
|
49324
|
+
const instructionTokens = this.estimateInstructionTokens(instruction);
|
|
49325
|
+
const typeLimit = this.config.perType[instruction.type] || 0;
|
|
49326
|
+
const currentTypeUsage = perTypeUsage[instruction.type] || 0;
|
|
49327
|
+
const wouldExceedTotal = tokensUsed + instructionTokens > availableBudget;
|
|
49328
|
+
const wouldExceedTypeLimit = currentTypeUsage + instructionTokens > typeLimit;
|
|
49329
|
+
if (instruction.priority === "critical") {
|
|
49330
|
+
const criticalBudget = availableBudget + this.config.criticalReserve;
|
|
49331
|
+
if (tokensUsed + instructionTokens <= criticalBudget) {
|
|
49332
|
+
included.push(instruction);
|
|
49333
|
+
tokensUsed += instructionTokens;
|
|
49334
|
+
perTypeUsage[instruction.type] = currentTypeUsage + instructionTokens;
|
|
49335
|
+
continue;
|
|
49336
|
+
}
|
|
49337
|
+
}
|
|
49338
|
+
if (!wouldExceedTotal && !wouldExceedTypeLimit) {
|
|
49339
|
+
included.push(instruction);
|
|
49340
|
+
tokensUsed += instructionTokens;
|
|
49341
|
+
perTypeUsage[instruction.type] = currentTypeUsage + instructionTokens;
|
|
49342
|
+
} else {
|
|
49343
|
+
excluded.push(instruction);
|
|
49344
|
+
logger.debug("Instruction excluded from budget", {
|
|
49345
|
+
type: instruction.type,
|
|
49346
|
+
priority: instruction.priority,
|
|
49347
|
+
tokens: instructionTokens,
|
|
49348
|
+
reason: wouldExceedTotal ? "total_limit" : "type_limit"
|
|
49349
|
+
});
|
|
49350
|
+
}
|
|
49351
|
+
}
|
|
49352
|
+
const result = {
|
|
49353
|
+
included,
|
|
49354
|
+
excluded,
|
|
49355
|
+
tokensUsed,
|
|
49356
|
+
remaining: availableBudget - tokensUsed,
|
|
49357
|
+
perTypeUsage
|
|
49358
|
+
};
|
|
49359
|
+
logger.debug("Budget allocation complete", {
|
|
49360
|
+
included: included.length,
|
|
49361
|
+
excluded: excluded.length,
|
|
49362
|
+
tokensUsed,
|
|
49363
|
+
remaining: result.remaining
|
|
49364
|
+
});
|
|
49365
|
+
return result;
|
|
49366
|
+
}
|
|
49367
|
+
/**
|
|
49368
|
+
* Check if an instruction fits within budget
|
|
49369
|
+
*/
|
|
49370
|
+
fitsInBudget(instruction, currentUsage, typeUsage) {
|
|
49371
|
+
const instructionTokens = this.estimateInstructionTokens(instruction);
|
|
49372
|
+
const typeLimit = this.config.perType[instruction.type] || 0;
|
|
49373
|
+
const currentTypeUsage = typeUsage[instruction.type] || 0;
|
|
49374
|
+
if (instruction.priority === "critical") {
|
|
49375
|
+
return currentUsage + instructionTokens <= this.config.maxTotal + this.config.criticalReserve;
|
|
49376
|
+
}
|
|
49377
|
+
return currentUsage + instructionTokens <= this.config.maxTotal && currentTypeUsage + instructionTokens <= typeLimit;
|
|
49378
|
+
}
|
|
49379
|
+
/**
|
|
49380
|
+
* Get current configuration
|
|
49381
|
+
*/
|
|
49382
|
+
getConfig() {
|
|
49383
|
+
return { ...this.config };
|
|
49384
|
+
}
|
|
49385
|
+
/**
|
|
49386
|
+
* Update configuration
|
|
49387
|
+
*/
|
|
49388
|
+
updateConfig(updates) {
|
|
49389
|
+
this.config = {
|
|
49390
|
+
...this.config,
|
|
49391
|
+
...updates,
|
|
49392
|
+
perType: {
|
|
49393
|
+
...this.config.perType,
|
|
49394
|
+
...updates.perType
|
|
49395
|
+
}
|
|
49396
|
+
};
|
|
49397
|
+
logger.debug("TokenBudgetManager config updated", {
|
|
49398
|
+
maxTotal: this.config.maxTotal
|
|
49399
|
+
});
|
|
49400
|
+
}
|
|
49401
|
+
/**
|
|
49402
|
+
* Get remaining budget for a specific type
|
|
49403
|
+
*/
|
|
49404
|
+
getRemainingTypeBudget(type, currentTypeUsage) {
|
|
49405
|
+
const limit = this.config.perType[type] || 0;
|
|
49406
|
+
const used = currentTypeUsage[type] || 0;
|
|
49407
|
+
return Math.max(0, limit - used);
|
|
49408
|
+
}
|
|
49409
|
+
/**
|
|
49410
|
+
* Format budget status for debugging
|
|
49411
|
+
*/
|
|
49412
|
+
formatBudgetStatus(allocation) {
|
|
49413
|
+
const lines = [
|
|
49414
|
+
`Token Budget Status:`,
|
|
49415
|
+
` Total: ${allocation.tokensUsed}/${this.config.maxTotal} (${allocation.remaining} remaining)`,
|
|
49416
|
+
` Per-Type Usage:`
|
|
49417
|
+
];
|
|
49418
|
+
for (const [type, used] of Object.entries(allocation.perTypeUsage)) {
|
|
49419
|
+
const limit = this.config.perType[type] || 0;
|
|
49420
|
+
lines.push(` ${type}: ${used}/${limit}`);
|
|
49421
|
+
}
|
|
49422
|
+
if (allocation.excluded.length > 0) {
|
|
49423
|
+
lines.push(` Excluded: ${allocation.excluded.length} instruction(s)`);
|
|
49424
|
+
}
|
|
49425
|
+
return lines.join("\n");
|
|
49426
|
+
}
|
|
49427
|
+
};
|
|
49428
|
+
|
|
49429
|
+
// src/core/orchestration/instruction-injector.ts
|
|
49430
|
+
var OrchestrationInstructionInjector = class {
|
|
49431
|
+
providers = /* @__PURE__ */ new Map();
|
|
49432
|
+
budgetManager;
|
|
49433
|
+
config;
|
|
49434
|
+
lastInjectionTime = 0;
|
|
49435
|
+
instructionCache = /* @__PURE__ */ new Map();
|
|
49436
|
+
constructor(config) {
|
|
49437
|
+
this.config = {
|
|
49438
|
+
...DEFAULT_ORCHESTRATION_CONFIG,
|
|
49439
|
+
...config
|
|
49440
|
+
};
|
|
49441
|
+
this.budgetManager = new TokenBudgetManager(this.config.tokenBudget);
|
|
49442
|
+
logger.debug("OrchestrationInstructionInjector initialized", {
|
|
49443
|
+
enabled: this.config.enabled,
|
|
49444
|
+
providers: this.providers.size
|
|
49445
|
+
});
|
|
49446
|
+
}
|
|
49447
|
+
/**
|
|
49448
|
+
* Register an instruction provider
|
|
49449
|
+
*/
|
|
49450
|
+
registerProvider(provider) {
|
|
49451
|
+
if (this.providers.has(provider.name)) {
|
|
49452
|
+
logger.warn("Provider already registered, replacing", {
|
|
49453
|
+
name: provider.name
|
|
49454
|
+
});
|
|
49455
|
+
}
|
|
49456
|
+
this.providers.set(provider.name, provider);
|
|
49457
|
+
logger.debug("Instruction provider registered", {
|
|
49458
|
+
name: provider.name,
|
|
49459
|
+
totalProviders: this.providers.size
|
|
49460
|
+
});
|
|
49461
|
+
}
|
|
49462
|
+
/**
|
|
49463
|
+
* Unregister an instruction provider
|
|
49464
|
+
*/
|
|
49465
|
+
unregisterProvider(name) {
|
|
49466
|
+
const removed = this.providers.delete(name);
|
|
49467
|
+
if (removed) {
|
|
49468
|
+
logger.debug("Instruction provider unregistered", { name });
|
|
49469
|
+
}
|
|
49470
|
+
return removed;
|
|
49471
|
+
}
|
|
49472
|
+
/**
|
|
49473
|
+
* Get all registered providers
|
|
49474
|
+
*/
|
|
49475
|
+
getProviders() {
|
|
49476
|
+
return Array.from(this.providers.values());
|
|
49477
|
+
}
|
|
49478
|
+
/**
|
|
49479
|
+
* Generate and inject instructions based on context
|
|
49480
|
+
*/
|
|
49481
|
+
async inject(context, options = {}) {
|
|
49482
|
+
if (!this.config.enabled) {
|
|
49483
|
+
return this.emptyResult();
|
|
49484
|
+
}
|
|
49485
|
+
const startTime = Date.now();
|
|
49486
|
+
const allInstructions = [];
|
|
49487
|
+
for (const provider of this.providers.values()) {
|
|
49488
|
+
try {
|
|
49489
|
+
if (!provider.shouldGenerate(context)) {
|
|
49490
|
+
continue;
|
|
49491
|
+
}
|
|
49492
|
+
const instructions = await provider.getInstructions(context);
|
|
49493
|
+
let filtered = instructions;
|
|
49494
|
+
if (options.includeTypes) {
|
|
49495
|
+
filtered = filtered.filter((i) => options.includeTypes.includes(i.type));
|
|
49496
|
+
}
|
|
49497
|
+
if (options.excludeTypes) {
|
|
49498
|
+
filtered = filtered.filter((i) => !options.excludeTypes.includes(i.type));
|
|
49499
|
+
}
|
|
49500
|
+
allInstructions.push(...filtered);
|
|
49501
|
+
} catch (error) {
|
|
49502
|
+
logger.error("Provider failed to generate instructions", {
|
|
49503
|
+
provider: provider.name,
|
|
49504
|
+
error: error instanceof Error ? error.message : String(error)
|
|
49505
|
+
});
|
|
49506
|
+
}
|
|
49507
|
+
}
|
|
49508
|
+
const activeInstructions = this.filterExpiredInstructions(
|
|
49509
|
+
allInstructions,
|
|
49510
|
+
context.turnCount
|
|
49511
|
+
);
|
|
49512
|
+
let allocation;
|
|
49513
|
+
if (options.skipBudget) {
|
|
49514
|
+
allocation = {
|
|
49515
|
+
included: activeInstructions,
|
|
49516
|
+
excluded: [],
|
|
49517
|
+
tokensUsed: activeInstructions.reduce(
|
|
49518
|
+
(sum, i) => sum + this.budgetManager.estimateInstructionTokens(i),
|
|
49519
|
+
0
|
|
49520
|
+
),
|
|
49521
|
+
remaining: 0,
|
|
49522
|
+
perTypeUsage: this.calculateTypeUsage(activeInstructions)
|
|
49523
|
+
};
|
|
49524
|
+
} else {
|
|
49525
|
+
allocation = this.budgetManager.allocateBudget(activeInstructions);
|
|
49526
|
+
}
|
|
49527
|
+
const formattedText = this.formatInstructions(allocation.included);
|
|
49528
|
+
this.lastInjectionTime = Date.now();
|
|
49529
|
+
const duration = Date.now() - startTime;
|
|
49530
|
+
logger.debug("Instruction injection complete", {
|
|
49531
|
+
providers: this.providers.size,
|
|
49532
|
+
instructionsGenerated: allInstructions.length,
|
|
49533
|
+
instructionsIncluded: allocation.included.length,
|
|
49534
|
+
tokensUsed: allocation.tokensUsed,
|
|
49535
|
+
durationMs: duration
|
|
49536
|
+
});
|
|
49537
|
+
return {
|
|
49538
|
+
formattedText,
|
|
49539
|
+
instructions: allocation.included,
|
|
49540
|
+
allocation,
|
|
49541
|
+
hasInstructions: allocation.included.length > 0
|
|
49542
|
+
};
|
|
49543
|
+
}
|
|
49544
|
+
/**
|
|
49545
|
+
* Format instructions as system reminder tags
|
|
49546
|
+
*/
|
|
49547
|
+
formatInstructions(instructions) {
|
|
49548
|
+
if (instructions.length === 0) {
|
|
49549
|
+
return "";
|
|
49550
|
+
}
|
|
49551
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
49552
|
+
for (const instruction of instructions) {
|
|
49553
|
+
const existing = grouped.get(instruction.type) || [];
|
|
49554
|
+
existing.push(instruction);
|
|
49555
|
+
grouped.set(instruction.type, existing);
|
|
49556
|
+
}
|
|
49557
|
+
const parts = [];
|
|
49558
|
+
const typeOrder = ["mode", "task", "memory", "session", "delegation"];
|
|
49559
|
+
for (const type of typeOrder) {
|
|
49560
|
+
const typeInstructions = grouped.get(type);
|
|
49561
|
+
if (!typeInstructions || typeInstructions.length === 0) continue;
|
|
49562
|
+
for (const instruction of typeInstructions) {
|
|
49563
|
+
parts.push(this.formatSingleInstruction(instruction));
|
|
49564
|
+
}
|
|
49565
|
+
}
|
|
49566
|
+
return parts.join("\n");
|
|
49567
|
+
}
|
|
49568
|
+
/**
|
|
49569
|
+
* Format a single instruction as a system reminder
|
|
49570
|
+
*/
|
|
49571
|
+
formatSingleInstruction(instruction) {
|
|
49572
|
+
return `<system-reminder>
|
|
49573
|
+
${instruction.content}
|
|
49574
|
+
</system-reminder>`;
|
|
49575
|
+
}
|
|
49576
|
+
/**
|
|
49577
|
+
* Filter out expired instructions
|
|
49578
|
+
*/
|
|
49579
|
+
filterExpiredInstructions(instructions, currentTurn) {
|
|
49580
|
+
return instructions.filter((instruction) => {
|
|
49581
|
+
if (instruction.expiresAfter === void 0) {
|
|
49582
|
+
return true;
|
|
49583
|
+
}
|
|
49584
|
+
const turnsSinceCreation = currentTurn;
|
|
49585
|
+
return turnsSinceCreation < instruction.expiresAfter;
|
|
49586
|
+
});
|
|
49587
|
+
}
|
|
49588
|
+
/**
|
|
49589
|
+
* Calculate per-type token usage
|
|
49590
|
+
*/
|
|
49591
|
+
calculateTypeUsage(instructions) {
|
|
49592
|
+
const usage = {
|
|
49593
|
+
task: 0,
|
|
49594
|
+
memory: 0,
|
|
49595
|
+
session: 0,
|
|
49596
|
+
delegation: 0,
|
|
49597
|
+
mode: 0
|
|
49598
|
+
};
|
|
49599
|
+
for (const instruction of instructions) {
|
|
49600
|
+
const tokens = this.budgetManager.estimateInstructionTokens(instruction);
|
|
49601
|
+
usage[instruction.type] = (usage[instruction.type] || 0) + tokens;
|
|
49602
|
+
}
|
|
49603
|
+
return usage;
|
|
49604
|
+
}
|
|
49605
|
+
/**
|
|
49606
|
+
* Create an empty result
|
|
49607
|
+
*/
|
|
49608
|
+
emptyResult() {
|
|
49609
|
+
return {
|
|
49610
|
+
formattedText: "",
|
|
49611
|
+
instructions: [],
|
|
49612
|
+
allocation: {
|
|
49613
|
+
included: [],
|
|
49614
|
+
excluded: [],
|
|
49615
|
+
tokensUsed: 0,
|
|
49616
|
+
remaining: this.budgetManager.getConfig().maxTotal,
|
|
49617
|
+
perTypeUsage: {
|
|
49618
|
+
task: 0,
|
|
49619
|
+
memory: 0,
|
|
49620
|
+
session: 0,
|
|
49621
|
+
delegation: 0,
|
|
49622
|
+
mode: 0
|
|
49623
|
+
}
|
|
49624
|
+
},
|
|
49625
|
+
hasInstructions: false
|
|
49626
|
+
};
|
|
49627
|
+
}
|
|
49628
|
+
/**
|
|
49629
|
+
* Clear instruction cache
|
|
49630
|
+
*/
|
|
49631
|
+
clearCache() {
|
|
49632
|
+
this.instructionCache.clear();
|
|
49633
|
+
logger.debug("Instruction cache cleared");
|
|
49634
|
+
}
|
|
49635
|
+
/**
|
|
49636
|
+
* Get current configuration
|
|
49637
|
+
*/
|
|
49638
|
+
getConfig() {
|
|
49639
|
+
return { ...this.config };
|
|
49640
|
+
}
|
|
49641
|
+
/**
|
|
49642
|
+
* Update configuration
|
|
49643
|
+
*/
|
|
49644
|
+
updateConfig(updates) {
|
|
49645
|
+
this.config = {
|
|
49646
|
+
...this.config,
|
|
49647
|
+
...updates
|
|
49648
|
+
};
|
|
49649
|
+
if (updates.tokenBudget) {
|
|
49650
|
+
this.budgetManager.updateConfig(updates.tokenBudget);
|
|
49651
|
+
}
|
|
49652
|
+
logger.debug("OrchestrationInstructionInjector config updated", {
|
|
49653
|
+
enabled: this.config.enabled
|
|
49654
|
+
});
|
|
49655
|
+
}
|
|
49656
|
+
/**
|
|
49657
|
+
* Get budget manager for direct access
|
|
49658
|
+
*/
|
|
49659
|
+
getBudgetManager() {
|
|
49660
|
+
return this.budgetManager;
|
|
49661
|
+
}
|
|
49662
|
+
/**
|
|
49663
|
+
* Check if orchestration is enabled
|
|
49664
|
+
*/
|
|
49665
|
+
isEnabled() {
|
|
49666
|
+
return this.config.enabled;
|
|
49667
|
+
}
|
|
49668
|
+
/**
|
|
49669
|
+
* Enable or disable orchestration
|
|
49670
|
+
*/
|
|
49671
|
+
setEnabled(enabled) {
|
|
49672
|
+
this.config.enabled = enabled;
|
|
49673
|
+
logger.debug("Orchestration enabled state changed", { enabled });
|
|
49674
|
+
}
|
|
49675
|
+
};
|
|
49676
|
+
|
|
49677
|
+
// src/core/orchestration/todo-instruction-provider.ts
|
|
49678
|
+
init_esm_shims();
|
|
49679
|
+
init_logger();
|
|
49680
|
+
var DEFAULT_TODO_CONFIG = {
|
|
49681
|
+
enabled: true,
|
|
49682
|
+
reminderFrequency: 3,
|
|
49683
|
+
compactMode: false,
|
|
49684
|
+
maxCompactItems: 5,
|
|
49685
|
+
showCompleted: false
|
|
49686
|
+
};
|
|
49687
|
+
var TodoInstructionProvider = class {
|
|
49688
|
+
name = "todo";
|
|
49689
|
+
config;
|
|
49690
|
+
lastStateHash = "";
|
|
49691
|
+
lastReminderTurn = 0;
|
|
49692
|
+
constructor(config) {
|
|
49693
|
+
this.config = {
|
|
49694
|
+
...DEFAULT_TODO_CONFIG,
|
|
49695
|
+
...config
|
|
49696
|
+
};
|
|
49697
|
+
logger.debug("TodoInstructionProvider initialized", {
|
|
49698
|
+
enabled: this.config.enabled,
|
|
49699
|
+
reminderFrequency: this.config.reminderFrequency
|
|
49700
|
+
});
|
|
49701
|
+
}
|
|
49702
|
+
/**
|
|
49703
|
+
* Check if provider should generate instructions
|
|
49704
|
+
*/
|
|
49705
|
+
shouldGenerate(context) {
|
|
49706
|
+
if (!this.config.enabled) {
|
|
49707
|
+
return false;
|
|
49708
|
+
}
|
|
49709
|
+
if (!context.todos || context.todos.length === 0) {
|
|
49710
|
+
return false;
|
|
49711
|
+
}
|
|
49712
|
+
const currentHash = this.computeStateHash(context.todos);
|
|
49713
|
+
const stateChanged = currentHash !== this.lastStateHash;
|
|
49714
|
+
const turnsSinceReminder = context.turnCount - this.lastReminderTurn;
|
|
49715
|
+
const reminderDue = turnsSinceReminder >= this.config.reminderFrequency;
|
|
49716
|
+
return stateChanged || reminderDue;
|
|
49717
|
+
}
|
|
49718
|
+
/**
|
|
49719
|
+
* Generate instructions based on todo state
|
|
49720
|
+
*/
|
|
49721
|
+
async getInstructions(context) {
|
|
49722
|
+
const instructions = [];
|
|
49723
|
+
if (!context.todos || context.todos.length === 0) {
|
|
49724
|
+
return instructions;
|
|
49725
|
+
}
|
|
49726
|
+
const currentHash = this.computeStateHash(context.todos);
|
|
49727
|
+
const stateChanged = currentHash !== this.lastStateHash;
|
|
49728
|
+
const activeTodos = context.todos.filter(
|
|
49729
|
+
(todo) => todo.status !== "completed" || this.config.showCompleted
|
|
49730
|
+
);
|
|
49731
|
+
const inProgressTasks = activeTodos.filter((todo) => todo.status === "in_progress");
|
|
49732
|
+
const pendingTasks = activeTodos.filter((todo) => todo.status === "pending");
|
|
49733
|
+
const completedTasks = context.todos.filter((todo) => todo.status === "completed");
|
|
49734
|
+
let content;
|
|
49735
|
+
let priority;
|
|
49736
|
+
if (stateChanged) {
|
|
49737
|
+
content = this.formatFullTodoList(inProgressTasks, pendingTasks, completedTasks);
|
|
49738
|
+
priority = "high";
|
|
49739
|
+
} else if (this.config.compactMode) {
|
|
49740
|
+
content = this.formatCompactReminder(inProgressTasks, pendingTasks);
|
|
49741
|
+
priority = "normal";
|
|
49742
|
+
} else {
|
|
49743
|
+
content = this.formatStandardReminder(inProgressTasks, pendingTasks);
|
|
49744
|
+
priority = "normal";
|
|
49745
|
+
}
|
|
49746
|
+
instructions.push({
|
|
49747
|
+
type: "task",
|
|
49748
|
+
priority,
|
|
49749
|
+
content,
|
|
49750
|
+
source: "automatosx",
|
|
49751
|
+
createdAt: Date.now(),
|
|
49752
|
+
expiresAfter: this.config.reminderFrequency + 1,
|
|
49753
|
+
id: `todo-${currentHash.substring(0, 8)}`
|
|
49754
|
+
});
|
|
49755
|
+
this.lastStateHash = currentHash;
|
|
49756
|
+
this.lastReminderTurn = context.turnCount;
|
|
49757
|
+
logger.debug("Todo instructions generated", {
|
|
49758
|
+
inProgress: inProgressTasks.length,
|
|
49759
|
+
pending: pendingTasks.length,
|
|
49760
|
+
completed: completedTasks.length,
|
|
49761
|
+
stateChanged
|
|
49762
|
+
});
|
|
49763
|
+
return instructions;
|
|
49764
|
+
}
|
|
49765
|
+
/**
|
|
49766
|
+
* Format full todo list (used when state changes)
|
|
49767
|
+
*/
|
|
49768
|
+
formatFullTodoList(inProgress, pending, completed) {
|
|
49769
|
+
const lines = [
|
|
49770
|
+
"## Current Task List"
|
|
49771
|
+
];
|
|
49772
|
+
if (inProgress.length > 0) {
|
|
49773
|
+
lines.push("");
|
|
49774
|
+
lines.push("### Currently Working On:");
|
|
49775
|
+
for (const task of inProgress) {
|
|
49776
|
+
lines.push(`- **${task.activeForm}**`);
|
|
49777
|
+
}
|
|
49778
|
+
}
|
|
49779
|
+
if (pending.length > 0) {
|
|
49780
|
+
lines.push("");
|
|
49781
|
+
lines.push("### Pending Tasks:");
|
|
49782
|
+
for (const task of pending) {
|
|
49783
|
+
lines.push(`- [ ] ${task.content}`);
|
|
49784
|
+
}
|
|
49785
|
+
}
|
|
49786
|
+
if (this.config.showCompleted && completed.length > 0) {
|
|
49787
|
+
lines.push("");
|
|
49788
|
+
lines.push("### Completed:");
|
|
49789
|
+
for (const task of completed.slice(-3)) {
|
|
49790
|
+
lines.push(`- [x] ${task.content}`);
|
|
49791
|
+
}
|
|
49792
|
+
}
|
|
49793
|
+
lines.push("");
|
|
49794
|
+
lines.push("**Remember:** Complete the current in-progress task before starting new ones.");
|
|
49795
|
+
lines.push("Mark tasks as completed as soon as they are done.");
|
|
49796
|
+
return lines.join("\n");
|
|
49797
|
+
}
|
|
49798
|
+
/**
|
|
49799
|
+
* Format standard reminder
|
|
49800
|
+
*/
|
|
49801
|
+
formatStandardReminder(inProgress, pending) {
|
|
49802
|
+
const lines = [];
|
|
49803
|
+
if (inProgress.length > 0) {
|
|
49804
|
+
lines.push(`**Current Task:** ${inProgress[0].activeForm}`);
|
|
49805
|
+
}
|
|
49806
|
+
if (pending.length > 0) {
|
|
49807
|
+
lines.push(`**Next:** ${pending[0].content}`);
|
|
49808
|
+
if (pending.length > 1) {
|
|
49809
|
+
lines.push(`(${pending.length - 1} more tasks pending)`);
|
|
49810
|
+
}
|
|
49811
|
+
}
|
|
49812
|
+
return lines.join("\n");
|
|
49813
|
+
}
|
|
49814
|
+
/**
|
|
49815
|
+
* Format compact reminder (minimal tokens)
|
|
49816
|
+
*/
|
|
49817
|
+
formatCompactReminder(inProgress, pending) {
|
|
49818
|
+
const parts = [];
|
|
49819
|
+
if (inProgress.length > 0) {
|
|
49820
|
+
parts.push(`Doing: ${inProgress[0].activeForm}`);
|
|
49821
|
+
}
|
|
49822
|
+
if (pending.length > 0) {
|
|
49823
|
+
const count = Math.min(pending.length, this.config.maxCompactItems);
|
|
49824
|
+
parts.push(`Next: ${pending.slice(0, count).map((t) => t.content).join(", ")}`);
|
|
49825
|
+
}
|
|
49826
|
+
return parts.join(" | ");
|
|
49827
|
+
}
|
|
49828
|
+
/**
|
|
49829
|
+
* Compute hash of todo state for change detection
|
|
49830
|
+
*/
|
|
49831
|
+
computeStateHash(todos) {
|
|
49832
|
+
const stateString = todos.map((t) => `${t.id}:${t.status}:${t.content}`).sort().join("|");
|
|
49833
|
+
return crypto2.createHash("sha256").update(stateString).digest("hex").substring(0, 16);
|
|
49834
|
+
}
|
|
49835
|
+
/**
|
|
49836
|
+
* Get current configuration
|
|
49837
|
+
*/
|
|
49838
|
+
getConfig() {
|
|
49839
|
+
return { ...this.config };
|
|
49840
|
+
}
|
|
49841
|
+
/**
|
|
49842
|
+
* Update configuration
|
|
49843
|
+
*/
|
|
49844
|
+
updateConfig(updates) {
|
|
49845
|
+
this.config = {
|
|
49846
|
+
...this.config,
|
|
49847
|
+
...updates
|
|
49848
|
+
};
|
|
49849
|
+
logger.debug("TodoInstructionProvider config updated", {
|
|
49850
|
+
enabled: this.config.enabled,
|
|
49851
|
+
compactMode: this.config.compactMode
|
|
49852
|
+
});
|
|
49853
|
+
}
|
|
49854
|
+
/**
|
|
49855
|
+
* Reset state tracking (useful for testing)
|
|
49856
|
+
*/
|
|
49857
|
+
reset() {
|
|
49858
|
+
this.lastStateHash = "";
|
|
49859
|
+
this.lastReminderTurn = 0;
|
|
49860
|
+
logger.debug("TodoInstructionProvider state reset");
|
|
49861
|
+
}
|
|
49862
|
+
};
|
|
49863
|
+
|
|
49864
|
+
// src/core/orchestration/memory-instruction-provider.ts
|
|
49865
|
+
init_esm_shims();
|
|
49866
|
+
init_logger();
|
|
49867
|
+
var DEFAULT_MEMORY_CONFIG = {
|
|
49868
|
+
enabled: true,
|
|
49869
|
+
maxEntries: 5,
|
|
49870
|
+
minRelevance: 0.5,
|
|
49871
|
+
searchFrequency: 3,
|
|
49872
|
+
maxAge: 0,
|
|
49873
|
+
// No limit by default
|
|
49874
|
+
includeMetadata: true,
|
|
49875
|
+
cacheTTL: 6e4
|
|
49876
|
+
// 1 minute
|
|
49877
|
+
};
|
|
49878
|
+
var MemoryInstructionProvider = class {
|
|
49879
|
+
name = "memory";
|
|
49880
|
+
config;
|
|
49881
|
+
searchProvider;
|
|
49882
|
+
cache;
|
|
49883
|
+
lastSearchTurn = 0;
|
|
49884
|
+
constructor(searchProvider, config) {
|
|
49885
|
+
this.config = {
|
|
49886
|
+
...DEFAULT_MEMORY_CONFIG,
|
|
49887
|
+
...config
|
|
49888
|
+
};
|
|
49889
|
+
this.searchProvider = searchProvider;
|
|
49890
|
+
logger.debug("MemoryInstructionProvider initialized", {
|
|
49891
|
+
enabled: this.config.enabled,
|
|
49892
|
+
maxEntries: this.config.maxEntries,
|
|
49893
|
+
hasSearchProvider: !!searchProvider
|
|
49894
|
+
});
|
|
49895
|
+
}
|
|
49896
|
+
/**
|
|
49897
|
+
* Set the memory search provider
|
|
49898
|
+
*/
|
|
49899
|
+
setSearchProvider(provider) {
|
|
49900
|
+
this.searchProvider = provider;
|
|
49901
|
+
this.clearCache();
|
|
49902
|
+
logger.debug("Memory search provider set");
|
|
49903
|
+
}
|
|
49904
|
+
/**
|
|
49905
|
+
* Check if provider should generate instructions
|
|
49906
|
+
*/
|
|
49907
|
+
shouldGenerate(context) {
|
|
49908
|
+
if (!this.config.enabled) {
|
|
49909
|
+
return false;
|
|
49910
|
+
}
|
|
49911
|
+
if (!this.searchProvider) {
|
|
49912
|
+
return false;
|
|
49913
|
+
}
|
|
49914
|
+
if (!context.currentTask && context.todos.length === 0) {
|
|
49915
|
+
return false;
|
|
49916
|
+
}
|
|
49917
|
+
const turnsSinceSearch = context.turnCount - this.lastSearchTurn;
|
|
49918
|
+
const searchDue = turnsSinceSearch >= this.config.searchFrequency;
|
|
49919
|
+
const cacheValid = this.cache && Date.now() - this.cache.timestamp < this.config.cacheTTL;
|
|
49920
|
+
return searchDue || !cacheValid;
|
|
49921
|
+
}
|
|
49922
|
+
/**
|
|
49923
|
+
* Generate instructions based on relevant memories
|
|
49924
|
+
*/
|
|
49925
|
+
async getInstructions(context) {
|
|
49926
|
+
const instructions = [];
|
|
49927
|
+
if (!this.searchProvider) {
|
|
49928
|
+
return instructions;
|
|
49929
|
+
}
|
|
49930
|
+
const searchQuery = this.buildSearchQuery(context);
|
|
49931
|
+
if (!searchQuery) {
|
|
49932
|
+
return instructions;
|
|
49933
|
+
}
|
|
49934
|
+
try {
|
|
49935
|
+
const memories = await this.searchMemories(searchQuery, context);
|
|
49936
|
+
if (memories.length === 0) {
|
|
49937
|
+
return instructions;
|
|
49938
|
+
}
|
|
49939
|
+
this.lastSearchTurn = context.turnCount;
|
|
49940
|
+
const content = this.formatMemories(memories);
|
|
49941
|
+
instructions.push({
|
|
49942
|
+
type: "memory",
|
|
49943
|
+
priority: "normal",
|
|
49944
|
+
content,
|
|
49945
|
+
source: "automatosx",
|
|
49946
|
+
createdAt: Date.now(),
|
|
49947
|
+
expiresAfter: this.config.searchFrequency + 1,
|
|
49948
|
+
id: `memory-${Date.now()}`
|
|
49949
|
+
});
|
|
49950
|
+
logger.debug("Memory instructions generated", {
|
|
49951
|
+
memoriesFound: memories.length,
|
|
49952
|
+
query: searchQuery.substring(0, 50)
|
|
49953
|
+
});
|
|
49954
|
+
} catch (error) {
|
|
49955
|
+
logger.error("Failed to search memories", {
|
|
49956
|
+
error: error instanceof Error ? error.message : String(error)
|
|
49957
|
+
});
|
|
49958
|
+
}
|
|
49959
|
+
return instructions;
|
|
49960
|
+
}
|
|
49961
|
+
/**
|
|
49962
|
+
* Build search query from context
|
|
49963
|
+
*/
|
|
49964
|
+
buildSearchQuery(context) {
|
|
49965
|
+
const parts = [];
|
|
49966
|
+
if (context.currentTask) {
|
|
49967
|
+
parts.push(context.currentTask);
|
|
49968
|
+
}
|
|
49969
|
+
const inProgressTodos = context.todos.filter((t) => t.status === "in_progress");
|
|
49970
|
+
for (const todo of inProgressTodos.slice(0, 2)) {
|
|
49971
|
+
parts.push(todo.content);
|
|
49972
|
+
}
|
|
49973
|
+
if (context.agentName) {
|
|
49974
|
+
parts.push(context.agentName);
|
|
49975
|
+
}
|
|
49976
|
+
if (parts.length === 0) {
|
|
49977
|
+
return null;
|
|
49978
|
+
}
|
|
49979
|
+
return parts.join(" ");
|
|
49980
|
+
}
|
|
49981
|
+
/**
|
|
49982
|
+
* Search for relevant memories
|
|
49983
|
+
*/
|
|
49984
|
+
async searchMemories(query, context) {
|
|
49985
|
+
if (!this.searchProvider) {
|
|
49986
|
+
return [];
|
|
49987
|
+
}
|
|
49988
|
+
if (this.cache && this.cache.query === query) {
|
|
49989
|
+
const age = Date.now() - this.cache.timestamp;
|
|
49990
|
+
if (age < this.config.cacheTTL) {
|
|
49991
|
+
logger.debug("Using cached memory results", {
|
|
49992
|
+
cacheAge: age,
|
|
49993
|
+
resultCount: this.cache.results.length
|
|
49994
|
+
});
|
|
49995
|
+
return this.cache.results;
|
|
49996
|
+
}
|
|
49997
|
+
}
|
|
49998
|
+
const results = await this.searchProvider.search({
|
|
49999
|
+
text: query,
|
|
50000
|
+
limit: this.config.maxEntries * 2,
|
|
50001
|
+
// Get extra in case some are filtered
|
|
50002
|
+
filters: context.agentName ? { agentId: context.agentName } : void 0
|
|
50003
|
+
});
|
|
50004
|
+
const filtered = results.filter((r) => r.score >= this.config.minRelevance).filter((r) => this.isWithinMaxAge(r.createdAt)).slice(0, this.config.maxEntries);
|
|
50005
|
+
const memories = filtered.map((r) => ({
|
|
50006
|
+
content: r.content,
|
|
50007
|
+
relevance: r.score,
|
|
50008
|
+
agent: r.metadata?.agentId,
|
|
50009
|
+
timestamp: r.createdAt.getTime()
|
|
50010
|
+
}));
|
|
50011
|
+
this.cache = {
|
|
50012
|
+
query,
|
|
50013
|
+
results: memories,
|
|
50014
|
+
timestamp: Date.now()
|
|
50015
|
+
};
|
|
50016
|
+
return memories;
|
|
50017
|
+
}
|
|
50018
|
+
/**
|
|
50019
|
+
* Check if memory is within max age limit
|
|
50020
|
+
*/
|
|
50021
|
+
isWithinMaxAge(createdAt) {
|
|
50022
|
+
if (this.config.maxAge === 0) {
|
|
50023
|
+
return true;
|
|
50024
|
+
}
|
|
50025
|
+
const age = Date.now() - createdAt.getTime();
|
|
50026
|
+
return age <= this.config.maxAge;
|
|
50027
|
+
}
|
|
50028
|
+
/**
|
|
50029
|
+
* Format memories into instruction content
|
|
50030
|
+
*/
|
|
50031
|
+
formatMemories(memories) {
|
|
50032
|
+
const lines = [
|
|
50033
|
+
"## Relevant Context from Memory",
|
|
50034
|
+
""
|
|
50035
|
+
];
|
|
50036
|
+
for (let i = 0; i < memories.length; i++) {
|
|
50037
|
+
const memory = memories[i];
|
|
50038
|
+
if (!memory) continue;
|
|
50039
|
+
const relevancePercent = Math.round(memory.relevance * 100);
|
|
50040
|
+
if (this.config.includeMetadata && memory.agent) {
|
|
50041
|
+
lines.push(`### Memory ${i + 1} (${relevancePercent}% relevant, from ${memory.agent})`);
|
|
50042
|
+
} else {
|
|
50043
|
+
lines.push(`### Memory ${i + 1} (${relevancePercent}% relevant)`);
|
|
50044
|
+
}
|
|
50045
|
+
const maxLength = 500;
|
|
50046
|
+
const content = memory.content.length > maxLength ? memory.content.substring(0, maxLength) + "..." : memory.content;
|
|
50047
|
+
lines.push(content);
|
|
50048
|
+
lines.push("");
|
|
50049
|
+
}
|
|
50050
|
+
lines.push("**Note:** Use this context to inform your decisions, but verify current state.");
|
|
50051
|
+
return lines.join("\n");
|
|
50052
|
+
}
|
|
50053
|
+
/**
|
|
50054
|
+
* Clear the memory cache
|
|
50055
|
+
*/
|
|
50056
|
+
clearCache() {
|
|
50057
|
+
this.cache = void 0;
|
|
50058
|
+
logger.debug("Memory cache cleared");
|
|
50059
|
+
}
|
|
50060
|
+
/**
|
|
50061
|
+
* Get current configuration
|
|
50062
|
+
*/
|
|
50063
|
+
getConfig() {
|
|
50064
|
+
return { ...this.config };
|
|
50065
|
+
}
|
|
50066
|
+
/**
|
|
50067
|
+
* Update configuration
|
|
50068
|
+
*/
|
|
50069
|
+
updateConfig(updates) {
|
|
50070
|
+
this.config = {
|
|
50071
|
+
...this.config,
|
|
50072
|
+
...updates
|
|
50073
|
+
};
|
|
50074
|
+
if (updates.minRelevance !== void 0 || updates.maxEntries !== void 0) {
|
|
50075
|
+
this.clearCache();
|
|
50076
|
+
}
|
|
50077
|
+
logger.debug("MemoryInstructionProvider config updated", {
|
|
50078
|
+
enabled: this.config.enabled,
|
|
50079
|
+
maxEntries: this.config.maxEntries
|
|
50080
|
+
});
|
|
50081
|
+
}
|
|
50082
|
+
/**
|
|
50083
|
+
* Reset state
|
|
50084
|
+
*/
|
|
50085
|
+
reset() {
|
|
50086
|
+
this.cache = void 0;
|
|
50087
|
+
this.lastSearchTurn = 0;
|
|
50088
|
+
logger.debug("MemoryInstructionProvider reset");
|
|
50089
|
+
}
|
|
50090
|
+
/**
|
|
50091
|
+
* Check if search provider is configured
|
|
50092
|
+
*/
|
|
50093
|
+
hasSearchProvider() {
|
|
50094
|
+
return !!this.searchProvider;
|
|
50095
|
+
}
|
|
50096
|
+
};
|
|
50097
|
+
|
|
50098
|
+
// src/core/orchestration/session-instruction-provider.ts
|
|
50099
|
+
init_esm_shims();
|
|
50100
|
+
init_logger();
|
|
50101
|
+
var DEFAULT_SESSION_CONFIG = {
|
|
50102
|
+
enabled: true,
|
|
50103
|
+
showCollaboration: true,
|
|
50104
|
+
showProgress: true,
|
|
50105
|
+
reminderFrequency: 5,
|
|
50106
|
+
showHandoffContext: true
|
|
50107
|
+
};
|
|
50108
|
+
var SessionInstructionProvider = class {
|
|
50109
|
+
name = "session";
|
|
50110
|
+
config;
|
|
50111
|
+
stateProvider;
|
|
50112
|
+
lastReminderTurn = 0;
|
|
50113
|
+
cachedState;
|
|
50114
|
+
cacheExpiry = 0;
|
|
50115
|
+
CACHE_TTL = 3e4;
|
|
50116
|
+
// 30 seconds
|
|
50117
|
+
constructor(stateProvider, config) {
|
|
50118
|
+
this.config = {
|
|
50119
|
+
...DEFAULT_SESSION_CONFIG,
|
|
50120
|
+
...config
|
|
50121
|
+
};
|
|
50122
|
+
this.stateProvider = stateProvider;
|
|
50123
|
+
logger.debug("SessionInstructionProvider initialized", {
|
|
50124
|
+
enabled: this.config.enabled,
|
|
50125
|
+
hasStateProvider: !!stateProvider
|
|
50126
|
+
});
|
|
50127
|
+
}
|
|
50128
|
+
/**
|
|
50129
|
+
* Set the session state provider
|
|
50130
|
+
*/
|
|
50131
|
+
setStateProvider(provider) {
|
|
50132
|
+
this.stateProvider = provider;
|
|
50133
|
+
this.clearCache();
|
|
50134
|
+
logger.debug("Session state provider set");
|
|
50135
|
+
}
|
|
50136
|
+
/**
|
|
50137
|
+
* Check if provider should generate instructions
|
|
50138
|
+
*/
|
|
50139
|
+
shouldGenerate(context) {
|
|
50140
|
+
if (!this.config.enabled) {
|
|
50141
|
+
return false;
|
|
50142
|
+
}
|
|
50143
|
+
if (!context.sessionId && !this.stateProvider) {
|
|
50144
|
+
return false;
|
|
50145
|
+
}
|
|
50146
|
+
const turnsSinceReminder = context.turnCount - this.lastReminderTurn;
|
|
50147
|
+
return turnsSinceReminder >= this.config.reminderFrequency;
|
|
50148
|
+
}
|
|
50149
|
+
/**
|
|
50150
|
+
* Generate instructions based on session state
|
|
50151
|
+
*/
|
|
50152
|
+
async getInstructions(context) {
|
|
50153
|
+
const instructions = [];
|
|
50154
|
+
const state = await this.getSessionState(context);
|
|
50155
|
+
if (!state && !context.sessionId) {
|
|
50156
|
+
return instructions;
|
|
50157
|
+
}
|
|
50158
|
+
const content = this.formatSessionContext(context, state);
|
|
50159
|
+
if (content) {
|
|
50160
|
+
instructions.push({
|
|
50161
|
+
type: "session",
|
|
50162
|
+
priority: "normal",
|
|
50163
|
+
content,
|
|
50164
|
+
source: "automatosx",
|
|
50165
|
+
createdAt: Date.now(),
|
|
50166
|
+
expiresAfter: this.config.reminderFrequency,
|
|
50167
|
+
id: `session-${context.sessionId || "default"}-${Date.now()}`
|
|
50168
|
+
});
|
|
50169
|
+
}
|
|
50170
|
+
this.lastReminderTurn = context.turnCount;
|
|
50171
|
+
logger.debug("Session instructions generated", {
|
|
50172
|
+
sessionId: context.sessionId,
|
|
50173
|
+
hasState: !!state
|
|
50174
|
+
});
|
|
50175
|
+
return instructions;
|
|
50176
|
+
}
|
|
50177
|
+
/**
|
|
50178
|
+
* Get session state from provider or cache
|
|
50179
|
+
*/
|
|
50180
|
+
async getSessionState(context) {
|
|
50181
|
+
if (!context.sessionId) {
|
|
50182
|
+
return null;
|
|
50183
|
+
}
|
|
50184
|
+
if (this.cachedState && this.cachedState.id === context.sessionId && Date.now() < this.cacheExpiry) {
|
|
50185
|
+
return this.cachedState;
|
|
50186
|
+
}
|
|
50187
|
+
if (!this.stateProvider) {
|
|
50188
|
+
return null;
|
|
50189
|
+
}
|
|
50190
|
+
try {
|
|
50191
|
+
const state = await this.stateProvider.getSessionState(context.sessionId);
|
|
50192
|
+
if (state) {
|
|
50193
|
+
this.cachedState = state;
|
|
50194
|
+
this.cacheExpiry = Date.now() + this.CACHE_TTL;
|
|
50195
|
+
}
|
|
50196
|
+
return state;
|
|
50197
|
+
} catch (error) {
|
|
50198
|
+
logger.error("Failed to get session state", {
|
|
50199
|
+
sessionId: context.sessionId,
|
|
50200
|
+
error: error instanceof Error ? error.message : String(error)
|
|
50201
|
+
});
|
|
50202
|
+
return null;
|
|
50203
|
+
}
|
|
50204
|
+
}
|
|
50205
|
+
/**
|
|
50206
|
+
* Format session context into instruction content
|
|
50207
|
+
*/
|
|
50208
|
+
formatSessionContext(context, state) {
|
|
50209
|
+
const lines = [];
|
|
50210
|
+
if (context.sessionId) {
|
|
50211
|
+
lines.push("## Session Context");
|
|
50212
|
+
lines.push("");
|
|
50213
|
+
}
|
|
50214
|
+
if (this.config.showCollaboration && state && state.participants.length > 1) {
|
|
50215
|
+
lines.push("### Multi-Agent Collaboration");
|
|
50216
|
+
lines.push(`- **Session:** ${state.id.substring(0, 8)}...`);
|
|
50217
|
+
lines.push(`- **Participants:** ${state.participants.join(", ")}`);
|
|
50218
|
+
if (state.activeAgent) {
|
|
50219
|
+
lines.push(`- **Currently Active:** ${state.activeAgent}`);
|
|
50220
|
+
}
|
|
50221
|
+
lines.push("");
|
|
50222
|
+
}
|
|
50223
|
+
if (this.config.showProgress && state) {
|
|
50224
|
+
const totalTasks = state.completedTasks + state.remainingTasks;
|
|
50225
|
+
if (totalTasks > 0) {
|
|
50226
|
+
const progress = Math.round(state.completedTasks / totalTasks * 100);
|
|
50227
|
+
lines.push("### Session Progress");
|
|
50228
|
+
lines.push(`- Completed: ${state.completedTasks}/${totalTasks} (${progress}%)`);
|
|
50229
|
+
if (state.remainingTasks > 0) {
|
|
50230
|
+
lines.push(`- Remaining: ${state.remainingTasks} task(s)`);
|
|
50231
|
+
}
|
|
50232
|
+
lines.push("");
|
|
50233
|
+
}
|
|
50234
|
+
}
|
|
50235
|
+
if (this.config.showHandoffContext && context.parentAgent) {
|
|
50236
|
+
lines.push("### Delegation Context");
|
|
50237
|
+
lines.push(`- **Delegated from:** ${context.parentAgent}`);
|
|
50238
|
+
if (context.currentTask) {
|
|
50239
|
+
lines.push(`- **Task:** ${context.currentTask}`);
|
|
50240
|
+
}
|
|
50241
|
+
lines.push("");
|
|
50242
|
+
lines.push("**Note:** Complete this task and return control to the parent agent.");
|
|
50243
|
+
lines.push("");
|
|
50244
|
+
}
|
|
50245
|
+
if (context.agentName && !context.parentAgent) {
|
|
50246
|
+
lines.push(`**Current Agent:** ${context.agentName}`);
|
|
50247
|
+
lines.push("");
|
|
50248
|
+
}
|
|
50249
|
+
if (lines.length <= 2) {
|
|
50250
|
+
return null;
|
|
50251
|
+
}
|
|
50252
|
+
return lines.join("\n");
|
|
50253
|
+
}
|
|
50254
|
+
/**
|
|
50255
|
+
* Clear cached state
|
|
50256
|
+
*/
|
|
50257
|
+
clearCache() {
|
|
50258
|
+
this.cachedState = void 0;
|
|
50259
|
+
this.cacheExpiry = 0;
|
|
50260
|
+
logger.debug("Session cache cleared");
|
|
50261
|
+
}
|
|
50262
|
+
/**
|
|
50263
|
+
* Get current configuration
|
|
50264
|
+
*/
|
|
50265
|
+
getConfig() {
|
|
50266
|
+
return { ...this.config };
|
|
50267
|
+
}
|
|
50268
|
+
/**
|
|
50269
|
+
* Update configuration
|
|
50270
|
+
*/
|
|
50271
|
+
updateConfig(updates) {
|
|
50272
|
+
this.config = {
|
|
50273
|
+
...this.config,
|
|
50274
|
+
...updates
|
|
50275
|
+
};
|
|
50276
|
+
logger.debug("SessionInstructionProvider config updated", {
|
|
50277
|
+
enabled: this.config.enabled
|
|
50278
|
+
});
|
|
50279
|
+
}
|
|
50280
|
+
/**
|
|
50281
|
+
* Reset state
|
|
50282
|
+
*/
|
|
50283
|
+
reset() {
|
|
50284
|
+
this.lastReminderTurn = 0;
|
|
50285
|
+
this.clearCache();
|
|
50286
|
+
logger.debug("SessionInstructionProvider reset");
|
|
50287
|
+
}
|
|
50288
|
+
/**
|
|
50289
|
+
* Check if state provider is configured
|
|
50290
|
+
*/
|
|
50291
|
+
hasStateProvider() {
|
|
50292
|
+
return !!this.stateProvider;
|
|
50293
|
+
}
|
|
50294
|
+
};
|
|
50295
|
+
|
|
50296
|
+
// src/agents/agent-instruction-injector.ts
|
|
50297
|
+
init_esm_shims();
|
|
50298
|
+
init_logger();
|
|
50299
|
+
|
|
50300
|
+
// src/agents/instruction-templates.ts
|
|
50301
|
+
init_esm_shims();
|
|
50302
|
+
var BACKEND_TEMPLATE = {
|
|
50303
|
+
domain: "backend",
|
|
50304
|
+
displayName: "Backend Engineer",
|
|
50305
|
+
domainReminders: [
|
|
50306
|
+
"Follow RESTful API design principles",
|
|
50307
|
+
"Use proper HTTP status codes",
|
|
50308
|
+
"Implement input validation at API boundaries",
|
|
50309
|
+
"Consider database query performance",
|
|
50310
|
+
"Handle errors gracefully with meaningful messages"
|
|
50311
|
+
],
|
|
50312
|
+
qualityChecklist: [
|
|
50313
|
+
"API endpoints follow REST conventions",
|
|
50314
|
+
"Database queries are optimized (no N+1)",
|
|
50315
|
+
"Input is validated before processing",
|
|
50316
|
+
"Errors are logged with context",
|
|
50317
|
+
"Sensitive data is not exposed in responses"
|
|
50318
|
+
],
|
|
50319
|
+
delegationTriggers: [
|
|
50320
|
+
{
|
|
50321
|
+
keywords: ["security", "authentication", "authorization", "OWASP", "vulnerability"],
|
|
50322
|
+
suggestedAgent: "security",
|
|
50323
|
+
reason: "Security-related tasks benefit from specialized security review"
|
|
50324
|
+
},
|
|
50325
|
+
{
|
|
50326
|
+
keywords: ["frontend", "UI", "React", "CSS", "component"],
|
|
50327
|
+
suggestedAgent: "frontend",
|
|
50328
|
+
reason: "Frontend implementation should be handled by frontend specialist"
|
|
50329
|
+
},
|
|
50330
|
+
{
|
|
50331
|
+
keywords: ["test", "testing", "unit test", "integration test"],
|
|
50332
|
+
suggestedAgent: "quality",
|
|
50333
|
+
reason: "Testing strategy benefits from QA expertise"
|
|
50334
|
+
}
|
|
50335
|
+
],
|
|
50336
|
+
antiPatterns: [
|
|
50337
|
+
"Avoid SQL injection by using parameterized queries",
|
|
50338
|
+
"Don't expose internal error details to clients",
|
|
50339
|
+
"Avoid synchronous blocking operations",
|
|
50340
|
+
"Don't hardcode configuration values"
|
|
50341
|
+
],
|
|
50342
|
+
bestPractices: [
|
|
50343
|
+
"Use prepared statements for database queries",
|
|
50344
|
+
"Implement proper logging with correlation IDs",
|
|
50345
|
+
"Use dependency injection for testability",
|
|
50346
|
+
"Follow the principle of least privilege"
|
|
50347
|
+
]
|
|
50348
|
+
};
|
|
50349
|
+
var FRONTEND_TEMPLATE = {
|
|
50350
|
+
domain: "frontend",
|
|
50351
|
+
displayName: "Frontend Engineer",
|
|
50352
|
+
domainReminders: [
|
|
50353
|
+
"Ensure accessibility (WCAG compliance)",
|
|
50354
|
+
"Optimize for performance (Core Web Vitals)",
|
|
50355
|
+
"Handle loading and error states",
|
|
50356
|
+
"Implement responsive design",
|
|
50357
|
+
"Consider keyboard navigation"
|
|
50358
|
+
],
|
|
50359
|
+
qualityChecklist: [
|
|
50360
|
+
"Components are accessible (ARIA labels, roles)",
|
|
50361
|
+
"Loading states are handled",
|
|
50362
|
+
"Error boundaries catch failures gracefully",
|
|
50363
|
+
"Forms have proper validation feedback",
|
|
50364
|
+
"Images have alt text"
|
|
50365
|
+
],
|
|
50366
|
+
delegationTriggers: [
|
|
50367
|
+
{
|
|
50368
|
+
keywords: ["API", "endpoint", "database", "backend", "server"],
|
|
50369
|
+
suggestedAgent: "backend",
|
|
50370
|
+
reason: "Backend changes should be handled by backend specialist"
|
|
50371
|
+
},
|
|
50372
|
+
{
|
|
50373
|
+
keywords: ["security", "XSS", "CSRF", "sanitize"],
|
|
50374
|
+
suggestedAgent: "security",
|
|
50375
|
+
reason: "Security concerns require specialized review"
|
|
50376
|
+
}
|
|
50377
|
+
],
|
|
50378
|
+
antiPatterns: [
|
|
50379
|
+
"Avoid inline styles for reusable components",
|
|
50380
|
+
"Don't mutate state directly",
|
|
50381
|
+
"Avoid excessive re-renders",
|
|
50382
|
+
"Don't ignore accessibility requirements"
|
|
50383
|
+
],
|
|
50384
|
+
bestPractices: [
|
|
50385
|
+
"Use semantic HTML elements",
|
|
50386
|
+
"Implement proper form validation",
|
|
50387
|
+
"Optimize bundle size",
|
|
50388
|
+
"Use React.memo for expensive components"
|
|
50389
|
+
]
|
|
50390
|
+
};
|
|
50391
|
+
var SECURITY_TEMPLATE = {
|
|
50392
|
+
domain: "security",
|
|
50393
|
+
displayName: "Security Engineer",
|
|
50394
|
+
domainReminders: [
|
|
50395
|
+
"Apply OWASP Top 10 security guidelines",
|
|
50396
|
+
"Validate and sanitize ALL user input",
|
|
50397
|
+
"Use parameterized queries to prevent SQL injection",
|
|
50398
|
+
"Implement proper authentication and authorization",
|
|
50399
|
+
"Never expose sensitive data in logs or responses"
|
|
50400
|
+
],
|
|
50401
|
+
qualityChecklist: [
|
|
50402
|
+
"Input validation is present at all entry points",
|
|
50403
|
+
"Authentication tokens are handled securely",
|
|
50404
|
+
"Sensitive data is encrypted at rest and in transit",
|
|
50405
|
+
"Error messages don't leak implementation details",
|
|
50406
|
+
"Dependencies are checked for known vulnerabilities"
|
|
50407
|
+
],
|
|
50408
|
+
delegationTriggers: [
|
|
50409
|
+
{
|
|
50410
|
+
keywords: ["performance", "optimization", "speed", "latency"],
|
|
50411
|
+
suggestedAgent: "backend",
|
|
50412
|
+
reason: "Performance optimization is a backend concern"
|
|
50413
|
+
}
|
|
50414
|
+
],
|
|
50415
|
+
antiPatterns: [
|
|
50416
|
+
"Never trust user input without validation",
|
|
50417
|
+
"Don't store passwords in plain text",
|
|
50418
|
+
"Avoid security through obscurity",
|
|
50419
|
+
"Don't disable security features for convenience"
|
|
50420
|
+
],
|
|
50421
|
+
bestPractices: [
|
|
50422
|
+
"Follow the principle of least privilege",
|
|
50423
|
+
"Implement defense in depth",
|
|
50424
|
+
"Use secure defaults",
|
|
50425
|
+
"Fail securely (deny by default)"
|
|
50426
|
+
]
|
|
50427
|
+
};
|
|
50428
|
+
var QUALITY_TEMPLATE = {
|
|
50429
|
+
domain: "quality",
|
|
50430
|
+
displayName: "Quality Assurance Engineer",
|
|
50431
|
+
domainReminders: [
|
|
50432
|
+
"Write tests that verify behavior, not implementation",
|
|
50433
|
+
"Cover edge cases and error scenarios",
|
|
50434
|
+
"Ensure test isolation (no shared state)",
|
|
50435
|
+
"Use meaningful test descriptions",
|
|
50436
|
+
"Follow the Arrange-Act-Assert pattern"
|
|
50437
|
+
],
|
|
50438
|
+
qualityChecklist: [
|
|
50439
|
+
"Unit tests cover critical paths",
|
|
50440
|
+
"Integration tests verify component interactions",
|
|
50441
|
+
"Edge cases are tested",
|
|
50442
|
+
"Error handling is verified",
|
|
50443
|
+
"Tests are maintainable and readable"
|
|
50444
|
+
],
|
|
50445
|
+
delegationTriggers: [
|
|
50446
|
+
{
|
|
50447
|
+
keywords: ["implement", "build", "create", "develop"],
|
|
50448
|
+
suggestedAgent: "backend",
|
|
50449
|
+
reason: "Implementation tasks should go to domain specialists"
|
|
50450
|
+
},
|
|
50451
|
+
{
|
|
50452
|
+
keywords: ["security", "vulnerability", "penetration"],
|
|
50453
|
+
suggestedAgent: "security",
|
|
50454
|
+
reason: "Security testing requires specialized expertise"
|
|
50455
|
+
}
|
|
50456
|
+
],
|
|
50457
|
+
antiPatterns: [
|
|
50458
|
+
"Avoid testing implementation details",
|
|
50459
|
+
"Don't use flaky tests",
|
|
50460
|
+
"Avoid excessive mocking",
|
|
50461
|
+
"Don't ignore failing tests"
|
|
50462
|
+
],
|
|
50463
|
+
bestPractices: [
|
|
50464
|
+
"Test behavior, not implementation",
|
|
50465
|
+
"Use descriptive test names",
|
|
50466
|
+
"Keep tests independent",
|
|
50467
|
+
"Follow the testing pyramid"
|
|
50468
|
+
]
|
|
50469
|
+
};
|
|
50470
|
+
var ARCHITECTURE_TEMPLATE = {
|
|
50471
|
+
domain: "architecture",
|
|
50472
|
+
displayName: "Software Architect",
|
|
50473
|
+
domainReminders: [
|
|
50474
|
+
"Consider scalability implications",
|
|
50475
|
+
"Document architectural decisions (ADRs)",
|
|
50476
|
+
"Evaluate trade-offs explicitly",
|
|
50477
|
+
"Design for maintainability",
|
|
50478
|
+
"Consider operational concerns"
|
|
50479
|
+
],
|
|
50480
|
+
qualityChecklist: [
|
|
50481
|
+
"Architecture supports future scaling",
|
|
50482
|
+
"Components have clear boundaries",
|
|
50483
|
+
"Dependencies are managed properly",
|
|
50484
|
+
"System is observable (logging, metrics)",
|
|
50485
|
+
"Failure modes are handled"
|
|
50486
|
+
],
|
|
50487
|
+
delegationTriggers: [
|
|
50488
|
+
{
|
|
50489
|
+
keywords: ["implement", "code", "fix", "bug"],
|
|
50490
|
+
suggestedAgent: "backend",
|
|
50491
|
+
reason: "Implementation details should be handled by domain specialists"
|
|
50492
|
+
},
|
|
50493
|
+
{
|
|
50494
|
+
keywords: ["security", "compliance", "audit"],
|
|
50495
|
+
suggestedAgent: "security",
|
|
50496
|
+
reason: "Security architecture needs specialized review"
|
|
50497
|
+
}
|
|
50498
|
+
],
|
|
50499
|
+
antiPatterns: [
|
|
50500
|
+
"Avoid premature optimization",
|
|
50501
|
+
"Don't over-engineer solutions",
|
|
50502
|
+
"Avoid tight coupling between components",
|
|
50503
|
+
"Don't ignore non-functional requirements"
|
|
50504
|
+
],
|
|
50505
|
+
bestPractices: [
|
|
50506
|
+
"Design for change",
|
|
50507
|
+
"Use well-known patterns",
|
|
50508
|
+
"Document decisions and rationale",
|
|
50509
|
+
"Consider operational requirements"
|
|
50510
|
+
]
|
|
50511
|
+
};
|
|
50512
|
+
var DEVOPS_TEMPLATE = {
|
|
50513
|
+
domain: "devops",
|
|
50514
|
+
displayName: "DevOps Engineer",
|
|
50515
|
+
domainReminders: [
|
|
50516
|
+
"Automate repetitive tasks",
|
|
50517
|
+
"Implement proper monitoring and alerting",
|
|
50518
|
+
"Follow infrastructure as code principles",
|
|
50519
|
+
"Consider disaster recovery",
|
|
50520
|
+
"Optimize for reliability and cost"
|
|
50521
|
+
],
|
|
50522
|
+
qualityChecklist: [
|
|
50523
|
+
"Deployments are automated and repeatable",
|
|
50524
|
+
"Monitoring covers key metrics",
|
|
50525
|
+
"Alerts are actionable",
|
|
50526
|
+
"Backups are tested",
|
|
50527
|
+
"Security is integrated into CI/CD"
|
|
50528
|
+
],
|
|
50529
|
+
delegationTriggers: [
|
|
50530
|
+
{
|
|
50531
|
+
keywords: ["code", "feature", "bug", "implement"],
|
|
50532
|
+
suggestedAgent: "backend",
|
|
50533
|
+
reason: "Application code changes should go to developers"
|
|
50534
|
+
},
|
|
50535
|
+
{
|
|
50536
|
+
keywords: ["security", "credentials", "secrets"],
|
|
50537
|
+
suggestedAgent: "security",
|
|
50538
|
+
reason: "Security-sensitive changes need security review"
|
|
50539
|
+
}
|
|
50540
|
+
],
|
|
50541
|
+
antiPatterns: [
|
|
50542
|
+
"Avoid manual deployments",
|
|
50543
|
+
"Don't store secrets in code",
|
|
50544
|
+
"Avoid single points of failure",
|
|
50545
|
+
"Don't ignore monitoring gaps"
|
|
50546
|
+
],
|
|
50547
|
+
bestPractices: [
|
|
50548
|
+
"Use infrastructure as code",
|
|
50549
|
+
"Implement CI/CD pipelines",
|
|
50550
|
+
"Follow GitOps practices",
|
|
50551
|
+
"Use immutable infrastructure"
|
|
50552
|
+
]
|
|
50553
|
+
};
|
|
50554
|
+
var WRITER_TEMPLATE = {
|
|
50555
|
+
domain: "writer",
|
|
50556
|
+
displayName: "Technical Writer",
|
|
50557
|
+
domainReminders: [
|
|
50558
|
+
"Write for the target audience",
|
|
50559
|
+
"Use clear, concise language",
|
|
50560
|
+
"Include practical examples",
|
|
50561
|
+
"Structure content logically",
|
|
50562
|
+
"Keep documentation up to date"
|
|
50563
|
+
],
|
|
50564
|
+
qualityChecklist: [
|
|
50565
|
+
"Documentation matches current code",
|
|
50566
|
+
"Examples are working and tested",
|
|
50567
|
+
"Content is well-organized",
|
|
50568
|
+
"Technical terms are explained",
|
|
50569
|
+
"Links and references are valid"
|
|
50570
|
+
],
|
|
50571
|
+
delegationTriggers: [
|
|
50572
|
+
{
|
|
50573
|
+
keywords: ["implement", "code", "fix", "develop"],
|
|
50574
|
+
suggestedAgent: "backend",
|
|
50575
|
+
reason: "Code changes should be handled by developers"
|
|
50576
|
+
}
|
|
50577
|
+
],
|
|
50578
|
+
antiPatterns: [
|
|
50579
|
+
"Avoid jargon without explanation",
|
|
50580
|
+
"Don't assume reader knowledge",
|
|
50581
|
+
"Avoid outdated examples",
|
|
50582
|
+
"Don't ignore code comments"
|
|
50583
|
+
],
|
|
50584
|
+
bestPractices: [
|
|
50585
|
+
"Use consistent terminology",
|
|
50586
|
+
"Include code examples",
|
|
50587
|
+
"Keep documentation near code",
|
|
50588
|
+
"Update docs with code changes"
|
|
50589
|
+
]
|
|
50590
|
+
};
|
|
50591
|
+
var STANDARD_TEMPLATE = {
|
|
50592
|
+
domain: "standard",
|
|
50593
|
+
displayName: "General Assistant",
|
|
50594
|
+
domainReminders: [
|
|
50595
|
+
"Understand the task before starting",
|
|
50596
|
+
"Ask clarifying questions when needed",
|
|
50597
|
+
"Break complex tasks into smaller steps",
|
|
50598
|
+
"Verify your work before completing",
|
|
50599
|
+
"Document your changes"
|
|
50600
|
+
],
|
|
50601
|
+
qualityChecklist: [
|
|
50602
|
+
"Task requirements are understood",
|
|
50603
|
+
"Changes are tested",
|
|
50604
|
+
"Code follows project conventions",
|
|
50605
|
+
"Documentation is updated",
|
|
50606
|
+
"No regressions introduced"
|
|
50607
|
+
],
|
|
50608
|
+
delegationTriggers: [
|
|
50609
|
+
{
|
|
50610
|
+
keywords: ["security", "vulnerability", "authentication"],
|
|
50611
|
+
suggestedAgent: "security",
|
|
50612
|
+
reason: "Security tasks need specialized attention"
|
|
50613
|
+
},
|
|
50614
|
+
{
|
|
50615
|
+
keywords: ["test", "testing", "QA", "quality"],
|
|
50616
|
+
suggestedAgent: "quality",
|
|
50617
|
+
reason: "Testing benefits from QA expertise"
|
|
50618
|
+
},
|
|
50619
|
+
{
|
|
50620
|
+
keywords: ["architecture", "design", "scalability"],
|
|
50621
|
+
suggestedAgent: "architecture",
|
|
50622
|
+
reason: "Architectural decisions need careful consideration"
|
|
50623
|
+
}
|
|
50624
|
+
],
|
|
50625
|
+
antiPatterns: [
|
|
50626
|
+
"Avoid making changes without understanding context",
|
|
50627
|
+
"Don't skip testing",
|
|
50628
|
+
"Avoid large, monolithic changes",
|
|
50629
|
+
"Don't ignore existing patterns"
|
|
50630
|
+
],
|
|
50631
|
+
bestPractices: [
|
|
50632
|
+
"Follow existing code conventions",
|
|
50633
|
+
"Write self-documenting code",
|
|
50634
|
+
"Test your changes",
|
|
50635
|
+
"Keep changes focused"
|
|
50636
|
+
]
|
|
50637
|
+
};
|
|
50638
|
+
var AGENT_TEMPLATES = {
|
|
50639
|
+
backend: BACKEND_TEMPLATE,
|
|
50640
|
+
frontend: FRONTEND_TEMPLATE,
|
|
50641
|
+
fullstack: { ...BACKEND_TEMPLATE, domain: "fullstack", displayName: "Fullstack Engineer" },
|
|
50642
|
+
security: SECURITY_TEMPLATE,
|
|
50643
|
+
quality: QUALITY_TEMPLATE,
|
|
50644
|
+
architecture: ARCHITECTURE_TEMPLATE,
|
|
50645
|
+
devops: DEVOPS_TEMPLATE,
|
|
50646
|
+
data: { ...BACKEND_TEMPLATE, domain: "data", displayName: "Data Engineer" },
|
|
50647
|
+
mobile: { ...FRONTEND_TEMPLATE, domain: "mobile", displayName: "Mobile Engineer" },
|
|
50648
|
+
writer: WRITER_TEMPLATE,
|
|
50649
|
+
researcher: { ...STANDARD_TEMPLATE, domain: "researcher", displayName: "Researcher" },
|
|
50650
|
+
standard: STANDARD_TEMPLATE
|
|
50651
|
+
};
|
|
50652
|
+
function getAgentTemplate(domain) {
|
|
50653
|
+
return AGENT_TEMPLATES[domain] || STANDARD_TEMPLATE;
|
|
50654
|
+
}
|
|
50655
|
+
function isValidAgentDomain(domain) {
|
|
50656
|
+
return domain in AGENT_TEMPLATES;
|
|
50657
|
+
}
|
|
50658
|
+
function getDelegationSuggestions(text, currentDomain) {
|
|
50659
|
+
const template = getAgentTemplate(currentDomain);
|
|
50660
|
+
const suggestions = [];
|
|
50661
|
+
const textLower = text.toLowerCase();
|
|
50662
|
+
for (const trigger of template.delegationTriggers) {
|
|
50663
|
+
const matchedKeywords = trigger.keywords.filter(
|
|
50664
|
+
(kw) => textLower.includes(kw.toLowerCase())
|
|
50665
|
+
);
|
|
50666
|
+
if (matchedKeywords.length > 0) {
|
|
50667
|
+
suggestions.push({
|
|
50668
|
+
agent: trigger.suggestedAgent,
|
|
50669
|
+
reason: trigger.reason,
|
|
50670
|
+
keywords: matchedKeywords
|
|
50671
|
+
});
|
|
50672
|
+
}
|
|
50673
|
+
}
|
|
50674
|
+
return suggestions;
|
|
50675
|
+
}
|
|
50676
|
+
|
|
50677
|
+
// src/agents/agent-instruction-injector.ts
|
|
50678
|
+
var DEFAULT_AGENT_CONFIG = {
|
|
50679
|
+
enabled: true,
|
|
50680
|
+
reminderFrequency: 5,
|
|
50681
|
+
delegationDetection: true,
|
|
50682
|
+
minDelegationKeywords: 1,
|
|
50683
|
+
includeQualityChecklist: true,
|
|
50684
|
+
qualityChecklistFrequency: 10,
|
|
50685
|
+
includeAntiPatterns: true
|
|
50686
|
+
};
|
|
50687
|
+
var AgentInstructionInjector = class {
|
|
50688
|
+
name = "agent-template";
|
|
50689
|
+
config;
|
|
50690
|
+
lastReminderTurn = 0;
|
|
50691
|
+
lastQualityCheckTurn = 0;
|
|
50692
|
+
currentDomain;
|
|
50693
|
+
recentTaskText = "";
|
|
50694
|
+
constructor(config) {
|
|
50695
|
+
this.config = {
|
|
50696
|
+
...DEFAULT_AGENT_CONFIG,
|
|
50697
|
+
...config
|
|
50698
|
+
};
|
|
50699
|
+
logger.debug("AgentInstructionInjector initialized", {
|
|
50700
|
+
enabled: this.config.enabled,
|
|
50701
|
+
reminderFrequency: this.config.reminderFrequency
|
|
50702
|
+
});
|
|
50703
|
+
}
|
|
50704
|
+
/**
|
|
50705
|
+
* Set the current agent domain
|
|
50706
|
+
*/
|
|
50707
|
+
setDomain(domain) {
|
|
50708
|
+
if (isValidAgentDomain(domain)) {
|
|
50709
|
+
this.currentDomain = domain;
|
|
50710
|
+
logger.debug("Agent domain set", { domain });
|
|
50711
|
+
} else {
|
|
50712
|
+
this.currentDomain = "standard";
|
|
50713
|
+
logger.debug("Unknown domain, using standard", { domain });
|
|
50714
|
+
}
|
|
50715
|
+
}
|
|
50716
|
+
/**
|
|
50717
|
+
* Get the current domain
|
|
50718
|
+
*/
|
|
50719
|
+
getDomain() {
|
|
50720
|
+
return this.currentDomain;
|
|
50721
|
+
}
|
|
50722
|
+
/**
|
|
50723
|
+
* Check if provider should generate instructions
|
|
50724
|
+
*/
|
|
50725
|
+
shouldGenerate(context) {
|
|
50726
|
+
if (!this.config.enabled) {
|
|
50727
|
+
return false;
|
|
50728
|
+
}
|
|
50729
|
+
const domain = this.resolveDomain(context);
|
|
50730
|
+
if (!domain) {
|
|
50731
|
+
return false;
|
|
50732
|
+
}
|
|
50733
|
+
const turnsSinceReminder = context.turnCount - this.lastReminderTurn;
|
|
50734
|
+
const reminderDue = turnsSinceReminder >= this.config.reminderFrequency;
|
|
50735
|
+
const turnsSinceQuality = context.turnCount - this.lastQualityCheckTurn;
|
|
50736
|
+
const qualityDue = this.config.includeQualityChecklist && turnsSinceQuality >= this.config.qualityChecklistFrequency;
|
|
50737
|
+
const hasDelegationTriggers = this.config.delegationDetection && this.checkDelegationTriggers(context);
|
|
50738
|
+
return reminderDue || qualityDue || hasDelegationTriggers;
|
|
50739
|
+
}
|
|
50740
|
+
/**
|
|
50741
|
+
* Generate instructions based on agent domain
|
|
50742
|
+
*/
|
|
50743
|
+
async getInstructions(context) {
|
|
50744
|
+
const instructions = [];
|
|
50745
|
+
const domain = this.resolveDomain(context);
|
|
50746
|
+
if (!domain) {
|
|
50747
|
+
return instructions;
|
|
50748
|
+
}
|
|
50749
|
+
const template = getAgentTemplate(domain);
|
|
50750
|
+
const turnsSinceReminder = context.turnCount - this.lastReminderTurn;
|
|
50751
|
+
const turnsSinceQuality = context.turnCount - this.lastQualityCheckTurn;
|
|
50752
|
+
if (turnsSinceReminder >= this.config.reminderFrequency) {
|
|
50753
|
+
const reminderContent = this.formatDomainReminders(template);
|
|
50754
|
+
instructions.push({
|
|
50755
|
+
type: "delegation",
|
|
50756
|
+
priority: "normal",
|
|
50757
|
+
content: reminderContent,
|
|
50758
|
+
source: "automatosx",
|
|
50759
|
+
createdAt: Date.now(),
|
|
50760
|
+
expiresAfter: this.config.reminderFrequency,
|
|
50761
|
+
id: `agent-reminder-${domain}-${Date.now()}`
|
|
50762
|
+
});
|
|
50763
|
+
this.lastReminderTurn = context.turnCount;
|
|
50764
|
+
}
|
|
50765
|
+
if (this.config.includeQualityChecklist && turnsSinceQuality >= this.config.qualityChecklistFrequency) {
|
|
50766
|
+
const checklistContent = this.formatQualityChecklist(template);
|
|
50767
|
+
instructions.push({
|
|
50768
|
+
type: "delegation",
|
|
50769
|
+
priority: "normal",
|
|
50770
|
+
content: checklistContent,
|
|
50771
|
+
source: "automatosx",
|
|
50772
|
+
createdAt: Date.now(),
|
|
50773
|
+
expiresAfter: this.config.qualityChecklistFrequency,
|
|
50774
|
+
id: `agent-quality-${domain}-${Date.now()}`
|
|
50775
|
+
});
|
|
50776
|
+
this.lastQualityCheckTurn = context.turnCount;
|
|
50777
|
+
}
|
|
50778
|
+
if (this.config.delegationDetection) {
|
|
50779
|
+
const taskText = this.extractTaskText(context);
|
|
50780
|
+
if (taskText !== this.recentTaskText) {
|
|
50781
|
+
this.recentTaskText = taskText;
|
|
50782
|
+
const delegationContent = this.checkAndFormatDelegation(template, taskText);
|
|
50783
|
+
if (delegationContent) {
|
|
50784
|
+
instructions.push({
|
|
50785
|
+
type: "delegation",
|
|
50786
|
+
priority: "high",
|
|
50787
|
+
content: delegationContent,
|
|
50788
|
+
source: "automatosx",
|
|
50789
|
+
createdAt: Date.now(),
|
|
50790
|
+
expiresAfter: 3,
|
|
50791
|
+
id: `agent-delegation-${Date.now()}`
|
|
50792
|
+
});
|
|
50793
|
+
}
|
|
50794
|
+
}
|
|
50795
|
+
}
|
|
50796
|
+
logger.debug("Agent instructions generated", {
|
|
50797
|
+
domain,
|
|
50798
|
+
instructionCount: instructions.length
|
|
50799
|
+
});
|
|
50800
|
+
return instructions;
|
|
50801
|
+
}
|
|
50802
|
+
/**
|
|
50803
|
+
* Resolve domain from context or current setting
|
|
50804
|
+
*/
|
|
50805
|
+
resolveDomain(context) {
|
|
50806
|
+
if (context.agentName && isValidAgentDomain(context.agentName)) {
|
|
50807
|
+
return context.agentName;
|
|
50808
|
+
}
|
|
50809
|
+
return this.currentDomain;
|
|
50810
|
+
}
|
|
50811
|
+
/**
|
|
50812
|
+
* Extract task text from context for delegation detection
|
|
50813
|
+
*/
|
|
50814
|
+
extractTaskText(context) {
|
|
50815
|
+
const parts = [];
|
|
50816
|
+
if (context.currentTask) {
|
|
50817
|
+
parts.push(context.currentTask);
|
|
50818
|
+
}
|
|
50819
|
+
for (const todo of context.todos.filter((t) => t.status === "in_progress")) {
|
|
50820
|
+
parts.push(todo.content);
|
|
50821
|
+
}
|
|
50822
|
+
return parts.join(" ");
|
|
50823
|
+
}
|
|
50824
|
+
/**
|
|
50825
|
+
* Check if delegation triggers are present
|
|
50826
|
+
*/
|
|
50827
|
+
checkDelegationTriggers(context) {
|
|
50828
|
+
const domain = this.resolveDomain(context);
|
|
50829
|
+
if (!domain) return false;
|
|
50830
|
+
const taskText = this.extractTaskText(context);
|
|
50831
|
+
if (!taskText) return false;
|
|
50832
|
+
const suggestions = getDelegationSuggestions(taskText, domain);
|
|
50833
|
+
return suggestions.some((s) => s.keywords.length >= this.config.minDelegationKeywords);
|
|
50834
|
+
}
|
|
50835
|
+
/**
|
|
50836
|
+
* Format domain reminders
|
|
50837
|
+
*/
|
|
50838
|
+
formatDomainReminders(template) {
|
|
50839
|
+
const lines = [
|
|
50840
|
+
`## ${template.displayName} Reminders`,
|
|
50841
|
+
""
|
|
50842
|
+
];
|
|
50843
|
+
for (const reminder of template.domainReminders) {
|
|
50844
|
+
lines.push(`- ${reminder}`);
|
|
50845
|
+
}
|
|
50846
|
+
if (this.config.includeAntiPatterns && template.antiPatterns.length > 0) {
|
|
50847
|
+
lines.push("");
|
|
50848
|
+
lines.push("**Avoid:**");
|
|
50849
|
+
for (const antiPattern of template.antiPatterns.slice(0, 3)) {
|
|
50850
|
+
lines.push(`- ${antiPattern}`);
|
|
50851
|
+
}
|
|
50852
|
+
}
|
|
50853
|
+
return lines.join("\n");
|
|
50854
|
+
}
|
|
50855
|
+
/**
|
|
50856
|
+
* Format quality checklist
|
|
50857
|
+
*/
|
|
50858
|
+
formatQualityChecklist(template) {
|
|
50859
|
+
const lines = [
|
|
50860
|
+
`## Quality Checklist (${template.displayName})`,
|
|
50861
|
+
"",
|
|
50862
|
+
"Before completing, verify:"
|
|
50863
|
+
];
|
|
50864
|
+
for (const item of template.qualityChecklist) {
|
|
50865
|
+
lines.push(`- [ ] ${item}`);
|
|
50866
|
+
}
|
|
50867
|
+
return lines.join("\n");
|
|
50868
|
+
}
|
|
50869
|
+
/**
|
|
50870
|
+
* Check for delegation triggers and format suggestion
|
|
50871
|
+
*/
|
|
50872
|
+
checkAndFormatDelegation(template, taskText) {
|
|
50873
|
+
const suggestions = getDelegationSuggestions(taskText, template.domain);
|
|
50874
|
+
const relevantSuggestions = suggestions.filter(
|
|
50875
|
+
(s) => s.keywords.length >= this.config.minDelegationKeywords
|
|
50876
|
+
);
|
|
50877
|
+
if (relevantSuggestions.length === 0) {
|
|
50878
|
+
return null;
|
|
50879
|
+
}
|
|
50880
|
+
const lines = [
|
|
50881
|
+
"## Delegation Suggestion",
|
|
50882
|
+
""
|
|
50883
|
+
];
|
|
50884
|
+
for (const suggestion of relevantSuggestions) {
|
|
50885
|
+
lines.push(`**Consider delegating to @${suggestion.agent}**`);
|
|
50886
|
+
lines.push(`- Reason: ${suggestion.reason}`);
|
|
50887
|
+
lines.push(`- Triggered by: ${suggestion.keywords.join(", ")}`);
|
|
50888
|
+
lines.push("");
|
|
50889
|
+
}
|
|
50890
|
+
lines.push("Use `DELEGATE TO @agent: task` or `@agent task` syntax to delegate.");
|
|
50891
|
+
return lines.join("\n");
|
|
50892
|
+
}
|
|
50893
|
+
/**
|
|
50894
|
+
* Get current configuration
|
|
50895
|
+
*/
|
|
50896
|
+
getConfig() {
|
|
50897
|
+
return { ...this.config };
|
|
50898
|
+
}
|
|
50899
|
+
/**
|
|
50900
|
+
* Update configuration
|
|
50901
|
+
*/
|
|
50902
|
+
updateConfig(updates) {
|
|
50903
|
+
this.config = {
|
|
50904
|
+
...this.config,
|
|
50905
|
+
...updates
|
|
50906
|
+
};
|
|
50907
|
+
logger.debug("AgentInstructionInjector config updated", {
|
|
50908
|
+
enabled: this.config.enabled
|
|
50909
|
+
});
|
|
50910
|
+
}
|
|
50911
|
+
/**
|
|
50912
|
+
* Reset state
|
|
50913
|
+
*/
|
|
50914
|
+
reset() {
|
|
50915
|
+
this.lastReminderTurn = 0;
|
|
50916
|
+
this.lastQualityCheckTurn = 0;
|
|
50917
|
+
this.recentTaskText = "";
|
|
50918
|
+
logger.debug("AgentInstructionInjector reset");
|
|
50919
|
+
}
|
|
50920
|
+
};
|
|
50921
|
+
|
|
50922
|
+
// src/core/orchestration/orchestration-service.ts
|
|
50923
|
+
var OrchestrationService = class {
|
|
50924
|
+
config;
|
|
50925
|
+
injector;
|
|
50926
|
+
tokenBudgetManager;
|
|
50927
|
+
workflowModeManager;
|
|
50928
|
+
agentInjector;
|
|
50929
|
+
todoProvider;
|
|
50930
|
+
memoryProvider;
|
|
50931
|
+
sessionProvider;
|
|
50932
|
+
turnCount = 0;
|
|
50933
|
+
currentTodos = [];
|
|
50934
|
+
constructor(serviceConfig = {}) {
|
|
50935
|
+
this.config = {
|
|
50936
|
+
...DEFAULT_ORCHESTRATION_CONFIG,
|
|
50937
|
+
...serviceConfig
|
|
50938
|
+
};
|
|
50939
|
+
this.injector = new OrchestrationInstructionInjector(this.config);
|
|
50940
|
+
this.tokenBudgetManager = new TokenBudgetManager(this.config.tokenBudget);
|
|
50941
|
+
this.workflowModeManager = new WorkflowModeManager();
|
|
50942
|
+
this.agentInjector = new AgentInstructionInjector({
|
|
50943
|
+
enabled: this.config.agentTemplates?.enabled ?? true,
|
|
50944
|
+
reminderFrequency: this.config.agentTemplates?.reminderFrequency ?? 5
|
|
50945
|
+
});
|
|
50946
|
+
this.initializeProviders(serviceConfig);
|
|
50947
|
+
logger.debug("OrchestrationService initialized", {
|
|
50948
|
+
todoEnabled: this.config.todoIntegration?.enabled,
|
|
50949
|
+
memoryEnabled: this.config.memoryIntegration?.enabled,
|
|
50950
|
+
sessionEnabled: this.config.sessionIntegration?.enabled,
|
|
50951
|
+
agentTemplatesEnabled: this.config.agentTemplates?.enabled
|
|
50952
|
+
});
|
|
50953
|
+
}
|
|
50954
|
+
/**
|
|
50955
|
+
* Initialize instruction providers
|
|
50956
|
+
*/
|
|
50957
|
+
initializeProviders(serviceConfig) {
|
|
50958
|
+
if (this.config.todoIntegration?.enabled !== false) {
|
|
50959
|
+
this.todoProvider = new TodoInstructionProvider({
|
|
50960
|
+
enabled: true,
|
|
50961
|
+
reminderFrequency: this.config.todoIntegration?.reminderFrequency ?? 3,
|
|
50962
|
+
compactMode: this.config.todoIntegration?.compactMode ?? false
|
|
50963
|
+
});
|
|
50964
|
+
this.injector.registerProvider(this.todoProvider);
|
|
50965
|
+
}
|
|
50966
|
+
if (this.config.memoryIntegration?.enabled !== false && serviceConfig.memorySearchProvider) {
|
|
50967
|
+
this.memoryProvider = new MemoryInstructionProvider(
|
|
50968
|
+
serviceConfig.memorySearchProvider,
|
|
50969
|
+
{
|
|
50970
|
+
enabled: true,
|
|
50971
|
+
maxEntries: this.config.memoryIntegration?.maxEntries ?? 5,
|
|
50972
|
+
minRelevance: this.config.memoryIntegration?.minRelevance ?? 0.5
|
|
50973
|
+
}
|
|
50974
|
+
);
|
|
50975
|
+
this.injector.registerProvider(this.memoryProvider);
|
|
50976
|
+
}
|
|
50977
|
+
if (this.config.sessionIntegration?.enabled !== false) {
|
|
50978
|
+
this.sessionProvider = new SessionInstructionProvider(
|
|
50979
|
+
serviceConfig.sessionStateProvider,
|
|
50980
|
+
{
|
|
50981
|
+
enabled: true,
|
|
50982
|
+
showCollaboration: this.config.sessionIntegration?.showCollaboration ?? true,
|
|
50983
|
+
showProgress: true,
|
|
50984
|
+
reminderFrequency: 5,
|
|
50985
|
+
showHandoffContext: true
|
|
50986
|
+
}
|
|
50987
|
+
);
|
|
50988
|
+
this.injector.registerProvider(this.sessionProvider);
|
|
50989
|
+
}
|
|
50990
|
+
if (this.config.agentTemplates?.enabled !== false) {
|
|
50991
|
+
if (serviceConfig.agentDomain) {
|
|
50992
|
+
this.agentInjector.setDomain(serviceConfig.agentDomain);
|
|
50993
|
+
}
|
|
50994
|
+
this.injector.registerProvider(this.agentInjector);
|
|
50995
|
+
}
|
|
50996
|
+
}
|
|
50997
|
+
/**
|
|
50998
|
+
* Set the current agent domain for agent-specific instructions
|
|
50999
|
+
*/
|
|
51000
|
+
setAgentDomain(domain) {
|
|
51001
|
+
this.agentInjector.setDomain(domain);
|
|
51002
|
+
logger.debug("Agent domain set", { domain });
|
|
51003
|
+
}
|
|
51004
|
+
/**
|
|
51005
|
+
* Set the memory search provider
|
|
51006
|
+
*/
|
|
51007
|
+
setMemoryProvider(provider) {
|
|
51008
|
+
if (this.memoryProvider) {
|
|
51009
|
+
this.memoryProvider.setSearchProvider(provider);
|
|
51010
|
+
} else if (this.config.memoryIntegration?.enabled !== false) {
|
|
51011
|
+
this.memoryProvider = new MemoryInstructionProvider(provider, {
|
|
51012
|
+
enabled: true,
|
|
51013
|
+
maxEntries: this.config.memoryIntegration?.maxEntries ?? 5,
|
|
51014
|
+
minRelevance: this.config.memoryIntegration?.minRelevance ?? 0.5
|
|
51015
|
+
});
|
|
51016
|
+
this.injector.registerProvider(this.memoryProvider);
|
|
51017
|
+
}
|
|
51018
|
+
}
|
|
51019
|
+
/**
|
|
51020
|
+
* Set the session state provider
|
|
51021
|
+
*/
|
|
51022
|
+
setSessionProvider(provider) {
|
|
51023
|
+
if (this.sessionProvider) {
|
|
51024
|
+
this.sessionProvider.setStateProvider(provider);
|
|
51025
|
+
}
|
|
51026
|
+
}
|
|
51027
|
+
/**
|
|
51028
|
+
* Update the current todo list
|
|
51029
|
+
*/
|
|
51030
|
+
updateTodos(todos) {
|
|
51031
|
+
this.currentTodos = todos;
|
|
51032
|
+
}
|
|
51033
|
+
/**
|
|
51034
|
+
* Set the workflow mode
|
|
51035
|
+
*/
|
|
51036
|
+
setWorkflowMode(mode) {
|
|
51037
|
+
this.workflowModeManager.setMode(mode);
|
|
51038
|
+
logger.debug("Workflow mode set", { mode });
|
|
51039
|
+
}
|
|
51040
|
+
/**
|
|
51041
|
+
* Get current workflow mode
|
|
51042
|
+
*/
|
|
51043
|
+
getWorkflowMode() {
|
|
51044
|
+
return this.workflowModeManager.getCurrentMode();
|
|
51045
|
+
}
|
|
51046
|
+
/**
|
|
51047
|
+
* Check if a tool is allowed in current workflow mode
|
|
51048
|
+
*/
|
|
51049
|
+
isToolAllowed(toolName) {
|
|
51050
|
+
return this.workflowModeManager.isToolAllowed(toolName);
|
|
51051
|
+
}
|
|
51052
|
+
/**
|
|
51053
|
+
* Filter tools based on current workflow mode
|
|
51054
|
+
*/
|
|
51055
|
+
filterTools(tools) {
|
|
51056
|
+
return this.workflowModeManager.filterTools(tools);
|
|
51057
|
+
}
|
|
51058
|
+
/**
|
|
51059
|
+
* Increment turn count (called after each agent response)
|
|
51060
|
+
*/
|
|
51061
|
+
incrementTurn() {
|
|
51062
|
+
this.turnCount++;
|
|
51063
|
+
}
|
|
51064
|
+
/**
|
|
51065
|
+
* Get current turn count
|
|
51066
|
+
*/
|
|
51067
|
+
getTurnCount() {
|
|
51068
|
+
return this.turnCount;
|
|
51069
|
+
}
|
|
51070
|
+
/**
|
|
51071
|
+
* Generate and inject instructions for the current context
|
|
51072
|
+
*/
|
|
51073
|
+
async injectInstructions(options = {}) {
|
|
51074
|
+
const context = {
|
|
51075
|
+
todos: this.currentTodos,
|
|
51076
|
+
turnCount: this.turnCount,
|
|
51077
|
+
workflowMode: this.workflowModeManager.getCurrentMode(),
|
|
51078
|
+
currentTask: options.task,
|
|
51079
|
+
agentName: options.agentName,
|
|
51080
|
+
sessionId: options.sessionId,
|
|
51081
|
+
parentAgent: options.parentAgent
|
|
51082
|
+
};
|
|
51083
|
+
const result = await this.injector.inject(context);
|
|
51084
|
+
logger.debug("Instructions injected", {
|
|
51085
|
+
instructionCount: result.instructions.length,
|
|
51086
|
+
tokensUsed: result.allocation.tokensUsed,
|
|
51087
|
+
hasInstructions: result.hasInstructions
|
|
51088
|
+
});
|
|
51089
|
+
return {
|
|
51090
|
+
content: result.formattedText,
|
|
51091
|
+
instructions: result.instructions,
|
|
51092
|
+
tokenCount: result.allocation.tokensUsed,
|
|
51093
|
+
applied: result.hasInstructions
|
|
51094
|
+
};
|
|
51095
|
+
}
|
|
51096
|
+
/**
|
|
51097
|
+
* Format instructions as system reminder tags
|
|
51098
|
+
*/
|
|
51099
|
+
formatAsSystemReminder(content) {
|
|
51100
|
+
if (!content || content.trim().length === 0) {
|
|
51101
|
+
return "";
|
|
51102
|
+
}
|
|
51103
|
+
return `<system-reminder>
|
|
51104
|
+
${content}
|
|
51105
|
+
</system-reminder>`;
|
|
51106
|
+
}
|
|
51107
|
+
/**
|
|
51108
|
+
* Get debug information about current orchestration state
|
|
51109
|
+
*/
|
|
51110
|
+
getDebugInfo() {
|
|
51111
|
+
const budgetConfig = this.tokenBudgetManager.getConfig();
|
|
51112
|
+
const providers = this.injector.getProviders().map((p) => p.name);
|
|
51113
|
+
return {
|
|
51114
|
+
turnCount: this.turnCount,
|
|
51115
|
+
workflowMode: this.workflowModeManager.getCurrentMode(),
|
|
51116
|
+
todoCount: this.currentTodos.length,
|
|
51117
|
+
providers,
|
|
51118
|
+
tokenBudget: {
|
|
51119
|
+
used: 0,
|
|
51120
|
+
// Would need to track this
|
|
51121
|
+
total: budgetConfig.maxTotal,
|
|
51122
|
+
remaining: budgetConfig.maxTotal
|
|
51123
|
+
}
|
|
51124
|
+
};
|
|
51125
|
+
}
|
|
51126
|
+
/**
|
|
51127
|
+
* Reset all state (for new conversations)
|
|
51128
|
+
*/
|
|
51129
|
+
reset() {
|
|
51130
|
+
this.turnCount = 0;
|
|
51131
|
+
this.currentTodos = [];
|
|
51132
|
+
this.workflowModeManager.reset();
|
|
51133
|
+
this.agentInjector.reset();
|
|
51134
|
+
this.injector.clearCache();
|
|
51135
|
+
if (this.todoProvider) {
|
|
51136
|
+
this.todoProvider.reset();
|
|
51137
|
+
}
|
|
51138
|
+
if (this.memoryProvider) {
|
|
51139
|
+
this.memoryProvider.clearCache();
|
|
51140
|
+
}
|
|
51141
|
+
if (this.sessionProvider) {
|
|
51142
|
+
this.sessionProvider.reset();
|
|
51143
|
+
}
|
|
51144
|
+
logger.debug("OrchestrationService reset");
|
|
51145
|
+
}
|
|
51146
|
+
/**
|
|
51147
|
+
* Update configuration
|
|
51148
|
+
*/
|
|
51149
|
+
updateConfig(updates) {
|
|
51150
|
+
this.config = {
|
|
51151
|
+
...this.config,
|
|
51152
|
+
...updates
|
|
51153
|
+
};
|
|
51154
|
+
if (updates.tokenBudget) {
|
|
51155
|
+
this.tokenBudgetManager = new TokenBudgetManager(updates.tokenBudget);
|
|
51156
|
+
}
|
|
51157
|
+
logger.debug("OrchestrationService config updated", { updates });
|
|
51158
|
+
}
|
|
51159
|
+
/**
|
|
51160
|
+
* Get current configuration
|
|
51161
|
+
*/
|
|
51162
|
+
getConfig() {
|
|
51163
|
+
return { ...this.config };
|
|
51164
|
+
}
|
|
51165
|
+
};
|
|
51166
|
+
|
|
51167
|
+
// src/cli/commands/debug-instructions.ts
|
|
51168
|
+
var debugInstructionsCommand = {
|
|
51169
|
+
command: "debug:instructions",
|
|
51170
|
+
describe: "Show current embedded instructions state (v11.3.0)",
|
|
51171
|
+
builder: (yargs2) => {
|
|
51172
|
+
return yargs2.option("tokens", {
|
|
51173
|
+
alias: "t",
|
|
51174
|
+
describe: "Show token budget details",
|
|
51175
|
+
type: "boolean",
|
|
51176
|
+
default: false
|
|
51177
|
+
}).option("providers", {
|
|
51178
|
+
alias: "p",
|
|
51179
|
+
describe: "Show registered instruction providers",
|
|
51180
|
+
type: "boolean",
|
|
51181
|
+
default: false
|
|
51182
|
+
}).option("templates", {
|
|
51183
|
+
describe: "Show available agent templates",
|
|
51184
|
+
type: "boolean",
|
|
51185
|
+
default: false
|
|
51186
|
+
}).option("agent", {
|
|
51187
|
+
alias: "a",
|
|
51188
|
+
describe: "Show template for specific agent domain",
|
|
51189
|
+
type: "string"
|
|
51190
|
+
}).option("verbose", {
|
|
51191
|
+
alias: "v",
|
|
51192
|
+
describe: "Show verbose output",
|
|
51193
|
+
type: "boolean",
|
|
51194
|
+
default: false
|
|
51195
|
+
}).example("$0 debug:instructions", "Show overall instruction state").example("$0 debug:instructions --tokens", "Show token budget details").example("$0 debug:instructions --providers", "List instruction providers").example("$0 debug:instructions --templates", "List agent templates").example("$0 debug:instructions --agent backend", "Show backend agent template");
|
|
51196
|
+
},
|
|
51197
|
+
handler: async (argv) => {
|
|
51198
|
+
try {
|
|
51199
|
+
if (argv.tokens) {
|
|
51200
|
+
displayTokenBudget(argv.verbose);
|
|
51201
|
+
return;
|
|
51202
|
+
}
|
|
51203
|
+
if (argv.providers) {
|
|
51204
|
+
displayProviders(argv.verbose);
|
|
51205
|
+
return;
|
|
51206
|
+
}
|
|
51207
|
+
if (argv.templates) {
|
|
51208
|
+
displayAgentTemplates(argv.verbose);
|
|
51209
|
+
return;
|
|
51210
|
+
}
|
|
51211
|
+
if (argv.agent) {
|
|
51212
|
+
displayAgentTemplate(argv.agent, argv.verbose);
|
|
51213
|
+
return;
|
|
51214
|
+
}
|
|
51215
|
+
displayOverallState(argv.verbose);
|
|
51216
|
+
} catch (error) {
|
|
51217
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
51218
|
+
console.error(chalk5.red.bold(`
|
|
51219
|
+
\u274C Error: ${err.message}
|
|
51220
|
+
`));
|
|
51221
|
+
logger.error("Debug instructions command failed", { error: err.message });
|
|
51222
|
+
process.exit(1);
|
|
51223
|
+
}
|
|
51224
|
+
}
|
|
51225
|
+
};
|
|
51226
|
+
function displayOverallState(verbose) {
|
|
51227
|
+
console.log(chalk5.blue.bold("\n\u{1F50D} Embedded Instructions Debug Info\n"));
|
|
51228
|
+
console.log(chalk5.dim("\u2550".repeat(60)));
|
|
51229
|
+
const service = new OrchestrationService();
|
|
51230
|
+
const debugInfo = service.getDebugInfo();
|
|
51231
|
+
console.log(chalk5.cyan("\n\u{1F4CA} Current State"));
|
|
51232
|
+
console.log(chalk5.dim("\u2500".repeat(40)));
|
|
51233
|
+
console.log(` Turn count: ${chalk5.yellow(debugInfo.turnCount)}`);
|
|
51234
|
+
console.log(` Workflow mode: ${chalk5.cyan(debugInfo.workflowMode)}`);
|
|
51235
|
+
console.log(` Active todos: ${chalk5.yellow(debugInfo.todoCount)}`);
|
|
51236
|
+
console.log(` Registered providers: ${chalk5.green(debugInfo.providers.length)}`);
|
|
51237
|
+
console.log(chalk5.cyan("\n\u{1F4B0} Token Budget"));
|
|
51238
|
+
console.log(chalk5.dim("\u2500".repeat(40)));
|
|
51239
|
+
console.log(` Used: ${chalk5.yellow(debugInfo.tokenBudget.used)} / ${debugInfo.tokenBudget.total}`);
|
|
51240
|
+
const usagePercent = Math.round(debugInfo.tokenBudget.used / debugInfo.tokenBudget.total * 100);
|
|
51241
|
+
const barLength = 30;
|
|
51242
|
+
const filledLength = Math.round(usagePercent / 100 * barLength);
|
|
51243
|
+
const bar = "\u2588".repeat(filledLength) + "\u2591".repeat(barLength - filledLength);
|
|
51244
|
+
const barColor = usagePercent > 80 ? chalk5.red : usagePercent > 50 ? chalk5.yellow : chalk5.green;
|
|
51245
|
+
console.log(` ${barColor(bar)} ${usagePercent}%`);
|
|
51246
|
+
if (debugInfo.providers.length > 0) {
|
|
51247
|
+
console.log(chalk5.cyan("\n\u{1F50C} Active Providers"));
|
|
51248
|
+
console.log(chalk5.dim("\u2500".repeat(40)));
|
|
51249
|
+
debugInfo.providers.forEach((provider, index) => {
|
|
51250
|
+
console.log(` ${index + 1}. ${chalk5.green(provider)}`);
|
|
51251
|
+
});
|
|
51252
|
+
}
|
|
51253
|
+
console.log(chalk5.cyan("\n\u{1F504} Workflow Modes"));
|
|
51254
|
+
console.log(chalk5.dim("\u2500".repeat(40)));
|
|
51255
|
+
Object.keys(WORKFLOW_MODES).forEach((mode) => {
|
|
51256
|
+
const isCurrent = mode === debugInfo.workflowMode;
|
|
51257
|
+
const prefix = isCurrent ? chalk5.green("\u25BA") : " ";
|
|
51258
|
+
const modeText = isCurrent ? chalk5.green.bold(mode) : chalk5.gray(mode);
|
|
51259
|
+
console.log(` ${prefix} ${modeText}`);
|
|
51260
|
+
});
|
|
51261
|
+
console.log(chalk5.dim("\n" + "\u2550".repeat(60)));
|
|
51262
|
+
console.log(chalk5.gray("\nUse --tokens, --providers, or --templates for detailed info.\n"));
|
|
51263
|
+
}
|
|
51264
|
+
function displayTokenBudget(verbose) {
|
|
51265
|
+
console.log(chalk5.blue.bold("\n\u{1F4B0} Token Budget Details\n"));
|
|
51266
|
+
console.log(chalk5.dim("\u2500".repeat(50)));
|
|
51267
|
+
const budgetManager = new TokenBudgetManager();
|
|
51268
|
+
const config = budgetManager.getConfig();
|
|
51269
|
+
console.log(`
|
|
51270
|
+
Total budget: ${chalk5.cyan(config.maxTotal)} tokens`);
|
|
51271
|
+
console.log(` Critical reserve: ${chalk5.yellow(config.criticalReserve)} tokens`);
|
|
51272
|
+
console.log(` Available: ${chalk5.green(config.maxTotal - config.criticalReserve)} tokens`);
|
|
51273
|
+
console.log(chalk5.cyan("\n Per-Type Allocations:"));
|
|
51274
|
+
const typeAllocations = [
|
|
51275
|
+
{ type: "task", budget: 500, description: "Todo/task reminders" },
|
|
51276
|
+
{ type: "memory", budget: 400, description: "Memory context" },
|
|
51277
|
+
{ type: "session", budget: 300, description: "Session state" },
|
|
51278
|
+
{ type: "delegation", budget: 300, description: "Agent delegation hints" },
|
|
51279
|
+
{ type: "mode", budget: 200, description: "Workflow mode instructions" }
|
|
51280
|
+
];
|
|
51281
|
+
typeAllocations.forEach(({ type, budget, description }) => {
|
|
51282
|
+
console.log(` \u2022 ${chalk5.cyan(type)}: ${budget} tokens`);
|
|
51283
|
+
if (verbose) {
|
|
51284
|
+
console.log(chalk5.gray(` ${description}`));
|
|
51285
|
+
}
|
|
51286
|
+
});
|
|
51287
|
+
console.log(chalk5.cyan("\n Token Estimation:"));
|
|
51288
|
+
console.log(chalk5.gray(" ~4 characters = 1 token (approximation)"));
|
|
51289
|
+
console.log(chalk5.gray(" Actual usage may vary by content"));
|
|
51290
|
+
console.log(chalk5.dim("\n\u2500".repeat(50)));
|
|
51291
|
+
console.log();
|
|
51292
|
+
}
|
|
51293
|
+
function displayProviders(verbose) {
|
|
51294
|
+
console.log(chalk5.blue.bold("\n\u{1F50C} Instruction Providers\n"));
|
|
51295
|
+
console.log(chalk5.dim("\u2500".repeat(50)));
|
|
51296
|
+
const providers = [
|
|
51297
|
+
{
|
|
51298
|
+
name: "TodoInstructionProvider",
|
|
51299
|
+
description: "Generates task reminders from todo list",
|
|
51300
|
+
triggers: "Todo state changes, periodic reminders",
|
|
51301
|
+
priority: "high"
|
|
51302
|
+
},
|
|
51303
|
+
{
|
|
51304
|
+
name: "MemoryInstructionProvider",
|
|
51305
|
+
description: "Injects relevant context from memory",
|
|
51306
|
+
triggers: "Task keywords, memory relevance",
|
|
51307
|
+
priority: "normal"
|
|
51308
|
+
},
|
|
51309
|
+
{
|
|
51310
|
+
name: "SessionInstructionProvider",
|
|
51311
|
+
description: "Shows multi-agent collaboration state",
|
|
51312
|
+
triggers: "Session changes, periodic reminders",
|
|
51313
|
+
priority: "normal"
|
|
51314
|
+
},
|
|
51315
|
+
{
|
|
51316
|
+
name: "AgentInstructionInjector",
|
|
51317
|
+
description: "Domain-specific reminders and delegation hints",
|
|
51318
|
+
triggers: "Agent domain, task keywords",
|
|
51319
|
+
priority: "normal"
|
|
51320
|
+
},
|
|
51321
|
+
{
|
|
51322
|
+
name: "WorkflowModeManager",
|
|
51323
|
+
description: "Mode-specific instructions and tool filtering",
|
|
51324
|
+
triggers: "Mode changes",
|
|
51325
|
+
priority: "high"
|
|
51326
|
+
}
|
|
51327
|
+
];
|
|
51328
|
+
providers.forEach((provider, index) => {
|
|
51329
|
+
console.log(`
|
|
51330
|
+
${index + 1}. ${chalk5.cyan.bold(provider.name)}`);
|
|
51331
|
+
console.log(chalk5.gray(` ${provider.description}`));
|
|
51332
|
+
if (verbose) {
|
|
51333
|
+
console.log(` Triggers: ${chalk5.yellow(provider.triggers)}`);
|
|
51334
|
+
console.log(` Priority: ${chalk5.green(provider.priority)}`);
|
|
51335
|
+
}
|
|
51336
|
+
});
|
|
51337
|
+
console.log(chalk5.dim("\n\u2500".repeat(50)));
|
|
51338
|
+
console.log();
|
|
51339
|
+
}
|
|
51340
|
+
function displayAgentTemplates(verbose) {
|
|
51341
|
+
console.log(chalk5.blue.bold("\n\u{1F4CB} Agent Instruction Templates\n"));
|
|
51342
|
+
console.log(chalk5.dim("\u2500".repeat(50)));
|
|
51343
|
+
for (const [domain, template] of Object.entries(AGENT_TEMPLATES)) {
|
|
51344
|
+
console.log(`
|
|
51345
|
+
${chalk5.cyan.bold(template.displayName)} (${domain})`);
|
|
51346
|
+
if (verbose) {
|
|
51347
|
+
console.log(chalk5.gray(` Reminders: ${template.domainReminders.length}`));
|
|
51348
|
+
console.log(chalk5.gray(` Checklist items: ${template.qualityChecklist.length}`));
|
|
51349
|
+
console.log(chalk5.gray(` Delegation triggers: ${template.delegationTriggers.length}`));
|
|
51350
|
+
console.log(chalk5.gray(` Anti-patterns: ${template.antiPatterns.length}`));
|
|
51351
|
+
console.log(chalk5.gray(` Best practices: ${template.bestPractices.length}`));
|
|
51352
|
+
}
|
|
51353
|
+
}
|
|
51354
|
+
console.log(chalk5.dim("\n\u2500".repeat(50)));
|
|
51355
|
+
console.log(chalk5.gray("\nUse --agent <domain> to see template details.\n"));
|
|
51356
|
+
}
|
|
51357
|
+
function displayAgentTemplate(domain, verbose) {
|
|
51358
|
+
const template = AGENT_TEMPLATES[domain];
|
|
51359
|
+
if (!template) {
|
|
51360
|
+
console.error(chalk5.red.bold(`
|
|
51361
|
+
\u274C Unknown agent domain: ${domain}
|
|
51362
|
+
`));
|
|
51363
|
+
console.log(chalk5.gray("Available domains:"));
|
|
51364
|
+
Object.keys(AGENT_TEMPLATES).forEach((d) => {
|
|
51365
|
+
console.log(chalk5.cyan(` \u2022 ${d}`));
|
|
51366
|
+
});
|
|
51367
|
+
console.log();
|
|
51368
|
+
process.exit(1);
|
|
51369
|
+
}
|
|
51370
|
+
console.log(chalk5.blue.bold(`
|
|
51371
|
+
\u{1F4CB} ${template.displayName} Agent Template
|
|
51372
|
+
`));
|
|
51373
|
+
console.log(chalk5.dim("\u2550".repeat(60)));
|
|
51374
|
+
console.log(chalk5.cyan("\n\u{1F514} Domain Reminders:"));
|
|
51375
|
+
template.domainReminders.forEach((reminder, i) => {
|
|
51376
|
+
console.log(` ${i + 1}. ${reminder}`);
|
|
51377
|
+
});
|
|
51378
|
+
console.log(chalk5.cyan("\n\u2705 Quality Checklist:"));
|
|
51379
|
+
template.qualityChecklist.forEach((item, i) => {
|
|
51380
|
+
console.log(` ${i + 1}. ${item}`);
|
|
51381
|
+
});
|
|
51382
|
+
if (template.delegationTriggers.length > 0) {
|
|
51383
|
+
console.log(chalk5.cyan("\n\u{1F500} Delegation Triggers:"));
|
|
51384
|
+
template.delegationTriggers.forEach((trigger, i) => {
|
|
51385
|
+
console.log(` ${i + 1}. \u2192 ${chalk5.yellow(trigger.suggestedAgent)}`);
|
|
51386
|
+
console.log(chalk5.gray(` Keywords: ${trigger.keywords.join(", ")}`));
|
|
51387
|
+
if (verbose) {
|
|
51388
|
+
console.log(chalk5.gray(` Reason: ${trigger.reason}`));
|
|
51389
|
+
}
|
|
51390
|
+
});
|
|
51391
|
+
}
|
|
51392
|
+
if (verbose && template.antiPatterns.length > 0) {
|
|
51393
|
+
console.log(chalk5.red("\n\u26A0\uFE0F Anti-Patterns to Avoid:"));
|
|
51394
|
+
template.antiPatterns.forEach((pattern, i) => {
|
|
51395
|
+
console.log(` ${i + 1}. ${pattern}`);
|
|
51396
|
+
});
|
|
51397
|
+
}
|
|
51398
|
+
if (verbose && template.bestPractices.length > 0) {
|
|
51399
|
+
console.log(chalk5.green("\n\u2728 Best Practices:"));
|
|
51400
|
+
template.bestPractices.forEach((practice, i) => {
|
|
51401
|
+
console.log(` ${i + 1}. ${practice}`);
|
|
51402
|
+
});
|
|
51403
|
+
}
|
|
51404
|
+
console.log(chalk5.dim("\n\u2550".repeat(60)));
|
|
51405
|
+
console.log();
|
|
51406
|
+
}
|
|
51407
|
+
|
|
48513
51408
|
// src/cli/index.ts
|
|
48514
51409
|
installExitHandlers();
|
|
48515
51410
|
var VERSION2 = getVersion();
|
|
@@ -48532,7 +51427,7 @@ globalTracker.mark("cli_start");
|
|
|
48532
51427
|
type: "string",
|
|
48533
51428
|
description: "Path to custom config file",
|
|
48534
51429
|
global: true
|
|
48535
|
-
}).command(setupCommand).command(initCommand).command(configureCommand).command(cliCommand).command(agentCommand).command(listCommand).command(runCommand).command(resumeCommand).command(runsCommand).command(sessionCommand).command(workspaceCommand).command(cacheCommand).command(configCommand).command(statusCommand4).command(doctorCommand2).command(cleanupCommand2).command(analyticsCommand).command(memoryCommand).command(mcpCommand).command(geminiCommand).command(providerLimitsCommand).command(providersCommand).command(flagsCommand).command(specCommand).command(genCommand).command(updateCommand).command(uninstallCommand).demandCommand(1, "You must provide a command. Run --help for usage.").help().version(VERSION2).alias("h", "help").alias("v", "version").strict().wrap(Math.min(120, yargs().terminalWidth())).parse();
|
|
51430
|
+
}).command(setupCommand).command(initCommand).command(configureCommand).command(cliCommand).command(agentCommand).command(listCommand).command(runCommand).command(resumeCommand).command(runsCommand).command(sessionCommand).command(workspaceCommand).command(cacheCommand).command(configCommand).command(statusCommand4).command(doctorCommand2).command(cleanupCommand2).command(analyticsCommand).command(memoryCommand).command(mcpCommand).command(geminiCommand).command(providerLimitsCommand).command(providersCommand).command(flagsCommand).command(specCommand).command(genCommand).command(updateCommand).command(uninstallCommand).command(modeCommand).command(debugInstructionsCommand).demandCommand(1, "You must provide a command. Run --help for usage.").help().version(VERSION2).alias("h", "help").alias("v", "version").strict().wrap(Math.min(120, yargs().terminalWidth())).parse();
|
|
48536
51431
|
globalTracker.mark("yargs_parse_end");
|
|
48537
51432
|
globalTracker.measure("yargs_parsing", "yargs_parse_start", "yargs_parse_end");
|
|
48538
51433
|
globalTracker.mark("options_setup_start");
|