substrate-ai 0.5.7 → 0.5.9
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/dist/cli/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { AdapterTelemetryPersistence, AppError, DEFAULT_CONFIG, DEFAULT_ROUTING_POLICY, DoltClient, DoltNotInstalled, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, FileStateStore, GitClient, GrammarLoader, IngestionServer, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SUBSTRATE_OWNED_SETTINGS_KEYS, SymbolParser, VALID_PHASES, WorkGraphRepository, buildPipelineStatusOutput, checkDoltInstalled, createConfigSystem, createContextCompiler, createDatabaseAdapter, createDispatcher, createDoltClient, createEventEmitter, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStateStore, createStopAfterGate, createTelemetryAdvisor, detectCycles, findPackageRoot, formatOutput, formatPhaseCompletionSummary, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, initSchema, initializeDolt, isSyncAdapter, parseDbTimestampAsUtc, registerHealthCommand, registerRunCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion, resolveMainRepoRoot, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runSolutioningPhase, validateStopAfterFromConflict } from "../run-
|
|
2
|
+
import { AdapterTelemetryPersistence, AppError, DEFAULT_CONFIG, DEFAULT_ROUTING_POLICY, DoltClient, DoltNotInstalled, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, FileStateStore, GitClient, GrammarLoader, IngestionServer, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SUBSTRATE_OWNED_SETTINGS_KEYS, SymbolParser, VALID_PHASES, WorkGraphRepository, buildPipelineStatusOutput, checkDoltInstalled, createConfigSystem, createContextCompiler, createDatabaseAdapter, createDispatcher, createDoltClient, createEventEmitter, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStateStore, createStopAfterGate, createTelemetryAdvisor, detectCycles, findPackageRoot, formatOutput, formatPhaseCompletionSummary, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, initSchema, initializeDolt, isSyncAdapter, parseDbTimestampAsUtc, registerHealthCommand, registerRunCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion, resolveMainRepoRoot, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runSolutioningPhase, validateStopAfterFromConflict } from "../run-DqMnPTZa.js";
|
|
3
3
|
import { createLogger } from "../logger-D2fS2ccL.js";
|
|
4
4
|
import { AdapterRegistry } from "../adapter-registry-D2zdMwVu.js";
|
|
5
5
|
import { CURRENT_CONFIG_FORMAT_VERSION, CURRENT_TASK_GRAPH_VERSION, PartialSubstrateConfigSchema } from "../config-migrator-DtZW1maj.js";
|
|
@@ -2969,7 +2969,7 @@ async function runSupervisorAction(options, deps = {}) {
|
|
|
2969
2969
|
await initSchema(expAdapter);
|
|
2970
2970
|
const { runRunAction: runPipeline } = await import(
|
|
2971
2971
|
/* @vite-ignore */
|
|
2972
|
-
"../run-
|
|
2972
|
+
"../run-hr7YMtJF.js"
|
|
2973
2973
|
);
|
|
2974
2974
|
const runStoryFn = async (opts) => {
|
|
2975
2975
|
const exitCode = await runPipeline({
|
|
@@ -6276,7 +6276,7 @@ const DEFAULT_TIMEOUTS = {
|
|
|
6276
6276
|
"planning": 3e5,
|
|
6277
6277
|
"architecture": 3e5,
|
|
6278
6278
|
"story-generation": 3e5,
|
|
6279
|
-
"create-story":
|
|
6279
|
+
"create-story": 6e5,
|
|
6280
6280
|
"dev-story": 18e5,
|
|
6281
6281
|
"code-review": 9e5,
|
|
6282
6282
|
"minor-fixes": 6e5,
|
|
@@ -6310,7 +6310,7 @@ const DEFAULT_MAX_TURNS = {
|
|
|
6310
6310
|
"dev-story": 75,
|
|
6311
6311
|
"major-rework": 50,
|
|
6312
6312
|
"code-review": 25,
|
|
6313
|
-
"create-story":
|
|
6313
|
+
"create-story": 30,
|
|
6314
6314
|
"minor-fixes": 25,
|
|
6315
6315
|
"analysis-vision": 8,
|
|
6316
6316
|
"analysis-scope": 10,
|
|
@@ -12680,6 +12680,20 @@ var AdapterTelemetryPersistence = class {
|
|
|
12680
12680
|
});
|
|
12681
12681
|
}
|
|
12682
12682
|
/**
|
|
12683
|
+
* Delete all telemetry data for a story across all 5 telemetry tables.
|
|
12684
|
+
* Used to purge stale data from prior runs before persisting new data.
|
|
12685
|
+
*/
|
|
12686
|
+
async purgeStoryTelemetry(storyKey) {
|
|
12687
|
+
await this._adapter.transaction(async (adapter) => {
|
|
12688
|
+
await adapter.query("DELETE FROM turn_analysis WHERE story_key = ?", [storyKey]);
|
|
12689
|
+
await adapter.query("DELETE FROM efficiency_scores WHERE story_key = ?", [storyKey]);
|
|
12690
|
+
await adapter.query("DELETE FROM recommendations WHERE story_key = ?", [storyKey]);
|
|
12691
|
+
await adapter.query("DELETE FROM category_stats WHERE story_key = ?", [storyKey]);
|
|
12692
|
+
await adapter.query("DELETE FROM consumer_stats WHERE story_key = ?", [storyKey]);
|
|
12693
|
+
});
|
|
12694
|
+
logger$9.debug({ storyKey }, "Purged stale telemetry data for story");
|
|
12695
|
+
}
|
|
12696
|
+
/**
|
|
12683
12697
|
* Record a named span with arbitrary attributes.
|
|
12684
12698
|
* Currently logs the span at debug level; no DB persistence.
|
|
12685
12699
|
*/
|
|
@@ -12749,6 +12763,9 @@ var TelemetryPersistence = class {
|
|
|
12749
12763
|
async getConsumerStats(storyKey) {
|
|
12750
12764
|
return this._impl.getConsumerStats(storyKey);
|
|
12751
12765
|
}
|
|
12766
|
+
async purgeStoryTelemetry(storyKey) {
|
|
12767
|
+
return this._impl.purgeStoryTelemetry(storyKey);
|
|
12768
|
+
}
|
|
12752
12769
|
/**
|
|
12753
12770
|
* Record a named span with arbitrary attributes.
|
|
12754
12771
|
* Currently logs the span at debug level; no DB persistence.
|
|
@@ -13038,32 +13055,42 @@ var IngestionServer = class {
|
|
|
13038
13055
|
};
|
|
13039
13056
|
}
|
|
13040
13057
|
/**
|
|
13041
|
-
*
|
|
13042
|
-
*
|
|
13058
|
+
* Substrate resource attributes extracted from an OTLP payload.
|
|
13059
|
+
* These are set by ClaudeCodeAdapter via OTEL_RESOURCE_ATTRIBUTES env var.
|
|
13043
13060
|
*/
|
|
13044
|
-
|
|
13045
|
-
if (!body || typeof body !== "object") return
|
|
13061
|
+
_extractSubstrateAttributes(body) {
|
|
13062
|
+
if (!body || typeof body !== "object") return {};
|
|
13046
13063
|
const payload = body;
|
|
13047
13064
|
const extractFromResources = (resources) => {
|
|
13048
|
-
|
|
13065
|
+
const result = {};
|
|
13066
|
+
if (!Array.isArray(resources)) return result;
|
|
13049
13067
|
for (const entry of resources) {
|
|
13050
13068
|
if (!entry || typeof entry !== "object") continue;
|
|
13051
13069
|
const resource = entry.resource;
|
|
13052
13070
|
if (!resource || typeof resource !== "object") continue;
|
|
13053
|
-
const attrs = resource.attributes;
|
|
13054
|
-
if (!Array.isArray(attrs)) continue;
|
|
13055
|
-
for (const attr of attrs) {
|
|
13071
|
+
const attrs$1 = resource.attributes;
|
|
13072
|
+
if (!Array.isArray(attrs$1)) continue;
|
|
13073
|
+
for (const attr of attrs$1) {
|
|
13056
13074
|
if (!attr || typeof attr !== "object") continue;
|
|
13057
13075
|
const a = attr;
|
|
13058
|
-
|
|
13076
|
+
const key = a.key;
|
|
13077
|
+
if (key !== void 0 && key.startsWith("substrate.")) {
|
|
13059
13078
|
const val = a.value;
|
|
13060
|
-
if (val && typeof val.stringValue === "string")
|
|
13079
|
+
if (val && typeof val.stringValue === "string") result[key] = val.stringValue;
|
|
13061
13080
|
}
|
|
13062
13081
|
}
|
|
13063
13082
|
}
|
|
13064
|
-
return
|
|
13083
|
+
return result;
|
|
13084
|
+
};
|
|
13085
|
+
const attrs = {
|
|
13086
|
+
...extractFromResources(payload.resourceSpans),
|
|
13087
|
+
...extractFromResources(payload.resourceLogs)
|
|
13088
|
+
};
|
|
13089
|
+
return {
|
|
13090
|
+
storyKey: attrs["substrate.story_key"],
|
|
13091
|
+
taskType: attrs["substrate.task_type"],
|
|
13092
|
+
dispatchId: attrs["substrate.dispatch_id"]
|
|
13065
13093
|
};
|
|
13066
|
-
return extractFromResources(payload.resourceSpans) ?? extractFromResources(payload.resourceLogs);
|
|
13067
13094
|
}
|
|
13068
13095
|
_handleRequest(req, res) {
|
|
13069
13096
|
if (req.url === "/health" && req.method === "GET") {
|
|
@@ -13087,12 +13114,19 @@ var IngestionServer = class {
|
|
|
13087
13114
|
if (this._buffer !== void 0) try {
|
|
13088
13115
|
const body = JSON.parse(bodyStr);
|
|
13089
13116
|
const source = detectSource(body);
|
|
13090
|
-
const storyKey = this.
|
|
13091
|
-
|
|
13117
|
+
const { storyKey, taskType, dispatchId } = this._extractSubstrateAttributes(body);
|
|
13118
|
+
let dispatchContext;
|
|
13119
|
+
if (taskType !== void 0 && dispatchId !== void 0) dispatchContext = {
|
|
13120
|
+
taskType,
|
|
13121
|
+
phase: taskType,
|
|
13122
|
+
dispatchId
|
|
13123
|
+
};
|
|
13124
|
+
else if (storyKey !== void 0) dispatchContext = this._activeDispatches.get(storyKey);
|
|
13092
13125
|
const payload = {
|
|
13093
13126
|
body,
|
|
13094
13127
|
source,
|
|
13095
13128
|
receivedAt: Date.now(),
|
|
13129
|
+
storyKey,
|
|
13096
13130
|
...dispatchContext !== void 0 && { dispatchContext }
|
|
13097
13131
|
};
|
|
13098
13132
|
this._buffer.push(payload);
|
|
@@ -13723,7 +13757,7 @@ var ConsumerAnalyzer = class {
|
|
|
13723
13757
|
|
|
13724
13758
|
//#endregion
|
|
13725
13759
|
//#region src/modules/telemetry/recommender.ts
|
|
13726
|
-
var Recommender = class {
|
|
13760
|
+
var Recommender = class Recommender {
|
|
13727
13761
|
_logger;
|
|
13728
13762
|
constructor(logger$27) {
|
|
13729
13763
|
this._logger = logger$27;
|
|
@@ -13781,8 +13815,21 @@ var Recommender = class {
|
|
|
13781
13815
|
return spans.reduce((sum, s) => sum + s.inputTokens + s.outputTokens, 0);
|
|
13782
13816
|
}
|
|
13783
13817
|
/**
|
|
13784
|
-
*
|
|
13785
|
-
*
|
|
13818
|
+
* Minimum absolute token count for a consumer to be flagged.
|
|
13819
|
+
* Below this, the consumer is too small to be actionable regardless of percentage.
|
|
13820
|
+
*/
|
|
13821
|
+
static MIN_SIGNIFICANT_TOKENS = 1e4;
|
|
13822
|
+
/**
|
|
13823
|
+
* Identify top 3 token consumers (by inputTokens + outputTokens) where pct >5%
|
|
13824
|
+
* AND absolute tokens exceed MIN_SIGNIFICANT_TOKENS.
|
|
13825
|
+
*
|
|
13826
|
+
* Filters out model-only consumers (empty toolName, format "model|") since those
|
|
13827
|
+
* just indicate which model ran — not an actionable optimization target.
|
|
13828
|
+
*
|
|
13829
|
+
* Severity factors both percentage share and absolute magnitude:
|
|
13830
|
+
* - percentage-based tier via _assignSeverity()
|
|
13831
|
+
* - capped at 'warning' when absolute tokens < 50,000
|
|
13832
|
+
* - capped at 'info' when absolute tokens < 20,000
|
|
13786
13833
|
*/
|
|
13787
13834
|
_runBiggestConsumers(ctx) {
|
|
13788
13835
|
const { consumers, storyKey, sprintId, generatedAt } = ctx;
|
|
@@ -13791,11 +13838,18 @@ var Recommender = class {
|
|
|
13791
13838
|
if (grandTotal === 0) return [];
|
|
13792
13839
|
const sorted = [...consumers].sort((a, b) => b.totalTokens - a.totalTokens);
|
|
13793
13840
|
const top3 = sorted.slice(0, 3).filter((c) => {
|
|
13794
|
-
|
|
13841
|
+
if (c.percentage <= 5) return false;
|
|
13842
|
+
if (c.totalTokens < Recommender.MIN_SIGNIFICANT_TOKENS) return false;
|
|
13843
|
+
if (c.consumerKey.endsWith("|") && !c.consumerKey.includes("|", 0)) return false;
|
|
13844
|
+
const parts = c.consumerKey.split("|");
|
|
13845
|
+
if (parts.length === 2 && parts[1] === "") return false;
|
|
13846
|
+
return true;
|
|
13795
13847
|
});
|
|
13796
13848
|
return top3.map((consumer, index) => {
|
|
13797
13849
|
const pct = consumer.percentage;
|
|
13798
|
-
|
|
13850
|
+
let severity = this._assignSeverity(pct);
|
|
13851
|
+
if (consumer.totalTokens < 2e4 && severity !== "info") severity = "info";
|
|
13852
|
+
else if (consumer.totalTokens < 5e4 && severity === "critical") severity = "warning";
|
|
13799
13853
|
const actionTarget = consumer.consumerKey;
|
|
13800
13854
|
const id = this._makeId("biggest_consumers", storyKey, actionTarget, index);
|
|
13801
13855
|
return {
|
|
@@ -14815,6 +14869,8 @@ var TelemetryPipeline = class {
|
|
|
14815
14869
|
_efficiencyScorer;
|
|
14816
14870
|
_recommender;
|
|
14817
14871
|
_persistence;
|
|
14872
|
+
/** Stories that have had stale telemetry purged this pipeline lifetime. */
|
|
14873
|
+
_purgedStories = new Set();
|
|
14818
14874
|
constructor(deps) {
|
|
14819
14875
|
this._normalizer = deps.normalizer;
|
|
14820
14876
|
this._turnAnalyzer = deps.turnAnalyzer;
|
|
@@ -15054,6 +15110,13 @@ var TelemetryPipeline = class {
|
|
|
15054
15110
|
*/
|
|
15055
15111
|
async _persistStoryData(storyKey, data) {
|
|
15056
15112
|
const { turns, efficiencyScore, categoryStats, consumerStats, recommendations, dispatchScores } = data;
|
|
15113
|
+
if (!this._purgedStories.has(storyKey)) {
|
|
15114
|
+
this._purgedStories.add(storyKey);
|
|
15115
|
+
await this._persistence.purgeStoryTelemetry(storyKey).catch((err) => logger$7.warn({
|
|
15116
|
+
err,
|
|
15117
|
+
storyKey
|
|
15118
|
+
}, "Failed to purge stale telemetry — continuing with persist"));
|
|
15119
|
+
}
|
|
15057
15120
|
await Promise.all([
|
|
15058
15121
|
turns.length > 0 ? this._persistence.storeTurnAnalysis(storyKey, turns).catch((err) => logger$7.warn({
|
|
15059
15122
|
err,
|
|
@@ -22642,4 +22705,4 @@ function registerRunCommand(program, _version = "0.0.0", projectRoot = process.c
|
|
|
22642
22705
|
|
|
22643
22706
|
//#endregion
|
|
22644
22707
|
export { AdapterTelemetryPersistence, AppError, DEFAULT_CONFIG, DEFAULT_ROUTING_POLICY, DoltClient, DoltNotInstalled, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, FileStateStore, GitClient, GrammarLoader, IngestionServer, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SUBSTRATE_OWNED_SETTINGS_KEYS, SymbolParser, VALID_PHASES, WorkGraphRepository, buildPipelineStatusOutput, checkDoltInstalled, createConfigSystem, createContextCompiler, createDatabaseAdapter, createDispatcher, createDoltClient, createEventEmitter, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStateStore, createStopAfterGate, createTelemetryAdvisor, detectCycles, findPackageRoot, formatOutput, formatPhaseCompletionSummary, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, initSchema, initializeDolt, isSyncAdapter, parseDbTimestampAsUtc, registerHealthCommand, registerRunCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion, resolveMainRepoRoot, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runRunAction, runSolutioningPhase, validateStopAfterFromConflict };
|
|
22645
|
-
//# sourceMappingURL=run-
|
|
22708
|
+
//# sourceMappingURL=run-DqMnPTZa.js.map
|