substrate-ai 0.5.9 → 0.5.11

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-DqMnPTZa.js";
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-DCW67EQW.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-hr7YMtJF.js"
2972
+ "../run-D2sZQ66W.js"
2973
2973
  );
2974
2974
  const runStoryFn = async (opts) => {
2975
2975
  const exitCode = await runPipeline({
@@ -1,4 +1,4 @@
1
- import { registerRunCommand, runRunAction } from "./run-DqMnPTZa.js";
1
+ import { registerRunCommand, runRunAction } from "./run-DCW67EQW.js";
2
2
  import "./logger-D2fS2ccL.js";
3
3
  import "./config-migrator-DtZW1maj.js";
4
4
  import "./helpers-BihqWgVe.js";
@@ -12920,8 +12920,6 @@ var IngestionServer = class {
12920
12920
  _flushIntervalMs;
12921
12921
  _buffer;
12922
12922
  _pendingBatches = new Set();
12923
- /** Map from storyKey → DispatchContext, tracking active dispatches. */
12924
- _activeDispatches = new Map();
12925
12923
  constructor(options = {}) {
12926
12924
  this._port = options.port ?? 4318;
12927
12925
  this._batchSize = options.batchSize ?? 100;
@@ -12939,32 +12937,6 @@ var IngestionServer = class {
12939
12937
  }
12940
12938
  this._initPipeline(pipeline);
12941
12939
  }
12942
- /**
12943
- * Register an active dispatch context for a story.
12944
- * All OTLP payloads received while this context is active will be stamped
12945
- * with the dispatch context so per-phase analysis is possible.
12946
- *
12947
- * @param storyKey - The story key being dispatched
12948
- * @param context - The dispatch context to associate with this story
12949
- */
12950
- setActiveDispatch(storyKey, context) {
12951
- this._activeDispatches.set(storyKey, context);
12952
- logger$8.debug({
12953
- storyKey,
12954
- taskType: context.taskType,
12955
- phase: context.phase
12956
- }, "IngestionServer: active dispatch registered");
12957
- }
12958
- /**
12959
- * Clear the active dispatch context for a story.
12960
- * Should be called after the dispatch completes (success or failure).
12961
- *
12962
- * @param storyKey - The story key whose dispatch context should be cleared
12963
- */
12964
- clearActiveDispatch(storyKey) {
12965
- this._activeDispatches.delete(storyKey);
12966
- logger$8.debug({ storyKey }, "IngestionServer: active dispatch cleared");
12967
- }
12968
12940
  _initPipeline(pipeline) {
12969
12941
  this._buffer = new BatchBuffer({
12970
12942
  batchSize: this._batchSize,
@@ -13115,13 +13087,11 @@ var IngestionServer = class {
13115
13087
  const body = JSON.parse(bodyStr);
13116
13088
  const source = detectSource(body);
13117
13089
  const { storyKey, taskType, dispatchId } = this._extractSubstrateAttributes(body);
13118
- let dispatchContext;
13119
- if (taskType !== void 0 && dispatchId !== void 0) dispatchContext = {
13090
+ const dispatchContext = taskType !== void 0 && dispatchId !== void 0 ? {
13120
13091
  taskType,
13121
13092
  phase: taskType,
13122
13093
  dispatchId
13123
- };
13124
- else if (storyKey !== void 0) dispatchContext = this._activeDispatches.get(storyKey);
13094
+ } : void 0;
13125
13095
  const payload = {
13126
13096
  body,
13127
13097
  source,
@@ -13993,13 +13963,20 @@ var Recommender = class Recommender {
13993
13963
  });
13994
13964
  }
13995
13965
  /**
13966
+ * Categories whose growth is inherent to normal agentic work and not actionable.
13967
+ * tool_outputs grows as the agent reads files, runs commands, etc. — expected behavior.
13968
+ * conversation_history grows naturally as conversations progress.
13969
+ */
13970
+ static EXPECTED_GROWTH_CATEGORIES = new Set(["tool_outputs", "conversation_history"]);
13971
+ /**
13996
13972
  * Flag semantic categories with trend === 'growing'.
13997
13973
  * Severity is 'info' by default; 'warning' if percentage > 25%.
13974
+ * Skips categories whose growth is inherent to normal agentic work.
13998
13975
  */
13999
13976
  _runGrowingCategories(ctx) {
14000
13977
  const { categories, storyKey, sprintId, generatedAt } = ctx;
14001
13978
  if (categories.length === 0) return [];
14002
- const growing = categories.filter((c) => c.trend === "growing");
13979
+ const growing = categories.filter((c) => c.trend === "growing" && !Recommender.EXPECTED_GROWTH_CATEGORIES.has(c.category));
14003
13980
  return growing.map((cat, index) => {
14004
13981
  const severity = cat.percentage > 25 ? "warning" : "info";
14005
13982
  const actionTarget = cat.category;
@@ -14059,8 +14036,15 @@ var Recommender = class Recommender {
14059
14036
  }];
14060
14037
  }
14061
14038
  /**
14039
+ * Models known to be intentionally routed for lightweight tasks.
14040
+ * These should not be flagged as "underperforming" — the orchestrator chose them
14041
+ * deliberately for cost/speed reasons, not as a performance optimization target.
14042
+ */
14043
+ static INTENTIONAL_LIGHTWEIGHT_MODELS = new Set(["claude-haiku-4-5-20251001", "claude-haiku-4-5"]);
14044
+ /**
14062
14045
  * If more than one model is present, flag the underperforming model.
14063
14046
  * Severity is 'info' by default; 'warning' if cache efficiency gap > 20pp.
14047
+ * Skips flagging models that are intentionally routed for lightweight tasks.
14064
14048
  */
14065
14049
  _runModelComparison(ctx) {
14066
14050
  const { efficiencyScore, storyKey, sprintId, generatedAt } = ctx;
@@ -14069,6 +14053,7 @@ var Recommender = class Recommender {
14069
14053
  const sorted = [...models].sort((a, b) => b.cacheHitRate - a.cacheHitRate);
14070
14054
  const best = sorted[0];
14071
14055
  const worst = sorted[sorted.length - 1];
14056
+ if (Recommender.INTENTIONAL_LIGHTWEIGHT_MODELS.has(worst.model)) return [];
14072
14057
  if (best.model === worst.model) return [];
14073
14058
  const gapPP = (best.cacheHitRate - worst.cacheHitRate) * 100;
14074
14059
  const severity = gapPP > 20 ? "warning" : "info";
@@ -16656,7 +16641,7 @@ function createImplementationOrchestrator(deps) {
16656
16641
  const fixTemplate = await pack.getPrompt("fix-story");
16657
16642
  const storyContent = await readFile$1(storyFilePath ?? "", "utf-8");
16658
16643
  const complexity = computeStoryComplexity(storyContent);
16659
- autoApproveMaxTurns = resolveFixStoryMaxTurns(complexity.complexityScore);
16644
+ autoApproveMaxTurns = Math.max(15, Math.floor(resolveFixStoryMaxTurns(complexity.complexityScore) / 2));
16660
16645
  logComplexityResult(storyKey, complexity, autoApproveMaxTurns);
16661
16646
  let reviewFeedback;
16662
16647
  if (issueList.length === 0) reviewFeedback = `Verdict: ${verdict}\nIssues: Minor issues flagged but no specifics provided. Review the story ACs and fix any remaining gaps.`;
@@ -16760,7 +16745,8 @@ function createImplementationOrchestrator(deps) {
16760
16745
  const storyContent = await readFile$1(storyFilePath ?? "", "utf-8");
16761
16746
  {
16762
16747
  const complexity = computeStoryComplexity(storyContent);
16763
- fixMaxTurns = resolveFixStoryMaxTurns(complexity.complexityScore);
16748
+ const fullBudget = resolveFixStoryMaxTurns(complexity.complexityScore);
16749
+ fixMaxTurns = taskType === "minor-fixes" ? Math.max(15, Math.floor(fullBudget / 2)) : fullBudget;
16764
16750
  logComplexityResult(storyKey, complexity, fixMaxTurns);
16765
16751
  }
16766
16752
  let reviewFeedback;
@@ -22705,4 +22691,4 @@ function registerRunCommand(program, _version = "0.0.0", projectRoot = process.c
22705
22691
 
22706
22692
  //#endregion
22707
22693
  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 };
22708
- //# sourceMappingURL=run-DqMnPTZa.js.map
22694
+ //# sourceMappingURL=run-DCW67EQW.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "substrate-ai",
3
- "version": "0.5.9",
3
+ "version": "0.5.11",
4
4
  "description": "Substrate — multi-agent orchestration daemon for AI coding agents",
5
5
  "type": "module",
6
6
  "license": "MIT",