@gracker/smartperfetto 1.0.13
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/.env.example +586 -0
- package/LICENSE +685 -0
- package/data/perfettoSqlDocs.json +33478 -0
- package/data/perfettoSqlIndex.json +9458 -0
- package/data/perfettoSqlIndex.light.json +13129 -0
- package/data/perfettoStdlibSymbols.json +677 -0
- package/dist/agent/agents/base/baseAgent.d.ts +378 -0
- package/dist/agent/agents/base/baseAgent.d.ts.map +1 -0
- package/dist/agent/agents/base/baseAgent.js +1484 -0
- package/dist/agent/agents/base/baseAgent.js.map +1 -0
- package/dist/agent/agents/base/baseSubAgent.d.ts +135 -0
- package/dist/agent/agents/base/baseSubAgent.d.ts.map +1 -0
- package/dist/agent/agents/base/baseSubAgent.js +483 -0
- package/dist/agent/agents/base/baseSubAgent.js.map +1 -0
- package/dist/agent/agents/baseExpertAgent.d.ts +37 -0
- package/dist/agent/agents/baseExpertAgent.d.ts.map +1 -0
- package/dist/agent/agents/baseExpertAgent.js +322 -0
- package/dist/agent/agents/baseExpertAgent.js.map +1 -0
- package/dist/agent/agents/domain/additionalAgents.d.ts +54 -0
- package/dist/agent/agents/domain/additionalAgents.d.ts.map +1 -0
- package/dist/agent/agents/domain/additionalAgents.js +292 -0
- package/dist/agent/agents/domain/additionalAgents.js.map +1 -0
- package/dist/agent/agents/domain/binderAgent.d.ts +27 -0
- package/dist/agent/agents/domain/binderAgent.d.ts.map +1 -0
- package/dist/agent/agents/domain/binderAgent.js +100 -0
- package/dist/agent/agents/domain/binderAgent.js.map +1 -0
- package/dist/agent/agents/domain/cpuAgent.d.ts +35 -0
- package/dist/agent/agents/domain/cpuAgent.d.ts.map +1 -0
- package/dist/agent/agents/domain/cpuAgent.js +163 -0
- package/dist/agent/agents/domain/cpuAgent.js.map +1 -0
- package/dist/agent/agents/domain/frameAgent.d.ts +59 -0
- package/dist/agent/agents/domain/frameAgent.d.ts.map +1 -0
- package/dist/agent/agents/domain/frameAgent.js +511 -0
- package/dist/agent/agents/domain/frameAgent.js.map +1 -0
- package/dist/agent/agents/domain/index.d.ts +92 -0
- package/dist/agent/agents/domain/index.d.ts.map +1 -0
- package/dist/agent/agents/domain/index.js +250 -0
- package/dist/agent/agents/domain/index.js.map +1 -0
- package/dist/agent/agents/domain/memoryAgent.d.ts +26 -0
- package/dist/agent/agents/domain/memoryAgent.d.ts.map +1 -0
- package/dist/agent/agents/domain/memoryAgent.js +94 -0
- package/dist/agent/agents/domain/memoryAgent.js.map +1 -0
- package/dist/agent/agents/domain/skillCatalog.d.ts +10 -0
- package/dist/agent/agents/domain/skillCatalog.d.ts.map +1 -0
- package/dist/agent/agents/domain/skillCatalog.js +66 -0
- package/dist/agent/agents/domain/skillCatalog.js.map +1 -0
- package/dist/agent/agents/evaluatorAgent.d.ts +76 -0
- package/dist/agent/agents/evaluatorAgent.d.ts.map +1 -0
- package/dist/agent/agents/evaluatorAgent.js +517 -0
- package/dist/agent/agents/evaluatorAgent.js.map +1 -0
- package/dist/agent/agents/index.d.ts +13 -0
- package/dist/agent/agents/index.d.ts.map +1 -0
- package/dist/agent/agents/index.js +25 -0
- package/dist/agent/agents/index.js.map +1 -0
- package/dist/agent/agents/iterationStrategyPlanner.d.ts +140 -0
- package/dist/agent/agents/iterationStrategyPlanner.d.ts.map +1 -0
- package/dist/agent/agents/iterationStrategyPlanner.js +359 -0
- package/dist/agent/agents/iterationStrategyPlanner.js.map +1 -0
- package/dist/agent/agents/plannerAgent.d.ts +56 -0
- package/dist/agent/agents/plannerAgent.d.ts.map +1 -0
- package/dist/agent/agents/plannerAgent.js +379 -0
- package/dist/agent/agents/plannerAgent.js.map +1 -0
- package/dist/agent/agents/scrollingExpertAgent.d.ts +11 -0
- package/dist/agent/agents/scrollingExpertAgent.d.ts.map +1 -0
- package/dist/agent/agents/scrollingExpertAgent.js +132 -0
- package/dist/agent/agents/scrollingExpertAgent.js.map +1 -0
- package/dist/agent/agents/tools/adbTools.d.ts +5 -0
- package/dist/agent/agents/tools/adbTools.d.ts.map +1 -0
- package/dist/agent/agents/tools/adbTools.js +326 -0
- package/dist/agent/agents/tools/adbTools.js.map +1 -0
- package/dist/agent/communication/agentMessageBus.d.ts +138 -0
- package/dist/agent/communication/agentMessageBus.d.ts.map +1 -0
- package/dist/agent/communication/agentMessageBus.js +542 -0
- package/dist/agent/communication/agentMessageBus.js.map +1 -0
- package/dist/agent/communication/index.d.ts +7 -0
- package/dist/agent/communication/index.d.ts.map +1 -0
- package/dist/agent/communication/index.js +15 -0
- package/dist/agent/communication/index.js.map +1 -0
- package/dist/agent/compaction/compactionTypes.d.ts +163 -0
- package/dist/agent/compaction/compactionTypes.d.ts.map +1 -0
- package/dist/agent/compaction/compactionTypes.js +32 -0
- package/dist/agent/compaction/compactionTypes.js.map +1 -0
- package/dist/agent/compaction/contextCompactor.d.ts +109 -0
- package/dist/agent/compaction/contextCompactor.d.ts.map +1 -0
- package/dist/agent/compaction/contextCompactor.js +225 -0
- package/dist/agent/compaction/contextCompactor.js.map +1 -0
- package/dist/agent/compaction/index.d.ts +10 -0
- package/dist/agent/compaction/index.d.ts.map +1 -0
- package/dist/agent/compaction/index.js +43 -0
- package/dist/agent/compaction/index.js.map +1 -0
- package/dist/agent/compaction/strategies/index.d.ts +5 -0
- package/dist/agent/compaction/strategies/index.d.ts.map +1 -0
- package/dist/agent/compaction/strategies/index.js +13 -0
- package/dist/agent/compaction/strategies/index.js.map +1 -0
- package/dist/agent/compaction/strategies/slidingWindowStrategy.d.ts +53 -0
- package/dist/agent/compaction/strategies/slidingWindowStrategy.d.ts.map +1 -0
- package/dist/agent/compaction/strategies/slidingWindowStrategy.js +237 -0
- package/dist/agent/compaction/strategies/slidingWindowStrategy.js.map +1 -0
- package/dist/agent/compaction/tokenEstimator.d.ts +78 -0
- package/dist/agent/compaction/tokenEstimator.d.ts.map +1 -0
- package/dist/agent/compaction/tokenEstimator.js +203 -0
- package/dist/agent/compaction/tokenEstimator.js.map +1 -0
- package/dist/agent/config/decisionThresholdManifest.d.ts +72 -0
- package/dist/agent/config/decisionThresholdManifest.d.ts.map +1 -0
- package/dist/agent/config/decisionThresholdManifest.js +77 -0
- package/dist/agent/config/decisionThresholdManifest.js.map +1 -0
- package/dist/agent/config/domainManifest.d.ts +77 -0
- package/dist/agent/config/domainManifest.d.ts.map +1 -0
- package/dist/agent/config/domainManifest.js +269 -0
- package/dist/agent/config/domainManifest.js.map +1 -0
- package/dist/agent/config/drillDownRegistry.d.ts +19 -0
- package/dist/agent/config/drillDownRegistry.d.ts.map +1 -0
- package/dist/agent/config/drillDownRegistry.js +118 -0
- package/dist/agent/config/drillDownRegistry.js.map +1 -0
- package/dist/agent/context/contextBuilder.d.ts +79 -0
- package/dist/agent/context/contextBuilder.d.ts.map +1 -0
- package/dist/agent/context/contextBuilder.js +273 -0
- package/dist/agent/context/contextBuilder.js.map +1 -0
- package/dist/agent/context/contextTypes.d.ts +121 -0
- package/dist/agent/context/contextTypes.d.ts.map +1 -0
- package/dist/agent/context/contextTypes.js +14 -0
- package/dist/agent/context/contextTypes.js.map +1 -0
- package/dist/agent/context/enhancedSessionContext.d.ts +283 -0
- package/dist/agent/context/enhancedSessionContext.d.ts.map +1 -0
- package/dist/agent/context/enhancedSessionContext.js +1636 -0
- package/dist/agent/context/enhancedSessionContext.js.map +1 -0
- package/dist/agent/context/entityStore.d.ts +374 -0
- package/dist/agent/context/entityStore.d.ts.map +1 -0
- package/dist/agent/context/entityStore.js +621 -0
- package/dist/agent/context/entityStore.js.map +1 -0
- package/dist/agent/context/focusStore.d.ts +229 -0
- package/dist/agent/context/focusStore.d.ts.map +1 -0
- package/dist/agent/context/focusStore.js +528 -0
- package/dist/agent/context/focusStore.js.map +1 -0
- package/dist/agent/context/index.d.ts +10 -0
- package/dist/agent/context/index.d.ts.map +1 -0
- package/dist/agent/context/index.js +42 -0
- package/dist/agent/context/index.js.map +1 -0
- package/dist/agent/context/policies/evaluatorPolicy.d.ts +22 -0
- package/dist/agent/context/policies/evaluatorPolicy.d.ts.map +1 -0
- package/dist/agent/context/policies/evaluatorPolicy.js +82 -0
- package/dist/agent/context/policies/evaluatorPolicy.js.map +1 -0
- package/dist/agent/context/policies/index.d.ts +7 -0
- package/dist/agent/context/policies/index.d.ts.map +1 -0
- package/dist/agent/context/policies/index.js +18 -0
- package/dist/agent/context/policies/index.js.map +1 -0
- package/dist/agent/context/policies/plannerPolicy.d.ts +27 -0
- package/dist/agent/context/policies/plannerPolicy.d.ts.map +1 -0
- package/dist/agent/context/policies/plannerPolicy.js +67 -0
- package/dist/agent/context/policies/plannerPolicy.js.map +1 -0
- package/dist/agent/context/policies/workerPolicy.d.ts +29 -0
- package/dist/agent/context/policies/workerPolicy.d.ts.map +1 -0
- package/dist/agent/context/policies/workerPolicy.js +99 -0
- package/dist/agent/context/policies/workerPolicy.js.map +1 -0
- package/dist/agent/core/circuitBreaker.d.ts +150 -0
- package/dist/agent/core/circuitBreaker.d.ts.map +1 -0
- package/dist/agent/core/circuitBreaker.js +500 -0
- package/dist/agent/core/circuitBreaker.js.map +1 -0
- package/dist/agent/core/conclusionContract.d.ts +61 -0
- package/dist/agent/core/conclusionContract.d.ts.map +1 -0
- package/dist/agent/core/conclusionContract.js +6 -0
- package/dist/agent/core/conclusionContract.js.map +1 -0
- package/dist/agent/core/conclusionGenerator.d.ts +42 -0
- package/dist/agent/core/conclusionGenerator.d.ts.map +1 -0
- package/dist/agent/core/conclusionGenerator.js +4109 -0
- package/dist/agent/core/conclusionGenerator.js.map +1 -0
- package/dist/agent/core/conclusionSceneTemplates.d.ts +8 -0
- package/dist/agent/core/conclusionSceneTemplates.d.ts.map +1 -0
- package/dist/agent/core/conclusionSceneTemplates.js +31 -0
- package/dist/agent/core/conclusionSceneTemplates.js.map +1 -0
- package/dist/agent/core/drillDownResolver.d.ts +67 -0
- package/dist/agent/core/drillDownResolver.d.ts.map +1 -0
- package/dist/agent/core/drillDownResolver.js +583 -0
- package/dist/agent/core/drillDownResolver.js.map +1 -0
- package/dist/agent/core/emittedEnvelopeRegistry.d.ts +75 -0
- package/dist/agent/core/emittedEnvelopeRegistry.d.ts.map +1 -0
- package/dist/agent/core/emittedEnvelopeRegistry.js +164 -0
- package/dist/agent/core/emittedEnvelopeRegistry.js.map +1 -0
- package/dist/agent/core/entityCapture.d.ts +53 -0
- package/dist/agent/core/entityCapture.d.ts.map +1 -0
- package/dist/agent/core/entityCapture.js +522 -0
- package/dist/agent/core/entityCapture.js.map +1 -0
- package/dist/agent/core/entityRegistry.d.ts +19 -0
- package/dist/agent/core/entityRegistry.d.ts.map +1 -0
- package/dist/agent/core/entityRegistry.js +102 -0
- package/dist/agent/core/entityRegistry.js.map +1 -0
- package/dist/agent/core/executors/analysisExecutor.d.ts +21 -0
- package/dist/agent/core/executors/analysisExecutor.d.ts.map +1 -0
- package/dist/agent/core/executors/analysisExecutor.js +6 -0
- package/dist/agent/core/executors/analysisExecutor.js.map +1 -0
- package/dist/agent/core/executors/clarifyExecutor.d.ts +42 -0
- package/dist/agent/core/executors/clarifyExecutor.d.ts.map +1 -0
- package/dist/agent/core/executors/clarifyExecutor.js +316 -0
- package/dist/agent/core/executors/clarifyExecutor.js.map +1 -0
- package/dist/agent/core/executors/comparisonExecutor.d.ts +39 -0
- package/dist/agent/core/executors/comparisonExecutor.d.ts.map +1 -0
- package/dist/agent/core/executors/comparisonExecutor.js +404 -0
- package/dist/agent/core/executors/comparisonExecutor.js.map +1 -0
- package/dist/agent/core/executors/directDrillDownExecutor.d.ts +56 -0
- package/dist/agent/core/executors/directDrillDownExecutor.d.ts.map +1 -0
- package/dist/agent/core/executors/directDrillDownExecutor.js +665 -0
- package/dist/agent/core/executors/directDrillDownExecutor.js.map +1 -0
- package/dist/agent/core/executors/directSkillExecutor.d.ts +106 -0
- package/dist/agent/core/executors/directSkillExecutor.d.ts.map +1 -0
- package/dist/agent/core/executors/directSkillExecutor.js +633 -0
- package/dist/agent/core/executors/directSkillExecutor.js.map +1 -0
- package/dist/agent/core/executors/extendExecutor.d.ts +50 -0
- package/dist/agent/core/executors/extendExecutor.d.ts.map +1 -0
- package/dist/agent/core/executors/extendExecutor.js +402 -0
- package/dist/agent/core/executors/extendExecutor.js.map +1 -0
- package/dist/agent/core/executors/hypothesisExecutor.d.ts +52 -0
- package/dist/agent/core/executors/hypothesisExecutor.d.ts.map +1 -0
- package/dist/agent/core/executors/hypothesisExecutor.js +564 -0
- package/dist/agent/core/executors/hypothesisExecutor.js.map +1 -0
- package/dist/agent/core/executors/index.d.ts +9 -0
- package/dist/agent/core/executors/index.d.ts.map +1 -0
- package/dist/agent/core/executors/index.js +15 -0
- package/dist/agent/core/executors/index.js.map +1 -0
- package/dist/agent/core/executors/strategy/strategyFrameEnvelopeCoordinator.d.ts +12 -0
- package/dist/agent/core/executors/strategy/strategyFrameEnvelopeCoordinator.d.ts.map +1 -0
- package/dist/agent/core/executors/strategy/strategyFrameEnvelopeCoordinator.js +186 -0
- package/dist/agent/core/executors/strategy/strategyFrameEnvelopeCoordinator.js.map +1 -0
- package/dist/agent/core/executors/strategy/strategyFrameMechanismCollector.d.ts +9 -0
- package/dist/agent/core/executors/strategy/strategyFrameMechanismCollector.d.ts.map +1 -0
- package/dist/agent/core/executors/strategy/strategyFrameMechanismCollector.js +123 -0
- package/dist/agent/core/executors/strategy/strategyFrameMechanismCollector.js.map +1 -0
- package/dist/agent/core/executors/strategy/strategyStagePlanner.d.ts +18 -0
- package/dist/agent/core/executors/strategy/strategyStagePlanner.d.ts.map +1 -0
- package/dist/agent/core/executors/strategy/strategyStagePlanner.js +69 -0
- package/dist/agent/core/executors/strategy/strategyStagePlanner.js.map +1 -0
- package/dist/agent/core/executors/strategy/strategyStageTaskBuilder.d.ts +14 -0
- package/dist/agent/core/executors/strategy/strategyStageTaskBuilder.d.ts.map +1 -0
- package/dist/agent/core/executors/strategy/strategyStageTaskBuilder.js +129 -0
- package/dist/agent/core/executors/strategy/strategyStageTaskBuilder.js.map +1 -0
- package/dist/agent/core/executors/strategyExecutor.d.ts +16 -0
- package/dist/agent/core/executors/strategyExecutor.d.ts.map +1 -0
- package/dist/agent/core/executors/strategyExecutor.js +377 -0
- package/dist/agent/core/executors/strategyExecutor.js.map +1 -0
- package/dist/agent/core/executors/traceConfigDetector.d.ts +28 -0
- package/dist/agent/core/executors/traceConfigDetector.d.ts.map +1 -0
- package/dist/agent/core/executors/traceConfigDetector.js +156 -0
- package/dist/agent/core/executors/traceConfigDetector.js.map +1 -0
- package/dist/agent/core/feedbackSynthesizer.d.ts +28 -0
- package/dist/agent/core/feedbackSynthesizer.d.ts.map +1 -0
- package/dist/agent/core/feedbackSynthesizer.js +841 -0
- package/dist/agent/core/feedbackSynthesizer.js.map +1 -0
- package/dist/agent/core/followUpHandler.d.ts +36 -0
- package/dist/agent/core/followUpHandler.d.ts.map +1 -0
- package/dist/agent/core/followUpHandler.js +413 -0
- package/dist/agent/core/followUpHandler.js.map +1 -0
- package/dist/agent/core/hypothesisGenerator.d.ts +45 -0
- package/dist/agent/core/hypothesisGenerator.d.ts.map +1 -0
- package/dist/agent/core/hypothesisGenerator.js +257 -0
- package/dist/agent/core/hypothesisGenerator.js.map +1 -0
- package/dist/agent/core/incrementalAnalyzer.d.ts +164 -0
- package/dist/agent/core/incrementalAnalyzer.d.ts.map +1 -0
- package/dist/agent/core/incrementalAnalyzer.js +382 -0
- package/dist/agent/core/incrementalAnalyzer.js.map +1 -0
- package/dist/agent/core/index.d.ts +25 -0
- package/dist/agent/core/index.d.ts.map +1 -0
- package/dist/agent/core/index.js +61 -0
- package/dist/agent/core/index.js.map +1 -0
- package/dist/agent/core/intentUnderstanding.d.ts +28 -0
- package/dist/agent/core/intentUnderstanding.d.ts.map +1 -0
- package/dist/agent/core/intentUnderstanding.js +451 -0
- package/dist/agent/core/intentUnderstanding.js.map +1 -0
- package/dist/agent/core/interventionController.d.ts +211 -0
- package/dist/agent/core/interventionController.d.ts.map +1 -0
- package/dist/agent/core/interventionController.js +477 -0
- package/dist/agent/core/interventionController.js.map +1 -0
- package/dist/agent/core/jankCauseSummarizer.d.ts +87 -0
- package/dist/agent/core/jankCauseSummarizer.d.ts.map +1 -0
- package/dist/agent/core/jankCauseSummarizer.js +432 -0
- package/dist/agent/core/jankCauseSummarizer.js.map +1 -0
- package/dist/agent/core/modelRouter.d.ts +164 -0
- package/dist/agent/core/modelRouter.d.ts.map +1 -0
- package/dist/agent/core/modelRouter.js +1169 -0
- package/dist/agent/core/modelRouter.js.map +1 -0
- package/dist/agent/core/modelRouterSingleton.d.ts +4 -0
- package/dist/agent/core/modelRouterSingleton.d.ts.map +1 -0
- package/dist/agent/core/modelRouterSingleton.js +20 -0
- package/dist/agent/core/modelRouterSingleton.js.map +1 -0
- package/dist/agent/core/orchestratorTypes.d.ts +506 -0
- package/dist/agent/core/orchestratorTypes.d.ts.map +1 -0
- package/dist/agent/core/orchestratorTypes.js +91 -0
- package/dist/agent/core/orchestratorTypes.js.map +1 -0
- package/dist/agent/core/pipelineExecutor.d.ts +154 -0
- package/dist/agent/core/pipelineExecutor.d.ts.map +1 -0
- package/dist/agent/core/pipelineExecutor.js +677 -0
- package/dist/agent/core/pipelineExecutor.js.map +1 -0
- package/dist/agent/core/scenePolicy.d.ts +3 -0
- package/dist/agent/core/scenePolicy.d.ts.map +1 -0
- package/dist/agent/core/scenePolicy.js +49 -0
- package/dist/agent/core/scenePolicy.js.map +1 -0
- package/dist/agent/core/sceneRouter.d.ts +8 -0
- package/dist/agent/core/sceneRouter.d.ts.map +1 -0
- package/dist/agent/core/sceneRouter.js +122 -0
- package/dist/agent/core/sceneRouter.js.map +1 -0
- package/dist/agent/core/sceneTaxonomy.d.ts +6 -0
- package/dist/agent/core/sceneTaxonomy.d.ts.map +1 -0
- package/dist/agent/core/sceneTaxonomy.js +83 -0
- package/dist/agent/core/sceneTaxonomy.js.map +1 -0
- package/dist/agent/core/sceneTemplateStore.d.ts +10 -0
- package/dist/agent/core/sceneTemplateStore.d.ts.map +1 -0
- package/dist/agent/core/sceneTemplateStore.js +244 -0
- package/dist/agent/core/sceneTemplateStore.js.map +1 -0
- package/dist/agent/core/sceneTemplateValidator.d.ts +22 -0
- package/dist/agent/core/sceneTemplateValidator.d.ts.map +1 -0
- package/dist/agent/core/sceneTemplateValidator.js +226 -0
- package/dist/agent/core/sceneTemplateValidator.js.map +1 -0
- package/dist/agent/core/sceneTypes.d.ts +53 -0
- package/dist/agent/core/sceneTypes.d.ts.map +1 -0
- package/dist/agent/core/sceneTypes.js +6 -0
- package/dist/agent/core/sceneTypes.js.map +1 -0
- package/dist/agent/core/stateMachine.d.ts +135 -0
- package/dist/agent/core/stateMachine.d.ts.map +1 -0
- package/dist/agent/core/stateMachine.js +516 -0
- package/dist/agent/core/stateMachine.js.map +1 -0
- package/dist/agent/core/strategySelector.d.ts +121 -0
- package/dist/agent/core/strategySelector.d.ts.map +1 -0
- package/dist/agent/core/strategySelector.js +344 -0
- package/dist/agent/core/strategySelector.js.map +1 -0
- package/dist/agent/core/taskGraphExecutor.d.ts +30 -0
- package/dist/agent/core/taskGraphExecutor.d.ts.map +1 -0
- package/dist/agent/core/taskGraphExecutor.js +142 -0
- package/dist/agent/core/taskGraphExecutor.js.map +1 -0
- package/dist/agent/core/taskGraphPlanner.d.ts +33 -0
- package/dist/agent/core/taskGraphPlanner.d.ts.map +1 -0
- package/dist/agent/core/taskGraphPlanner.js +312 -0
- package/dist/agent/core/taskGraphPlanner.js.map +1 -0
- package/dist/agent/decision/decisionTreeExecutor.d.ts +55 -0
- package/dist/agent/decision/decisionTreeExecutor.d.ts.map +1 -0
- package/dist/agent/decision/decisionTreeExecutor.js +250 -0
- package/dist/agent/decision/decisionTreeExecutor.js.map +1 -0
- package/dist/agent/decision/decisionTreeStageExecutor.d.ts +65 -0
- package/dist/agent/decision/decisionTreeStageExecutor.d.ts.map +1 -0
- package/dist/agent/decision/decisionTreeStageExecutor.js +286 -0
- package/dist/agent/decision/decisionTreeStageExecutor.js.map +1 -0
- package/dist/agent/decision/index.d.ts +27 -0
- package/dist/agent/decision/index.d.ts.map +1 -0
- package/dist/agent/decision/index.js +70 -0
- package/dist/agent/decision/index.js.map +1 -0
- package/dist/agent/decision/skillExecutorAdapter.d.ts +89 -0
- package/dist/agent/decision/skillExecutorAdapter.d.ts.map +1 -0
- package/dist/agent/decision/skillExecutorAdapter.js +447 -0
- package/dist/agent/decision/skillExecutorAdapter.js.map +1 -0
- package/dist/agent/decision/trees/index.d.ts +8 -0
- package/dist/agent/decision/trees/index.d.ts.map +1 -0
- package/dist/agent/decision/trees/index.js +16 -0
- package/dist/agent/decision/trees/index.js.map +1 -0
- package/dist/agent/decision/trees/launchDecisionTree.d.ts +7 -0
- package/dist/agent/decision/trees/launchDecisionTree.d.ts.map +1 -0
- package/dist/agent/decision/trees/launchDecisionTree.js +670 -0
- package/dist/agent/decision/trees/launchDecisionTree.js.map +1 -0
- package/dist/agent/decision/trees/scrollingDecisionTree.d.ts +7 -0
- package/dist/agent/decision/trees/scrollingDecisionTree.d.ts.map +1 -0
- package/dist/agent/decision/trees/scrollingDecisionTree.js +698 -0
- package/dist/agent/decision/trees/scrollingDecisionTree.js.map +1 -0
- package/dist/agent/decision/types.d.ts +191 -0
- package/dist/agent/decision/types.d.ts.map +1 -0
- package/dist/agent/decision/types.js +6 -0
- package/dist/agent/decision/types.js.map +1 -0
- package/dist/agent/detectors/architectureDetector.d.ts +31 -0
- package/dist/agent/detectors/architectureDetector.d.ts.map +1 -0
- package/dist/agent/detectors/architectureDetector.js +190 -0
- package/dist/agent/detectors/architectureDetector.js.map +1 -0
- package/dist/agent/detectors/index.d.ts +11 -0
- package/dist/agent/detectors/index.d.ts.map +1 -0
- package/dist/agent/detectors/index.js +36 -0
- package/dist/agent/detectors/index.js.map +1 -0
- package/dist/agent/detectors/types.d.ts +113 -0
- package/dist/agent/detectors/types.d.ts.map +1 -0
- package/dist/agent/detectors/types.js +6 -0
- package/dist/agent/detectors/types.js.map +1 -0
- package/dist/agent/evalSystem.d.ts +61 -0
- package/dist/agent/evalSystem.d.ts.map +1 -0
- package/dist/agent/evalSystem.js +210 -0
- package/dist/agent/evalSystem.js.map +1 -0
- package/dist/agent/experts/base/baseExpert.d.ts +108 -0
- package/dist/agent/experts/base/baseExpert.d.ts.map +1 -0
- package/dist/agent/experts/base/baseExpert.js +359 -0
- package/dist/agent/experts/base/baseExpert.js.map +1 -0
- package/dist/agent/experts/base/index.d.ts +9 -0
- package/dist/agent/experts/base/index.d.ts.map +1 -0
- package/dist/agent/experts/base/index.js +15 -0
- package/dist/agent/experts/base/index.js.map +1 -0
- package/dist/agent/experts/base/types.d.ts +202 -0
- package/dist/agent/experts/base/types.d.ts.map +1 -0
- package/dist/agent/experts/base/types.js +6 -0
- package/dist/agent/experts/base/types.js.map +1 -0
- package/dist/agent/experts/crossDomain/baseCrossDomainExpert.d.ts +113 -0
- package/dist/agent/experts/crossDomain/baseCrossDomainExpert.d.ts.map +1 -0
- package/dist/agent/experts/crossDomain/baseCrossDomainExpert.js +412 -0
- package/dist/agent/experts/crossDomain/baseCrossDomainExpert.js.map +1 -0
- package/dist/agent/experts/crossDomain/dialogueProtocol.d.ts +164 -0
- package/dist/agent/experts/crossDomain/dialogueProtocol.d.ts.map +1 -0
- package/dist/agent/experts/crossDomain/dialogueProtocol.js +390 -0
- package/dist/agent/experts/crossDomain/dialogueProtocol.js.map +1 -0
- package/dist/agent/experts/crossDomain/experts/performanceExpert.d.ts +119 -0
- package/dist/agent/experts/crossDomain/experts/performanceExpert.d.ts.map +1 -0
- package/dist/agent/experts/crossDomain/experts/performanceExpert.js +736 -0
- package/dist/agent/experts/crossDomain/experts/performanceExpert.js.map +1 -0
- package/dist/agent/experts/crossDomain/hypothesisManager.d.ts +105 -0
- package/dist/agent/experts/crossDomain/hypothesisManager.d.ts.map +1 -0
- package/dist/agent/experts/crossDomain/hypothesisManager.js +283 -0
- package/dist/agent/experts/crossDomain/hypothesisManager.js.map +1 -0
- package/dist/agent/experts/crossDomain/index.d.ts +18 -0
- package/dist/agent/experts/crossDomain/index.d.ts.map +1 -0
- package/dist/agent/experts/crossDomain/index.js +28 -0
- package/dist/agent/experts/crossDomain/index.js.map +1 -0
- package/dist/agent/experts/crossDomain/moduleCatalog.d.ts +97 -0
- package/dist/agent/experts/crossDomain/moduleCatalog.d.ts.map +1 -0
- package/dist/agent/experts/crossDomain/moduleCatalog.js +453 -0
- package/dist/agent/experts/crossDomain/moduleCatalog.js.map +1 -0
- package/dist/agent/experts/crossDomain/moduleExpertInvoker.d.ts +149 -0
- package/dist/agent/experts/crossDomain/moduleExpertInvoker.d.ts.map +1 -0
- package/dist/agent/experts/crossDomain/moduleExpertInvoker.js +582 -0
- package/dist/agent/experts/crossDomain/moduleExpertInvoker.js.map +1 -0
- package/dist/agent/experts/crossDomain/types.d.ts +369 -0
- package/dist/agent/experts/crossDomain/types.d.ts.map +1 -0
- package/dist/agent/experts/crossDomain/types.js +6 -0
- package/dist/agent/experts/crossDomain/types.js.map +1 -0
- package/dist/agent/experts/index.d.ts +81 -0
- package/dist/agent/experts/index.d.ts.map +1 -0
- package/dist/agent/experts/index.js +222 -0
- package/dist/agent/experts/index.js.map +1 -0
- package/dist/agent/experts/interactionExpert.d.ts +66 -0
- package/dist/agent/experts/interactionExpert.d.ts.map +1 -0
- package/dist/agent/experts/interactionExpert.js +280 -0
- package/dist/agent/experts/interactionExpert.js.map +1 -0
- package/dist/agent/experts/launchExpert.d.ts +73 -0
- package/dist/agent/experts/launchExpert.d.ts.map +1 -0
- package/dist/agent/experts/launchExpert.js +411 -0
- package/dist/agent/experts/launchExpert.js.map +1 -0
- package/dist/agent/experts/systemExpert.d.ts +81 -0
- package/dist/agent/experts/systemExpert.d.ts.map +1 -0
- package/dist/agent/experts/systemExpert.js +507 -0
- package/dist/agent/experts/systemExpert.js.map +1 -0
- package/dist/agent/fork/forkManager.d.ts +161 -0
- package/dist/agent/fork/forkManager.d.ts.map +1 -0
- package/dist/agent/fork/forkManager.js +721 -0
- package/dist/agent/fork/forkManager.js.map +1 -0
- package/dist/agent/fork/forkTypes.d.ts +274 -0
- package/dist/agent/fork/forkTypes.d.ts.map +1 -0
- package/dist/agent/fork/forkTypes.js +18 -0
- package/dist/agent/fork/forkTypes.js.map +1 -0
- package/dist/agent/fork/index.d.ts +10 -0
- package/dist/agent/fork/index.d.ts.map +1 -0
- package/dist/agent/fork/index.js +47 -0
- package/dist/agent/fork/index.js.map +1 -0
- package/dist/agent/fork/mergeStrategies.d.ts +115 -0
- package/dist/agent/fork/mergeStrategies.d.ts.map +1 -0
- package/dist/agent/fork/mergeStrategies.js +404 -0
- package/dist/agent/fork/mergeStrategies.js.map +1 -0
- package/dist/agent/fork/sessionTree.d.ts +141 -0
- package/dist/agent/fork/sessionTree.d.ts.map +1 -0
- package/dist/agent/fork/sessionTree.js +443 -0
- package/dist/agent/fork/sessionTree.js.map +1 -0
- package/dist/agent/hooks/hookContext.d.ts +19 -0
- package/dist/agent/hooks/hookContext.d.ts.map +1 -0
- package/dist/agent/hooks/hookContext.js +67 -0
- package/dist/agent/hooks/hookContext.js.map +1 -0
- package/dist/agent/hooks/hookRegistry.d.ts +73 -0
- package/dist/agent/hooks/hookRegistry.d.ts.map +1 -0
- package/dist/agent/hooks/hookRegistry.js +271 -0
- package/dist/agent/hooks/hookRegistry.js.map +1 -0
- package/dist/agent/hooks/hookTypes.d.ts +186 -0
- package/dist/agent/hooks/hookTypes.d.ts.map +1 -0
- package/dist/agent/hooks/hookTypes.js +24 -0
- package/dist/agent/hooks/hookTypes.js.map +1 -0
- package/dist/agent/hooks/index.d.ts +10 -0
- package/dist/agent/hooks/index.d.ts.map +1 -0
- package/dist/agent/hooks/index.js +41 -0
- package/dist/agent/hooks/index.js.map +1 -0
- package/dist/agent/hooks/middleware/index.d.ts +6 -0
- package/dist/agent/hooks/middleware/index.d.ts.map +1 -0
- package/dist/agent/hooks/middleware/index.js +17 -0
- package/dist/agent/hooks/middleware/index.js.map +1 -0
- package/dist/agent/hooks/middleware/loggingMiddleware.d.ts +27 -0
- package/dist/agent/hooks/middleware/loggingMiddleware.d.ts.map +1 -0
- package/dist/agent/hooks/middleware/loggingMiddleware.js +104 -0
- package/dist/agent/hooks/middleware/loggingMiddleware.js.map +1 -0
- package/dist/agent/hooks/middleware/timingMiddleware.d.ts +56 -0
- package/dist/agent/hooks/middleware/timingMiddleware.d.ts.map +1 -0
- package/dist/agent/hooks/middleware/timingMiddleware.js +171 -0
- package/dist/agent/hooks/middleware/timingMiddleware.js.map +1 -0
- package/dist/agent/index.d.ts +15 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +88 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/llmAdapter.d.ts +33 -0
- package/dist/agent/llmAdapter.d.ts.map +1 -0
- package/dist/agent/llmAdapter.js +257 -0
- package/dist/agent/llmAdapter.js.map +1 -0
- package/dist/agent/scene/sceneAnalysisJobRunner.d.ts +106 -0
- package/dist/agent/scene/sceneAnalysisJobRunner.d.ts.map +1 -0
- package/dist/agent/scene/sceneAnalysisJobRunner.js +201 -0
- package/dist/agent/scene/sceneAnalysisJobRunner.js.map +1 -0
- package/dist/agent/scene/sceneCostEstimator.d.ts +33 -0
- package/dist/agent/scene/sceneCostEstimator.d.ts.map +1 -0
- package/dist/agent/scene/sceneCostEstimator.js +42 -0
- package/dist/agent/scene/sceneCostEstimator.js.map +1 -0
- package/dist/agent/scene/sceneIntervalBuilder.d.ts +37 -0
- package/dist/agent/scene/sceneIntervalBuilder.d.ts.map +1 -0
- package/dist/agent/scene/sceneIntervalBuilder.js +748 -0
- package/dist/agent/scene/sceneIntervalBuilder.js.map +1 -0
- package/dist/agent/scene/sceneStage1Runner.d.ts +47 -0
- package/dist/agent/scene/sceneStage1Runner.d.ts.map +1 -0
- package/dist/agent/scene/sceneStage1Runner.js +49 -0
- package/dist/agent/scene/sceneStage1Runner.js.map +1 -0
- package/dist/agent/scene/sceneStage3Summarizer.d.ts +11 -0
- package/dist/agent/scene/sceneStage3Summarizer.d.ts.map +1 -0
- package/dist/agent/scene/sceneStage3Summarizer.js +155 -0
- package/dist/agent/scene/sceneStage3Summarizer.js.map +1 -0
- package/dist/agent/scene/sceneStoryService.d.ts +168 -0
- package/dist/agent/scene/sceneStoryService.d.ts.map +1 -0
- package/dist/agent/scene/sceneStoryService.js +623 -0
- package/dist/agent/scene/sceneStoryService.js.map +1 -0
- package/dist/agent/scene/sceneTraceDurationProbe.d.ts +16 -0
- package/dist/agent/scene/sceneTraceDurationProbe.d.ts.map +1 -0
- package/dist/agent/scene/sceneTraceDurationProbe.js +22 -0
- package/dist/agent/scene/sceneTraceDurationProbe.js.map +1 -0
- package/dist/agent/scene/traceHash.d.ts +23 -0
- package/dist/agent/scene/traceHash.d.ts.map +1 -0
- package/dist/agent/scene/traceHash.js +65 -0
- package/dist/agent/scene/traceHash.js.map +1 -0
- package/dist/agent/scene/types.d.ts +199 -0
- package/dist/agent/scene/types.d.ts.map +1 -0
- package/dist/agent/scene/types.js +6 -0
- package/dist/agent/scene/types.js.map +1 -0
- package/dist/agent/state/checkpointManager.d.ts +85 -0
- package/dist/agent/state/checkpointManager.d.ts.map +1 -0
- package/dist/agent/state/checkpointManager.js +339 -0
- package/dist/agent/state/checkpointManager.js.map +1 -0
- package/dist/agent/state/index.d.ts +11 -0
- package/dist/agent/state/index.d.ts.map +1 -0
- package/dist/agent/state/index.js +21 -0
- package/dist/agent/state/index.js.map +1 -0
- package/dist/agent/state/sessionStore.d.ts +126 -0
- package/dist/agent/state/sessionStore.d.ts.map +1 -0
- package/dist/agent/state/sessionStore.js +440 -0
- package/dist/agent/state/sessionStore.js.map +1 -0
- package/dist/agent/state/traceAgentState.d.ts +125 -0
- package/dist/agent/state/traceAgentState.d.ts.map +1 -0
- package/dist/agent/state/traceAgentState.js +173 -0
- package/dist/agent/state/traceAgentState.js.map +1 -0
- package/dist/agent/strategies/helpers.d.ts +44 -0
- package/dist/agent/strategies/helpers.d.ts.map +1 -0
- package/dist/agent/strategies/helpers.js +138 -0
- package/dist/agent/strategies/helpers.js.map +1 -0
- package/dist/agent/strategies/index.d.ts +15 -0
- package/dist/agent/strategies/index.d.ts.map +1 -0
- package/dist/agent/strategies/index.js +23 -0
- package/dist/agent/strategies/index.js.map +1 -0
- package/dist/agent/strategies/interactionStrategy.d.ts +3 -0
- package/dist/agent/strategies/interactionStrategy.d.ts.map +1 -0
- package/dist/agent/strategies/interactionStrategy.js +242 -0
- package/dist/agent/strategies/interactionStrategy.js.map +1 -0
- package/dist/agent/strategies/registry.d.ts +110 -0
- package/dist/agent/strategies/registry.d.ts.map +1 -0
- package/dist/agent/strategies/registry.js +264 -0
- package/dist/agent/strategies/registry.js.map +1 -0
- package/dist/agent/strategies/sceneReconstructionStrategy.d.ts +4 -0
- package/dist/agent/strategies/sceneReconstructionStrategy.d.ts.map +1 -0
- package/dist/agent/strategies/sceneReconstructionStrategy.js +593 -0
- package/dist/agent/strategies/sceneReconstructionStrategy.js.map +1 -0
- package/dist/agent/strategies/scrollingStrategy.d.ts +3 -0
- package/dist/agent/strategies/scrollingStrategy.d.ts.map +1 -0
- package/dist/agent/strategies/scrollingStrategy.js +414 -0
- package/dist/agent/strategies/scrollingStrategy.js.map +1 -0
- package/dist/agent/strategies/startupStrategy.d.ts +3 -0
- package/dist/agent/strategies/startupStrategy.d.ts.map +1 -0
- package/dist/agent/strategies/startupStrategy.js +495 -0
- package/dist/agent/strategies/startupStrategy.js.map +1 -0
- package/dist/agent/strategies/types.d.ts +156 -0
- package/dist/agent/strategies/types.d.ts.map +1 -0
- package/dist/agent/strategies/types.js +6 -0
- package/dist/agent/strategies/types.js.map +1 -0
- package/dist/agent/toolRegistry.d.ts +4 -0
- package/dist/agent/toolRegistry.d.ts.map +1 -0
- package/dist/agent/toolRegistry.js +45 -0
- package/dist/agent/toolRegistry.js.map +1 -0
- package/dist/agent/tools/dataStats.d.ts +23 -0
- package/dist/agent/tools/dataStats.d.ts.map +1 -0
- package/dist/agent/tools/dataStats.js +123 -0
- package/dist/agent/tools/dataStats.js.map +1 -0
- package/dist/agent/tools/frameAnalyzer.d.ts +45 -0
- package/dist/agent/tools/frameAnalyzer.d.ts.map +1 -0
- package/dist/agent/tools/frameAnalyzer.js +338 -0
- package/dist/agent/tools/frameAnalyzer.js.map +1 -0
- package/dist/agent/tools/index.d.ts +6 -0
- package/dist/agent/tools/index.d.ts.map +1 -0
- package/dist/agent/tools/index.js +31 -0
- package/dist/agent/tools/index.js.map +1 -0
- package/dist/agent/tools/skillInvoker.d.ts +50 -0
- package/dist/agent/tools/skillInvoker.d.ts.map +1 -0
- package/dist/agent/tools/skillInvoker.js +279 -0
- package/dist/agent/tools/skillInvoker.js.map +1 -0
- package/dist/agent/tools/sqlExecutor.d.ts +12 -0
- package/dist/agent/tools/sqlExecutor.d.ts.map +1 -0
- package/dist/agent/tools/sqlExecutor.js +193 -0
- package/dist/agent/tools/sqlExecutor.js.map +1 -0
- package/dist/agent/tools/sqlGenerator.d.ts +154 -0
- package/dist/agent/tools/sqlGenerator.d.ts.map +1 -0
- package/dist/agent/tools/sqlGenerator.js +449 -0
- package/dist/agent/tools/sqlGenerator.js.map +1 -0
- package/dist/agent/tools/sqlValidator.d.ts +149 -0
- package/dist/agent/tools/sqlValidator.d.ts.map +1 -0
- package/dist/agent/tools/sqlValidator.js +376 -0
- package/dist/agent/tools/sqlValidator.js.map +1 -0
- package/dist/agent/traceRecorder.d.ts +42 -0
- package/dist/agent/traceRecorder.d.ts.map +1 -0
- package/dist/agent/traceRecorder.js +122 -0
- package/dist/agent/traceRecorder.js.map +1 -0
- package/dist/agent/types/agentProtocol.d.ts +377 -0
- package/dist/agent/types/agentProtocol.d.ts.map +1 -0
- package/dist/agent/types/agentProtocol.js +102 -0
- package/dist/agent/types/agentProtocol.js.map +1 -0
- package/dist/agent/types/jankCause.d.ts +47 -0
- package/dist/agent/types/jankCause.d.ts.map +1 -0
- package/dist/agent/types/jankCause.js +6 -0
- package/dist/agent/types/jankCause.js.map +1 -0
- package/dist/agent/types.d.ts +725 -0
- package/dist/agent/types.d.ts.map +1 -0
- package/dist/agent/types.js +63 -0
- package/dist/agent/types.js.map +1 -0
- package/dist/agentOpenAI/index.d.ts +4 -0
- package/dist/agentOpenAI/index.d.ts.map +1 -0
- package/dist/agentOpenAI/index.js +17 -0
- package/dist/agentOpenAI/index.js.map +1 -0
- package/dist/agentOpenAI/mimoReasoningCompat.d.ts +9 -0
- package/dist/agentOpenAI/mimoReasoningCompat.d.ts.map +1 -0
- package/dist/agentOpenAI/mimoReasoningCompat.js +367 -0
- package/dist/agentOpenAI/mimoReasoningCompat.js.map +1 -0
- package/dist/agentOpenAI/openAiComplexityClassifier.d.ts +18 -0
- package/dist/agentOpenAI/openAiComplexityClassifier.d.ts.map +1 -0
- package/dist/agentOpenAI/openAiComplexityClassifier.js +102 -0
- package/dist/agentOpenAI/openAiComplexityClassifier.js.map +1 -0
- package/dist/agentOpenAI/openAiConfig.d.ts +38 -0
- package/dist/agentOpenAI/openAiConfig.d.ts.map +1 -0
- package/dist/agentOpenAI/openAiConfig.js +104 -0
- package/dist/agentOpenAI/openAiConfig.js.map +1 -0
- package/dist/agentOpenAI/openAiRuntime.d.ts +99 -0
- package/dist/agentOpenAI/openAiRuntime.d.ts.map +1 -0
- package/dist/agentOpenAI/openAiRuntime.js +1440 -0
- package/dist/agentOpenAI/openAiRuntime.js.map +1 -0
- package/dist/agentOpenAI/openAiToolAdapter.d.ts +9 -0
- package/dist/agentOpenAI/openAiToolAdapter.d.ts.map +1 -0
- package/dist/agentOpenAI/openAiToolAdapter.js +111 -0
- package/dist/agentOpenAI/openAiToolAdapter.js.map +1 -0
- package/dist/agentRuntime/envCredentialSources.d.ts +6 -0
- package/dist/agentRuntime/envCredentialSources.d.ts.map +1 -0
- package/dist/agentRuntime/envCredentialSources.js +104 -0
- package/dist/agentRuntime/envCredentialSources.js.map +1 -0
- package/dist/agentRuntime/index.d.ts +2 -0
- package/dist/agentRuntime/index.d.ts.map +1 -0
- package/dist/agentRuntime/index.js +10 -0
- package/dist/agentRuntime/index.js.map +1 -0
- package/dist/agentRuntime/runtimeHealth.d.ts +65 -0
- package/dist/agentRuntime/runtimeHealth.d.ts.map +1 -0
- package/dist/agentRuntime/runtimeHealth.js +58 -0
- package/dist/agentRuntime/runtimeHealth.js.map +1 -0
- package/dist/agentRuntime/runtimeSelection.d.ts +25 -0
- package/dist/agentRuntime/runtimeSelection.d.ts.map +1 -0
- package/dist/agentRuntime/runtimeSelection.js +66 -0
- package/dist/agentRuntime/runtimeSelection.js.map +1 -0
- package/dist/agentv3/__mocks__/claude-agent-sdk.d.ts +25 -0
- package/dist/agentv3/__mocks__/claude-agent-sdk.d.ts.map +1 -0
- package/dist/agentv3/__mocks__/claude-agent-sdk.js +48 -0
- package/dist/agentv3/__mocks__/claude-agent-sdk.js.map +1 -0
- package/dist/agentv3/activePhaseReminder.d.ts +12 -0
- package/dist/agentv3/activePhaseReminder.d.ts.map +1 -0
- package/dist/agentv3/activePhaseReminder.js +73 -0
- package/dist/agentv3/activePhaseReminder.js.map +1 -0
- package/dist/agentv3/agentMetrics.d.ts +114 -0
- package/dist/agentv3/agentMetrics.d.ts.map +1 -0
- package/dist/agentv3/agentMetrics.js +262 -0
- package/dist/agentv3/agentMetrics.js.map +1 -0
- package/dist/agentv3/analysisPatternMemory.d.ts +146 -0
- package/dist/agentv3/analysisPatternMemory.d.ts.map +1 -0
- package/dist/agentv3/analysisPatternMemory.js +860 -0
- package/dist/agentv3/analysisPatternMemory.js.map +1 -0
- package/dist/agentv3/analysisTermination.d.ts +21 -0
- package/dist/agentv3/analysisTermination.d.ts.map +1 -0
- package/dist/agentv3/analysisTermination.js +97 -0
- package/dist/agentv3/analysisTermination.js.map +1 -0
- package/dist/agentv3/artifactStore.d.ts +131 -0
- package/dist/agentv3/artifactStore.d.ts.map +1 -0
- package/dist/agentv3/artifactStore.js +208 -0
- package/dist/agentv3/artifactStore.js.map +1 -0
- package/dist/agentv3/claudeAgentDefinitions.d.ts +44 -0
- package/dist/agentv3/claudeAgentDefinitions.d.ts.map +1 -0
- package/dist/agentv3/claudeAgentDefinitions.js +209 -0
- package/dist/agentv3/claudeAgentDefinitions.js.map +1 -0
- package/dist/agentv3/claudeConfig.d.ts +156 -0
- package/dist/agentv3/claudeConfig.d.ts.map +1 -0
- package/dist/agentv3/claudeConfig.js +553 -0
- package/dist/agentv3/claudeConfig.js.map +1 -0
- package/dist/agentv3/claudeFindingExtractor.d.ts +15 -0
- package/dist/agentv3/claudeFindingExtractor.d.ts.map +1 -0
- package/dist/agentv3/claudeFindingExtractor.js +150 -0
- package/dist/agentv3/claudeFindingExtractor.js.map +1 -0
- package/dist/agentv3/claudeMcpServer.d.ts +89 -0
- package/dist/agentv3/claudeMcpServer.d.ts.map +1 -0
- package/dist/agentv3/claudeMcpServer.js +3785 -0
- package/dist/agentv3/claudeMcpServer.js.map +1 -0
- package/dist/agentv3/claudeRuntime.d.ts +137 -0
- package/dist/agentv3/claudeRuntime.d.ts.map +1 -0
- package/dist/agentv3/claudeRuntime.js +2541 -0
- package/dist/agentv3/claudeRuntime.js.map +1 -0
- package/dist/agentv3/claudeSseBridge.d.ts +23 -0
- package/dist/agentv3/claudeSseBridge.d.ts.map +1 -0
- package/dist/agentv3/claudeSseBridge.js +385 -0
- package/dist/agentv3/claudeSseBridge.js.map +1 -0
- package/dist/agentv3/claudeSystemPrompt.d.ts +65 -0
- package/dist/agentv3/claudeSystemPrompt.d.ts.map +1 -0
- package/dist/agentv3/claudeSystemPrompt.js +486 -0
- package/dist/agentv3/claudeSystemPrompt.js.map +1 -0
- package/dist/agentv3/claudeVerifier.d.ts +82 -0
- package/dist/agentv3/claudeVerifier.d.ts.map +1 -0
- package/dist/agentv3/claudeVerifier.js +1047 -0
- package/dist/agentv3/claudeVerifier.js.map +1 -0
- package/dist/agentv3/contextTokenMeter.d.ts +78 -0
- package/dist/agentv3/contextTokenMeter.d.ts.map +1 -0
- package/dist/agentv3/contextTokenMeter.js +88 -0
- package/dist/agentv3/contextTokenMeter.js.map +1 -0
- package/dist/agentv3/focusAppDetector.d.ts +22 -0
- package/dist/agentv3/focusAppDetector.d.ts.map +1 -0
- package/dist/agentv3/focusAppDetector.js +208 -0
- package/dist/agentv3/focusAppDetector.js.map +1 -0
- package/dist/agentv3/index.d.ts +6 -0
- package/dist/agentv3/index.d.ts.map +1 -0
- package/dist/agentv3/index.js +16 -0
- package/dist/agentv3/index.js.map +1 -0
- package/dist/agentv3/mcpToolRegistry.d.ts +90 -0
- package/dist/agentv3/mcpToolRegistry.d.ts.map +1 -0
- package/dist/agentv3/mcpToolRegistry.js +152 -0
- package/dist/agentv3/mcpToolRegistry.js.map +1 -0
- package/dist/agentv3/outputLanguage.d.ts +6 -0
- package/dist/agentv3/outputLanguage.d.ts.map +1 -0
- package/dist/agentv3/outputLanguage.js +37 -0
- package/dist/agentv3/outputLanguage.js.map +1 -0
- package/dist/agentv3/phaseHintMatcher.d.ts +36 -0
- package/dist/agentv3/phaseHintMatcher.d.ts.map +1 -0
- package/dist/agentv3/phaseHintMatcher.js +48 -0
- package/dist/agentv3/phaseHintMatcher.js.map +1 -0
- package/dist/agentv3/projectMemory.d.ts +80 -0
- package/dist/agentv3/projectMemory.d.ts.map +1 -0
- package/dist/agentv3/projectMemory.js +334 -0
- package/dist/agentv3/projectMemory.js.map +1 -0
- package/dist/agentv3/queryComplexityClassifier.d.ts +21 -0
- package/dist/agentv3/queryComplexityClassifier.d.ts.map +1 -0
- package/dist/agentv3/queryComplexityClassifier.js +196 -0
- package/dist/agentv3/queryComplexityClassifier.js.map +1 -0
- package/dist/agentv3/rawSqlNormalizer.d.ts +11 -0
- package/dist/agentv3/rawSqlNormalizer.d.ts.map +1 -0
- package/dist/agentv3/rawSqlNormalizer.js +649 -0
- package/dist/agentv3/rawSqlNormalizer.js.map +1 -0
- package/dist/agentv3/recoveryNoteBuilder.d.ts +51 -0
- package/dist/agentv3/recoveryNoteBuilder.d.ts.map +1 -0
- package/dist/agentv3/recoveryNoteBuilder.js +84 -0
- package/dist/agentv3/recoveryNoteBuilder.js.map +1 -0
- package/dist/agentv3/sceneClassifier.d.ts +11 -0
- package/dist/agentv3/sceneClassifier.d.ts.map +1 -0
- package/dist/agentv3/sceneClassifier.js +46 -0
- package/dist/agentv3/sceneClassifier.js.map +1 -0
- package/dist/agentv3/scenePlanTemplates.d.ts +80 -0
- package/dist/agentv3/scenePlanTemplates.d.ts.map +1 -0
- package/dist/agentv3/scenePlanTemplates.js +164 -0
- package/dist/agentv3/scenePlanTemplates.js.map +1 -0
- package/dist/agentv3/selfImprove/contentScanner.d.ts +44 -0
- package/dist/agentv3/selfImprove/contentScanner.d.ts.map +1 -0
- package/dist/agentv3/selfImprove/contentScanner.js +112 -0
- package/dist/agentv3/selfImprove/contentScanner.js.map +1 -0
- package/dist/agentv3/selfImprove/failureTaxonomy.d.ts +38 -0
- package/dist/agentv3/selfImprove/failureTaxonomy.d.ts.map +1 -0
- package/dist/agentv3/selfImprove/failureTaxonomy.js +102 -0
- package/dist/agentv3/selfImprove/failureTaxonomy.js.map +1 -0
- package/dist/agentv3/selfImprove/feedbackEnricher.d.ts +69 -0
- package/dist/agentv3/selfImprove/feedbackEnricher.d.ts.map +1 -0
- package/dist/agentv3/selfImprove/feedbackEnricher.js +135 -0
- package/dist/agentv3/selfImprove/feedbackEnricher.js.map +1 -0
- package/dist/agentv3/selfImprove/feedbackPipeline.d.ts +63 -0
- package/dist/agentv3/selfImprove/feedbackPipeline.d.ts.map +1 -0
- package/dist/agentv3/selfImprove/feedbackPipeline.js +239 -0
- package/dist/agentv3/selfImprove/feedbackPipeline.js.map +1 -0
- package/dist/agentv3/selfImprove/hintFingerprint.d.ts +14 -0
- package/dist/agentv3/selfImprove/hintFingerprint.d.ts.map +1 -0
- package/dist/agentv3/selfImprove/hintFingerprint.js +47 -0
- package/dist/agentv3/selfImprove/hintFingerprint.js.map +1 -0
- package/dist/agentv3/selfImprove/metricsAggregator.d.ts +46 -0
- package/dist/agentv3/selfImprove/metricsAggregator.d.ts.map +1 -0
- package/dist/agentv3/selfImprove/metricsAggregator.js +195 -0
- package/dist/agentv3/selfImprove/metricsAggregator.js.map +1 -0
- package/dist/agentv3/selfImprove/migrateFailureModeHash.d.ts +31 -0
- package/dist/agentv3/selfImprove/migrateFailureModeHash.d.ts.map +1 -0
- package/dist/agentv3/selfImprove/migrateFailureModeHash.js +220 -0
- package/dist/agentv3/selfImprove/migrateFailureModeHash.js.map +1 -0
- package/dist/agentv3/selfImprove/phaseHintsRenderer.d.ts +56 -0
- package/dist/agentv3/selfImprove/phaseHintsRenderer.d.ts.map +1 -0
- package/dist/agentv3/selfImprove/phaseHintsRenderer.js +202 -0
- package/dist/agentv3/selfImprove/phaseHintsRenderer.js.map +1 -0
- package/dist/agentv3/selfImprove/promoteSkillNote.d.ts +17 -0
- package/dist/agentv3/selfImprove/promoteSkillNote.d.ts.map +1 -0
- package/dist/agentv3/selfImprove/promoteSkillNote.js +146 -0
- package/dist/agentv3/selfImprove/promoteSkillNote.js.map +1 -0
- package/dist/agentv3/selfImprove/proposeStrategyPatch.d.ts +40 -0
- package/dist/agentv3/selfImprove/proposeStrategyPatch.d.ts.map +1 -0
- package/dist/agentv3/selfImprove/proposeStrategyPatch.js +115 -0
- package/dist/agentv3/selfImprove/proposeStrategyPatch.js.map +1 -0
- package/dist/agentv3/selfImprove/reviewAgentSdk.d.ts +32 -0
- package/dist/agentv3/selfImprove/reviewAgentSdk.d.ts.map +1 -0
- package/dist/agentv3/selfImprove/reviewAgentSdk.js +173 -0
- package/dist/agentv3/selfImprove/reviewAgentSdk.js.map +1 -0
- package/dist/agentv3/selfImprove/reviewOutbox.d.ts +128 -0
- package/dist/agentv3/selfImprove/reviewOutbox.d.ts.map +1 -0
- package/dist/agentv3/selfImprove/reviewOutbox.js +313 -0
- package/dist/agentv3/selfImprove/reviewOutbox.js.map +1 -0
- package/dist/agentv3/selfImprove/reviewWorker.d.ts +95 -0
- package/dist/agentv3/selfImprove/reviewWorker.d.ts.map +1 -0
- package/dist/agentv3/selfImprove/reviewWorker.js +172 -0
- package/dist/agentv3/selfImprove/reviewWorker.js.map +1 -0
- package/dist/agentv3/selfImprove/skillNotesInjector.d.ts +71 -0
- package/dist/agentv3/selfImprove/skillNotesInjector.d.ts.map +1 -0
- package/dist/agentv3/selfImprove/skillNotesInjector.js +214 -0
- package/dist/agentv3/selfImprove/skillNotesInjector.js.map +1 -0
- package/dist/agentv3/selfImprove/skillNotesWriter.d.ts +89 -0
- package/dist/agentv3/selfImprove/skillNotesWriter.d.ts.map +1 -0
- package/dist/agentv3/selfImprove/skillNotesWriter.js +274 -0
- package/dist/agentv3/selfImprove/skillNotesWriter.js.map +1 -0
- package/dist/agentv3/selfImprove/strategyFingerprint.d.ts +85 -0
- package/dist/agentv3/selfImprove/strategyFingerprint.d.ts.map +1 -0
- package/dist/agentv3/selfImprove/strategyFingerprint.js +189 -0
- package/dist/agentv3/selfImprove/strategyFingerprint.js.map +1 -0
- package/dist/agentv3/selfImprove/strategyPatchApplier.d.ts +15 -0
- package/dist/agentv3/selfImprove/strategyPatchApplier.d.ts.map +1 -0
- package/dist/agentv3/selfImprove/strategyPatchApplier.js +138 -0
- package/dist/agentv3/selfImprove/strategyPatchApplier.js.map +1 -0
- package/dist/agentv3/selfImprove/supersedeStore.d.ts +136 -0
- package/dist/agentv3/selfImprove/supersedeStore.d.ts.map +1 -0
- package/dist/agentv3/selfImprove/supersedeStore.js +386 -0
- package/dist/agentv3/selfImprove/supersedeStore.js.map +1 -0
- package/dist/agentv3/selfImprove/worktreeRunner.d.ts +49 -0
- package/dist/agentv3/selfImprove/worktreeRunner.d.ts.map +1 -0
- package/dist/agentv3/selfImprove/worktreeRunner.js +153 -0
- package/dist/agentv3/selfImprove/worktreeRunner.js.map +1 -0
- package/dist/agentv3/sessionStateSnapshot.d.ts +166 -0
- package/dist/agentv3/sessionStateSnapshot.d.ts.map +1 -0
- package/dist/agentv3/sessionStateSnapshot.js +6 -0
- package/dist/agentv3/sessionStateSnapshot.js.map +1 -0
- package/dist/agentv3/sqlIncludeInjector.d.ts +24 -0
- package/dist/agentv3/sqlIncludeInjector.d.ts.map +1 -0
- package/dist/agentv3/sqlIncludeInjector.js +78 -0
- package/dist/agentv3/sqlIncludeInjector.js.map +1 -0
- package/dist/agentv3/sqlSummarizer.d.ts +38 -0
- package/dist/agentv3/sqlSummarizer.d.ts.map +1 -0
- package/dist/agentv3/sqlSummarizer.js +101 -0
- package/dist/agentv3/sqlSummarizer.js.map +1 -0
- package/dist/agentv3/standaloneMcpServer.d.ts +96 -0
- package/dist/agentv3/standaloneMcpServer.d.ts.map +1 -0
- package/dist/agentv3/standaloneMcpServer.js +244 -0
- package/dist/agentv3/standaloneMcpServer.js.map +1 -0
- package/dist/agentv3/strategyLoader.d.ts +96 -0
- package/dist/agentv3/strategyLoader.d.ts.map +1 -0
- package/dist/agentv3/strategyLoader.js +204 -0
- package/dist/agentv3/strategyLoader.js.map +1 -0
- package/dist/agentv3/toolCallSummary.d.ts +15 -0
- package/dist/agentv3/toolCallSummary.d.ts.map +1 -0
- package/dist/agentv3/toolCallSummary.js +66 -0
- package/dist/agentv3/toolCallSummary.js.map +1 -0
- package/dist/agentv3/toolNarration.d.ts +4 -0
- package/dist/agentv3/toolNarration.d.ts.map +1 -0
- package/dist/agentv3/toolNarration.js +371 -0
- package/dist/agentv3/toolNarration.js.map +1 -0
- package/dist/agentv3/traceCompletenessProber.d.ts +56 -0
- package/dist/agentv3/traceCompletenessProber.d.ts.map +1 -0
- package/dist/agentv3/traceCompletenessProber.js +337 -0
- package/dist/agentv3/traceCompletenessProber.js.map +1 -0
- package/dist/agentv3/types.d.ts +443 -0
- package/dist/agentv3/types.d.ts.map +1 -0
- package/dist/agentv3/types.js +37 -0
- package/dist/agentv3/types.js.map +1 -0
- package/dist/assistant/application/agentAnalyzeSessionService.d.ts +130 -0
- package/dist/assistant/application/agentAnalyzeSessionService.d.ts.map +1 -0
- package/dist/assistant/application/agentAnalyzeSessionService.js +433 -0
- package/dist/assistant/application/agentAnalyzeSessionService.js.map +1 -0
- package/dist/assistant/application/assistantApplicationService.d.ts +39 -0
- package/dist/assistant/application/assistantApplicationService.d.ts.map +1 -0
- package/dist/assistant/application/assistantApplicationService.js +88 -0
- package/dist/assistant/application/assistantApplicationService.js.map +1 -0
- package/dist/assistant/contracts/assistantResultContract.d.ts +41 -0
- package/dist/assistant/contracts/assistantResultContract.d.ts.map +1 -0
- package/dist/assistant/contracts/assistantResultContract.js +145 -0
- package/dist/assistant/contracts/assistantResultContract.js.map +1 -0
- package/dist/assistant/stream/sessionSseReplay.d.ts +10 -0
- package/dist/assistant/stream/sessionSseReplay.d.ts.map +1 -0
- package/dist/assistant/stream/sessionSseReplay.js +42 -0
- package/dist/assistant/stream/sessionSseReplay.js.map +1 -0
- package/dist/assistant/stream/streamProjector.d.ts +53 -0
- package/dist/assistant/stream/streamProjector.d.ts.map +1 -0
- package/dist/assistant/stream/streamProjector.js +150 -0
- package/dist/assistant/stream/streamProjector.js.map +1 -0
- package/dist/cli/commands/coverage.d.ts +12 -0
- package/dist/cli/commands/coverage.d.ts.map +1 -0
- package/dist/cli/commands/coverage.js +106 -0
- package/dist/cli/commands/coverage.js.map +1 -0
- package/dist/cli/commands/list.d.ts +11 -0
- package/dist/cli/commands/list.d.ts.map +1 -0
- package/dist/cli/commands/list.js +169 -0
- package/dist/cli/commands/list.js.map +1 -0
- package/dist/cli/commands/smoke.d.ts +11 -0
- package/dist/cli/commands/smoke.d.ts.map +1 -0
- package/dist/cli/commands/smoke.js +215 -0
- package/dist/cli/commands/smoke.js.map +1 -0
- package/dist/cli/commands/test.d.ts +11 -0
- package/dist/cli/commands/test.d.ts.map +1 -0
- package/dist/cli/commands/test.js +183 -0
- package/dist/cli/commands/test.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +26 -0
- package/dist/cli/commands/validate.d.ts.map +1 -0
- package/dist/cli/commands/validate.js +918 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +29 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli-user/bin.d.ts +3 -0
- package/dist/cli-user/bin.d.ts.map +1 -0
- package/dist/cli-user/bin.js +490 -0
- package/dist/cli-user/bin.js.map +1 -0
- package/dist/cli-user/bootstrap.d.ts +12 -0
- package/dist/cli-user/bootstrap.d.ts.map +1 -0
- package/dist/cli-user/bootstrap.js +165 -0
- package/dist/cli-user/bootstrap.js.map +1 -0
- package/dist/cli-user/commands/analyze.d.ts +12 -0
- package/dist/cli-user/commands/analyze.d.ts.map +1 -0
- package/dist/cli-user/commands/analyze.js +83 -0
- package/dist/cli-user/commands/analyze.js.map +1 -0
- package/dist/cli-user/commands/capture.d.ts +12 -0
- package/dist/cli-user/commands/capture.d.ts.map +1 -0
- package/dist/cli-user/commands/capture.js +155 -0
- package/dist/cli-user/commands/capture.js.map +1 -0
- package/dist/cli-user/commands/compare.d.ts +13 -0
- package/dist/cli-user/commands/compare.d.ts.map +1 -0
- package/dist/cli-user/commands/compare.js +74 -0
- package/dist/cli-user/commands/compare.js.map +1 -0
- package/dist/cli-user/commands/config.d.ts +9 -0
- package/dist/cli-user/commands/config.d.ts.map +1 -0
- package/dist/cli-user/commands/config.js +109 -0
- package/dist/cli-user/commands/config.js.map +1 -0
- package/dist/cli-user/commands/doctor.d.ts +8 -0
- package/dist/cli-user/commands/doctor.d.ts.map +1 -0
- package/dist/cli-user/commands/doctor.js +37 -0
- package/dist/cli-user/commands/doctor.js.map +1 -0
- package/dist/cli-user/commands/list.d.ts +10 -0
- package/dist/cli-user/commands/list.d.ts.map +1 -0
- package/dist/cli-user/commands/list.js +79 -0
- package/dist/cli-user/commands/list.js.map +1 -0
- package/dist/cli-user/commands/provider.d.ts +12 -0
- package/dist/cli-user/commands/provider.d.ts.map +1 -0
- package/dist/cli-user/commands/provider.js +121 -0
- package/dist/cli-user/commands/provider.js.map +1 -0
- package/dist/cli-user/commands/query.d.ts +10 -0
- package/dist/cli-user/commands/query.d.ts.map +1 -0
- package/dist/cli-user/commands/query.js +128 -0
- package/dist/cli-user/commands/query.js.map +1 -0
- package/dist/cli-user/commands/report.d.ts +18 -0
- package/dist/cli-user/commands/report.d.ts.map +1 -0
- package/dist/cli-user/commands/report.js +225 -0
- package/dist/cli-user/commands/report.js.map +1 -0
- package/dist/cli-user/commands/resume.d.ts +12 -0
- package/dist/cli-user/commands/resume.d.ts.map +1 -0
- package/dist/cli-user/commands/resume.js +48 -0
- package/dist/cli-user/commands/resume.js.map +1 -0
- package/dist/cli-user/commands/rm.d.ts +8 -0
- package/dist/cli-user/commands/rm.d.ts.map +1 -0
- package/dist/cli-user/commands/rm.js +91 -0
- package/dist/cli-user/commands/rm.js.map +1 -0
- package/dist/cli-user/commands/show.d.ts +8 -0
- package/dist/cli-user/commands/show.d.ts.map +1 -0
- package/dist/cli-user/commands/show.js +84 -0
- package/dist/cli-user/commands/show.js.map +1 -0
- package/dist/cli-user/commands/skill.d.ts +11 -0
- package/dist/cli-user/commands/skill.d.ts.map +1 -0
- package/dist/cli-user/commands/skill.js +118 -0
- package/dist/cli-user/commands/skill.js.map +1 -0
- package/dist/cli-user/constants.d.ts +10 -0
- package/dist/cli-user/constants.d.ts.map +1 -0
- package/dist/cli-user/constants.js +16 -0
- package/dist/cli-user/constants.js.map +1 -0
- package/dist/cli-user/io/indexJson.d.ts +11 -0
- package/dist/cli-user/io/indexJson.d.ts.map +1 -0
- package/dist/cli-user/io/indexJson.js +79 -0
- package/dist/cli-user/io/indexJson.js.map +1 -0
- package/dist/cli-user/io/openFile.d.ts +8 -0
- package/dist/cli-user/io/openFile.d.ts.map +1 -0
- package/dist/cli-user/io/openFile.js +34 -0
- package/dist/cli-user/io/openFile.js.map +1 -0
- package/dist/cli-user/io/paths.d.ts +33 -0
- package/dist/cli-user/io/paths.d.ts.map +1 -0
- package/dist/cli-user/io/paths.js +149 -0
- package/dist/cli-user/io/paths.js.map +1 -0
- package/dist/cli-user/io/sessionStore.d.ts +17 -0
- package/dist/cli-user/io/sessionStore.d.ts.map +1 -0
- package/dist/cli-user/io/sessionStore.js +101 -0
- package/dist/cli-user/io/sessionStore.js.map +1 -0
- package/dist/cli-user/io/stdio.d.ts +8 -0
- package/dist/cli-user/io/stdio.d.ts.map +1 -0
- package/dist/cli-user/io/stdio.js +25 -0
- package/dist/cli-user/io/stdio.js.map +1 -0
- package/dist/cli-user/io/transcriptWriter.d.ts +5 -0
- package/dist/cli-user/io/transcriptWriter.d.ts.map +1 -0
- package/dist/cli-user/io/transcriptWriter.js +60 -0
- package/dist/cli-user/io/transcriptWriter.js.map +1 -0
- package/dist/cli-user/repl/index.d.ts +14 -0
- package/dist/cli-user/repl/index.d.ts.map +1 -0
- package/dist/cli-user/repl/index.js +301 -0
- package/dist/cli-user/repl/index.js.map +1 -0
- package/dist/cli-user/repl/renderer.d.ts +43 -0
- package/dist/cli-user/repl/renderer.d.ts.map +1 -0
- package/dist/cli-user/repl/renderer.js +210 -0
- package/dist/cli-user/repl/renderer.js.map +1 -0
- package/dist/cli-user/repl/slashCommands.d.ts +49 -0
- package/dist/cli-user/repl/slashCommands.d.ts.map +1 -0
- package/dist/cli-user/repl/slashCommands.js +65 -0
- package/dist/cli-user/repl/slashCommands.js.map +1 -0
- package/dist/cli-user/services/cliAnalyzeService.d.ts +73 -0
- package/dist/cli-user/services/cliAnalyzeService.d.ts.map +1 -0
- package/dist/cli-user/services/cliAnalyzeService.js +393 -0
- package/dist/cli-user/services/cliAnalyzeService.js.map +1 -0
- package/dist/cli-user/services/runtimeGuard.d.ts +46 -0
- package/dist/cli-user/services/runtimeGuard.d.ts.map +1 -0
- package/dist/cli-user/services/runtimeGuard.js +188 -0
- package/dist/cli-user/services/runtimeGuard.js.map +1 -0
- package/dist/cli-user/services/traceProcessorInstaller.d.ts +2 -0
- package/dist/cli-user/services/traceProcessorInstaller.d.ts.map +1 -0
- package/dist/cli-user/services/traceProcessorInstaller.js +241 -0
- package/dist/cli-user/services/traceProcessorInstaller.js.map +1 -0
- package/dist/cli-user/services/turnPersistence.d.ts +41 -0
- package/dist/cli-user/services/turnPersistence.d.ts.map +1 -0
- package/dist/cli-user/services/turnPersistence.js +55 -0
- package/dist/cli-user/services/turnPersistence.js.map +1 -0
- package/dist/cli-user/services/turnRunner.d.ts +49 -0
- package/dist/cli-user/services/turnRunner.d.ts.map +1 -0
- package/dist/cli-user/services/turnRunner.js +436 -0
- package/dist/cli-user/services/turnRunner.js.map +1 -0
- package/dist/cli-user/types.d.ts +62 -0
- package/dist/cli-user/types.d.ts.map +1 -0
- package/dist/cli-user/types.js +6 -0
- package/dist/cli-user/types.js.map +1 -0
- package/dist/config/index.d.ts +393 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +334 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/prompts.d.ts +20 -0
- package/dist/config/prompts.d.ts.map +1 -0
- package/dist/config/prompts.js +74 -0
- package/dist/config/prompts.js.map +1 -0
- package/dist/config/teaching.config.d.ts +253 -0
- package/dist/config/teaching.config.d.ts.map +1 -0
- package/dist/config/teaching.config.js +203 -0
- package/dist/config/teaching.config.js.map +1 -0
- package/dist/config/thresholds.d.ts +300 -0
- package/dist/config/thresholds.d.ts.map +1 -0
- package/dist/config/thresholds.js +338 -0
- package/dist/config/thresholds.js.map +1 -0
- package/dist/controllers/skillAdminController.d.ts +62 -0
- package/dist/controllers/skillAdminController.d.ts.map +1 -0
- package/dist/controllers/skillAdminController.js +482 -0
- package/dist/controllers/skillAdminController.js.map +1 -0
- package/dist/controllers/skillController.d.ts +49 -0
- package/dist/controllers/skillController.d.ts.map +1 -0
- package/dist/controllers/skillController.js +246 -0
- package/dist/controllers/skillController.js.map +1 -0
- package/dist/controllers/sqlController.d.ts +9 -0
- package/dist/controllers/sqlController.d.ts.map +1 -0
- package/dist/controllers/sqlController.js +125 -0
- package/dist/controllers/sqlController.js.map +1 -0
- package/dist/controllers/traceController.d.ts +13 -0
- package/dist/controllers/traceController.d.ts.map +1 -0
- package/dist/controllers/traceController.js +209 -0
- package/dist/controllers/traceController.js.map +1 -0
- package/dist/controllers/traceProcessorController.d.ts +14 -0
- package/dist/controllers/traceProcessorController.d.ts.map +1 -0
- package/dist/controllers/traceProcessorController.js +222 -0
- package/dist/controllers/traceProcessorController.js.map +1 -0
- package/dist/data/perfettoSchema.d.ts +9 -0
- package/dist/data/perfettoSchema.d.ts.map +1 -0
- package/dist/data/perfettoSchema.js +286 -0
- package/dist/data/perfettoSchema.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +251 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/auth.d.ts +37 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +307 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/middleware/legacyAgentApi.d.ts +8 -0
- package/dist/middleware/legacyAgentApi.d.ts.map +1 -0
- package/dist/middleware/legacyAgentApi.js +64 -0
- package/dist/middleware/legacyAgentApi.js.map +1 -0
- package/dist/middleware/workspaceRouteContext.d.ts +4 -0
- package/dist/middleware/workspaceRouteContext.d.ts.map +1 -0
- package/dist/middleware/workspaceRouteContext.js +44 -0
- package/dist/middleware/workspaceRouteContext.js.map +1 -0
- package/dist/models/sessionSchema.d.ts +106 -0
- package/dist/models/sessionSchema.d.ts.map +1 -0
- package/dist/models/sessionSchema.js +6 -0
- package/dist/models/sessionSchema.js.map +1 -0
- package/dist/routes/agentLogsRoutes.d.ts +3 -0
- package/dist/routes/agentLogsRoutes.d.ts.map +1 -0
- package/dist/routes/agentLogsRoutes.js +283 -0
- package/dist/routes/agentLogsRoutes.js.map +1 -0
- package/dist/routes/agentQuickSceneRoutes.d.ts +9 -0
- package/dist/routes/agentQuickSceneRoutes.d.ts.map +1 -0
- package/dist/routes/agentQuickSceneRoutes.js +51 -0
- package/dist/routes/agentQuickSceneRoutes.js.map +1 -0
- package/dist/routes/agentReportRoutes.d.ts +11 -0
- package/dist/routes/agentReportRoutes.d.ts.map +1 -0
- package/dist/routes/agentReportRoutes.js +100 -0
- package/dist/routes/agentReportRoutes.js.map +1 -0
- package/dist/routes/agentResumeRoutes.d.ts +14 -0
- package/dist/routes/agentResumeRoutes.d.ts.map +1 -0
- package/dist/routes/agentResumeRoutes.js +263 -0
- package/dist/routes/agentResumeRoutes.js.map +1 -0
- package/dist/routes/agentRoutes.d.ts +3 -0
- package/dist/routes/agentRoutes.d.ts.map +1 -0
- package/dist/routes/agentRoutes.js +4349 -0
- package/dist/routes/agentRoutes.js.map +1 -0
- package/dist/routes/agentSceneReconstructRoutes.d.ts +68 -0
- package/dist/routes/agentSceneReconstructRoutes.d.ts.map +1 -0
- package/dist/routes/agentSceneReconstructRoutes.js +448 -0
- package/dist/routes/agentSceneReconstructRoutes.js.map +1 -0
- package/dist/routes/agentSessionCatalogRoutes.d.ts +20 -0
- package/dist/routes/agentSessionCatalogRoutes.d.ts.map +1 -0
- package/dist/routes/agentSessionCatalogRoutes.js +90 -0
- package/dist/routes/agentSessionCatalogRoutes.js.map +1 -0
- package/dist/routes/agentTeachingRoutes.d.ts +3 -0
- package/dist/routes/agentTeachingRoutes.d.ts.map +1 -0
- package/dist/routes/agentTeachingRoutes.js +62 -0
- package/dist/routes/agentTeachingRoutes.js.map +1 -0
- package/dist/routes/analysisResultRoutes.d.ts +3 -0
- package/dist/routes/analysisResultRoutes.d.ts.map +1 -0
- package/dist/routes/analysisResultRoutes.js +216 -0
- package/dist/routes/analysisResultRoutes.js.map +1 -0
- package/dist/routes/baselineRoutes.d.ts +29 -0
- package/dist/routes/baselineRoutes.d.ts.map +1 -0
- package/dist/routes/baselineRoutes.js +123 -0
- package/dist/routes/baselineRoutes.js.map +1 -0
- package/dist/routes/caseRoutes.d.ts +29 -0
- package/dist/routes/caseRoutes.d.ts.map +1 -0
- package/dist/routes/caseRoutes.js +194 -0
- package/dist/routes/caseRoutes.js.map +1 -0
- package/dist/routes/ciGateRoutes.d.ts +11 -0
- package/dist/routes/ciGateRoutes.d.ts.map +1 -0
- package/dist/routes/ciGateRoutes.js +363 -0
- package/dist/routes/ciGateRoutes.js.map +1 -0
- package/dist/routes/comparisonRoutes.d.ts +3 -0
- package/dist/routes/comparisonRoutes.d.ts.map +1 -0
- package/dist/routes/comparisonRoutes.js +536 -0
- package/dist/routes/comparisonRoutes.js.map +1 -0
- package/dist/routes/criticalPathRoutes.d.ts +3 -0
- package/dist/routes/criticalPathRoutes.d.ts.map +1 -0
- package/dist/routes/criticalPathRoutes.js +88 -0
- package/dist/routes/criticalPathRoutes.js.map +1 -0
- package/dist/routes/enterpriseApiKeyRoutes.d.ts +9 -0
- package/dist/routes/enterpriseApiKeyRoutes.d.ts.map +1 -0
- package/dist/routes/enterpriseApiKeyRoutes.js +126 -0
- package/dist/routes/enterpriseApiKeyRoutes.js.map +1 -0
- package/dist/routes/enterpriseAuthRoutes.d.ts +18 -0
- package/dist/routes/enterpriseAuthRoutes.d.ts.map +1 -0
- package/dist/routes/enterpriseAuthRoutes.js +160 -0
- package/dist/routes/enterpriseAuthRoutes.js.map +1 -0
- package/dist/routes/enterpriseRuntimeDashboardRoutes.d.ts +6 -0
- package/dist/routes/enterpriseRuntimeDashboardRoutes.d.ts.map +1 -0
- package/dist/routes/enterpriseRuntimeDashboardRoutes.js +32 -0
- package/dist/routes/enterpriseRuntimeDashboardRoutes.js.map +1 -0
- package/dist/routes/enterpriseTenantRoutes.d.ts +4 -0
- package/dist/routes/enterpriseTenantRoutes.d.ts.map +1 -0
- package/dist/routes/enterpriseTenantRoutes.js +313 -0
- package/dist/routes/enterpriseTenantRoutes.js.map +1 -0
- package/dist/routes/exportRoutes.d.ts +3 -0
- package/dist/routes/exportRoutes.d.ts.map +1 -0
- package/dist/routes/exportRoutes.js +196 -0
- package/dist/routes/exportRoutes.js.map +1 -0
- package/dist/routes/flamegraphRoutes.d.ts +3 -0
- package/dist/routes/flamegraphRoutes.d.ts.map +1 -0
- package/dist/routes/flamegraphRoutes.js +99 -0
- package/dist/routes/flamegraphRoutes.js.map +1 -0
- package/dist/routes/memoryRoutes.d.ts +31 -0
- package/dist/routes/memoryRoutes.d.ts.map +1 -0
- package/dist/routes/memoryRoutes.js +150 -0
- package/dist/routes/memoryRoutes.js.map +1 -0
- package/dist/routes/narrativeSanitizer.d.ts +2 -0
- package/dist/routes/narrativeSanitizer.d.ts.map +1 -0
- package/dist/routes/narrativeSanitizer.js +167 -0
- package/dist/routes/narrativeSanitizer.js.map +1 -0
- package/dist/routes/perfettoLocalRoutes.d.ts +3 -0
- package/dist/routes/perfettoLocalRoutes.d.ts.map +1 -0
- package/dist/routes/perfettoLocalRoutes.js +222 -0
- package/dist/routes/perfettoLocalRoutes.js.map +1 -0
- package/dist/routes/perfettoSqlRoutes.d.ts +7 -0
- package/dist/routes/perfettoSqlRoutes.d.ts.map +1 -0
- package/dist/routes/perfettoSqlRoutes.js +738 -0
- package/dist/routes/perfettoSqlRoutes.js.map +1 -0
- package/dist/routes/providerRoutes.d.ts +3 -0
- package/dist/routes/providerRoutes.d.ts.map +1 -0
- package/dist/routes/providerRoutes.js +219 -0
- package/dist/routes/providerRoutes.js.map +1 -0
- package/dist/routes/ragAdminRoutes.d.ts +30 -0
- package/dist/routes/ragAdminRoutes.d.ts.map +1 -0
- package/dist/routes/ragAdminRoutes.js +93 -0
- package/dist/routes/ragAdminRoutes.js.map +1 -0
- package/dist/routes/reportRoutes.d.ts +17 -0
- package/dist/routes/reportRoutes.d.ts.map +1 -0
- package/dist/routes/reportRoutes.js +579 -0
- package/dist/routes/reportRoutes.js.map +1 -0
- package/dist/routes/sessionRoutes.d.ts +3 -0
- package/dist/routes/sessionRoutes.d.ts.map +1 -0
- package/dist/routes/sessionRoutes.js +144 -0
- package/dist/routes/sessionRoutes.js.map +1 -0
- package/dist/routes/simpleTraceRoutes.d.ts +3 -0
- package/dist/routes/simpleTraceRoutes.d.ts.map +1 -0
- package/dist/routes/simpleTraceRoutes.js +1131 -0
- package/dist/routes/simpleTraceRoutes.js.map +1 -0
- package/dist/routes/skillAdminRoutes.d.ts +3 -0
- package/dist/routes/skillAdminRoutes.d.ts.map +1 -0
- package/dist/routes/skillAdminRoutes.js +100 -0
- package/dist/routes/skillAdminRoutes.js.map +1 -0
- package/dist/routes/skillRoutes.d.ts +3 -0
- package/dist/routes/skillRoutes.d.ts.map +1 -0
- package/dist/routes/skillRoutes.js +88 -0
- package/dist/routes/skillRoutes.js.map +1 -0
- package/dist/routes/sql.d.ts +3 -0
- package/dist/routes/sql.d.ts.map +1 -0
- package/dist/routes/sql.js +19 -0
- package/dist/routes/sql.js.map +1 -0
- package/dist/routes/strategyAdminRoutes.d.ts +3 -0
- package/dist/routes/strategyAdminRoutes.d.ts.map +1 -0
- package/dist/routes/strategyAdminRoutes.js +65 -0
- package/dist/routes/strategyAdminRoutes.js.map +1 -0
- package/dist/routes/templateAnalysisRoutes.d.ts +3 -0
- package/dist/routes/templateAnalysisRoutes.d.ts.map +1 -0
- package/dist/routes/templateAnalysisRoutes.js +173 -0
- package/dist/routes/templateAnalysisRoutes.js.map +1 -0
- package/dist/routes/trace.d.ts +3 -0
- package/dist/routes/trace.d.ts.map +1 -0
- package/dist/routes/trace.js +48 -0
- package/dist/routes/trace.js.map +1 -0
- package/dist/routes/traceProcessorProxyRoutes.d.ts +6 -0
- package/dist/routes/traceProcessorProxyRoutes.d.ts.map +1 -0
- package/dist/routes/traceProcessorProxyRoutes.js +607 -0
- package/dist/routes/traceProcessorProxyRoutes.js.map +1 -0
- package/dist/routes/traceProcessorRoutes.d.ts +3 -0
- package/dist/routes/traceProcessorRoutes.d.ts.map +1 -0
- package/dist/routes/traceProcessorRoutes.js +40 -0
- package/dist/routes/traceProcessorRoutes.js.map +1 -0
- package/dist/routes/workspaceWindowRoutes.d.ts +3 -0
- package/dist/routes/workspaceWindowRoutes.d.ts.map +1 -0
- package/dist/routes/workspaceWindowRoutes.js +146 -0
- package/dist/routes/workspaceWindowRoutes.js.map +1 -0
- package/dist/runtimePaths.d.ts +3 -0
- package/dist/runtimePaths.d.ts.map +1 -0
- package/dist/runtimePaths.js +20 -0
- package/dist/runtimePaths.js.map +1 -0
- package/dist/scripts/analyzeComprehensiveTrace.d.ts +2 -0
- package/dist/scripts/analyzeComprehensiveTrace.d.ts.map +1 -0
- package/dist/scripts/analyzeComprehensiveTrace.js +210 -0
- package/dist/scripts/analyzeComprehensiveTrace.js.map +1 -0
- package/dist/scripts/analyzeUserTrace.d.ts +2 -0
- package/dist/scripts/analyzeUserTrace.d.ts.map +1 -0
- package/dist/scripts/analyzeUserTrace.js +170 -0
- package/dist/scripts/analyzeUserTrace.js.map +1 -0
- package/dist/scripts/auditTraceProcessorRssMatrix.d.ts +49 -0
- package/dist/scripts/auditTraceProcessorRssMatrix.d.ts.map +1 -0
- package/dist/scripts/auditTraceProcessorRssMatrix.js +390 -0
- package/dist/scripts/auditTraceProcessorRssMatrix.js.map +1 -0
- package/dist/scripts/benchmarkTraceProcessorRss.d.ts +96 -0
- package/dist/scripts/benchmarkTraceProcessorRss.d.ts.map +1 -0
- package/dist/scripts/benchmarkTraceProcessorRss.js +569 -0
- package/dist/scripts/benchmarkTraceProcessorRss.js.map +1 -0
- package/dist/scripts/captureContextEngineeringBaseline.d.ts +2 -0
- package/dist/scripts/captureContextEngineeringBaseline.d.ts.map +1 -0
- package/dist/scripts/captureContextEngineeringBaseline.js +271 -0
- package/dist/scripts/captureContextEngineeringBaseline.js.map +1 -0
- package/dist/scripts/checkTables.d.ts +2 -0
- package/dist/scripts/checkTables.d.ts.map +1 -0
- package/dist/scripts/checkTables.js +22 -0
- package/dist/scripts/checkTables.js.map +1 -0
- package/dist/scripts/diagnoseJankDetection.d.ts +2 -0
- package/dist/scripts/diagnoseJankDetection.d.ts.map +1 -0
- package/dist/scripts/diagnoseJankDetection.js +314 -0
- package/dist/scripts/diagnoseJankDetection.js.map +1 -0
- package/dist/scripts/diagnoseTrace.d.ts +2 -0
- package/dist/scripts/diagnoseTrace.d.ts.map +1 -0
- package/dist/scripts/diagnoseTrace.js +74 -0
- package/dist/scripts/diagnoseTrace.js.map +1 -0
- package/dist/scripts/enterpriseAcceptanceLoadTest.d.ts +193 -0
- package/dist/scripts/enterpriseAcceptanceLoadTest.d.ts.map +1 -0
- package/dist/scripts/enterpriseAcceptanceLoadTest.js +912 -0
- package/dist/scripts/enterpriseAcceptanceLoadTest.js.map +1 -0
- package/dist/scripts/enterpriseMigrationSnapshot.d.ts +3 -0
- package/dist/scripts/enterpriseMigrationSnapshot.d.ts.map +1 -0
- package/dist/scripts/enterpriseMigrationSnapshot.js +57 -0
- package/dist/scripts/enterpriseMigrationSnapshot.js.map +1 -0
- package/dist/scripts/enterpriseReadinessAudit.d.ts +30 -0
- package/dist/scripts/enterpriseReadinessAudit.d.ts.map +1 -0
- package/dist/scripts/enterpriseReadinessAudit.js +743 -0
- package/dist/scripts/enterpriseReadinessAudit.js.map +1 -0
- package/dist/scripts/enterpriseRssBenchmarkMatrix.d.ts +6 -0
- package/dist/scripts/enterpriseRssBenchmarkMatrix.d.ts.map +1 -0
- package/dist/scripts/enterpriseRssBenchmarkMatrix.js +20 -0
- package/dist/scripts/enterpriseRssBenchmarkMatrix.js.map +1 -0
- package/dist/scripts/enterpriseRuntimeIsolationChecklist.d.ts +22 -0
- package/dist/scripts/enterpriseRuntimeIsolationChecklist.d.ts.map +1 -0
- package/dist/scripts/enterpriseRuntimeIsolationChecklist.js +374 -0
- package/dist/scripts/enterpriseRuntimeIsolationChecklist.js.map +1 -0
- package/dist/scripts/enterpriseSecurityAuditChecklist.d.ts +20 -0
- package/dist/scripts/enterpriseSecurityAuditChecklist.d.ts.map +1 -0
- package/dist/scripts/enterpriseSecurityAuditChecklist.js +113 -0
- package/dist/scripts/enterpriseSecurityAuditChecklist.js.map +1 -0
- package/dist/scripts/probeStdlibSchema.d.ts +2 -0
- package/dist/scripts/probeStdlibSchema.d.ts.map +1 -0
- package/dist/scripts/probeStdlibSchema.js +209 -0
- package/dist/scripts/probeStdlibSchema.js.map +1 -0
- package/dist/scripts/runAgentTest.d.ts +2 -0
- package/dist/scripts/runAgentTest.d.ts.map +1 -0
- package/dist/scripts/runAgentTest.js +149 -0
- package/dist/scripts/runAgentTest.js.map +1 -0
- package/dist/scripts/runScrollingTest.d.ts +2 -0
- package/dist/scripts/runScrollingTest.d.ts.map +1 -0
- package/dist/scripts/runScrollingTest.js +199 -0
- package/dist/scripts/runScrollingTest.js.map +1 -0
- package/dist/scripts/runScrollingTestRealData.d.ts +2 -0
- package/dist/scripts/runScrollingTestRealData.d.ts.map +1 -0
- package/dist/scripts/runScrollingTestRealData.js +121 -0
- package/dist/scripts/runScrollingTestRealData.js.map +1 -0
- package/dist/scripts/testAndroidTrace.d.ts +2 -0
- package/dist/scripts/testAndroidTrace.d.ts.map +1 -0
- package/dist/scripts/testAndroidTrace.js +21 -0
- package/dist/scripts/testAndroidTrace.js.map +1 -0
- package/dist/scripts/testCrossDomainExpert.d.ts +2 -0
- package/dist/scripts/testCrossDomainExpert.d.ts.map +1 -0
- package/dist/scripts/testCrossDomainExpert.js +288 -0
- package/dist/scripts/testCrossDomainExpert.js.map +1 -0
- package/dist/scripts/testCrossDomainIntegration.d.ts +2 -0
- package/dist/scripts/testCrossDomainIntegration.d.ts.map +1 -0
- package/dist/scripts/testCrossDomainIntegration.js +282 -0
- package/dist/scripts/testCrossDomainIntegration.js.map +1 -0
- package/dist/scripts/testDeepLayerFix.d.ts +2 -0
- package/dist/scripts/testDeepLayerFix.d.ts.map +1 -0
- package/dist/scripts/testDeepLayerFix.js +137 -0
- package/dist/scripts/testDeepLayerFix.js.map +1 -0
- package/dist/scripts/testHtmlReportGen.d.ts +2 -0
- package/dist/scripts/testHtmlReportGen.d.ts.map +1 -0
- package/dist/scripts/testHtmlReportGen.js +148 -0
- package/dist/scripts/testHtmlReportGen.js.map +1 -0
- package/dist/scripts/verifyAgentSseScrolling.d.ts +2 -0
- package/dist/scripts/verifyAgentSseScrolling.d.ts.map +1 -0
- package/dist/scripts/verifyAgentSseScrolling.js +558 -0
- package/dist/scripts/verifyAgentSseScrolling.js.map +1 -0
- package/dist/scripts/verifyCriticalPathE2E.d.ts +2 -0
- package/dist/scripts/verifyCriticalPathE2E.d.ts.map +1 -0
- package/dist/scripts/verifyCriticalPathE2E.js +171 -0
- package/dist/scripts/verifyCriticalPathE2E.js.map +1 -0
- package/dist/scripts/verifyEnterpriseMultiTenantWindows.d.ts +24 -0
- package/dist/scripts/verifyEnterpriseMultiTenantWindows.d.ts.map +1 -0
- package/dist/scripts/verifyEnterpriseMultiTenantWindows.js +1363 -0
- package/dist/scripts/verifyEnterpriseMultiTenantWindows.js.map +1 -0
- package/dist/services/adb/adbContextDetector.d.ts +3 -0
- package/dist/services/adb/adbContextDetector.d.ts.map +1 -0
- package/dist/services/adb/adbContextDetector.js +151 -0
- package/dist/services/adb/adbContextDetector.js.map +1 -0
- package/dist/services/adb/adbService.d.ts +28 -0
- package/dist/services/adb/adbService.d.ts.map +1 -0
- package/dist/services/adb/adbService.js +238 -0
- package/dist/services/adb/adbService.js.map +1 -0
- package/dist/services/adb/index.d.ts +5 -0
- package/dist/services/adb/index.d.ts.map +1 -0
- package/dist/services/adb/index.js +24 -0
- package/dist/services/adb/index.js.map +1 -0
- package/dist/services/adb/traceDeviceMatcher.d.ts +12 -0
- package/dist/services/adb/traceDeviceMatcher.d.ts.map +1 -0
- package/dist/services/adb/traceDeviceMatcher.js +149 -0
- package/dist/services/adb/traceDeviceMatcher.js.map +1 -0
- package/dist/services/adb/types.d.ts +69 -0
- package/dist/services/adb/types.d.ts.map +1 -0
- package/dist/services/adb/types.js +6 -0
- package/dist/services/adb/types.js.map +1 -0
- package/dist/services/agentEventStore.d.ts +17 -0
- package/dist/services/agentEventStore.d.ts.map +1 -0
- package/dist/services/agentEventStore.js +139 -0
- package/dist/services/agentEventStore.js.map +1 -0
- package/dist/services/agentReportData.d.ts +42 -0
- package/dist/services/agentReportData.d.ts.map +1 -0
- package/dist/services/agentReportData.js +81 -0
- package/dist/services/agentReportData.js.map +1 -0
- package/dist/services/agentResultNormalizer.d.ts +33 -0
- package/dist/services/agentResultNormalizer.d.ts.map +1 -0
- package/dist/services/agentResultNormalizer.js +92 -0
- package/dist/services/agentResultNormalizer.js.map +1 -0
- package/dist/services/analysisResultSnapshotPipeline.d.ts +24 -0
- package/dist/services/analysisResultSnapshotPipeline.d.ts.map +1 -0
- package/dist/services/analysisResultSnapshotPipeline.js +466 -0
- package/dist/services/analysisResultSnapshotPipeline.js.map +1 -0
- package/dist/services/analysisResultSnapshotStore.d.ts +29 -0
- package/dist/services/analysisResultSnapshotStore.d.ts.map +1 -0
- package/dist/services/analysisResultSnapshotStore.js +457 -0
- package/dist/services/analysisResultSnapshotStore.js.map +1 -0
- package/dist/services/analysisResultWindowStateStore.d.ts +37 -0
- package/dist/services/analysisResultWindowStateStore.d.ts.map +1 -0
- package/dist/services/analysisResultWindowStateStore.js +190 -0
- package/dist/services/analysisResultWindowStateStore.js.map +1 -0
- package/dist/services/analysisRunStore.d.ts +38 -0
- package/dist/services/analysisRunStore.d.ts.map +1 -0
- package/dist/services/analysisRunStore.js +195 -0
- package/dist/services/analysisRunStore.js.map +1 -0
- package/dist/services/analysisTemplates/cpuCoreAnalysis.d.ts +70 -0
- package/dist/services/analysisTemplates/cpuCoreAnalysis.d.ts.map +1 -0
- package/dist/services/analysisTemplates/cpuCoreAnalysis.js +277 -0
- package/dist/services/analysisTemplates/cpuCoreAnalysis.js.map +1 -0
- package/dist/services/analysisTemplates/fourQuadrantAnalysis.d.ts +64 -0
- package/dist/services/analysisTemplates/fourQuadrantAnalysis.d.ts.map +1 -0
- package/dist/services/analysisTemplates/fourQuadrantAnalysis.js +288 -0
- package/dist/services/analysisTemplates/fourQuadrantAnalysis.js.map +1 -0
- package/dist/services/analysisTemplates/frameStatsAnalysis.d.ts +77 -0
- package/dist/services/analysisTemplates/frameStatsAnalysis.d.ts.map +1 -0
- package/dist/services/analysisTemplates/frameStatsAnalysis.js +232 -0
- package/dist/services/analysisTemplates/frameStatsAnalysis.js.map +1 -0
- package/dist/services/analysisTemplates/templateManager.d.ts +70 -0
- package/dist/services/analysisTemplates/templateManager.d.ts.map +1 -0
- package/dist/services/analysisTemplates/templateManager.js +293 -0
- package/dist/services/analysisTemplates/templateManager.js.map +1 -0
- package/dist/services/anonymizer.d.ts +61 -0
- package/dist/services/anonymizer.d.ts.map +1 -0
- package/dist/services/anonymizer.js +232 -0
- package/dist/services/anonymizer.js.map +1 -0
- package/dist/services/aospKnowledgeIngester.d.ts +67 -0
- package/dist/services/aospKnowledgeIngester.d.ts.map +1 -0
- package/dist/services/aospKnowledgeIngester.js +171 -0
- package/dist/services/aospKnowledgeIngester.js.map +1 -0
- package/dist/services/artifactCompression.d.ts +52 -0
- package/dist/services/artifactCompression.d.ts.map +1 -0
- package/dist/services/artifactCompression.js +215 -0
- package/dist/services/artifactCompression.js.map +1 -0
- package/dist/services/baselineDiffer.d.ts +85 -0
- package/dist/services/baselineDiffer.d.ts.map +1 -0
- package/dist/services/baselineDiffer.js +287 -0
- package/dist/services/baselineDiffer.js.map +1 -0
- package/dist/services/baselineStore.d.ts +52 -0
- package/dist/services/baselineStore.d.ts.map +1 -0
- package/dist/services/baselineStore.js +224 -0
- package/dist/services/baselineStore.js.map +1 -0
- package/dist/services/binderRootCauseChain.d.ts +38 -0
- package/dist/services/binderRootCauseChain.d.ts.map +1 -0
- package/dist/services/binderRootCauseChain.js +74 -0
- package/dist/services/binderRootCauseChain.js.map +1 -0
- package/dist/services/blogKnowledgeIngester.d.ts +89 -0
- package/dist/services/blogKnowledgeIngester.d.ts.map +1 -0
- package/dist/services/blogKnowledgeIngester.js +192 -0
- package/dist/services/blogKnowledgeIngester.js.map +1 -0
- package/dist/services/caseGraph.d.ts +55 -0
- package/dist/services/caseGraph.d.ts.map +1 -0
- package/dist/services/caseGraph.js +260 -0
- package/dist/services/caseGraph.js.map +1 -0
- package/dist/services/caseLibrary.d.ts +61 -0
- package/dist/services/caseLibrary.d.ts.map +1 -0
- package/dist/services/caseLibrary.js +269 -0
- package/dist/services/caseLibrary.js.map +1 -0
- package/dist/services/ciGateRunStore.d.ts +39 -0
- package/dist/services/ciGateRunStore.d.ts.map +1 -0
- package/dist/services/ciGateRunStore.js +208 -0
- package/dist/services/ciGateRunStore.js.map +1 -0
- package/dist/services/comparisonAiConclusionService.d.ts +23 -0
- package/dist/services/comparisonAiConclusionService.d.ts.map +1 -0
- package/dist/services/comparisonAiConclusionService.js +207 -0
- package/dist/services/comparisonAiConclusionService.js.map +1 -0
- package/dist/services/comparisonAppendixService.d.ts +50 -0
- package/dist/services/comparisonAppendixService.d.ts.map +1 -0
- package/dist/services/comparisonAppendixService.js +276 -0
- package/dist/services/comparisonAppendixService.js.map +1 -0
- package/dist/services/comparisonHtmlReportService.d.ts +20 -0
- package/dist/services/comparisonHtmlReportService.d.ts.map +1 -0
- package/dist/services/comparisonHtmlReportService.js +214 -0
- package/dist/services/comparisonHtmlReportService.js.map +1 -0
- package/dist/services/comparisonMatrixService.d.ts +7 -0
- package/dist/services/comparisonMatrixService.d.ts.map +1 -0
- package/dist/services/comparisonMatrixService.js +211 -0
- package/dist/services/comparisonMatrixService.js.map +1 -0
- package/dist/services/comparisonResultService.d.ts +13 -0
- package/dist/services/comparisonResultService.d.ts.map +1 -0
- package/dist/services/comparisonResultService.js +99 -0
- package/dist/services/comparisonResultService.js.map +1 -0
- package/dist/services/comparisonSignificance.d.ts +3 -0
- package/dist/services/comparisonSignificance.d.ts.map +1 -0
- package/dist/services/comparisonSignificance.js +42 -0
- package/dist/services/comparisonSignificance.js.map +1 -0
- package/dist/services/cpuThermalPmu.d.ts +38 -0
- package/dist/services/cpuThermalPmu.d.ts.map +1 -0
- package/dist/services/cpuThermalPmu.js +141 -0
- package/dist/services/cpuThermalPmu.js.map +1 -0
- package/dist/services/criticalPathAiSummary.d.ts +29 -0
- package/dist/services/criticalPathAiSummary.d.ts.map +1 -0
- package/dist/services/criticalPathAiSummary.js +310 -0
- package/dist/services/criticalPathAiSummary.js.map +1 -0
- package/dist/services/criticalPathAnalyzer.d.ts +108 -0
- package/dist/services/criticalPathAnalyzer.d.ts.map +1 -0
- package/dist/services/criticalPathAnalyzer.js +880 -0
- package/dist/services/criticalPathAnalyzer.js.map +1 -0
- package/dist/services/criticalPathQuantify.d.ts +70 -0
- package/dist/services/criticalPathQuantify.d.ts.map +1 -0
- package/dist/services/criticalPathQuantify.js +214 -0
- package/dist/services/criticalPathQuantify.js.map +1 -0
- package/dist/services/criticalPathSemantics.d.ts +95 -0
- package/dist/services/criticalPathSemantics.d.ts.map +1 -0
- package/dist/services/criticalPathSemantics.js +453 -0
- package/dist/services/criticalPathSemantics.js.map +1 -0
- package/dist/services/criticalPathWakerChain.d.ts +38 -0
- package/dist/services/criticalPathWakerChain.d.ts.map +1 -0
- package/dist/services/criticalPathWakerChain.js +144 -0
- package/dist/services/criticalPathWakerChain.js.map +1 -0
- package/dist/services/domainSkillEvalHarness.d.ts +51 -0
- package/dist/services/domainSkillEvalHarness.d.ts.map +1 -0
- package/dist/services/domainSkillEvalHarness.js +141 -0
- package/dist/services/domainSkillEvalHarness.js.map +1 -0
- package/dist/services/enhancedAIService.d.ts +81 -0
- package/dist/services/enhancedAIService.d.ts.map +1 -0
- package/dist/services/enhancedAIService.js +277 -0
- package/dist/services/enhancedAIService.js.map +1 -0
- package/dist/services/enterpriseAdminControlPlaneService.d.ts +124 -0
- package/dist/services/enterpriseAdminControlPlaneService.d.ts.map +1 -0
- package/dist/services/enterpriseAdminControlPlaneService.js +323 -0
- package/dist/services/enterpriseAdminControlPlaneService.js.map +1 -0
- package/dist/services/enterpriseApiKeyService.d.ts +56 -0
- package/dist/services/enterpriseApiKeyService.d.ts.map +1 -0
- package/dist/services/enterpriseApiKeyService.js +260 -0
- package/dist/services/enterpriseApiKeyService.js.map +1 -0
- package/dist/services/enterpriseAuditService.d.ts +30 -0
- package/dist/services/enterpriseAuditService.d.ts.map +1 -0
- package/dist/services/enterpriseAuditService.js +73 -0
- package/dist/services/enterpriseAuditService.js.map +1 -0
- package/dist/services/enterpriseDb.d.ts +5 -0
- package/dist/services/enterpriseDb.d.ts.map +1 -0
- package/dist/services/enterpriseDb.js +33 -0
- package/dist/services/enterpriseDb.js.map +1 -0
- package/dist/services/enterpriseMigration.d.ts +89 -0
- package/dist/services/enterpriseMigration.d.ts.map +1 -0
- package/dist/services/enterpriseMigration.js +506 -0
- package/dist/services/enterpriseMigration.js.map +1 -0
- package/dist/services/enterpriseOidcClient.d.ts +36 -0
- package/dist/services/enterpriseOidcClient.d.ts.map +1 -0
- package/dist/services/enterpriseOidcClient.js +124 -0
- package/dist/services/enterpriseOidcClient.js.map +1 -0
- package/dist/services/enterpriseQuotaPolicyService.d.ts +37 -0
- package/dist/services/enterpriseQuotaPolicyService.d.ts.map +1 -0
- package/dist/services/enterpriseQuotaPolicyService.js +198 -0
- package/dist/services/enterpriseQuotaPolicyService.js.map +1 -0
- package/dist/services/enterpriseRepository.d.ts +36 -0
- package/dist/services/enterpriseRepository.d.ts.map +1 -0
- package/dist/services/enterpriseRepository.js +208 -0
- package/dist/services/enterpriseRepository.js.map +1 -0
- package/dist/services/enterpriseRuntimeDashboardService.d.ts +114 -0
- package/dist/services/enterpriseRuntimeDashboardService.d.ts.map +1 -0
- package/dist/services/enterpriseRuntimeDashboardService.js +205 -0
- package/dist/services/enterpriseRuntimeDashboardService.js.map +1 -0
- package/dist/services/enterpriseSchema.d.ts +7 -0
- package/dist/services/enterpriseSchema.d.ts.map +1 -0
- package/dist/services/enterpriseSchema.js +688 -0
- package/dist/services/enterpriseSchema.js.map +1 -0
- package/dist/services/enterpriseSsoService.d.ts +99 -0
- package/dist/services/enterpriseSsoService.d.ts.map +1 -0
- package/dist/services/enterpriseSsoService.js +538 -0
- package/dist/services/enterpriseSsoService.js.map +1 -0
- package/dist/services/enterpriseTenantExportService.d.ts +58 -0
- package/dist/services/enterpriseTenantExportService.d.ts.map +1 -0
- package/dist/services/enterpriseTenantExportService.js +339 -0
- package/dist/services/enterpriseTenantExportService.js.map +1 -0
- package/dist/services/enterpriseTenantLifecycleService.d.ts +52 -0
- package/dist/services/enterpriseTenantLifecycleService.d.ts.map +1 -0
- package/dist/services/enterpriseTenantLifecycleService.js +323 -0
- package/dist/services/enterpriseTenantLifecycleService.js.map +1 -0
- package/dist/services/flamegraphAiSummary.d.ts +4 -0
- package/dist/services/flamegraphAiSummary.d.ts.map +1 -0
- package/dist/services/flamegraphAiSummary.js +172 -0
- package/dist/services/flamegraphAiSummary.js.map +1 -0
- package/dist/services/flamegraphAnalyzer.d.ts +14 -0
- package/dist/services/flamegraphAnalyzer.d.ts.map +1 -0
- package/dist/services/flamegraphAnalyzer.js +607 -0
- package/dist/services/flamegraphAnalyzer.js.map +1 -0
- package/dist/services/flamegraphTypes.d.ts +106 -0
- package/dist/services/flamegraphTypes.d.ts.map +1 -0
- package/dist/services/flamegraphTypes.js +6 -0
- package/dist/services/flamegraphTypes.js.map +1 -0
- package/dist/services/gpuSurfaceFlinger.d.ts +27 -0
- package/dist/services/gpuSurfaceFlinger.d.ts.map +1 -0
- package/dist/services/gpuSurfaceFlinger.js +68 -0
- package/dist/services/gpuSurfaceFlinger.js.map +1 -0
- package/dist/services/htmlReportGenerator.d.ts +425 -0
- package/dist/services/htmlReportGenerator.d.ts.map +1 -0
- package/dist/services/htmlReportGenerator.js +5110 -0
- package/dist/services/htmlReportGenerator.js.map +1 -0
- package/dist/services/ioNetworkWakeup.d.ts +27 -0
- package/dist/services/ioNetworkWakeup.d.ts.map +1 -0
- package/dist/services/ioNetworkWakeup.js +68 -0
- package/dist/services/ioNetworkWakeup.js.map +1 -0
- package/dist/services/jankDecisionTree.d.ts +39 -0
- package/dist/services/jankDecisionTree.d.ts.map +1 -0
- package/dist/services/jankDecisionTree.js +230 -0
- package/dist/services/jankDecisionTree.js.map +1 -0
- package/dist/services/legacyApiTelemetry.d.ts +28 -0
- package/dist/services/legacyApiTelemetry.d.ts.map +1 -0
- package/dist/services/legacyApiTelemetry.js +157 -0
- package/dist/services/legacyApiTelemetry.js.map +1 -0
- package/dist/services/memoryRootCause.d.ts +24 -0
- package/dist/services/memoryRootCause.d.ts.map +1 -0
- package/dist/services/memoryRootCause.js +70 -0
- package/dist/services/memoryRootCause.js.map +1 -0
- package/dist/services/multiTraceComparisonStore.d.ts +28 -0
- package/dist/services/multiTraceComparisonStore.d.ts.map +1 -0
- package/dist/services/multiTraceComparisonStore.js +220 -0
- package/dist/services/multiTraceComparisonStore.js.map +1 -0
- package/dist/services/oemSdkKnowledgeIngester.d.ts +62 -0
- package/dist/services/oemSdkKnowledgeIngester.d.ts.map +1 -0
- package/dist/services/oemSdkKnowledgeIngester.js +154 -0
- package/dist/services/oemSdkKnowledgeIngester.js.map +1 -0
- package/dist/services/perfettoLocalService.d.ts +25 -0
- package/dist/services/perfettoLocalService.d.ts.map +1 -0
- package/dist/services/perfettoLocalService.js +213 -0
- package/dist/services/perfettoLocalService.js.map +1 -0
- package/dist/services/perfettoService.d.ts +39 -0
- package/dist/services/perfettoService.d.ts.map +1 -0
- package/dist/services/perfettoService.js +330 -0
- package/dist/services/perfettoService.js.map +1 -0
- package/dist/services/perfettoSqlDocs.d.ts +94 -0
- package/dist/services/perfettoSqlDocs.d.ts.map +1 -0
- package/dist/services/perfettoSqlDocs.js +222 -0
- package/dist/services/perfettoSqlDocs.js.map +1 -0
- package/dist/services/perfettoSqlSkill.d.ts +263 -0
- package/dist/services/perfettoSqlSkill.d.ts.map +1 -0
- package/dist/services/perfettoSqlSkill.js +3731 -0
- package/dist/services/perfettoSqlSkill.js.map +1 -0
- package/dist/services/perfettoStdlibScanner.d.ts +66 -0
- package/dist/services/perfettoStdlibScanner.d.ts.map +1 -0
- package/dist/services/perfettoStdlibScanner.js +345 -0
- package/dist/services/perfettoStdlibScanner.js.map +1 -0
- package/dist/services/persistAgentSession.d.ts +43 -0
- package/dist/services/persistAgentSession.d.ts.map +1 -0
- package/dist/services/persistAgentSession.js +146 -0
- package/dist/services/persistAgentSession.js.map +1 -0
- package/dist/services/pipelineDocService.d.ts +83 -0
- package/dist/services/pipelineDocService.d.ts.map +1 -0
- package/dist/services/pipelineDocService.js +417 -0
- package/dist/services/pipelineDocService.js.map +1 -0
- package/dist/services/pipelineSkillLoader.d.ts +173 -0
- package/dist/services/pipelineSkillLoader.d.ts.map +1 -0
- package/dist/services/pipelineSkillLoader.js +301 -0
- package/dist/services/pipelineSkillLoader.js.map +1 -0
- package/dist/services/portPool.d.ts +85 -0
- package/dist/services/portPool.d.ts.map +1 -0
- package/dist/services/portPool.js +221 -0
- package/dist/services/portPool.js.map +1 -0
- package/dist/services/processIdentity/identityGate.d.ts +27 -0
- package/dist/services/processIdentity/identityGate.d.ts.map +1 -0
- package/dist/services/processIdentity/identityGate.js +284 -0
- package/dist/services/processIdentity/identityGate.js.map +1 -0
- package/dist/services/processIdentity/types.d.ts +49 -0
- package/dist/services/processIdentity/types.d.ts.map +1 -0
- package/dist/services/processIdentity/types.js +16 -0
- package/dist/services/processIdentity/types.js.map +1 -0
- package/dist/services/processRss.d.ts +10 -0
- package/dist/services/processRss.d.ts.map +1 -0
- package/dist/services/processRss.js +78 -0
- package/dist/services/processRss.js.map +1 -0
- package/dist/services/promptTemplateService.d.ts +68 -0
- package/dist/services/promptTemplateService.d.ts.map +1 -0
- package/dist/services/promptTemplateService.js +196 -0
- package/dist/services/promptTemplateService.js.map +1 -0
- package/dist/services/providerManager/connectionTester.d.ts +3 -0
- package/dist/services/providerManager/connectionTester.d.ts.map +1 -0
- package/dist/services/providerManager/connectionTester.js +479 -0
- package/dist/services/providerManager/connectionTester.js.map +1 -0
- package/dist/services/providerManager/envIsolation.d.ts +3 -0
- package/dist/services/providerManager/envIsolation.d.ts.map +1 -0
- package/dist/services/providerManager/envIsolation.js +31 -0
- package/dist/services/providerManager/envIsolation.js.map +1 -0
- package/dist/services/providerManager/index.d.ts +9 -0
- package/dist/services/providerManager/index.d.ts.map +1 -0
- package/dist/services/providerManager/index.js +40 -0
- package/dist/services/providerManager/index.js.map +1 -0
- package/dist/services/providerManager/localSecretStore.d.ts +32 -0
- package/dist/services/providerManager/localSecretStore.d.ts.map +1 -0
- package/dist/services/providerManager/localSecretStore.js +338 -0
- package/dist/services/providerManager/localSecretStore.js.map +1 -0
- package/dist/services/providerManager/providerService.d.ts +31 -0
- package/dist/services/providerManager/providerService.d.ts.map +1 -0
- package/dist/services/providerManager/providerService.js +460 -0
- package/dist/services/providerManager/providerService.js.map +1 -0
- package/dist/services/providerManager/providerSnapshot.d.ts +30 -0
- package/dist/services/providerManager/providerSnapshot.d.ts.map +1 -0
- package/dist/services/providerManager/providerSnapshot.js +224 -0
- package/dist/services/providerManager/providerSnapshot.js.map +1 -0
- package/dist/services/providerManager/providerStore.d.ts +31 -0
- package/dist/services/providerManager/providerStore.d.ts.map +1 -0
- package/dist/services/providerManager/providerStore.js +553 -0
- package/dist/services/providerManager/providerStore.js.map +1 -0
- package/dist/services/providerManager/templates.d.ts +3 -0
- package/dist/services/providerManager/templates.d.ts.map +1 -0
- package/dist/services/providerManager/templates.js +328 -0
- package/dist/services/providerManager/templates.js.map +1 -0
- package/dist/services/providerManager/types.d.ts +119 -0
- package/dist/services/providerManager/types.d.ts.map +1 -0
- package/dist/services/providerManager/types.js +5 -0
- package/dist/services/providerManager/types.js.map +1 -0
- package/dist/services/ragStore.d.ts +60 -0
- package/dist/services/ragStore.d.ts.map +1 -0
- package/dist/services/ragStore.js +297 -0
- package/dist/services/ragStore.js.map +1 -0
- package/dist/services/rbac.d.ts +19 -0
- package/dist/services/rbac.d.ts.map +1 -0
- package/dist/services/rbac.js +153 -0
- package/dist/services/rbac.js.map +1 -0
- package/dist/services/renderingPipelineDetectionSkillGenerator.d.ts +3 -0
- package/dist/services/renderingPipelineDetectionSkillGenerator.d.ts.map +1 -0
- package/dist/services/renderingPipelineDetectionSkillGenerator.js +1120 -0
- package/dist/services/renderingPipelineDetectionSkillGenerator.js.map +1 -0
- package/dist/services/renderingPipelineTeachingService.d.ts +33 -0
- package/dist/services/renderingPipelineTeachingService.d.ts.map +1 -0
- package/dist/services/renderingPipelineTeachingService.js +1312 -0
- package/dist/services/renderingPipelineTeachingService.js.map +1 -0
- package/dist/services/reportCausalMapAssets.d.ts +3 -0
- package/dist/services/reportCausalMapAssets.d.ts.map +1 -0
- package/dist/services/reportCausalMapAssets.js +898 -0
- package/dist/services/reportCausalMapAssets.js.map +1 -0
- package/dist/services/reportGenerator.d.ts +54 -0
- package/dist/services/reportGenerator.d.ts.map +1 -0
- package/dist/services/reportGenerator.js +241 -0
- package/dist/services/reportGenerator.js.map +1 -0
- package/dist/services/resourceOwnership.d.ts +21 -0
- package/dist/services/resourceOwnership.d.ts.map +1 -0
- package/dist/services/resourceOwnership.js +50 -0
- package/dist/services/resourceOwnership.js.map +1 -0
- package/dist/services/resultExportService.d.ts +66 -0
- package/dist/services/resultExportService.d.ts.map +1 -0
- package/dist/services/resultExportService.js +170 -0
- package/dist/services/resultExportService.js.map +1 -0
- package/dist/services/runtimeSnapshotStore.d.ts +19 -0
- package/dist/services/runtimeSnapshotStore.d.ts.map +1 -0
- package/dist/services/runtimeSnapshotStore.js +222 -0
- package/dist/services/runtimeSnapshotStore.js.map +1 -0
- package/dist/services/sceneReport/sceneReportMemoryCache.d.ts +38 -0
- package/dist/services/sceneReport/sceneReportMemoryCache.d.ts.map +1 -0
- package/dist/services/sceneReport/sceneReportMemoryCache.js +55 -0
- package/dist/services/sceneReport/sceneReportMemoryCache.js.map +1 -0
- package/dist/services/sceneReport/sceneReportStore.d.ts +41 -0
- package/dist/services/sceneReport/sceneReportStore.d.ts.map +1 -0
- package/dist/services/sceneReport/sceneReportStore.js +248 -0
- package/dist/services/sceneReport/sceneReportStore.js.map +1 -0
- package/dist/services/scopedKnowledgeStore.d.ts +45 -0
- package/dist/services/scopedKnowledgeStore.d.ts.map +1 -0
- package/dist/services/scopedKnowledgeStore.js +225 -0
- package/dist/services/scopedKnowledgeStore.js.map +1 -0
- package/dist/services/sessionLogger.d.ts +142 -0
- package/dist/services/sessionLogger.d.ts.map +1 -0
- package/dist/services/sessionLogger.js +566 -0
- package/dist/services/sessionLogger.js.map +1 -0
- package/dist/services/sessionPersistenceService.d.ts +190 -0
- package/dist/services/sessionPersistenceService.d.ts.map +1 -0
- package/dist/services/sessionPersistenceService.js +737 -0
- package/dist/services/sessionPersistenceService.js.map +1 -0
- package/dist/services/skillEngine/answerGenerator.d.ts +102 -0
- package/dist/services/skillEngine/answerGenerator.d.ts.map +1 -0
- package/dist/services/skillEngine/answerGenerator.js +508 -0
- package/dist/services/skillEngine/answerGenerator.js.map +1 -0
- package/dist/services/skillEngine/displayContractValidator.d.ts +26 -0
- package/dist/services/skillEngine/displayContractValidator.d.ts.map +1 -0
- package/dist/services/skillEngine/displayContractValidator.js +232 -0
- package/dist/services/skillEngine/displayContractValidator.js.map +1 -0
- package/dist/services/skillEngine/eventCollector.d.ts +96 -0
- package/dist/services/skillEngine/eventCollector.d.ts.map +1 -0
- package/dist/services/skillEngine/eventCollector.js +226 -0
- package/dist/services/skillEngine/eventCollector.js.map +1 -0
- package/dist/services/skillEngine/expressionUtils.d.ts +25 -0
- package/dist/services/skillEngine/expressionUtils.d.ts.map +1 -0
- package/dist/services/skillEngine/expressionUtils.js +66 -0
- package/dist/services/skillEngine/expressionUtils.js.map +1 -0
- package/dist/services/skillEngine/index.d.ts +25 -0
- package/dist/services/skillEngine/index.d.ts.map +1 -0
- package/dist/services/skillEngine/index.js +98 -0
- package/dist/services/skillEngine/index.js.map +1 -0
- package/dist/services/skillEngine/skillAnalysisAdapter.d.ts +149 -0
- package/dist/services/skillEngine/skillAnalysisAdapter.d.ts.map +1 -0
- package/dist/services/skillEngine/skillAnalysisAdapter.js +752 -0
- package/dist/services/skillEngine/skillAnalysisAdapter.js.map +1 -0
- package/dist/services/skillEngine/skillExecutor.d.ts +371 -0
- package/dist/services/skillEngine/skillExecutor.d.ts.map +1 -0
- package/dist/services/skillEngine/skillExecutor.js +4129 -0
- package/dist/services/skillEngine/skillExecutor.js.map +1 -0
- package/dist/services/skillEngine/skillLoader.d.ts +163 -0
- package/dist/services/skillEngine/skillLoader.d.ts.map +1 -0
- package/dist/services/skillEngine/skillLoader.js +840 -0
- package/dist/services/skillEngine/skillLoader.js.map +1 -0
- package/dist/services/skillEngine/skillValidator.d.ts +53 -0
- package/dist/services/skillEngine/skillValidator.d.ts.map +1 -0
- package/dist/services/skillEngine/skillValidator.js +274 -0
- package/dist/services/skillEngine/skillValidator.js.map +1 -0
- package/dist/services/skillEngine/smartSummaryGenerator.d.ts +70 -0
- package/dist/services/skillEngine/smartSummaryGenerator.d.ts.map +1 -0
- package/dist/services/skillEngine/smartSummaryGenerator.js +324 -0
- package/dist/services/skillEngine/smartSummaryGenerator.js.map +1 -0
- package/dist/services/skillEngine/types.d.ts +584 -0
- package/dist/services/skillEngine/types.d.ts.map +1 -0
- package/dist/services/skillEngine/types.js +6 -0
- package/dist/services/skillEngine/types.js.map +1 -0
- package/dist/services/smartperfettoSqlPackage.d.ts +11 -0
- package/dist/services/smartperfettoSqlPackage.d.ts.map +1 -0
- package/dist/services/smartperfettoSqlPackage.js +168 -0
- package/dist/services/smartperfettoSqlPackage.js.map +1 -0
- package/dist/services/sqlGuardrailAnalyzer.d.ts +24 -0
- package/dist/services/sqlGuardrailAnalyzer.d.ts.map +1 -0
- package/dist/services/sqlGuardrailAnalyzer.js +362 -0
- package/dist/services/sqlGuardrailAnalyzer.js.map +1 -0
- package/dist/services/sqlKnowledgeBase.d.ts +236 -0
- package/dist/services/sqlKnowledgeBase.d.ts.map +1 -0
- package/dist/services/sqlKnowledgeBase.js +1109 -0
- package/dist/services/sqlKnowledgeBase.js.map +1 -0
- package/dist/services/sqlStdlibDependencyAnalyzer.d.ts +26 -0
- package/dist/services/sqlStdlibDependencyAnalyzer.d.ts.map +1 -0
- package/dist/services/sqlStdlibDependencyAnalyzer.js +486 -0
- package/dist/services/sqlStdlibDependencyAnalyzer.js.map +1 -0
- package/dist/services/sqlTemplateEngine.d.ts +134 -0
- package/dist/services/sqlTemplateEngine.d.ts.map +1 -0
- package/dist/services/sqlTemplateEngine.js +430 -0
- package/dist/services/sqlTemplateEngine.js.map +1 -0
- package/dist/services/sqlValidator.d.ts +21 -0
- package/dist/services/sqlValidator.d.ts.map +1 -0
- package/dist/services/sqlValidator.js +175 -0
- package/dist/services/sqlValidator.js.map +1 -0
- package/dist/services/standardMetricBackfillService.d.ts +23 -0
- package/dist/services/standardMetricBackfillService.d.ts.map +1 -0
- package/dist/services/standardMetricBackfillService.js +196 -0
- package/dist/services/standardMetricBackfillService.js.map +1 -0
- package/dist/services/startupAnrMethodGraph.d.ts +20 -0
- package/dist/services/startupAnrMethodGraph.d.ts.map +1 -0
- package/dist/services/startupAnrMethodGraph.js +70 -0
- package/dist/services/startupAnrMethodGraph.js.map +1 -0
- package/dist/services/stdlibSkillCoverage.d.ts +23 -0
- package/dist/services/stdlibSkillCoverage.d.ts.map +1 -0
- package/dist/services/stdlibSkillCoverage.js +289 -0
- package/dist/services/stdlibSkillCoverage.js.map +1 -0
- package/dist/services/threadSchedContext.d.ts +49 -0
- package/dist/services/threadSchedContext.d.ts.map +1 -0
- package/dist/services/threadSchedContext.js +84 -0
- package/dist/services/threadSchedContext.js.map +1 -0
- package/dist/services/timelineBinning.d.ts +44 -0
- package/dist/services/timelineBinning.d.ts.map +1 -0
- package/dist/services/timelineBinning.js +150 -0
- package/dist/services/timelineBinning.js.map +1 -0
- package/dist/services/traceConfigGenerator.d.ts +36 -0
- package/dist/services/traceConfigGenerator.d.ts.map +1 -0
- package/dist/services/traceConfigGenerator.js +110 -0
- package/dist/services/traceConfigGenerator.js.map +1 -0
- package/dist/services/traceFormatDetector.d.ts +39 -0
- package/dist/services/traceFormatDetector.d.ts.map +1 -0
- package/dist/services/traceFormatDetector.js +287 -0
- package/dist/services/traceFormatDetector.js.map +1 -0
- package/dist/services/traceMetadataStore.d.ts +32 -0
- package/dist/services/traceMetadataStore.d.ts.map +1 -0
- package/dist/services/traceMetadataStore.js +375 -0
- package/dist/services/traceMetadataStore.js.map +1 -0
- package/dist/services/traceProcessorConnectionModel.d.ts +32 -0
- package/dist/services/traceProcessorConnectionModel.d.ts.map +1 -0
- package/dist/services/traceProcessorConnectionModel.js +38 -0
- package/dist/services/traceProcessorConnectionModel.js.map +1 -0
- package/dist/services/traceProcessorHttpRpcClient.d.ts +22 -0
- package/dist/services/traceProcessorHttpRpcClient.d.ts.map +1 -0
- package/dist/services/traceProcessorHttpRpcClient.js +89 -0
- package/dist/services/traceProcessorHttpRpcClient.js.map +1 -0
- package/dist/services/traceProcessorLeaseModeDecision.d.ts +52 -0
- package/dist/services/traceProcessorLeaseModeDecision.d.ts.map +1 -0
- package/dist/services/traceProcessorLeaseModeDecision.js +150 -0
- package/dist/services/traceProcessorLeaseModeDecision.js.map +1 -0
- package/dist/services/traceProcessorLeaseStore.d.ts +88 -0
- package/dist/services/traceProcessorLeaseStore.d.ts.map +1 -0
- package/dist/services/traceProcessorLeaseStore.js +463 -0
- package/dist/services/traceProcessorLeaseStore.js.map +1 -0
- package/dist/services/traceProcessorProtobuf.d.ts +56 -0
- package/dist/services/traceProcessorProtobuf.d.ts.map +1 -0
- package/dist/services/traceProcessorProtobuf.js +442 -0
- package/dist/services/traceProcessorProtobuf.js.map +1 -0
- package/dist/services/traceProcessorRamBudget.d.ts +55 -0
- package/dist/services/traceProcessorRamBudget.d.ts.map +1 -0
- package/dist/services/traceProcessorRamBudget.js +140 -0
- package/dist/services/traceProcessorRamBudget.js.map +1 -0
- package/dist/services/traceProcessorService.d.ts +223 -0
- package/dist/services/traceProcessorService.d.ts.map +1 -0
- package/dist/services/traceProcessorService.js +838 -0
- package/dist/services/traceProcessorService.js.map +1 -0
- package/dist/services/traceProcessorSqlWorker.d.ts +49 -0
- package/dist/services/traceProcessorSqlWorker.d.ts.map +1 -0
- package/dist/services/traceProcessorSqlWorker.js +218 -0
- package/dist/services/traceProcessorSqlWorker.js.map +1 -0
- package/dist/services/traceProcessorSqlWorkerThread.d.ts +2 -0
- package/dist/services/traceProcessorSqlWorkerThread.d.ts.map +1 -0
- package/dist/services/traceProcessorSqlWorkerThread.js +35 -0
- package/dist/services/traceProcessorSqlWorkerThread.js.map +1 -0
- package/dist/services/traceSummaryV2.d.ts +47 -0
- package/dist/services/traceSummaryV2.d.ts.map +1 -0
- package/dist/services/traceSummaryV2.js +241 -0
- package/dist/services/traceSummaryV2.js.map +1 -0
- package/dist/services/traceUploadLimit.d.ts +3 -0
- package/dist/services/traceUploadLimit.d.ts.map +1 -0
- package/dist/services/traceUploadLimit.js +24 -0
- package/dist/services/traceUploadLimit.js.map +1 -0
- package/dist/services/workingTraceProcessor.d.ts +226 -0
- package/dist/services/workingTraceProcessor.d.ts.map +1 -0
- package/dist/services/workingTraceProcessor.js +1093 -0
- package/dist/services/workingTraceProcessor.js.map +1 -0
- package/dist/trace-processor-pin.env +39 -0
- package/dist/types/analysis.d.ts +511 -0
- package/dist/types/analysis.d.ts.map +1 -0
- package/dist/types/analysis.js +112 -0
- package/dist/types/analysis.js.map +1 -0
- package/dist/types/ciGateContracts.d.ts +63 -0
- package/dist/types/ciGateContracts.d.ts.map +1 -0
- package/dist/types/ciGateContracts.js +6 -0
- package/dist/types/ciGateContracts.js.map +1 -0
- package/dist/types/dataContract.d.ts +624 -0
- package/dist/types/dataContract.d.ts.map +1 -0
- package/dist/types/dataContract.js +775 -0
- package/dist/types/dataContract.js.map +1 -0
- package/dist/types/index.d.ts +40 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +21 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/multiTraceComparison.d.ts +215 -0
- package/dist/types/multiTraceComparison.d.ts.map +1 -0
- package/dist/types/multiTraceComparison.js +33 -0
- package/dist/types/multiTraceComparison.js.map +1 -0
- package/dist/types/perfettoSql.d.ts +596 -0
- package/dist/types/perfettoSql.d.ts.map +1 -0
- package/dist/types/perfettoSql.js +28 -0
- package/dist/types/perfettoSql.js.map +1 -0
- package/dist/types/sparkContracts.d.ts +1642 -0
- package/dist/types/sparkContracts.d.ts.map +1 -0
- package/dist/types/sparkContracts.js +25 -0
- package/dist/types/sparkContracts.js.map +1 -0
- package/dist/types/teaching.types.d.ts +395 -0
- package/dist/types/teaching.types.d.ts.map +1 -0
- package/dist/types/teaching.types.js +300 -0
- package/dist/types/teaching.types.js.map +1 -0
- package/dist/utils/analysisNarrative.d.ts +24 -0
- package/dist/utils/analysisNarrative.d.ts.map +1 -0
- package/dist/utils/analysisNarrative.js +101 -0
- package/dist/utils/analysisNarrative.js.map +1 -0
- package/dist/utils/atomicFileWriter.d.ts +5 -0
- package/dist/utils/atomicFileWriter.d.ts.map +1 -0
- package/dist/utils/atomicFileWriter.js +90 -0
- package/dist/utils/atomicFileWriter.js.map +1 -0
- package/dist/utils/epipeGuard.d.ts +10 -0
- package/dist/utils/epipeGuard.d.ts.map +1 -0
- package/dist/utils/epipeGuard.js +40 -0
- package/dist/utils/epipeGuard.js.map +1 -0
- package/dist/utils/httpValue.d.ts +2 -0
- package/dist/utils/httpValue.d.ts.map +1 -0
- package/dist/utils/httpValue.js +24 -0
- package/dist/utils/httpValue.js.map +1 -0
- package/dist/utils/llmJson.d.ts +33 -0
- package/dist/utils/llmJson.d.ts.map +1 -0
- package/dist/utils/llmJson.js +148 -0
- package/dist/utils/llmJson.js.map +1 -0
- package/dist/utils/llmPrivacy.d.ts +15 -0
- package/dist/utils/llmPrivacy.d.ts.map +1 -0
- package/dist/utils/llmPrivacy.js +126 -0
- package/dist/utils/llmPrivacy.js.map +1 -0
- package/dist/utils/logger.d.ts +24 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +68 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/traceProcessorRowUtils.d.ts +11 -0
- package/dist/utils/traceProcessorRowUtils.d.ts.map +1 -0
- package/dist/utils/traceProcessorRowUtils.js +64 -0
- package/dist/utils/traceProcessorRowUtils.js.map +1 -0
- package/dist/utils/uuid.d.ts +3 -0
- package/dist/utils/uuid.d.ts.map +1 -0
- package/dist/utils/uuid.js +7 -0
- package/dist/utils/uuid.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +53 -0
- package/dist/version.js.map +1 -0
- package/package.json +128 -0
- package/prebuilts/trace_processor/README.md +20 -0
- package/prebuilts/trace_processor/darwin-arm64/trace_processor_shell +0 -0
- package/prebuilts/trace_processor/linux-x64/trace_processor_shell +0 -0
- package/prebuilts/trace_processor/win32-x64/trace_processor_shell.exe +0 -0
- package/skills/README.md +686 -0
- package/skills/_template/README.md +43 -0
- package/skills/_template/atomic_A_template.skill.yaml +79 -0
- package/skills/_template/atomic_B_template.skill.yaml +61 -0
- package/skills/_template/atomic_S_template.skill.yaml +92 -0
- package/skills/_template/composite_S_template.skill.yaml +198 -0
- package/skills/_template/vendor_override_template.yaml +72 -0
- package/skills/atomic/android_bitmap_memory_per_process.skill.yaml +203 -0
- package/skills/atomic/android_dvfs_counter_stats.skill.yaml +60 -0
- package/skills/atomic/android_gpu_work_period_track.skill.yaml +55 -0
- package/skills/atomic/android_heap_graph_summary.skill.yaml +232 -0
- package/skills/atomic/android_job_scheduler_events.skill.yaml +58 -0
- package/skills/atomic/android_kernel_wakelock_summary.skill.yaml +57 -0
- package/skills/atomic/anr_context_in_range.skill.yaml +99 -0
- package/skills/atomic/anr_main_thread_blocking.skill.yaml +513 -0
- package/skills/atomic/app_frame_production.skill.yaml +147 -0
- package/skills/atomic/app_lifecycle_in_range.skill.yaml +142 -0
- package/skills/atomic/app_process_starts_summary.skill.yaml +75 -0
- package/skills/atomic/battery_charge_timeline.skill.yaml +72 -0
- package/skills/atomic/battery_doze_state_timeline.skill.yaml +83 -0
- package/skills/atomic/binder_blocking_in_range.skill.yaml +99 -0
- package/skills/atomic/binder_in_range.skill.yaml +86 -0
- package/skills/atomic/binder_root_cause.skill.yaml +191 -0
- package/skills/atomic/binder_storm_detection.skill.yaml +394 -0
- package/skills/atomic/blocking_chain_analysis.skill.yaml +316 -0
- package/skills/atomic/buffer_transaction_lifecycle.skill.yaml +256 -0
- package/skills/atomic/cache_miss_impact.skill.yaml +115 -0
- package/skills/atomic/chrome_scroll_jank_frame_timeline.skill.yaml +337 -0
- package/skills/atomic/compose_recomposition_hotspot.skill.yaml +403 -0
- package/skills/atomic/consumer_jank_detection.skill.yaml +556 -0
- package/skills/atomic/cpu_cluster_load_in_range.skill.yaml +138 -0
- package/skills/atomic/cpu_cluster_mapping_view.skill.yaml +47 -0
- package/skills/atomic/cpu_freq_timeline.skill.yaml +143 -0
- package/skills/atomic/cpu_idle_analysis.skill.yaml +101 -0
- package/skills/atomic/cpu_idle_state_residency.skill.yaml +54 -0
- package/skills/atomic/cpu_load_in_range.skill.yaml +145 -0
- package/skills/atomic/cpu_process_utilization_period.skill.yaml +51 -0
- package/skills/atomic/cpu_slice_analysis.skill.yaml +118 -0
- package/skills/atomic/cpu_thread_utilization_period.skill.yaml +68 -0
- package/skills/atomic/cpu_throttling_in_range.skill.yaml +131 -0
- package/skills/atomic/cpu_time_per_frame.skill.yaml +59 -0
- package/skills/atomic/cpu_topology_detection.skill.yaml +233 -0
- package/skills/atomic/cpu_topology_view.skill.yaml +272 -0
- package/skills/atomic/cpu_utilization_per_period.skill.yaml +55 -0
- package/skills/atomic/device_state_snapshot.skill.yaml +171 -0
- package/skills/atomic/device_state_timeline.skill.yaml +308 -0
- package/skills/atomic/fence_wait_decomposition.skill.yaml +314 -0
- package/skills/atomic/fpsgo_analysis.skill.yaml +80 -0
- package/skills/atomic/frame_blocking_calls.skill.yaml +215 -0
- package/skills/atomic/frame_overrun_summary.skill.yaml +68 -0
- package/skills/atomic/frame_pipeline_variance.skill.yaml +124 -0
- package/skills/atomic/frame_production_gap.skill.yaml +337 -0
- package/skills/atomic/frame_ui_time_breakdown.skill.yaml +58 -0
- package/skills/atomic/futex_wait_distribution.skill.yaml +117 -0
- package/skills/atomic/game_fps_analysis.skill.yaml +385 -0
- package/skills/atomic/game_main_loop_jank.skill.yaml +309 -0
- package/skills/atomic/gc_events_in_range.skill.yaml +118 -0
- package/skills/atomic/gl_standalone_swap_jank.skill.yaml +259 -0
- package/skills/atomic/gpu_freq_in_range.skill.yaml +99 -0
- package/skills/atomic/gpu_frequency_analysis.skill.yaml +94 -0
- package/skills/atomic/gpu_metrics.skill.yaml +411 -0
- package/skills/atomic/gpu_power_state_analysis.skill.yaml +117 -0
- package/skills/atomic/gpu_render_in_range.skill.yaml +104 -0
- package/skills/atomic/input_events_in_range.skill.yaml +130 -0
- package/skills/atomic/input_to_frame_latency.skill.yaml +436 -0
- package/skills/atomic/linux_irq_summary.skill.yaml +66 -0
- package/skills/atomic/linux_perf_counter_hotspots.skill.yaml +108 -0
- package/skills/atomic/linux_process_rss_swap_timeline.skill.yaml +96 -0
- package/skills/atomic/linux_runqueue_depth_timeline.skill.yaml +132 -0
- package/skills/atomic/linux_sched_latency_distribution.skill.yaml +130 -0
- package/skills/atomic/lmk_kill_attribution.skill.yaml +72 -0
- package/skills/atomic/lock_contention_in_range.skill.yaml +402 -0
- package/skills/atomic/logcat_analysis.skill.yaml +85 -0
- package/skills/atomic/main_thread_file_io_in_range.skill.yaml +116 -0
- package/skills/atomic/main_thread_sched_latency_in_range.skill.yaml +91 -0
- package/skills/atomic/main_thread_slices_in_range.skill.yaml +129 -0
- package/skills/atomic/main_thread_states_in_range.skill.yaml +105 -0
- package/skills/atomic/mali_gpu_power_state.skill.yaml +54 -0
- package/skills/atomic/media_codec_activity.skill.yaml +236 -0
- package/skills/atomic/memory_growth_detector.skill.yaml +146 -0
- package/skills/atomic/memory_pressure_in_range.skill.yaml +382 -0
- package/skills/atomic/memory_rss_high_watermark.skill.yaml +62 -0
- package/skills/atomic/native_heap_breakdown.skill.yaml +80 -0
- package/skills/atomic/oom_adjuster_score_timeline.skill.yaml +77 -0
- package/skills/atomic/page_fault_in_range.skill.yaml +113 -0
- package/skills/atomic/pipeline_4feature_scoring.skill.yaml +299 -0
- package/skills/atomic/pipeline_key_slices_overlay.skill.yaml +108 -0
- package/skills/atomic/present_fence_timing.skill.yaml +156 -0
- package/skills/atomic/process_identity_resolver.skill.yaml +503 -0
- package/skills/atomic/render_pipeline_latency.skill.yaml +120 -0
- package/skills/atomic/render_thread_slices.skill.yaml +107 -0
- package/skills/atomic/rendering_pipeline_detection.skill.yaml +770 -0
- package/skills/atomic/rn_bridge_to_frame_jank.skill.yaml +209 -0
- package/skills/atomic/rn_fabric_render_jank.skill.yaml +213 -0
- package/skills/atomic/sched_latency_in_range.skill.yaml +94 -0
- package/skills/atomic/scheduling_analysis.skill.yaml +103 -0
- package/skills/atomic/scroll_response_latency.skill.yaml +131 -0
- package/skills/atomic/sf_composition_in_range.skill.yaml +99 -0
- package/skills/atomic/sf_frame_consumption.skill.yaml +133 -0
- package/skills/atomic/sf_layer_count_in_range.skill.yaml +155 -0
- package/skills/atomic/startup_binder_in_range.skill.yaml +106 -0
- package/skills/atomic/startup_binder_pool_analysis.skill.yaml +115 -0
- package/skills/atomic/startup_breakdown_in_range.skill.yaml +115 -0
- package/skills/atomic/startup_class_loading_in_range.skill.yaml +93 -0
- package/skills/atomic/startup_cpu_placement_timeline.skill.yaml +135 -0
- package/skills/atomic/startup_critical_tasks.skill.yaml +247 -0
- package/skills/atomic/startup_events_in_range.skill.yaml +251 -0
- package/skills/atomic/startup_freq_rampup.skill.yaml +110 -0
- package/skills/atomic/startup_gc_in_range.skill.yaml +97 -0
- package/skills/atomic/startup_hot_slice_states.skill.yaml +116 -0
- package/skills/atomic/startup_jit_analysis.skill.yaml +158 -0
- package/skills/atomic/startup_main_thread_binder_blocking_in_range.skill.yaml +114 -0
- package/skills/atomic/startup_main_thread_file_io_in_range.skill.yaml +117 -0
- package/skills/atomic/startup_main_thread_slices_in_range.skill.yaml +138 -0
- package/skills/atomic/startup_main_thread_states_in_range.skill.yaml +100 -0
- package/skills/atomic/startup_main_thread_sync_binder_in_range.skill.yaml +103 -0
- package/skills/atomic/startup_sched_latency_in_range.skill.yaml +93 -0
- package/skills/atomic/startup_slow_reasons.skill.yaml +625 -0
- package/skills/atomic/startup_thread_blocking_graph.skill.yaml +181 -0
- package/skills/atomic/system_load_in_range.skill.yaml +95 -0
- package/skills/atomic/task_migration_in_range.skill.yaml +115 -0
- package/skills/atomic/textureview_producer_frame_timing.skill.yaml +302 -0
- package/skills/atomic/thermal_predictor.skill.yaml +182 -0
- package/skills/atomic/thread_affinity_violation.skill.yaml +139 -0
- package/skills/atomic/touch_to_display_latency.skill.yaml +130 -0
- package/skills/atomic/util_tracking_analysis.skill.yaml +89 -0
- package/skills/atomic/vrr_detection.skill.yaml +301 -0
- package/skills/atomic/vsync_alignment_in_range.skill.yaml +116 -0
- package/skills/atomic/vsync_config.skill.yaml +147 -0
- package/skills/atomic/vsync_period_detection.skill.yaml +178 -0
- package/skills/atomic/vsync_phase_alignment.skill.yaml +255 -0
- package/skills/atomic/wakelock_tracking.skill.yaml +276 -0
- package/skills/atomic/wattson_app_startup_power.skill.yaml +66 -0
- package/skills/atomic/wattson_rails_power_breakdown.skill.yaml +70 -0
- package/skills/atomic/wattson_thread_power_attribution.skill.yaml +74 -0
- package/skills/atomic/webview_v8_analysis.skill.yaml +297 -0
- package/skills/comparison/multi_trace_result_comparison.skill.yaml +60 -0
- package/skills/composite/anr_analysis.skill.yaml +889 -0
- package/skills/composite/anr_detail.skill.yaml +796 -0
- package/skills/composite/battery_drain_attribution.skill.yaml +134 -0
- package/skills/composite/binder_analysis.skill.yaml +742 -0
- package/skills/composite/binder_detail.skill.yaml +388 -0
- package/skills/composite/block_io_analysis.skill.yaml +559 -0
- package/skills/composite/click_response_analysis.skill.yaml +915 -0
- package/skills/composite/click_response_detail.skill.yaml +800 -0
- package/skills/composite/cpu_analysis.skill.yaml +960 -0
- package/skills/composite/dmabuf_analysis.skill.yaml +622 -0
- package/skills/composite/flutter_scrolling_analysis.skill.yaml +443 -0
- package/skills/composite/gc_analysis.skill.yaml +744 -0
- package/skills/composite/global_trace_sanity_check.skill.yaml +716 -0
- package/skills/composite/gpu_analysis.skill.yaml +700 -0
- package/skills/composite/io_pressure.skill.yaml +654 -0
- package/skills/composite/irq_analysis.skill.yaml +696 -0
- package/skills/composite/jank_frame_detail.skill.yaml +2065 -0
- package/skills/composite/lmk_analysis.skill.yaml +626 -0
- package/skills/composite/lock_binder_wait.skill.yaml +95 -0
- package/skills/composite/lock_contention_analysis.skill.yaml +878 -0
- package/skills/composite/memory_analysis.skill.yaml +718 -0
- package/skills/composite/navigation_analysis.skill.yaml +901 -0
- package/skills/composite/network_analysis.skill.yaml +760 -0
- package/skills/composite/power_consumption_overview.skill.yaml +143 -0
- package/skills/composite/scene_reconstruction.skill.yaml +2788 -0
- package/skills/composite/scroll_session_analysis.skill.yaml +496 -0
- package/skills/composite/scrolling_analysis.skill.yaml +3295 -0
- package/skills/composite/startup_analysis.skill.yaml +1172 -0
- package/skills/composite/startup_detail.skill.yaml +1339 -0
- package/skills/composite/state_timeline.skill.yaml +1021 -0
- package/skills/composite/surfaceflinger_analysis.skill.yaml +808 -0
- package/skills/composite/suspend_wakeup_analysis.skill.yaml +698 -0
- package/skills/composite/thermal_throttling.skill.yaml +964 -0
- package/skills/composite/thermal_throttling_chain.skill.yaml +147 -0
- package/skills/composite/webview_drawfunctor_jank_chain.skill.yaml +343 -0
- package/skills/config/conclusion_scene_templates.base.yaml +181 -0
- package/skills/config/conclusion_scene_templates.yaml +17 -0
- package/skills/deep/callstack_analysis.skill.yaml +436 -0
- package/skills/deep/cpu_profiling.skill.yaml +617 -0
- package/skills/docs/scrolling.sop.md +312 -0
- package/skills/docs/startup.sop.md +382 -0
- package/skills/docs/upstream-perfetto-ai-skill-translation.sop.md +50 -0
- package/skills/fragments/target_threads.sql +34 -0
- package/skills/fragments/thread_states_quadrant.sql +26 -0
- package/skills/fragments/vsync_config.sql +32 -0
- package/skills/modules/app/launcher_module.skill.yaml +473 -0
- package/skills/modules/app/systemui_module.skill.yaml +565 -0
- package/skills/modules/app/third_party_module.skill.yaml +275 -0
- package/skills/modules/framework/ams_module.skill.yaml +239 -0
- package/skills/modules/framework/art_module.skill.yaml +266 -0
- package/skills/modules/framework/choreographer_module.skill.yaml +419 -0
- package/skills/modules/framework/input_module.skill.yaml +219 -0
- package/skills/modules/framework/surfaceflinger_module.skill.yaml +343 -0
- package/skills/modules/framework/wms_module.skill.yaml +356 -0
- package/skills/modules/hardware/cpu_module.skill.yaml +300 -0
- package/skills/modules/hardware/gpu_module.skill.yaml +229 -0
- package/skills/modules/hardware/memory_module.skill.yaml +443 -0
- package/skills/modules/hardware/power_module.skill.yaml +377 -0
- package/skills/modules/hardware/thermal_module.skill.yaml +410 -0
- package/skills/modules/kernel/binder_module.skill.yaml +223 -0
- package/skills/modules/kernel/filesystem_module.skill.yaml +423 -0
- package/skills/modules/kernel/lock_contention_module.skill.yaml +424 -0
- package/skills/modules/kernel/scheduler_module.skill.yaml +247 -0
- package/skills/pipelines/_base.skill.yaml +103 -0
- package/skills/pipelines/android_pip_freeform.skill.yaml +224 -0
- package/skills/pipelines/android_view_mixed.skill.yaml +305 -0
- package/skills/pipelines/android_view_multi_window.skill.yaml +271 -0
- package/skills/pipelines/android_view_software.skill.yaml +172 -0
- package/skills/pipelines/android_view_standard_blast.skill.yaml +357 -0
- package/skills/pipelines/android_view_standard_legacy.skill.yaml +233 -0
- package/skills/pipelines/angle_gles_vulkan.skill.yaml +178 -0
- package/skills/pipelines/camera_pipeline.skill.yaml +215 -0
- package/skills/pipelines/chrome_browser_viz.skill.yaml +288 -0
- package/skills/pipelines/compose_standard.skill.yaml +250 -0
- package/skills/pipelines/flutter_surfaceview_impeller.skill.yaml +233 -0
- package/skills/pipelines/flutter_surfaceview_skia.skill.yaml +194 -0
- package/skills/pipelines/flutter_textureview.skill.yaml +219 -0
- package/skills/pipelines/game_engine.skill.yaml +311 -0
- package/skills/pipelines/hardware_buffer_renderer.skill.yaml +205 -0
- package/skills/pipelines/imagereader_pipeline.skill.yaml +237 -0
- package/skills/pipelines/index.yaml +122 -0
- package/skills/pipelines/opengl_es.skill.yaml +185 -0
- package/skills/pipelines/rn_new_arch.skill.yaml +126 -0
- package/skills/pipelines/rn_old_arch.skill.yaml +137 -0
- package/skills/pipelines/rn_skia.skill.yaml +115 -0
- package/skills/pipelines/software_compositing.skill.yaml +203 -0
- package/skills/pipelines/surface_control_api.skill.yaml +208 -0
- package/skills/pipelines/surfaceview_blast.skill.yaml +210 -0
- package/skills/pipelines/textureview_standard.skill.yaml +301 -0
- package/skills/pipelines/variable_refresh_rate.skill.yaml +264 -0
- package/skills/pipelines/video_overlay_hwc.skill.yaml +193 -0
- package/skills/pipelines/vulkan_native.skill.yaml +215 -0
- package/skills/pipelines/webview_gl_functor.skill.yaml +232 -0
- package/skills/pipelines/webview_surface_control.skill.yaml +187 -0
- package/skills/pipelines/webview_surfaceview_wrapper.skill.yaml +196 -0
- package/skills/pipelines/webview_textureview_custom.skill.yaml +201 -0
- package/skills/vendors/honor/startup.override.yaml +117 -0
- package/skills/vendors/mtk/startup.override.yaml +133 -0
- package/skills/vendors/oppo/startup.override.yaml +188 -0
- package/skills/vendors/pixel/startup.override.yaml +163 -0
- package/skills/vendors/qualcomm/startup.override.yaml +175 -0
- package/skills/vendors/samsung/startup.override.yaml +161 -0
- package/skills/vendors/vivo/startup.override.yaml +144 -0
- package/skills/vendors/xiaomi/startup.override.yaml +120 -0
- package/sql/smartperfetto/PACKAGE.json +24 -0
- package/sql/smartperfetto/binder/victim_to_server.sql +36 -0
- package/sql/smartperfetto/scrolling/jank_frames.sql +55 -0
- package/strategies/anr.strategy.md +200 -0
- package/strategies/arch-compose.template.md +10 -0
- package/strategies/arch-flutter.template.md +17 -0
- package/strategies/arch-standard.template.md +31 -0
- package/strategies/arch-webview.template.md +9 -0
- package/strategies/comparison-conclusion.template.md +36 -0
- package/strategies/comparison-methodology.template.md +41 -0
- package/strategies/comparison-result-methodology.template.md +35 -0
- package/strategies/game.strategy.md +121 -0
- package/strategies/general.strategy.md +48 -0
- package/strategies/interaction.strategy.md +149 -0
- package/strategies/knowledge-binder-ipc.template.md +59 -0
- package/strategies/knowledge-cpu-scheduler.template.md +67 -0
- package/strategies/knowledge-data-sources.template.md +738 -0
- package/strategies/knowledge-gc-dynamics.template.md +65 -0
- package/strategies/knowledge-harmonyos-rendering.template.md +54 -0
- package/strategies/knowledge-harmonyos-tools.template.md +73 -0
- package/strategies/knowledge-lock-contention.template.md +61 -0
- package/strategies/knowledge-pipeline-anchors.template.md +136 -0
- package/strategies/knowledge-pipeline-fences.template.md +158 -0
- package/strategies/knowledge-rendering-pipeline.template.md +170 -0
- package/strategies/knowledge-startup-root-causes.template.md +951 -0
- package/strategies/knowledge-thermal-throttling.template.md +53 -0
- package/strategies/linux.strategy.md +86 -0
- package/strategies/media.strategy.md +75 -0
- package/strategies/memory.strategy.md +94 -0
- package/strategies/multi-trace-result-comparison.strategy.md +96 -0
- package/strategies/network.strategy.md +80 -0
- package/strategies/overview.strategy.md +139 -0
- package/strategies/phase_hint_templates/misdiagnosis_vsync_vrr.template.yaml +37 -0
- package/strategies/pipeline.strategy.md +208 -0
- package/strategies/power.strategy.md +165 -0
- package/strategies/prompt-complexity-classifier.template.md +26 -0
- package/strategies/prompt-language-en.template.md +9 -0
- package/strategies/prompt-language-zh.template.md +8 -0
- package/strategies/prompt-methodology.template.md +183 -0
- package/strategies/prompt-output-format.template.md +115 -0
- package/strategies/prompt-quick.template.md +44 -0
- package/strategies/prompt-role.template.md +13 -0
- package/strategies/runtime-correctness.strategy.md +73 -0
- package/strategies/scroll-response.strategy.md +236 -0
- package/strategies/scrolling.strategy.md +467 -0
- package/strategies/selection-area.template.md +46 -0
- package/strategies/selection-slice.template.md +126 -0
- package/strategies/startup.strategy.md +694 -0
- package/strategies/teaching.strategy.md +176 -0
- package/strategies/touch-tracking.strategy.md +213 -0
|
@@ -0,0 +1,4129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
3
|
+
// Copyright (C) 2024-2026 Gracker (Chris)
|
|
4
|
+
// This file is part of SmartPerfetto. See LICENSE for details.
|
|
5
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
6
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.SkillExecutor = void 0;
|
|
10
|
+
exports.normalizeLayer = normalizeLayer;
|
|
11
|
+
exports.extractFindings = extractFindings;
|
|
12
|
+
exports.extractSuggestions = extractSuggestions;
|
|
13
|
+
exports.createSkillExecutor = createSkillExecutor;
|
|
14
|
+
const skillValidator_1 = require("./skillValidator");
|
|
15
|
+
const logger_1 = __importDefault(require("../../utils/logger"));
|
|
16
|
+
const llmJson_1 = require("../../utils/llmJson");
|
|
17
|
+
const llmPrivacy_1 = require("../../utils/llmPrivacy");
|
|
18
|
+
const pipelineDocService_1 = require("../pipelineDocService");
|
|
19
|
+
const pipelineSkillLoader_1 = require("../pipelineSkillLoader");
|
|
20
|
+
const teaching_config_1 = require("../../config/teaching.config");
|
|
21
|
+
const teaching_types_1 = require("../../types/teaching.types");
|
|
22
|
+
const dataContract_1 = require("../../types/dataContract");
|
|
23
|
+
const displayContractValidator_1 = require("./displayContractValidator");
|
|
24
|
+
const identityGate_1 = require("../processIdentity/identityGate");
|
|
25
|
+
/**
|
|
26
|
+
* 将 YAML 中的 layer 值规范化为语义名称
|
|
27
|
+
*/
|
|
28
|
+
function normalizeLayer(layer) {
|
|
29
|
+
if (!layer)
|
|
30
|
+
return undefined;
|
|
31
|
+
// 只接受语义名称
|
|
32
|
+
if (['overview', 'list', 'session', 'deep', 'diagnosis'].includes(layer)) {
|
|
33
|
+
return layer;
|
|
34
|
+
}
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
// =============================================================================
|
|
38
|
+
// 表达式求值器
|
|
39
|
+
// =============================================================================
|
|
40
|
+
class ExpressionEvaluator {
|
|
41
|
+
static warnConditionOnce(reason, condition, extra) {
|
|
42
|
+
const key = `${reason}::${condition}`;
|
|
43
|
+
if (this.warnedConditionMessages.has(key))
|
|
44
|
+
return;
|
|
45
|
+
this.warnedConditionMessages.add(key);
|
|
46
|
+
logger_1.default.warn('ExpressionEvaluator', `${reason}: ${condition}${extra ? ` (${extra})` : ''}`);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* 在上下文中求值表达式
|
|
50
|
+
* 支持:${variable}、${step.field}、比较运算符等
|
|
51
|
+
*/
|
|
52
|
+
static evaluate(expression, context) {
|
|
53
|
+
const parsePathWithDefault = (raw) => {
|
|
54
|
+
const m = raw.trim().match(/^([a-zA-Z_][a-zA-Z0-9_]*(?:\.[a-zA-Z_][a-zA-Z0-9_]*|\[[0-9]+\])*)\|([^|].*)$/);
|
|
55
|
+
if (!m)
|
|
56
|
+
return null;
|
|
57
|
+
return { actualPath: m[1].trim(), defaultValue: m[2].trim() };
|
|
58
|
+
};
|
|
59
|
+
// 检查是否是完整的 ${...} 表达式(整个字符串被包裹)
|
|
60
|
+
const fullExprMatch = expression.match(/^\$\{(.+)\}$/s);
|
|
61
|
+
// 如果内部还包含 ${...},说明这是一个模板串(如 "${a} + ${b}"),不要当成单个 JS 表达式执行
|
|
62
|
+
if (fullExprMatch && !fullExprMatch[1].includes('${')) {
|
|
63
|
+
const innerExpr = fullExprMatch[1].trim();
|
|
64
|
+
// Support ${varName|defaultValue} syntax for full expressions
|
|
65
|
+
const defaultSyntax = parsePathWithDefault(innerExpr);
|
|
66
|
+
if (defaultSyntax) {
|
|
67
|
+
const value = this.resolvePath(defaultSyntax.actualPath, context);
|
|
68
|
+
if (value !== undefined && value !== null)
|
|
69
|
+
return value;
|
|
70
|
+
const defaultPart = defaultSyntax.defaultValue;
|
|
71
|
+
// Parse default: try number, boolean, then string
|
|
72
|
+
if (/^\d+(\.\d+)?$/.test(defaultPart))
|
|
73
|
+
return parseFloat(defaultPart);
|
|
74
|
+
if (defaultPart === 'true')
|
|
75
|
+
return true;
|
|
76
|
+
if (defaultPart === 'false')
|
|
77
|
+
return false;
|
|
78
|
+
return defaultPart;
|
|
79
|
+
}
|
|
80
|
+
// 这是一个 JavaScript 表达式,需要完整求值
|
|
81
|
+
return this.evaluateJsExpression(innerExpr, context);
|
|
82
|
+
}
|
|
83
|
+
// 否则,做变量替换(支持嵌入的 JavaScript 表达式)
|
|
84
|
+
let result = expression;
|
|
85
|
+
// 替换 ${xxx} 格式的变量
|
|
86
|
+
// 简单路径走 resolvePath;复杂表达式走 JS 表达式求值(例如: a * 16.7, foo?.bar, arr.find(...))
|
|
87
|
+
const isSimplePath = (path) => {
|
|
88
|
+
const p = path.trim();
|
|
89
|
+
// 仅允许:标识符 + ".prop" + "[0]" 组合(不支持 ?. / 函数调用 / 算术运算等)
|
|
90
|
+
return /^[a-zA-Z_][a-zA-Z0-9_]*(?:\.[a-zA-Z_][a-zA-Z0-9_]*|\[[0-9]+\])*$/.test(p);
|
|
91
|
+
};
|
|
92
|
+
result = result.replace(/\$\{([^}]+)\}/g, (match, path) => {
|
|
93
|
+
const rawPath = String(path ?? '').trim();
|
|
94
|
+
// Support ${varName|defaultValue} syntax
|
|
95
|
+
const defaultSyntax = parsePathWithDefault(rawPath);
|
|
96
|
+
const actualPath = defaultSyntax?.actualPath ?? rawPath;
|
|
97
|
+
const defaultValue = defaultSyntax?.defaultValue;
|
|
98
|
+
// 复杂表达式:使用完整的 JS 表达式求值
|
|
99
|
+
if (!isSimplePath(actualPath)) {
|
|
100
|
+
try {
|
|
101
|
+
const value = this.evaluateJsExpression(actualPath, context);
|
|
102
|
+
if (value === undefined || value === null) {
|
|
103
|
+
return defaultValue !== undefined ? defaultValue : '';
|
|
104
|
+
}
|
|
105
|
+
if (typeof value === 'object')
|
|
106
|
+
return JSON.stringify(value);
|
|
107
|
+
return String(value);
|
|
108
|
+
}
|
|
109
|
+
catch (e) {
|
|
110
|
+
logger_1.default.debug('ExpressionEvaluator', `Failed to evaluate embedded JS: ${actualPath}`);
|
|
111
|
+
return defaultValue !== undefined ? defaultValue : '';
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// 简单路径:使用 resolvePath
|
|
115
|
+
const value = this.resolvePath(actualPath, context);
|
|
116
|
+
if (value === undefined || value === null) {
|
|
117
|
+
return defaultValue !== undefined ? defaultValue : '';
|
|
118
|
+
}
|
|
119
|
+
if (typeof value === 'object')
|
|
120
|
+
return JSON.stringify(value);
|
|
121
|
+
return String(value);
|
|
122
|
+
});
|
|
123
|
+
// 如果是简单的比较表达式,尝试求值
|
|
124
|
+
if (/^[\d\.\s\+\-\*\/\>\<\=\!\&\|]+$/.test(result)) {
|
|
125
|
+
try {
|
|
126
|
+
// 安全地执行简单数学/比较表达式
|
|
127
|
+
return new Function(`return ${result}`)();
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return result;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return result;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* 评估 JavaScript 表达式
|
|
137
|
+
* 例如: performance_summary.data[0]?.app_jank_rate > 10
|
|
138
|
+
*/
|
|
139
|
+
static evaluateJsExpression(expr, context, options) {
|
|
140
|
+
try {
|
|
141
|
+
// 从表达式中提取根变量名
|
|
142
|
+
const rootVarNames = this.extractRootVariables(expr);
|
|
143
|
+
// 构建作用域对象
|
|
144
|
+
const scope = {};
|
|
145
|
+
for (const varName of rootVarNames) {
|
|
146
|
+
// 从步骤结果中获取
|
|
147
|
+
if (context.results[varName]) {
|
|
148
|
+
scope[varName] = this.wrapAsDataScope(context.results[varName].data);
|
|
149
|
+
}
|
|
150
|
+
// 从变量中获取
|
|
151
|
+
else if (context.variables[varName] !== undefined) {
|
|
152
|
+
scope[varName] = this.wrapAsDataScope(context.variables[varName]);
|
|
153
|
+
}
|
|
154
|
+
// 从参数中获取
|
|
155
|
+
else if (context.params[varName] !== undefined) {
|
|
156
|
+
scope[varName] = context.params[varName];
|
|
157
|
+
}
|
|
158
|
+
// 从继承上下文中获取
|
|
159
|
+
else if (context.inherited[varName] !== undefined) {
|
|
160
|
+
scope[varName] = context.inherited[varName];
|
|
161
|
+
}
|
|
162
|
+
// 当前迭代项
|
|
163
|
+
else if (varName === 'item' && context.currentItem) {
|
|
164
|
+
scope[varName] = context.currentItem;
|
|
165
|
+
}
|
|
166
|
+
// 未找到时也显式注入 undefined,避免 ReferenceError(例如 expr: "package" 或 "frame_ts")
|
|
167
|
+
else {
|
|
168
|
+
scope[varName] = undefined;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// Debug log removed for cleaner output
|
|
172
|
+
// 构建并执行函数
|
|
173
|
+
const varNames = Object.keys(scope);
|
|
174
|
+
const varValues = Object.values(scope);
|
|
175
|
+
if (varNames.length === 0) {
|
|
176
|
+
// 没有变量,直接求值(纯表达式如 true, false, 数字比较)
|
|
177
|
+
return new Function(`return ${expr}`)();
|
|
178
|
+
}
|
|
179
|
+
const fn = new Function(...varNames, `return ${expr}`);
|
|
180
|
+
const result = fn(...varValues);
|
|
181
|
+
return result;
|
|
182
|
+
}
|
|
183
|
+
catch (e) {
|
|
184
|
+
if (!options?.suppressErrorLog) {
|
|
185
|
+
logger_1.default.debug('ExpressionEvaluator', `JS expression failed: ${expr} (${e.message})`);
|
|
186
|
+
}
|
|
187
|
+
return undefined;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* 从表达式中提取根变量名
|
|
192
|
+
* "performance_summary.data[0]?.app_jank_rate > 10" => ["performance_summary"]
|
|
193
|
+
* "jank_stats.data.find(j => j.jank_type)" => ["jank_stats"]
|
|
194
|
+
*/
|
|
195
|
+
static extractRootVariables(expr) {
|
|
196
|
+
const varNames = new Set();
|
|
197
|
+
// 匹配标识符开头的词(不是关键字)
|
|
198
|
+
const identifierRegex = /\b([a-zA-Z_][a-zA-Z0-9_]*)\b/g;
|
|
199
|
+
const jsKeywords = new Set([
|
|
200
|
+
'true', 'false', 'null', 'undefined', 'if', 'else', 'return',
|
|
201
|
+
'function', 'var', 'let', 'const', 'new', 'this', 'typeof',
|
|
202
|
+
'instanceof', 'in', 'of', 'for', 'while', 'do', 'break', 'continue',
|
|
203
|
+
'switch', 'case', 'default', 'try', 'catch', 'finally', 'throw',
|
|
204
|
+
'async', 'await', 'class', 'extends', 'super', 'import', 'export',
|
|
205
|
+
'NaN', 'Infinity', 'Math', 'JSON', 'Array', 'Object', 'String',
|
|
206
|
+
'Number', 'Boolean', 'Date', 'RegExp', 'Error', 'Map', 'Set',
|
|
207
|
+
]);
|
|
208
|
+
let match;
|
|
209
|
+
while ((match = identifierRegex.exec(expr)) !== null) {
|
|
210
|
+
const name = match[1];
|
|
211
|
+
// 跳过 JavaScript 关键字和内置对象
|
|
212
|
+
if (!jsKeywords.has(name)) {
|
|
213
|
+
// 检查是否是表达式开头或者在运算符后面(说明是根变量)
|
|
214
|
+
const beforeMatch = expr.substring(0, match.index);
|
|
215
|
+
const lastChar = beforeMatch.trim().slice(-1);
|
|
216
|
+
// 如果之前没有 . 则是根变量
|
|
217
|
+
if (lastChar !== '.') {
|
|
218
|
+
varNames.add(name);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
return Array.from(varNames);
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Unwrap SkillExecutionResult-like objects from referenced skills.
|
|
226
|
+
* save_as on `skill:` steps stores nested result objects, while most YAML
|
|
227
|
+
* expressions expect plain row arrays at `.data`.
|
|
228
|
+
*/
|
|
229
|
+
static unwrapSkillResultData(value) {
|
|
230
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
231
|
+
return value;
|
|
232
|
+
}
|
|
233
|
+
const maybeSkillResult = value;
|
|
234
|
+
// Full SkillExecutionResult from a referenced skill step.
|
|
235
|
+
// Prefer explicit `data` if present; otherwise fallback to raw step outputs.
|
|
236
|
+
if (Object.prototype.hasOwnProperty.call(maybeSkillResult, 'rawResults')) {
|
|
237
|
+
if (Object.prototype.hasOwnProperty.call(maybeSkillResult, 'data')) {
|
|
238
|
+
return maybeSkillResult.data;
|
|
239
|
+
}
|
|
240
|
+
const raw = maybeSkillResult.rawResults;
|
|
241
|
+
if (raw && typeof raw === 'object') {
|
|
242
|
+
const rootStepData = raw?.root?.data;
|
|
243
|
+
if (rootStepData !== undefined) {
|
|
244
|
+
return rootStepData;
|
|
245
|
+
}
|
|
246
|
+
for (const step of Object.values(raw)) {
|
|
247
|
+
if (step && typeof step === 'object' && Object.prototype.hasOwnProperty.call(step, 'data')) {
|
|
248
|
+
return step.data;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
// StepResult-like object.
|
|
254
|
+
if (Object.prototype.hasOwnProperty.call(maybeSkillResult, 'success') &&
|
|
255
|
+
Object.prototype.hasOwnProperty.call(maybeSkillResult, 'data')) {
|
|
256
|
+
return maybeSkillResult.data;
|
|
257
|
+
}
|
|
258
|
+
return value;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Wrap values for `.data[...]` access pattern used by skill conditions.
|
|
262
|
+
*/
|
|
263
|
+
static wrapAsDataScope(value) {
|
|
264
|
+
return { data: this.unwrapSkillResultData(value) };
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* 解析路径引用,支持深层嵌套和数组索引
|
|
268
|
+
* 例如: "step1.data[0].field" 或 "performance_summary.data[0].app_jank_rate"
|
|
269
|
+
*/
|
|
270
|
+
static resolvePath(path, context) {
|
|
271
|
+
// 解析路径为 token 数组,支持 . 分隔和 [n] 数组索引
|
|
272
|
+
const tokens = this.parsePath(path);
|
|
273
|
+
if (tokens.length === 0)
|
|
274
|
+
return undefined;
|
|
275
|
+
const rootKey = tokens[0];
|
|
276
|
+
// 获取根值
|
|
277
|
+
let value;
|
|
278
|
+
// 尝试从不同来源解析根值
|
|
279
|
+
// 1. 当前迭代项
|
|
280
|
+
if (rootKey === 'item' && context.currentItem) {
|
|
281
|
+
value = context.currentItem;
|
|
282
|
+
}
|
|
283
|
+
// 2. 参数
|
|
284
|
+
else if (context.params[rootKey] !== undefined) {
|
|
285
|
+
value = context.params[rootKey];
|
|
286
|
+
}
|
|
287
|
+
// 3. 继承的上下文
|
|
288
|
+
else if (context.inherited[rootKey] !== undefined) {
|
|
289
|
+
value = context.inherited[rootKey];
|
|
290
|
+
}
|
|
291
|
+
// 4. 变量(save_as 保存的)- 也需要包装以支持 .data[0].field 访问
|
|
292
|
+
else if (context.variables[rootKey] !== undefined) {
|
|
293
|
+
// 如果路径包含 .data,需要包装;否则直接返回
|
|
294
|
+
const nextToken = tokens[1];
|
|
295
|
+
if (nextToken === 'data') {
|
|
296
|
+
value = this.wrapAsDataScope(context.variables[rootKey]);
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
// 直接访问数组元素,如 ${main_slices[0].name}
|
|
300
|
+
value = context.variables[rootKey];
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
// 5. 步骤结果 - 返回包装对象以支持 .data[0].field 访问
|
|
304
|
+
else if (context.results[rootKey]) {
|
|
305
|
+
// 返回包含 data 属性的对象,这样 ${main_slices.data[0].name} 才能正确解析
|
|
306
|
+
value = this.wrapAsDataScope(context.results[rootKey].data);
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
return undefined;
|
|
310
|
+
}
|
|
311
|
+
// 遍历剩余 token 解析深层路径
|
|
312
|
+
for (let i = 1; i < tokens.length; i++) {
|
|
313
|
+
if (value == null)
|
|
314
|
+
return undefined;
|
|
315
|
+
const token = tokens[i];
|
|
316
|
+
// 处理数组索引 (纯数字)
|
|
317
|
+
if (/^\d+$/.test(token)) {
|
|
318
|
+
const index = parseInt(token, 10);
|
|
319
|
+
if (!Array.isArray(value))
|
|
320
|
+
return undefined;
|
|
321
|
+
value = value[index];
|
|
322
|
+
}
|
|
323
|
+
else {
|
|
324
|
+
// 处理对象属性
|
|
325
|
+
value = value[token];
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
return value;
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* 解析路径字符串为 token 数组
|
|
332
|
+
* "step.data[0].field" => ["step", "data", "0", "field"]
|
|
333
|
+
*/
|
|
334
|
+
static parsePath(path) {
|
|
335
|
+
const tokens = [];
|
|
336
|
+
let current = '';
|
|
337
|
+
for (let i = 0; i < path.length; i++) {
|
|
338
|
+
const char = path[i];
|
|
339
|
+
if (char === '.') {
|
|
340
|
+
if (current) {
|
|
341
|
+
tokens.push(current);
|
|
342
|
+
current = '';
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
else if (char === '[') {
|
|
346
|
+
if (current) {
|
|
347
|
+
tokens.push(current);
|
|
348
|
+
current = '';
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
else if (char === ']') {
|
|
352
|
+
if (current) {
|
|
353
|
+
tokens.push(current);
|
|
354
|
+
current = '';
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
current += char;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
if (current) {
|
|
362
|
+
tokens.push(current);
|
|
363
|
+
}
|
|
364
|
+
return tokens;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* 评估条件表达式,返回 boolean
|
|
368
|
+
* 条件表达式始终作为 JavaScript 表达式求值(不需要 ${} 包裹)
|
|
369
|
+
* 例如: environment.data[0]?.frame_data_status === 'available'
|
|
370
|
+
*/
|
|
371
|
+
static evaluateCondition(condition, context) {
|
|
372
|
+
try {
|
|
373
|
+
// 允许 condition 中混用 ${...} 模板(如 "${vsync_missed} >= 3" 或 "cpu.data[0] > ${frame_dur} ...")
|
|
374
|
+
// 先做模板替换/简单表达式求值,再作为 JS 表达式执行。
|
|
375
|
+
let prepared = condition;
|
|
376
|
+
if (typeof condition === 'string' && condition.includes('${')) {
|
|
377
|
+
prepared = this.evaluate(condition, context);
|
|
378
|
+
}
|
|
379
|
+
// evaluate 可能直接返回 boolean/number(例如 "3 >= 1")
|
|
380
|
+
if (prepared === undefined || prepared === null) {
|
|
381
|
+
return false;
|
|
382
|
+
}
|
|
383
|
+
if (typeof prepared === 'boolean') {
|
|
384
|
+
return prepared;
|
|
385
|
+
}
|
|
386
|
+
if (typeof prepared === 'number') {
|
|
387
|
+
return prepared !== 0;
|
|
388
|
+
}
|
|
389
|
+
if (typeof prepared !== 'string') {
|
|
390
|
+
return Boolean(prepared);
|
|
391
|
+
}
|
|
392
|
+
const expr = prepared.trim();
|
|
393
|
+
if (!expr)
|
|
394
|
+
return false;
|
|
395
|
+
if (expr.includes('${')) {
|
|
396
|
+
// 未替换完的模板通常意味着上游数据缺失,不作为告警噪声输出。
|
|
397
|
+
logger_1.default.debug('ExpressionEvaluator', `Condition still contains template placeholders: ${expr}`);
|
|
398
|
+
return false;
|
|
399
|
+
}
|
|
400
|
+
// 条件表达式作为 JavaScript 表达式求值
|
|
401
|
+
const result = this.evaluateJsExpression(expr, context, { suppressErrorLog: true });
|
|
402
|
+
// 如果求值失败(返回 undefined),默认为 false
|
|
403
|
+
if (result === undefined) {
|
|
404
|
+
return false;
|
|
405
|
+
}
|
|
406
|
+
return Boolean(result);
|
|
407
|
+
}
|
|
408
|
+
catch (e) {
|
|
409
|
+
this.warnConditionOnce('Condition evaluation failed', condition, e.message);
|
|
410
|
+
return false;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
ExpressionEvaluator.warnedConditionMessages = new Set();
|
|
415
|
+
// =============================================================================
|
|
416
|
+
// SQL 变量替换
|
|
417
|
+
// =============================================================================
|
|
418
|
+
function substituteVariables(sql, context) {
|
|
419
|
+
let result = sql;
|
|
420
|
+
// 判断 offset 位置是否处于 SQL 单引号字符串常量内部(用于决定缺省值是 '' 还是 NULL)
|
|
421
|
+
// 注:这里只做轻量扫描,足够覆盖 skill SQL 模板中常见的 '${package}*' / '%${name}%' 等模式。
|
|
422
|
+
const isInsideSingleQuotes = (s, offset) => {
|
|
423
|
+
let inSingle = false;
|
|
424
|
+
for (let i = 0; i < offset; i++) {
|
|
425
|
+
const ch = s[i];
|
|
426
|
+
if (ch !== '\'')
|
|
427
|
+
continue;
|
|
428
|
+
// SQL 中单引号转义使用 ''(两个单引号)。
|
|
429
|
+
if (inSingle && s[i + 1] === '\'') {
|
|
430
|
+
i++; // skip escaped quote
|
|
431
|
+
continue;
|
|
432
|
+
}
|
|
433
|
+
inSingle = !inSingle;
|
|
434
|
+
}
|
|
435
|
+
return inSingle;
|
|
436
|
+
};
|
|
437
|
+
// 替换所有 ${xxx} 格式的变量(支持 ${varName|defaultValue} 语法)
|
|
438
|
+
result = result.replace(/\$\{([^}]+)\}/g, (match, path, offset, full) => {
|
|
439
|
+
const rawPath = String(path ?? '').trim();
|
|
440
|
+
const insideQuotes = typeof offset === 'number' && typeof full === 'string'
|
|
441
|
+
? isInsideSingleQuotes(full, offset)
|
|
442
|
+
: false;
|
|
443
|
+
// Support ${varName|defaultValue} syntax
|
|
444
|
+
const pipeIndex = rawPath.indexOf('|');
|
|
445
|
+
const actualPath = pipeIndex >= 0 ? rawPath.substring(0, pipeIndex).trim() : rawPath;
|
|
446
|
+
const explicitDefault = pipeIndex >= 0 ? rawPath.substring(pipeIndex + 1).trim() : undefined;
|
|
447
|
+
const value = ExpressionEvaluator.resolvePath(actualPath, context);
|
|
448
|
+
// 缺省值优先级:
|
|
449
|
+
// 1. 显式 |default 值
|
|
450
|
+
// 2. 字符串常量内部:用 ''
|
|
451
|
+
// 3. 其它位置:用 NULL
|
|
452
|
+
if (value === undefined || value === null) {
|
|
453
|
+
if (explicitDefault !== undefined)
|
|
454
|
+
return explicitDefault;
|
|
455
|
+
if (insideQuotes)
|
|
456
|
+
return '';
|
|
457
|
+
return 'NULL';
|
|
458
|
+
}
|
|
459
|
+
// 如果值被插入到单引号字符串中,必须转义单引号,避免 SQL 解析错误
|
|
460
|
+
if (insideQuotes && typeof value === 'string') {
|
|
461
|
+
return value.replace(/'/g, '\'\'');
|
|
462
|
+
}
|
|
463
|
+
// save_as 存储的是行数组 [{col: val, ...}, ...]。
|
|
464
|
+
// 当下游 SQL 用 SELECT * FROM ${variable} 引用时,需要转为 inline CTE。
|
|
465
|
+
if (Array.isArray(value) && value.length > 0 && typeof value[0] === 'object') {
|
|
466
|
+
return arrayToInlineCte(value);
|
|
467
|
+
}
|
|
468
|
+
return String(value);
|
|
469
|
+
});
|
|
470
|
+
return result;
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Convert a save_as row array to an inline SQLite CTE.
|
|
474
|
+
* [{a: 1, b: 'x'}, {a: 2, b: 'y'}] → (SELECT 1 as a, 'x' as b UNION ALL SELECT 2, 'y')
|
|
475
|
+
*/
|
|
476
|
+
function arrayToInlineCte(rows) {
|
|
477
|
+
if (rows.length === 0)
|
|
478
|
+
return '(SELECT NULL LIMIT 0)';
|
|
479
|
+
const columns = Object.keys(rows[0]);
|
|
480
|
+
const selects = rows.map((row, i) => {
|
|
481
|
+
const values = columns.map((col) => {
|
|
482
|
+
const v = row[col];
|
|
483
|
+
if (v === null || v === undefined)
|
|
484
|
+
return 'NULL';
|
|
485
|
+
if (typeof v === 'number' || typeof v === 'bigint')
|
|
486
|
+
return String(v);
|
|
487
|
+
// String values: escape single quotes for SQL
|
|
488
|
+
return `'${String(v).replace(/'/g, "''")}'`;
|
|
489
|
+
});
|
|
490
|
+
// First row includes column aliases; subsequent rows omit them
|
|
491
|
+
if (i === 0) {
|
|
492
|
+
return `SELECT ${values.map((v, j) => `${v} as ${columns[j]}`).join(', ')}`;
|
|
493
|
+
}
|
|
494
|
+
return `SELECT ${values.join(', ')}`;
|
|
495
|
+
});
|
|
496
|
+
return `(${selects.join(' UNION ALL ')})`;
|
|
497
|
+
}
|
|
498
|
+
// =============================================================================
|
|
499
|
+
// Display 配置处理(支持模板变量替换)
|
|
500
|
+
// =============================================================================
|
|
501
|
+
/**
|
|
502
|
+
* 处理 display 配置,对字符串值进行模板变量替换
|
|
503
|
+
* 支持 ${variable} 格式的变量替换
|
|
504
|
+
*/
|
|
505
|
+
function processDisplayConfig(display, context) {
|
|
506
|
+
const processed = { ...display };
|
|
507
|
+
// 处理 title 字段(字符串类型)
|
|
508
|
+
if (processed.title && typeof processed.title === 'string') {
|
|
509
|
+
processed.title = substituteVariables(processed.title, context);
|
|
510
|
+
}
|
|
511
|
+
// 如果未来需要处理其他字符串字段(如 description),可以在这里添加
|
|
512
|
+
// if (processed.description && typeof processed.description === 'string') {
|
|
513
|
+
// processed.description = substituteVariables(processed.description, context);
|
|
514
|
+
// }
|
|
515
|
+
return processed;
|
|
516
|
+
}
|
|
517
|
+
// =============================================================================
|
|
518
|
+
// Layer Organization Functions
|
|
519
|
+
// =============================================================================
|
|
520
|
+
/**
|
|
521
|
+
* Transform deep layer frame analysis results from displayResults format to frontend-expected format.
|
|
522
|
+
*
|
|
523
|
+
* This function is a generic data pass-through that:
|
|
524
|
+
* 1. Maps step IDs to output property names (e.g., 'quadrant_analysis' → 'quadrants')
|
|
525
|
+
* 2. Converts table format { columns, rows } to object array
|
|
526
|
+
* 3. Passes through data without field-level transformations
|
|
527
|
+
*
|
|
528
|
+
* Field naming is the responsibility of the Skill YAML, not this function.
|
|
529
|
+
* The Skill YAML should output data with field names that match frontend expectations.
|
|
530
|
+
*/
|
|
531
|
+
function transformDeepFrameAnalysis(displayResults) {
|
|
532
|
+
logger_1.default.debug('SkillExecutor', `transformDeepFrameAnalysis: ${displayResults.length} steps [${displayResults.map(dr => dr.stepId).join(', ')}]`);
|
|
533
|
+
const fullAnalysis = {
|
|
534
|
+
quadrants: { main_thread: {}, render_thread: {} },
|
|
535
|
+
binder_calls: [],
|
|
536
|
+
cpu_frequency: { big_avg_mhz: 0, little_avg_mhz: 0 },
|
|
537
|
+
main_thread_slices: [],
|
|
538
|
+
render_thread_slices: [],
|
|
539
|
+
cpu_freq_timeline: [],
|
|
540
|
+
lock_contentions: [],
|
|
541
|
+
};
|
|
542
|
+
let diagnosisSummary = '';
|
|
543
|
+
// Step ID to output property mapping
|
|
544
|
+
// This configuration defines which step output goes to which analysis property
|
|
545
|
+
const stepIdMapping = {
|
|
546
|
+
'binder_calls': 'binder_calls',
|
|
547
|
+
'binder_data': 'binder_calls',
|
|
548
|
+
'main_thread_slices': 'main_thread_slices',
|
|
549
|
+
'main_slices': 'main_thread_slices',
|
|
550
|
+
'render_thread_slices': 'render_thread_slices',
|
|
551
|
+
'render_slices': 'render_thread_slices',
|
|
552
|
+
'cpu_freq_timeline': 'cpu_freq_timeline',
|
|
553
|
+
'freq_timeline': 'cpu_freq_timeline',
|
|
554
|
+
'lock_contention': 'lock_contentions',
|
|
555
|
+
'lock_data': 'lock_contentions',
|
|
556
|
+
};
|
|
557
|
+
for (const dr of displayResults) {
|
|
558
|
+
const stepId = dr.stepId;
|
|
559
|
+
const rawData = dr.data;
|
|
560
|
+
// Handle both array data and table format { columns, rows }
|
|
561
|
+
let dataArray = [];
|
|
562
|
+
if (Array.isArray(rawData)) {
|
|
563
|
+
dataArray = rawData;
|
|
564
|
+
}
|
|
565
|
+
else if (rawData?.rows && rawData?.columns) {
|
|
566
|
+
// Convert table format to object array (generic transformation)
|
|
567
|
+
dataArray = rawData.rows.map((row) => {
|
|
568
|
+
const obj = {};
|
|
569
|
+
rawData.columns.forEach((col, idx) => {
|
|
570
|
+
obj[col] = row[idx];
|
|
571
|
+
});
|
|
572
|
+
return obj;
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
// Handle diagnostic step specially (extracts diagnosis text)
|
|
576
|
+
if (stepId === 'frame_diagnosis') {
|
|
577
|
+
const diagnostics = rawData?.diagnostics || [];
|
|
578
|
+
if (Array.isArray(diagnostics) && diagnostics.length > 0) {
|
|
579
|
+
diagnosisSummary = diagnostics
|
|
580
|
+
.filter((d) => d.diagnosis)
|
|
581
|
+
.map((d) => d.diagnosis)
|
|
582
|
+
.join('; ');
|
|
583
|
+
logger_1.default.debug('SkillExecutor', `frame_diagnosis: ${diagnostics.length} diagnostics`);
|
|
584
|
+
}
|
|
585
|
+
continue;
|
|
586
|
+
}
|
|
587
|
+
// Handle root_cause_summary step - extract primary_cause as diagnosis
|
|
588
|
+
// stepId is 'root_cause_summary' (from skill step id), not 'root_cause' (save_as variable name)
|
|
589
|
+
if (stepId === 'root_cause_summary') {
|
|
590
|
+
// Extract primary_cause as the main diagnosis
|
|
591
|
+
if (dataArray.length > 0) {
|
|
592
|
+
const rootCause = dataArray[0];
|
|
593
|
+
if (rootCause?.primary_cause) {
|
|
594
|
+
// Use root_cause as primary diagnosis (more reliable than frame_diagnosis rules)
|
|
595
|
+
diagnosisSummary = rootCause.primary_cause;
|
|
596
|
+
if (rootCause.secondary_info) {
|
|
597
|
+
diagnosisSummary += ` (${rootCause.secondary_info})`;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
continue;
|
|
602
|
+
}
|
|
603
|
+
// Handle cpu_freq_analysis specially (converts rows to single object)
|
|
604
|
+
if (stepId === 'cpu_freq_analysis' || stepId === 'freq_data') {
|
|
605
|
+
const bigCore = dataArray.find((d) => d.core_type === 'big');
|
|
606
|
+
const littleCore = dataArray.find((d) => d.core_type === 'little');
|
|
607
|
+
fullAnalysis.cpu_frequency = {
|
|
608
|
+
big_avg_mhz: bigCore?.avg_freq_mhz || 0,
|
|
609
|
+
little_avg_mhz: littleCore?.avg_freq_mhz || 0,
|
|
610
|
+
};
|
|
611
|
+
continue;
|
|
612
|
+
}
|
|
613
|
+
// Handle quadrant_analysis specially - convert flat array to nested object
|
|
614
|
+
// Input format: [{ quadrant: "MainThread Q1_大核运行", dur_ms, percentage }, ...]
|
|
615
|
+
// Output format: { main_thread: { q1, q2, q3, q4 }, render_thread: { q1, q2, q3, q4 } }
|
|
616
|
+
if (stepId === 'quadrant_analysis' || stepId === 'quadrant_data') {
|
|
617
|
+
const mainThread = { q1: 0, q2: 0, q3: 0, q4: 0 };
|
|
618
|
+
const renderThread = { q1: 0, q2: 0, q3: 0, q4: 0 };
|
|
619
|
+
for (const item of dataArray) {
|
|
620
|
+
const quadrant = item.quadrant || item.name || '';
|
|
621
|
+
const percentage = item.percentage || 0;
|
|
622
|
+
// Parse quadrant name: "MainThread Q1_大核运行" -> thread=MainThread, q=1
|
|
623
|
+
if (quadrant.includes('MainThread')) {
|
|
624
|
+
if (quadrant.includes('Q1'))
|
|
625
|
+
mainThread.q1 = percentage;
|
|
626
|
+
else if (quadrant.includes('Q2'))
|
|
627
|
+
mainThread.q2 = percentage;
|
|
628
|
+
else if (quadrant.includes('Q3'))
|
|
629
|
+
mainThread.q3 = percentage;
|
|
630
|
+
// Q4a (IO-block) + Q4b (voluntary sleep) both contribute to Q4 total
|
|
631
|
+
else if (quadrant.includes('Q4'))
|
|
632
|
+
mainThread.q4 = (mainThread.q4 || 0) + percentage;
|
|
633
|
+
}
|
|
634
|
+
else if (quadrant.includes('RenderThread')) {
|
|
635
|
+
if (quadrant.includes('Q1'))
|
|
636
|
+
renderThread.q1 = percentage;
|
|
637
|
+
else if (quadrant.includes('Q2'))
|
|
638
|
+
renderThread.q2 = percentage;
|
|
639
|
+
else if (quadrant.includes('Q3'))
|
|
640
|
+
renderThread.q3 = percentage;
|
|
641
|
+
else if (quadrant.includes('Q4'))
|
|
642
|
+
renderThread.q4 = (renderThread.q4 || 0) + percentage;
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
fullAnalysis.quadrants = {
|
|
646
|
+
main_thread: mainThread,
|
|
647
|
+
render_thread: renderThread,
|
|
648
|
+
};
|
|
649
|
+
continue;
|
|
650
|
+
}
|
|
651
|
+
// Generic pass-through: map step ID to property and assign data directly
|
|
652
|
+
const outputProperty = stepIdMapping[stepId];
|
|
653
|
+
if (outputProperty && dataArray.length > 0) {
|
|
654
|
+
// Map field names to match what renderDeepFrameAnalysis expects
|
|
655
|
+
if (outputProperty === 'binder_calls') {
|
|
656
|
+
// Skill outputs: interface, count, dur_ms, max_ms, sync_count
|
|
657
|
+
// Renderer expects: server_process, call_count, total_ms, max_ms
|
|
658
|
+
fullAnalysis[outputProperty] = dataArray.map((item) => ({
|
|
659
|
+
server_process: item.interface || item.server_process || '',
|
|
660
|
+
call_count: item.count || item.call_count || 0,
|
|
661
|
+
total_ms: item.dur_ms || item.total_ms || 0,
|
|
662
|
+
max_ms: item.max_ms || 0,
|
|
663
|
+
sync_count: item.sync_count || 0,
|
|
664
|
+
}));
|
|
665
|
+
}
|
|
666
|
+
else if (outputProperty === 'main_thread_slices' || outputProperty === 'render_thread_slices') {
|
|
667
|
+
// Skill outputs: name, dur_ms, count, max_ms, ts
|
|
668
|
+
// Renderer expects: name, total_ms, count, max_ms
|
|
669
|
+
fullAnalysis[outputProperty] = dataArray.map((item) => ({
|
|
670
|
+
name: item.name || '',
|
|
671
|
+
total_ms: item.dur_ms || item.total_ms || 0,
|
|
672
|
+
count: item.count || 1,
|
|
673
|
+
max_ms: item.max_ms || 0,
|
|
674
|
+
ts: item.ts,
|
|
675
|
+
}));
|
|
676
|
+
}
|
|
677
|
+
else {
|
|
678
|
+
fullAnalysis[outputProperty] = dataArray;
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
return {
|
|
683
|
+
diagnosis_summary: diagnosisSummary || '暂无明显问题',
|
|
684
|
+
full_analysis: fullAnalysis,
|
|
685
|
+
};
|
|
686
|
+
}
|
|
687
|
+
function organizeByLayer(steps) {
|
|
688
|
+
const layers = {
|
|
689
|
+
overview: {},
|
|
690
|
+
list: {},
|
|
691
|
+
session: {},
|
|
692
|
+
deep: {},
|
|
693
|
+
diagnosis: {},
|
|
694
|
+
};
|
|
695
|
+
for (const step of steps) {
|
|
696
|
+
const rawLayer = step.display?.layer;
|
|
697
|
+
if (!rawLayer) {
|
|
698
|
+
continue;
|
|
699
|
+
}
|
|
700
|
+
// 规范化 layer 名称为语义名称(overview/list/session/deep/diagnosis)
|
|
701
|
+
const layer = normalizeLayer(rawLayer) || rawLayer;
|
|
702
|
+
// Ensure failed steps have empty array data for consistent handling
|
|
703
|
+
const normalizedStep = step.success ? step : {
|
|
704
|
+
...step,
|
|
705
|
+
data: [], // Default to empty array for failed steps
|
|
706
|
+
error: step.error,
|
|
707
|
+
};
|
|
708
|
+
switch (layer) {
|
|
709
|
+
case 'overview':
|
|
710
|
+
case 'list':
|
|
711
|
+
case 'diagnosis':
|
|
712
|
+
const targetLayer = layers[layer];
|
|
713
|
+
if (targetLayer) {
|
|
714
|
+
targetLayer[normalizedStep.stepId] = normalizedStep;
|
|
715
|
+
}
|
|
716
|
+
break;
|
|
717
|
+
case 'session':
|
|
718
|
+
// session 数据需要按 session_id 组织
|
|
719
|
+
const sessionLayer = layers.session;
|
|
720
|
+
if (sessionLayer) {
|
|
721
|
+
const sessionId = extractSessionId(normalizedStep);
|
|
722
|
+
if (!sessionLayer[sessionId]) {
|
|
723
|
+
sessionLayer[sessionId] = {};
|
|
724
|
+
}
|
|
725
|
+
sessionLayer[sessionId][normalizedStep.stepId] = normalizedStep;
|
|
726
|
+
}
|
|
727
|
+
break;
|
|
728
|
+
case 'deep':
|
|
729
|
+
// deep 数据需要按 session_id 和 frame_id 组织
|
|
730
|
+
const deepLayer = layers.deep;
|
|
731
|
+
if (deepLayer) {
|
|
732
|
+
// 特殊处理 iterator 结果:每个迭代项都是单独的 deep 条目
|
|
733
|
+
if (normalizedStep.stepType === 'iterator' && Array.isArray(normalizedStep.data)) {
|
|
734
|
+
logger_1.default.debug('SkillExecutor', `organizeByLayer: iterator step ${normalizedStep.stepId} with ${normalizedStep.data.length} items`);
|
|
735
|
+
// Iterator 返回 { itemIndex, item, result }[] 数组
|
|
736
|
+
for (let i = 0; i < normalizedStep.data.length; i++) {
|
|
737
|
+
const iterItem = normalizedStep.data[i];
|
|
738
|
+
const item = iterItem?.item;
|
|
739
|
+
if (!item) {
|
|
740
|
+
console.warn(`[organizeByLayer] Iterator item ${i} has no item data, skipping`);
|
|
741
|
+
continue;
|
|
742
|
+
}
|
|
743
|
+
const frameId = `frame_${item.frame_id || item.frame_index || i}`;
|
|
744
|
+
const sessionId = `session_${item.session_id ?? 0}`;
|
|
745
|
+
if (!deepLayer[sessionId]) {
|
|
746
|
+
deepLayer[sessionId] = {};
|
|
747
|
+
}
|
|
748
|
+
// Transform displayResults into format expected by frontend
|
|
749
|
+
const displayResults = iterItem.result?.displayResults || [];
|
|
750
|
+
const transformedData = transformDeepFrameAnalysis(displayResults);
|
|
751
|
+
const frameStepResult = {
|
|
752
|
+
stepId: frameId,
|
|
753
|
+
stepType: 'atomic',
|
|
754
|
+
success: iterItem.result?.success ?? false,
|
|
755
|
+
data: transformedData,
|
|
756
|
+
executionTimeMs: iterItem.result?.executionTimeMs || 0,
|
|
757
|
+
display: {
|
|
758
|
+
title: `帧 #${item.frame_id || item.frame_index || i} - ${item.jank_type || 'Unknown'}`,
|
|
759
|
+
level: 'key',
|
|
760
|
+
layer: 'deep',
|
|
761
|
+
format: 'table',
|
|
762
|
+
},
|
|
763
|
+
};
|
|
764
|
+
frameStepResult.item = item;
|
|
765
|
+
deepLayer[sessionId][frameId] = frameStepResult;
|
|
766
|
+
}
|
|
767
|
+
logger_1.default.debug('SkillExecutor', `organizeByLayer: deep layer sessions: [${Object.keys(deepLayer).join(', ')}]`);
|
|
768
|
+
}
|
|
769
|
+
else if (normalizedStep.stepType === 'atomic' && Array.isArray(normalizedStep.data) && normalizedStep.data.length > 0) {
|
|
770
|
+
// 检查是否是帧列表数据(如 get_app_jank_frames)
|
|
771
|
+
// 如果 data 是数组且每个元素都有 frame_id 或 frame_index,展开为多个帧
|
|
772
|
+
const firstItem = normalizedStep.data[0];
|
|
773
|
+
const hasFrameId = firstItem && typeof firstItem === 'object' && ('frame_id' in firstItem || 'frame_index' in firstItem);
|
|
774
|
+
if (hasFrameId) {
|
|
775
|
+
// 将每一行作为一个单独的帧条目
|
|
776
|
+
for (let i = 0; i < normalizedStep.data.length; i++) {
|
|
777
|
+
const item = normalizedStep.data[i];
|
|
778
|
+
if (!item || typeof item !== 'object')
|
|
779
|
+
continue;
|
|
780
|
+
const frameId = `frame_${item.frame_id || item.frame_index || i}`;
|
|
781
|
+
const sessionId = `session_${item.session_id ?? 0}`;
|
|
782
|
+
if (!deepLayer[sessionId]) {
|
|
783
|
+
deepLayer[sessionId] = {};
|
|
784
|
+
}
|
|
785
|
+
const frameStepResult = {
|
|
786
|
+
stepId: frameId,
|
|
787
|
+
stepType: 'atomic',
|
|
788
|
+
success: normalizedStep.success,
|
|
789
|
+
data: [item],
|
|
790
|
+
executionTimeMs: normalizedStep.executionTimeMs / normalizedStep.data.length,
|
|
791
|
+
display: {
|
|
792
|
+
title: `帧 #${item.frame_id || item.frame_index || i} - ${item.jank_type || 'Unknown'}`,
|
|
793
|
+
level: 'key',
|
|
794
|
+
layer: 'deep',
|
|
795
|
+
format: 'table',
|
|
796
|
+
},
|
|
797
|
+
};
|
|
798
|
+
frameStepResult.item = item;
|
|
799
|
+
deepLayer[sessionId][frameId] = frameStepResult;
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
else {
|
|
803
|
+
// 普通的 deep 步骤(不是帧列表)
|
|
804
|
+
const sessionId = extractSessionId(normalizedStep);
|
|
805
|
+
const frameId = extractFrameId(normalizedStep);
|
|
806
|
+
if (!deepLayer[sessionId]) {
|
|
807
|
+
deepLayer[sessionId] = {};
|
|
808
|
+
}
|
|
809
|
+
deepLayer[sessionId][frameId] = normalizedStep;
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
else {
|
|
813
|
+
// 普通的 deep 步骤
|
|
814
|
+
const sessionId = extractSessionId(normalizedStep);
|
|
815
|
+
const frameId = extractFrameId(normalizedStep);
|
|
816
|
+
if (!deepLayer[sessionId]) {
|
|
817
|
+
deepLayer[sessionId] = {};
|
|
818
|
+
}
|
|
819
|
+
deepLayer[sessionId][frameId] = normalizedStep;
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
break;
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
return layers;
|
|
826
|
+
}
|
|
827
|
+
function extractSessionId(step) {
|
|
828
|
+
// 尝试从 step.data 中提取 session_id
|
|
829
|
+
if (Array.isArray(step.data) && step.data.length > 0) {
|
|
830
|
+
return `session_${step.data[0].session_id ?? 0}`;
|
|
831
|
+
}
|
|
832
|
+
return 'session_0';
|
|
833
|
+
}
|
|
834
|
+
function extractFrameId(step) {
|
|
835
|
+
// 尝试从 step 中提取 frame_id
|
|
836
|
+
if (step.stepId.startsWith('frame_')) {
|
|
837
|
+
return step.stepId;
|
|
838
|
+
}
|
|
839
|
+
if (Array.isArray(step.data) && step.data.length > 0) {
|
|
840
|
+
return `frame_${step.data[0].frame_index ?? step.data[0].frame_id ?? 0}`;
|
|
841
|
+
}
|
|
842
|
+
// For non-frame deep steps, use stepId as key to avoid overwriting previous steps.
|
|
843
|
+
if (step.stepId && step.stepId.length > 0) {
|
|
844
|
+
return step.stepId;
|
|
845
|
+
}
|
|
846
|
+
return 'frame_0';
|
|
847
|
+
}
|
|
848
|
+
// =============================================================================
|
|
849
|
+
// Skill Executor
|
|
850
|
+
// =============================================================================
|
|
851
|
+
class SkillExecutor {
|
|
852
|
+
constructor(traceProcessor, aiService, eventEmitter) {
|
|
853
|
+
this.fragmentRegistry = new Map();
|
|
854
|
+
this.identityGate = new identityGate_1.IdentityGate();
|
|
855
|
+
this.processIdentityCache = new Map();
|
|
856
|
+
this.traceProcessor = traceProcessor;
|
|
857
|
+
this.aiService = aiService;
|
|
858
|
+
this.eventEmitter = eventEmitter;
|
|
859
|
+
this.skillRegistry = new Map();
|
|
860
|
+
}
|
|
861
|
+
/**
|
|
862
|
+
* Set the SQL fragment registry (loaded by SkillRegistry).
|
|
863
|
+
* Fragments are reusable CTE definitions injected into step SQL at runtime.
|
|
864
|
+
*/
|
|
865
|
+
setFragmentRegistry(cache) {
|
|
866
|
+
this.fragmentRegistry = cache;
|
|
867
|
+
}
|
|
868
|
+
/**
|
|
869
|
+
* Inject SQL fragment CTEs into a step's SQL query.
|
|
870
|
+
*
|
|
871
|
+
* Fragment files contain bare CTE definitions (no WITH keyword), e.g.:
|
|
872
|
+
* target_threads AS (SELECT ...)
|
|
873
|
+
*
|
|
874
|
+
* Injection rules:
|
|
875
|
+
* - If the SQL starts with WITH: insert fragments after WITH, before existing CTEs
|
|
876
|
+
* - Otherwise: wrap as WITH <fragments>\n<sql>
|
|
877
|
+
*/
|
|
878
|
+
injectSqlFragments(sql, fragmentPaths, context) {
|
|
879
|
+
const fragmentCteBodies = [];
|
|
880
|
+
for (const fragPath of fragmentPaths) {
|
|
881
|
+
const content = this.fragmentRegistry.get(fragPath);
|
|
882
|
+
if (!content) {
|
|
883
|
+
logger_1.default.warn('SkillExecutor', `Fragment not found: ${fragPath}, skipping`);
|
|
884
|
+
continue;
|
|
885
|
+
}
|
|
886
|
+
// Apply variable substitution to the fragment content
|
|
887
|
+
const substituted = substituteVariables(content, context);
|
|
888
|
+
fragmentCteBodies.push(substituted);
|
|
889
|
+
}
|
|
890
|
+
if (fragmentCteBodies.length === 0)
|
|
891
|
+
return sql;
|
|
892
|
+
const fragmentBlock = fragmentCteBodies.join(',\n');
|
|
893
|
+
const trimmed = sql.trimStart();
|
|
894
|
+
// Strip leading SQL single-line comments (-- ...) before WITH detection,
|
|
895
|
+
// since steps like root_cause_summary prefix SQL with comment lines.
|
|
896
|
+
const noLeadingComments = trimmed.replace(/^(--[^\n]*\n\s*)*/g, '');
|
|
897
|
+
const withMatch = noLeadingComments.match(/^WITH\s+/i);
|
|
898
|
+
if (withMatch) {
|
|
899
|
+
// Preserve original comments, insert fragments after WITH
|
|
900
|
+
const commentPrefix = trimmed.slice(0, trimmed.length - noLeadingComments.length);
|
|
901
|
+
const afterWith = noLeadingComments.slice(withMatch[0].length);
|
|
902
|
+
return `${commentPrefix}WITH\n${fragmentBlock},\n${afterWith}`;
|
|
903
|
+
}
|
|
904
|
+
// Wrap the entire SQL in a WITH clause
|
|
905
|
+
return `WITH\n${fragmentBlock}\n${trimmed}`;
|
|
906
|
+
}
|
|
907
|
+
/**
|
|
908
|
+
* 注册 skill
|
|
909
|
+
*/
|
|
910
|
+
registerSkill(skill) {
|
|
911
|
+
this.skillRegistry.set(skill.name, skill);
|
|
912
|
+
}
|
|
913
|
+
/**
|
|
914
|
+
* 批量注册 skills
|
|
915
|
+
*/
|
|
916
|
+
registerSkills(skills) {
|
|
917
|
+
for (const skill of skills) {
|
|
918
|
+
this.registerSkill(skill);
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
/**
|
|
922
|
+
* 发送事件到前端
|
|
923
|
+
*/
|
|
924
|
+
emit(event) {
|
|
925
|
+
if (this.eventEmitter) {
|
|
926
|
+
this.eventEmitter({
|
|
927
|
+
...event,
|
|
928
|
+
timestamp: Date.now(),
|
|
929
|
+
});
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
buildIdentityCacheKey(traceId, target) {
|
|
933
|
+
return JSON.stringify({
|
|
934
|
+
traceId,
|
|
935
|
+
requestedName: target.requestedName || '',
|
|
936
|
+
threadName: target.threadName || '',
|
|
937
|
+
upid: target.upid ?? null,
|
|
938
|
+
pid: target.pid ?? null,
|
|
939
|
+
startTs: target.startTs ?? null,
|
|
940
|
+
endTs: target.endTs ?? null,
|
|
941
|
+
});
|
|
942
|
+
}
|
|
943
|
+
toNumber(value) {
|
|
944
|
+
if (value === undefined || value === null || value === '')
|
|
945
|
+
return undefined;
|
|
946
|
+
const n = Number(value);
|
|
947
|
+
return Number.isFinite(n) ? n : undefined;
|
|
948
|
+
}
|
|
949
|
+
splitSources(...values) {
|
|
950
|
+
const sources = new Set();
|
|
951
|
+
for (const value of values) {
|
|
952
|
+
if (typeof value !== 'string')
|
|
953
|
+
continue;
|
|
954
|
+
for (const part of value.split(',')) {
|
|
955
|
+
const s = part.trim();
|
|
956
|
+
if (s)
|
|
957
|
+
sources.add(s);
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
return Array.from(sources);
|
|
961
|
+
}
|
|
962
|
+
rowToIdentityCandidate(row) {
|
|
963
|
+
return {
|
|
964
|
+
rank: this.toNumber(row.rank) ?? 0,
|
|
965
|
+
confidenceScore: this.toNumber(row.confidence_score) ?? 0,
|
|
966
|
+
rawStatus: row.identity_status ? String(row.identity_status) : undefined,
|
|
967
|
+
canonicalPackageName: row.canonical_package_name ? String(row.canonical_package_name) : undefined,
|
|
968
|
+
recommendedProcessNameParam: row.recommended_process_name_param ? String(row.recommended_process_name_param) : undefined,
|
|
969
|
+
upid: this.toNumber(row.upid),
|
|
970
|
+
pid: this.toNumber(row.pid),
|
|
971
|
+
processName: row.process_name ? String(row.process_name) : undefined,
|
|
972
|
+
metadataProcessName: row.metadata_process_name ? String(row.metadata_process_name) : undefined,
|
|
973
|
+
packageName: row.package_name ? String(row.package_name) : undefined,
|
|
974
|
+
cmdline: row.cmdline ? String(row.cmdline) : undefined,
|
|
975
|
+
targetMatchSources: row.target_match_sources ? String(row.target_match_sources) : undefined,
|
|
976
|
+
supportingSources: row.supporting_sources ? String(row.supporting_sources) : undefined,
|
|
977
|
+
identityWarning: row.identity_warning ? String(row.identity_warning) : undefined,
|
|
978
|
+
};
|
|
979
|
+
}
|
|
980
|
+
normalizeIdentityStatus(candidate) {
|
|
981
|
+
if (!candidate)
|
|
982
|
+
return 'not_found';
|
|
983
|
+
if ((candidate.rawStatus === 'confirmed' || candidate.rawStatus === 'probable') &&
|
|
984
|
+
candidate.confidenceScore >= 50) {
|
|
985
|
+
return 'verified';
|
|
986
|
+
}
|
|
987
|
+
if (candidate.confidenceScore <= 0)
|
|
988
|
+
return 'not_found';
|
|
989
|
+
return 'ambiguous';
|
|
990
|
+
}
|
|
991
|
+
async resolveProcessIdentityForGate(traceId, target, inherited) {
|
|
992
|
+
const cacheKey = this.buildIdentityCacheKey(traceId, target);
|
|
993
|
+
const cached = this.processIdentityCache.get(cacheKey);
|
|
994
|
+
if (cached)
|
|
995
|
+
return cached;
|
|
996
|
+
const params = {
|
|
997
|
+
max_rows: 10,
|
|
998
|
+
};
|
|
999
|
+
if (target.requestedName) {
|
|
1000
|
+
params.package = target.requestedName;
|
|
1001
|
+
params.process_name = target.requestedName;
|
|
1002
|
+
}
|
|
1003
|
+
if (target.threadName)
|
|
1004
|
+
params.thread_name = target.threadName;
|
|
1005
|
+
if (target.upid !== undefined)
|
|
1006
|
+
params.upid = target.upid;
|
|
1007
|
+
if (target.pid !== undefined)
|
|
1008
|
+
params.pid = target.pid;
|
|
1009
|
+
if (target.startTs !== undefined)
|
|
1010
|
+
params.start_ts = target.startTs;
|
|
1011
|
+
if (target.endTs !== undefined)
|
|
1012
|
+
params.end_ts = target.endTs;
|
|
1013
|
+
let resolution;
|
|
1014
|
+
try {
|
|
1015
|
+
const result = await this.execute('process_identity_resolver', traceId, params, { ...inherited, __skipIdentityGate: true });
|
|
1016
|
+
if (!result.success) {
|
|
1017
|
+
resolution = {
|
|
1018
|
+
status: 'unresolved',
|
|
1019
|
+
requestedName: target.requestedName,
|
|
1020
|
+
upids: [],
|
|
1021
|
+
confidenceScore: 0,
|
|
1022
|
+
evidenceSources: [],
|
|
1023
|
+
warnings: [],
|
|
1024
|
+
candidates: [],
|
|
1025
|
+
resolverError: result.error || 'process_identity_resolver failed',
|
|
1026
|
+
};
|
|
1027
|
+
}
|
|
1028
|
+
else {
|
|
1029
|
+
const rows = Array.isArray(result.rawResults?.root?.data)
|
|
1030
|
+
? result.rawResults.root.data
|
|
1031
|
+
: [];
|
|
1032
|
+
const candidates = rows.map(row => this.rowToIdentityCandidate(row));
|
|
1033
|
+
const top = candidates[0];
|
|
1034
|
+
const warning = top?.identityWarning && top.identityWarning !== 'ok' ? top.identityWarning : undefined;
|
|
1035
|
+
resolution = {
|
|
1036
|
+
status: this.normalizeIdentityStatus(top),
|
|
1037
|
+
requestedName: target.requestedName,
|
|
1038
|
+
canonicalPackageName: top?.canonicalPackageName,
|
|
1039
|
+
recommendedProcessNameParam: top?.recommendedProcessNameParam,
|
|
1040
|
+
upids: candidates.map(c => c.upid).filter((upid) => upid !== undefined),
|
|
1041
|
+
confidenceScore: top?.confidenceScore ?? 0,
|
|
1042
|
+
rawStatus: top?.rawStatus,
|
|
1043
|
+
evidenceSources: this.splitSources(top?.targetMatchSources, top?.supportingSources),
|
|
1044
|
+
warnings: warning ? [warning] : [],
|
|
1045
|
+
candidates,
|
|
1046
|
+
};
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
catch (error) {
|
|
1050
|
+
resolution = {
|
|
1051
|
+
status: 'unresolved',
|
|
1052
|
+
requestedName: target.requestedName,
|
|
1053
|
+
upids: [],
|
|
1054
|
+
confidenceScore: 0,
|
|
1055
|
+
evidenceSources: [],
|
|
1056
|
+
warnings: [],
|
|
1057
|
+
candidates: [],
|
|
1058
|
+
resolverError: error?.message || 'process_identity_resolver threw',
|
|
1059
|
+
};
|
|
1060
|
+
}
|
|
1061
|
+
if (!resolution.resolverError) {
|
|
1062
|
+
this.processIdentityCache.set(cacheKey, resolution);
|
|
1063
|
+
}
|
|
1064
|
+
return resolution;
|
|
1065
|
+
}
|
|
1066
|
+
async applyIdentityGate(skill, traceId, params, inherited) {
|
|
1067
|
+
return this.identityGate.apply({
|
|
1068
|
+
traceId,
|
|
1069
|
+
skill,
|
|
1070
|
+
params,
|
|
1071
|
+
inherited,
|
|
1072
|
+
resolve: (target) => this.resolveProcessIdentityForGate(traceId, target, inherited),
|
|
1073
|
+
});
|
|
1074
|
+
}
|
|
1075
|
+
buildIdentityBlockedResult(skillId, skill, startTime, gate) {
|
|
1076
|
+
const error = gate.error || `Process identity gate blocked skill: ${skillId}`;
|
|
1077
|
+
return {
|
|
1078
|
+
skillId,
|
|
1079
|
+
skillName: skill.meta.display_name,
|
|
1080
|
+
success: false,
|
|
1081
|
+
displayResults: [],
|
|
1082
|
+
diagnostics: [{
|
|
1083
|
+
id: 'process_identity_gate_blocked',
|
|
1084
|
+
diagnosis: error,
|
|
1085
|
+
confidence: 1,
|
|
1086
|
+
severity: 'critical',
|
|
1087
|
+
evidence: {
|
|
1088
|
+
target: gate.target,
|
|
1089
|
+
resolution: gate.resolution,
|
|
1090
|
+
policy: gate.config.policy,
|
|
1091
|
+
},
|
|
1092
|
+
suggestions: [
|
|
1093
|
+
'先确认目标应用身份;如果候选进程不唯一,请使用用户明确包名、线程名或 UPID 重新运行。',
|
|
1094
|
+
'报告中使用 canonicalPackageName,旧 Skill 参数使用 recommendedProcessNameParam。',
|
|
1095
|
+
],
|
|
1096
|
+
source: 'rule',
|
|
1097
|
+
}],
|
|
1098
|
+
executionTimeMs: Date.now() - startTime,
|
|
1099
|
+
error,
|
|
1100
|
+
};
|
|
1101
|
+
}
|
|
1102
|
+
/**
|
|
1103
|
+
* Expand prerequisite module aliases to canonical stdlib module ids.
|
|
1104
|
+
*/
|
|
1105
|
+
resolvePrerequisiteModules(modules) {
|
|
1106
|
+
if (!Array.isArray(modules) || modules.length === 0)
|
|
1107
|
+
return [];
|
|
1108
|
+
const expanded = [];
|
|
1109
|
+
for (const m of modules) {
|
|
1110
|
+
switch (m) {
|
|
1111
|
+
case 'sched':
|
|
1112
|
+
// stdlib/sched/ 下不存在 sched.sql;常用能力在 states/runnable
|
|
1113
|
+
expanded.push('sched.states', 'sched.runnable');
|
|
1114
|
+
break;
|
|
1115
|
+
case 'stack_profile':
|
|
1116
|
+
// stdlib/callstacks/stack_profile.sql
|
|
1117
|
+
expanded.push('callstacks.stack_profile');
|
|
1118
|
+
break;
|
|
1119
|
+
case 'android.frames':
|
|
1120
|
+
// stdlib/android/frames/ 无 frames.sql;常见能力来自 timeline/jank_type
|
|
1121
|
+
expanded.push('android.frames.timeline', 'android.frames.jank_type');
|
|
1122
|
+
break;
|
|
1123
|
+
case 'android.frames.jank':
|
|
1124
|
+
// 实际模块名为 jank_type.sql
|
|
1125
|
+
expanded.push('android.frames.jank_type');
|
|
1126
|
+
break;
|
|
1127
|
+
default:
|
|
1128
|
+
expanded.push(m);
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
return Array.from(new Set(expanded));
|
|
1132
|
+
}
|
|
1133
|
+
/**
|
|
1134
|
+
* Best-effort probe for prerequisite modules and return only available ones.
|
|
1135
|
+
* Note: some trace processor builds treat INCLUDE as statement-scoped, so
|
|
1136
|
+
* SQL execution still prepends INCLUDE per-step for determinism.
|
|
1137
|
+
*/
|
|
1138
|
+
async resolveAvailableModules(traceId, modules) {
|
|
1139
|
+
const available = [];
|
|
1140
|
+
for (const module of modules) {
|
|
1141
|
+
try {
|
|
1142
|
+
const includeResult = await this.traceProcessor.query(traceId, `INCLUDE PERFETTO MODULE ${module};`);
|
|
1143
|
+
if (includeResult?.error) {
|
|
1144
|
+
console.warn(`[SkillExecutor] Module not available: ${module}`);
|
|
1145
|
+
continue;
|
|
1146
|
+
}
|
|
1147
|
+
available.push(module);
|
|
1148
|
+
}
|
|
1149
|
+
catch {
|
|
1150
|
+
console.warn(`[SkillExecutor] Module not available: ${module}`);
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
return available;
|
|
1154
|
+
}
|
|
1155
|
+
/**
|
|
1156
|
+
* Prefix SQL with prerequisite INCLUDE statements.
|
|
1157
|
+
*/
|
|
1158
|
+
buildSqlWithModuleIncludes(sql, context) {
|
|
1159
|
+
const modules = context.moduleIncludes || [];
|
|
1160
|
+
if (modules.length === 0)
|
|
1161
|
+
return sql;
|
|
1162
|
+
const prefix = modules.map(module => `INCLUDE PERFETTO MODULE ${module};`).join('\n');
|
|
1163
|
+
return `${prefix}\n${sql}`;
|
|
1164
|
+
}
|
|
1165
|
+
/**
|
|
1166
|
+
* 执行 skill
|
|
1167
|
+
*/
|
|
1168
|
+
async execute(skillId, traceId, params = {}, inherited = {}) {
|
|
1169
|
+
const startTime = Date.now();
|
|
1170
|
+
const skill = this.skillRegistry.get(skillId);
|
|
1171
|
+
if (!skill) {
|
|
1172
|
+
return {
|
|
1173
|
+
skillId,
|
|
1174
|
+
skillName: skillId,
|
|
1175
|
+
success: false,
|
|
1176
|
+
displayResults: [],
|
|
1177
|
+
diagnostics: [],
|
|
1178
|
+
executionTimeMs: Date.now() - startTime,
|
|
1179
|
+
error: `Skill not found: ${skillId}`,
|
|
1180
|
+
};
|
|
1181
|
+
}
|
|
1182
|
+
this.emit({
|
|
1183
|
+
type: 'skill_started',
|
|
1184
|
+
skillId,
|
|
1185
|
+
data: { skillName: skill.meta.display_name },
|
|
1186
|
+
});
|
|
1187
|
+
const gate = await this.applyIdentityGate(skill, traceId, params, inherited);
|
|
1188
|
+
if (!gate.allowed) {
|
|
1189
|
+
this.emit({
|
|
1190
|
+
type: 'skill_error',
|
|
1191
|
+
skillId,
|
|
1192
|
+
data: { error: gate.error },
|
|
1193
|
+
});
|
|
1194
|
+
return this.buildIdentityBlockedResult(skillId, skill, startTime, gate);
|
|
1195
|
+
}
|
|
1196
|
+
// Validate and coerce input parameters against skill.inputs declarations
|
|
1197
|
+
const validated = (0, skillValidator_1.validateSkillInputs)(skillId, skill.inputs, gate.params);
|
|
1198
|
+
for (const w of validated.warnings) {
|
|
1199
|
+
logger_1.default.warn('SkillExecutor', `[${skillId}] ${w.paramName}: ${w.message}`);
|
|
1200
|
+
}
|
|
1201
|
+
if (validated.errors.length > 0) {
|
|
1202
|
+
const msg = validated.errors.map(e => `${e.paramName}: ${e.message}`).join('; ');
|
|
1203
|
+
logger_1.default.error('SkillExecutor', `[${skillId}] Input validation failed: ${msg}`);
|
|
1204
|
+
return {
|
|
1205
|
+
skillId,
|
|
1206
|
+
skillName: skill.meta.display_name,
|
|
1207
|
+
success: false,
|
|
1208
|
+
displayResults: [],
|
|
1209
|
+
diagnostics: [],
|
|
1210
|
+
executionTimeMs: Date.now() - startTime,
|
|
1211
|
+
error: `Input validation failed: ${msg}`,
|
|
1212
|
+
};
|
|
1213
|
+
}
|
|
1214
|
+
const prerequisiteModules = this.resolvePrerequisiteModules(skill.prerequisites?.modules);
|
|
1215
|
+
let moduleIncludes = prerequisiteModules;
|
|
1216
|
+
// 仅注入可用模块,避免未知模块导致整条 SQL 失败
|
|
1217
|
+
if (prerequisiteModules.length > 0) {
|
|
1218
|
+
moduleIncludes = await this.resolveAvailableModules(traceId, prerequisiteModules);
|
|
1219
|
+
}
|
|
1220
|
+
// 创建执行上下文 (use validated.params with coerced types and defaults)
|
|
1221
|
+
const context = {
|
|
1222
|
+
traceId,
|
|
1223
|
+
params: validated.params,
|
|
1224
|
+
inherited: gate.inherited,
|
|
1225
|
+
results: {},
|
|
1226
|
+
variables: {},
|
|
1227
|
+
moduleIncludes,
|
|
1228
|
+
};
|
|
1229
|
+
// 检查表依赖
|
|
1230
|
+
const prereqCheck = await this.checkPrerequisites(skill, traceId);
|
|
1231
|
+
if (!prereqCheck.success) {
|
|
1232
|
+
return {
|
|
1233
|
+
skillId,
|
|
1234
|
+
skillName: skill.meta.display_name,
|
|
1235
|
+
success: false,
|
|
1236
|
+
displayResults: [],
|
|
1237
|
+
diagnostics: [],
|
|
1238
|
+
executionTimeMs: Date.now() - startTime,
|
|
1239
|
+
error: `Skipped: ${prereqCheck.error}`,
|
|
1240
|
+
};
|
|
1241
|
+
}
|
|
1242
|
+
try {
|
|
1243
|
+
const displayResults = [];
|
|
1244
|
+
const diagnostics = [];
|
|
1245
|
+
const synthesizeData = [];
|
|
1246
|
+
let aiSummary;
|
|
1247
|
+
// 根据 skill 类型执行
|
|
1248
|
+
switch (skill.type) {
|
|
1249
|
+
case 'atomic':
|
|
1250
|
+
if (skill.sql) {
|
|
1251
|
+
const atomicResult = await this.executeAtomicSkill(skill, context);
|
|
1252
|
+
// Handle atomic skill errors
|
|
1253
|
+
if (!atomicResult.success) {
|
|
1254
|
+
this.emit({
|
|
1255
|
+
type: 'skill_error',
|
|
1256
|
+
skillId,
|
|
1257
|
+
data: { error: atomicResult.error },
|
|
1258
|
+
});
|
|
1259
|
+
return {
|
|
1260
|
+
skillId,
|
|
1261
|
+
skillName: skill.meta.display_name,
|
|
1262
|
+
success: false,
|
|
1263
|
+
displayResults: [],
|
|
1264
|
+
diagnostics: [],
|
|
1265
|
+
executionTimeMs: Date.now() - startTime,
|
|
1266
|
+
error: atomicResult.error,
|
|
1267
|
+
};
|
|
1268
|
+
}
|
|
1269
|
+
// Keep parity with step-based execution so referenced atomic skills
|
|
1270
|
+
// can expose their payload via rawResults.root.data.
|
|
1271
|
+
context.results['root'] = atomicResult;
|
|
1272
|
+
if (atomicResult.display) {
|
|
1273
|
+
displayResults.push(this.createDisplayResult('root', skill.meta.display_name, atomicResult, skill.output?.display));
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
else {
|
|
1277
|
+
// Backward compatibility: some "atomic" skills are authored as step-based YAML.
|
|
1278
|
+
// Treat them as composite execution when `sql` is absent but `steps` exist.
|
|
1279
|
+
if (!skill.steps || skill.steps.length === 0) {
|
|
1280
|
+
return {
|
|
1281
|
+
skillId,
|
|
1282
|
+
skillName: skill.meta.display_name,
|
|
1283
|
+
success: false,
|
|
1284
|
+
displayResults: [],
|
|
1285
|
+
diagnostics: [],
|
|
1286
|
+
executionTimeMs: Date.now() - startTime,
|
|
1287
|
+
error: 'No SQL or steps defined for atomic skill',
|
|
1288
|
+
};
|
|
1289
|
+
}
|
|
1290
|
+
const stepExec = await this.executeStepBasedSkill(skill, skillId, context, displayResults, diagnostics, synthesizeData);
|
|
1291
|
+
aiSummary = stepExec.aiSummary;
|
|
1292
|
+
}
|
|
1293
|
+
break;
|
|
1294
|
+
case 'composite':
|
|
1295
|
+
case 'iterator':
|
|
1296
|
+
case 'diagnostic':
|
|
1297
|
+
case 'ai_decision':
|
|
1298
|
+
case 'ai_summary':
|
|
1299
|
+
case 'pipeline':
|
|
1300
|
+
{
|
|
1301
|
+
if (!skill.steps || skill.steps.length === 0) {
|
|
1302
|
+
return {
|
|
1303
|
+
skillId,
|
|
1304
|
+
skillName: skill.meta.display_name,
|
|
1305
|
+
success: false,
|
|
1306
|
+
displayResults: [],
|
|
1307
|
+
diagnostics: [],
|
|
1308
|
+
executionTimeMs: Date.now() - startTime,
|
|
1309
|
+
error: `No steps defined for skill: ${skillId}`,
|
|
1310
|
+
};
|
|
1311
|
+
}
|
|
1312
|
+
const stepExec = await this.executeStepBasedSkill(skill, skillId, context, displayResults, diagnostics, synthesizeData);
|
|
1313
|
+
aiSummary = stepExec.aiSummary;
|
|
1314
|
+
}
|
|
1315
|
+
break;
|
|
1316
|
+
case 'pipeline_definition':
|
|
1317
|
+
case 'comparison':
|
|
1318
|
+
return {
|
|
1319
|
+
skillId,
|
|
1320
|
+
skillName: skill.meta.display_name,
|
|
1321
|
+
success: false,
|
|
1322
|
+
displayResults: [],
|
|
1323
|
+
diagnostics: [],
|
|
1324
|
+
executionTimeMs: Date.now() - startTime,
|
|
1325
|
+
error: `Skill type '${skill.type}' is metadata-only and not executable by the single-trace SkillExecutor: ${skillId}`,
|
|
1326
|
+
};
|
|
1327
|
+
}
|
|
1328
|
+
// If skills provide data-driven synthesize configs, generate a deterministic
|
|
1329
|
+
// "insight summary" DisplayResult so Agents can cite KPIs/insights without LLM.
|
|
1330
|
+
// Best-effort and only triggers for config.role === 'overview'.
|
|
1331
|
+
const synthesizeSummary = this.buildSynthesizeSummaryDisplayResult(synthesizeData);
|
|
1332
|
+
if (synthesizeSummary) {
|
|
1333
|
+
displayResults.unshift(synthesizeSummary);
|
|
1334
|
+
}
|
|
1335
|
+
this.emit({
|
|
1336
|
+
type: 'skill_completed',
|
|
1337
|
+
skillId,
|
|
1338
|
+
data: {
|
|
1339
|
+
success: true,
|
|
1340
|
+
displayResultsCount: displayResults.length,
|
|
1341
|
+
diagnosticsCount: diagnostics.length,
|
|
1342
|
+
},
|
|
1343
|
+
});
|
|
1344
|
+
return {
|
|
1345
|
+
skillId,
|
|
1346
|
+
skillName: skill.meta.display_name,
|
|
1347
|
+
success: true,
|
|
1348
|
+
displayResults,
|
|
1349
|
+
diagnostics,
|
|
1350
|
+
aiSummary,
|
|
1351
|
+
synthesizeData: synthesizeData.length > 0 ? synthesizeData : undefined,
|
|
1352
|
+
rawResults: context.results,
|
|
1353
|
+
executionTimeMs: Date.now() - startTime,
|
|
1354
|
+
};
|
|
1355
|
+
}
|
|
1356
|
+
catch (error) {
|
|
1357
|
+
this.emit({
|
|
1358
|
+
type: 'skill_error',
|
|
1359
|
+
skillId,
|
|
1360
|
+
data: { error: error.message },
|
|
1361
|
+
});
|
|
1362
|
+
return {
|
|
1363
|
+
skillId,
|
|
1364
|
+
skillName: skill.meta.display_name,
|
|
1365
|
+
success: false,
|
|
1366
|
+
displayResults: [],
|
|
1367
|
+
diagnostics: [],
|
|
1368
|
+
executionTimeMs: Date.now() - startTime,
|
|
1369
|
+
error: error.message,
|
|
1370
|
+
};
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
/**
|
|
1374
|
+
* Execute a step-based skill (composite/iterator/diagnostic, and legacy atomic skills without root-level `sql`).
|
|
1375
|
+
* Mutates `context.results` / `context.variables` and appends into `displayResults` / `diagnostics` / `synthesizeData`.
|
|
1376
|
+
*/
|
|
1377
|
+
extractSaveAsValue(stepResult) {
|
|
1378
|
+
// Most steps already store direct row arrays/objects in stepResult.data.
|
|
1379
|
+
if (stepResult.stepType !== 'skill') {
|
|
1380
|
+
return stepResult.data;
|
|
1381
|
+
}
|
|
1382
|
+
const nested = stepResult.data;
|
|
1383
|
+
if (!nested || typeof nested !== 'object') {
|
|
1384
|
+
return stepResult.data;
|
|
1385
|
+
}
|
|
1386
|
+
// Future-proof: if nested result already exposes .data directly, use it.
|
|
1387
|
+
if (Object.prototype.hasOwnProperty.call(nested, 'data')) {
|
|
1388
|
+
return nested.data;
|
|
1389
|
+
}
|
|
1390
|
+
// SkillExecutionResult currently exposes payloads via rawResults.
|
|
1391
|
+
const rawResults = nested.rawResults;
|
|
1392
|
+
if (rawResults && typeof rawResults === 'object') {
|
|
1393
|
+
if (rawResults.root?.data !== undefined) {
|
|
1394
|
+
return rawResults.root.data;
|
|
1395
|
+
}
|
|
1396
|
+
for (const step of Object.values(rawResults)) {
|
|
1397
|
+
if (step && typeof step === 'object' && Object.prototype.hasOwnProperty.call(step, 'data')) {
|
|
1398
|
+
return step.data;
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
return stepResult.data;
|
|
1403
|
+
}
|
|
1404
|
+
async executeStepBasedSkill(skill, skillId, context, displayResults, diagnostics, synthesizeData) {
|
|
1405
|
+
let aiSummary;
|
|
1406
|
+
if (!skill.steps) {
|
|
1407
|
+
return { aiSummary };
|
|
1408
|
+
}
|
|
1409
|
+
for (const step of skill.steps) {
|
|
1410
|
+
const stepResult = await this.executeStep(step, context, skillId);
|
|
1411
|
+
// Collect synthesize-marked data for downstream summarization (execute path parity).
|
|
1412
|
+
// Supports:
|
|
1413
|
+
// 1) synthesize: true (legacy)
|
|
1414
|
+
// 2) synthesize: { role: ..., fields: ... } (data-driven)
|
|
1415
|
+
if ('synthesize' in step && step.synthesize) {
|
|
1416
|
+
const synthesizeValue = step.synthesize;
|
|
1417
|
+
const displayConfig = this.getDisplayConfig(step) || {};
|
|
1418
|
+
let config;
|
|
1419
|
+
if (typeof synthesizeValue === 'object' && synthesizeValue.role) {
|
|
1420
|
+
config = synthesizeValue;
|
|
1421
|
+
}
|
|
1422
|
+
synthesizeData.push({
|
|
1423
|
+
stepId: step.id,
|
|
1424
|
+
stepName: ('name' in step ? step.name : step.id) || step.id,
|
|
1425
|
+
stepType: typeof step.type === 'string' ? step.type : 'skill',
|
|
1426
|
+
layer: displayConfig.layer,
|
|
1427
|
+
data: stepResult.data,
|
|
1428
|
+
success: stepResult.success,
|
|
1429
|
+
config,
|
|
1430
|
+
});
|
|
1431
|
+
}
|
|
1432
|
+
if (stepResult.success) {
|
|
1433
|
+
// 保存结果
|
|
1434
|
+
context.results[step.id] = stepResult;
|
|
1435
|
+
// 如果有 save_as,保存到变量
|
|
1436
|
+
if ('save_as' in step && step.save_as) {
|
|
1437
|
+
context.variables[step.save_as] = this.extractSaveAsValue(stepResult);
|
|
1438
|
+
}
|
|
1439
|
+
// 收集需要展示的结果
|
|
1440
|
+
if (this.shouldDisplay(step)) {
|
|
1441
|
+
// Substitute template variables (e.g., ${startup_id}) in display config
|
|
1442
|
+
const rawDisplay = this.getDisplayConfig(step);
|
|
1443
|
+
const processedDisplay = rawDisplay ? processDisplayConfig(rawDisplay, context) : undefined;
|
|
1444
|
+
displayResults.push(this.createDisplayResult(step.id, ('name' in step ? step.name : step.id) || step.id, stepResult, processedDisplay, ('sql' in step ? step.sql : undefined)));
|
|
1445
|
+
}
|
|
1446
|
+
// Iterator 结果绑回源列表:将 expandableData 绑定到 source step 的 DisplayResult
|
|
1447
|
+
if (step.type === 'iterator' && 'source' in step && step.source) {
|
|
1448
|
+
const sourceName = step.source;
|
|
1449
|
+
// source 引用的是 save_as 名称,需要找到对应的 step.id
|
|
1450
|
+
const sourceStep = skill.steps.find((s) => s.save_as === sourceName || s.id === sourceName);
|
|
1451
|
+
const sourceStepId = sourceStep ? sourceStep.id : sourceName;
|
|
1452
|
+
const sourceDisplayResult = displayResults.find(dr => dr.stepId === sourceStepId);
|
|
1453
|
+
// expandableData 在 DisplayResult.data 中(由 flattenIteratorResults 创建)
|
|
1454
|
+
const iteratorDisplayResult = displayResults.find(dr => dr.stepId === step.id);
|
|
1455
|
+
if (sourceDisplayResult?.data && iteratorDisplayResult?.data?.expandableData) {
|
|
1456
|
+
sourceDisplayResult.data.expandableData = iteratorDisplayResult.data.expandableData;
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
// 收集诊断结果
|
|
1460
|
+
if (step.type === 'diagnostic' && stepResult.data?.diagnostics) {
|
|
1461
|
+
diagnostics.push(...stepResult.data.diagnostics);
|
|
1462
|
+
}
|
|
1463
|
+
// 收集 AI 总结
|
|
1464
|
+
if (step.type === 'ai_summary' && stepResult.data?.summary) {
|
|
1465
|
+
aiSummary = stepResult.data.summary;
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
// Batch-to-expandable binding: bind batch step row data as expandableData for list steps.
|
|
1470
|
+
// This avoids N+1 iterator queries by reusing a single batch SQL result.
|
|
1471
|
+
this.applyExpandableBindSources(skill.steps, context, displayResults);
|
|
1472
|
+
return { aiSummary };
|
|
1473
|
+
}
|
|
1474
|
+
/**
|
|
1475
|
+
* Apply expandableBindSource declarations: for each step that declares an expandableBindSource,
|
|
1476
|
+
* find the batch data in context.variables and bind it as expandableData on the target DisplayResult.
|
|
1477
|
+
*/
|
|
1478
|
+
applyExpandableBindSources(steps, context, displayResults) {
|
|
1479
|
+
for (const step of steps) {
|
|
1480
|
+
const display = this.getDisplayConfig(step);
|
|
1481
|
+
const bindSource = display?.expandableBindSource;
|
|
1482
|
+
if (!bindSource)
|
|
1483
|
+
continue;
|
|
1484
|
+
const sourceData = context.variables[bindSource];
|
|
1485
|
+
const targetDisplayResult = displayResults.find(dr => dr.stepId === step.id);
|
|
1486
|
+
if (!Array.isArray(sourceData) || sourceData.length === 0)
|
|
1487
|
+
continue;
|
|
1488
|
+
if (!targetDisplayResult?.data?.rows?.length || !targetDisplayResult.data.columns?.length)
|
|
1489
|
+
continue;
|
|
1490
|
+
targetDisplayResult.data.expandableData = this.buildExpandableFromBatch(targetDisplayResult.data.rows, targetDisplayResult.data.columns, sourceData);
|
|
1491
|
+
}
|
|
1492
|
+
}
|
|
1493
|
+
/**
|
|
1494
|
+
* Build expandableData by matching batch source rows to target list rows.
|
|
1495
|
+
*
|
|
1496
|
+
* Matching strategy: both datasets are ordered by (session_id, frame_start), so
|
|
1497
|
+
* we match by frame_index when available, falling back to start_ts, then positional index.
|
|
1498
|
+
*
|
|
1499
|
+
* Accepts two data shapes:
|
|
1500
|
+
* - Columnar: targetRows (any[][]) + targetColumns (string[]) — from executeStepBasedSkill DisplayResults
|
|
1501
|
+
* - Object array: targetObjects (Record<string, any>[]) — from executeCompositeSkill StepResults
|
|
1502
|
+
*/
|
|
1503
|
+
buildExpandableFromBatch(targetRows, targetColumns, sourceData, targetObjects) {
|
|
1504
|
+
const isColumnar = targetRows != null && targetColumns != null;
|
|
1505
|
+
const rowCount = isColumnar ? targetRows.length : (targetObjects?.length ?? 0);
|
|
1506
|
+
// Build lookup maps lazily — only construct the map if its matching column exists
|
|
1507
|
+
const frameIndexCol = isColumnar ? targetColumns.indexOf('frame_index') : -1;
|
|
1508
|
+
const hasFrameIndex = isColumnar ? frameIndexCol >= 0 : targetObjects?.some(o => o.frame_index != null);
|
|
1509
|
+
const sessionIdCol = isColumnar ? targetColumns.indexOf('session_id') : -1;
|
|
1510
|
+
const hasSessionId = isColumnar ? sessionIdCol >= 0 : targetObjects?.some(o => o.session_id != null);
|
|
1511
|
+
const processNameCol = isColumnar ? targetColumns.indexOf('process_name') : -1;
|
|
1512
|
+
const startTsCol = isColumnar ? targetColumns.indexOf('start_ts') : -1;
|
|
1513
|
+
const hasStartTs = isColumnar ? startTsCol >= 0 : targetObjects?.some(o => o.start_ts != null);
|
|
1514
|
+
let sourceByFrameIndex;
|
|
1515
|
+
let sourceBySessionKey;
|
|
1516
|
+
let sourceByStartTs;
|
|
1517
|
+
if (hasFrameIndex) {
|
|
1518
|
+
sourceByFrameIndex = new Map();
|
|
1519
|
+
for (const row of sourceData) {
|
|
1520
|
+
if (row.frame_index != null)
|
|
1521
|
+
sourceByFrameIndex.set(Number(row.frame_index), row);
|
|
1522
|
+
}
|
|
1523
|
+
}
|
|
1524
|
+
// Composite key: process_name + session_id (for session-level expandable)
|
|
1525
|
+
if (hasSessionId && !sourceByFrameIndex) {
|
|
1526
|
+
sourceBySessionKey = new Map();
|
|
1527
|
+
for (const row of sourceData) {
|
|
1528
|
+
if (row.session_id != null) {
|
|
1529
|
+
const key = `${row.process_name ?? ''}::${row.session_id}`;
|
|
1530
|
+
sourceBySessionKey.set(key, row);
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1533
|
+
}
|
|
1534
|
+
if (hasStartTs && !sourceByFrameIndex && !sourceBySessionKey) {
|
|
1535
|
+
sourceByStartTs = new Map();
|
|
1536
|
+
for (const row of sourceData) {
|
|
1537
|
+
if (row.start_ts != null)
|
|
1538
|
+
sourceByStartTs.set(String(row.start_ts), row);
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1541
|
+
const expandableData = [];
|
|
1542
|
+
for (let i = 0; i < rowCount; i++) {
|
|
1543
|
+
// Get matching keys without constructing the full item yet
|
|
1544
|
+
let frameIndexVal;
|
|
1545
|
+
let sessionIdVal;
|
|
1546
|
+
let processNameVal;
|
|
1547
|
+
let startTsVal;
|
|
1548
|
+
if (isColumnar) {
|
|
1549
|
+
const row = targetRows[i];
|
|
1550
|
+
if (frameIndexCol >= 0)
|
|
1551
|
+
frameIndexVal = row[frameIndexCol];
|
|
1552
|
+
if (sessionIdCol >= 0)
|
|
1553
|
+
sessionIdVal = row[sessionIdCol];
|
|
1554
|
+
if (processNameCol >= 0)
|
|
1555
|
+
processNameVal = row[processNameCol];
|
|
1556
|
+
if (startTsCol >= 0)
|
|
1557
|
+
startTsVal = row[startTsCol];
|
|
1558
|
+
}
|
|
1559
|
+
else {
|
|
1560
|
+
const obj = targetObjects[i];
|
|
1561
|
+
frameIndexVal = obj.frame_index;
|
|
1562
|
+
sessionIdVal = obj.session_id;
|
|
1563
|
+
processNameVal = obj.process_name;
|
|
1564
|
+
startTsVal = obj.start_ts;
|
|
1565
|
+
}
|
|
1566
|
+
// Find matching source row: frame_index → session_key → start_ts → positional
|
|
1567
|
+
let matched;
|
|
1568
|
+
if (sourceByFrameIndex && frameIndexVal != null) {
|
|
1569
|
+
matched = sourceByFrameIndex.get(Number(frameIndexVal));
|
|
1570
|
+
}
|
|
1571
|
+
if (!matched && sourceBySessionKey && sessionIdVal != null) {
|
|
1572
|
+
const key = `${processNameVal ?? ''}::${sessionIdVal}`;
|
|
1573
|
+
matched = sourceBySessionKey.get(key);
|
|
1574
|
+
}
|
|
1575
|
+
if (!matched && sourceByStartTs && startTsVal != null) {
|
|
1576
|
+
matched = sourceByStartTs.get(String(startTsVal));
|
|
1577
|
+
}
|
|
1578
|
+
if (!matched && i < sourceData.length) {
|
|
1579
|
+
matched = sourceData[i];
|
|
1580
|
+
}
|
|
1581
|
+
if (!matched) {
|
|
1582
|
+
// Push undefined for unmatched rows — front-end checks truthiness per entry
|
|
1583
|
+
expandableData.push(undefined);
|
|
1584
|
+
continue;
|
|
1585
|
+
}
|
|
1586
|
+
// Reconstruct item object only for matched rows
|
|
1587
|
+
let item;
|
|
1588
|
+
if (isColumnar) {
|
|
1589
|
+
item = {};
|
|
1590
|
+
for (let c = 0; c < targetColumns.length; c++) {
|
|
1591
|
+
item[targetColumns[c]] = targetRows[i][c];
|
|
1592
|
+
}
|
|
1593
|
+
}
|
|
1594
|
+
else {
|
|
1595
|
+
item = { ...targetObjects[i] };
|
|
1596
|
+
}
|
|
1597
|
+
expandableData.push({
|
|
1598
|
+
item,
|
|
1599
|
+
result: { success: true, sections: this.groupBatchRowIntoSections(matched) },
|
|
1600
|
+
});
|
|
1601
|
+
}
|
|
1602
|
+
return expandableData;
|
|
1603
|
+
}
|
|
1604
|
+
/**
|
|
1605
|
+
* Group a batch row into named sections for the expandable UI.
|
|
1606
|
+
* Uses a declarative registry for JSON columns + imperative handlers for scalar fields.
|
|
1607
|
+
*/
|
|
1608
|
+
groupBatchRowIntoSections(row) {
|
|
1609
|
+
const sections = {};
|
|
1610
|
+
// ── Declarative JSON column registry ─────────────────────────────────
|
|
1611
|
+
// Each entry maps a JSON column name → { key, title, transform }.
|
|
1612
|
+
// The transform receives the parsed array and returns formatted data rows.
|
|
1613
|
+
const jsonSectionRegistry = [
|
|
1614
|
+
// --- Per-frame sections (from batch_frame_root_cause) ---
|
|
1615
|
+
{
|
|
1616
|
+
column: 'cpu_freq_clusters_json',
|
|
1617
|
+
key: 'CPU 频率',
|
|
1618
|
+
title: 'CPU 频率 (Prime / Big / Little)',
|
|
1619
|
+
transform: (items) => items.map((c) => ({
|
|
1620
|
+
核心类型: c.core_type,
|
|
1621
|
+
平均频率: (c.avg_mhz / 1000).toFixed(2) + 'GHz',
|
|
1622
|
+
最高频率: (c.max_mhz / 1000).toFixed(2) + 'GHz',
|
|
1623
|
+
最低频率: (c.min_mhz / 1000).toFixed(2) + 'GHz',
|
|
1624
|
+
})),
|
|
1625
|
+
},
|
|
1626
|
+
{
|
|
1627
|
+
column: 'freq_timeline_json',
|
|
1628
|
+
key: 'CPU 频率变化',
|
|
1629
|
+
title: '各 CPU 频率变化时间线',
|
|
1630
|
+
transform: (items) => items.map((e) => ({
|
|
1631
|
+
相对时间: e.relative_ms + 'ms',
|
|
1632
|
+
CPU: e.cpu,
|
|
1633
|
+
核心类型: e.core_type,
|
|
1634
|
+
频率: e.freq_ghz + 'GHz',
|
|
1635
|
+
变化: e.change === 'up' ? '↑升频' : e.change === 'down' ? '↓降频' : '初始',
|
|
1636
|
+
})),
|
|
1637
|
+
},
|
|
1638
|
+
{
|
|
1639
|
+
column: 'main_slices_json',
|
|
1640
|
+
key: '主线程耗时操作',
|
|
1641
|
+
title: '主线程耗时操作 (Top 8)',
|
|
1642
|
+
transform: (items) => items.map((s) => ({
|
|
1643
|
+
操作: s.name, 总耗时: s.total_ms + 'ms', 次数: s.count, 最大耗时: s.max_ms + 'ms',
|
|
1644
|
+
})),
|
|
1645
|
+
},
|
|
1646
|
+
{
|
|
1647
|
+
column: 'render_slices_json',
|
|
1648
|
+
key: 'RenderThread 耗时操作',
|
|
1649
|
+
title: 'RenderThread 耗时操作 (Top 8)',
|
|
1650
|
+
transform: (items) => items.map((s) => ({
|
|
1651
|
+
操作: s.name, 总耗时: s.total_ms + 'ms', 次数: s.count, 最大耗时: s.max_ms + 'ms',
|
|
1652
|
+
})),
|
|
1653
|
+
},
|
|
1654
|
+
{
|
|
1655
|
+
column: 'binder_calls_json',
|
|
1656
|
+
key: 'Binder 调用详情',
|
|
1657
|
+
title: 'Binder 调用(按耗时降序)',
|
|
1658
|
+
transform: (items) => items.map((b) => ({
|
|
1659
|
+
目标进程: b.server, 调用次数: b.count, 总耗时: b.dur_ms + 'ms', 最大耗时: b.max_ms + 'ms',
|
|
1660
|
+
})),
|
|
1661
|
+
},
|
|
1662
|
+
{
|
|
1663
|
+
column: 'gc_events_json',
|
|
1664
|
+
key: 'GC 事件详情',
|
|
1665
|
+
title: 'GC 事件(按类型聚合)',
|
|
1666
|
+
transform: (items) => items.map((g) => ({
|
|
1667
|
+
类型: g.gc_type, 次数: g.count, 总耗时: g.total_ms + 'ms', 帧重叠: g.overlap_ms + 'ms',
|
|
1668
|
+
})),
|
|
1669
|
+
},
|
|
1670
|
+
{
|
|
1671
|
+
column: 'lock_contention_json',
|
|
1672
|
+
key: '锁竞争详情',
|
|
1673
|
+
title: '锁竞争(按等待时间降序)',
|
|
1674
|
+
transform: (items) => items.map((l) => ({
|
|
1675
|
+
阻塞方法: l.method, 阻塞线程: l.blocker, 等待: l.wait_ms + 'ms',
|
|
1676
|
+
主线程阻塞: l.main_blocked ? '是' : '否',
|
|
1677
|
+
})),
|
|
1678
|
+
},
|
|
1679
|
+
// --- Per-session sections (from session_stats_batch) ---
|
|
1680
|
+
{
|
|
1681
|
+
column: 'quadrant_json',
|
|
1682
|
+
key: '四象限分布',
|
|
1683
|
+
title: '滑动区间四象限分布 (Q1大核运行/Q2小核运行/Q3调度等待/Q4a IO阻塞/Q4b 休眠)',
|
|
1684
|
+
transform: (items) => items.map((q) => ({
|
|
1685
|
+
线程: q.thread,
|
|
1686
|
+
'Q1 大核%': q.q1_big_pct + '%',
|
|
1687
|
+
'Q2 小核%': q.q2_little_pct + '%',
|
|
1688
|
+
'Q3 调度%': q.q3_runnable_pct + '%',
|
|
1689
|
+
'Q4a IO%': q.q4a_io_pct + '%',
|
|
1690
|
+
'Q4b 休眠%': q.q4b_sleep_pct + '%',
|
|
1691
|
+
'总时间': q.total_ms + 'ms',
|
|
1692
|
+
})),
|
|
1693
|
+
},
|
|
1694
|
+
{
|
|
1695
|
+
column: 'cpu_freq_json',
|
|
1696
|
+
key: 'CPU 频率统计',
|
|
1697
|
+
title: '滑动区间 CPU 频率',
|
|
1698
|
+
transform: (items) => items.map((f) => ({
|
|
1699
|
+
核心类型: f.core_type,
|
|
1700
|
+
核心数: f.num_cores,
|
|
1701
|
+
'均频(MHz)': f.avg_freq_mhz,
|
|
1702
|
+
'最高频(MHz)': f.max_freq_mhz,
|
|
1703
|
+
'最低频(MHz)': f.min_freq_mhz,
|
|
1704
|
+
})),
|
|
1705
|
+
},
|
|
1706
|
+
{
|
|
1707
|
+
column: 'core_affinity_json',
|
|
1708
|
+
key: '大小核分布',
|
|
1709
|
+
title: '滑动区间关键线程大小核分布',
|
|
1710
|
+
transform: (items) => items.map((a) => ({
|
|
1711
|
+
线程: a.thread_name,
|
|
1712
|
+
核心类型: a.core_type,
|
|
1713
|
+
'运行时间(ms)': a.run_ms,
|
|
1714
|
+
'占比%': a.pct + '%',
|
|
1715
|
+
})),
|
|
1716
|
+
},
|
|
1717
|
+
];
|
|
1718
|
+
// ── Scalar field sections (per-frame only) ───────────────────────────
|
|
1719
|
+
// Section: Root cause diagnosis
|
|
1720
|
+
const diagnosisFields = ['reason_code', 'primary_cause', 'confidence', 'top_slice_name', 'top_slice_ms'];
|
|
1721
|
+
const diagnosisData = {};
|
|
1722
|
+
for (const f of diagnosisFields) {
|
|
1723
|
+
if (row[f] != null)
|
|
1724
|
+
diagnosisData[f] = row[f];
|
|
1725
|
+
}
|
|
1726
|
+
if (Object.keys(diagnosisData).length > 0) {
|
|
1727
|
+
sections['根因诊断'] = { title: '根因诊断', data: [diagnosisData] };
|
|
1728
|
+
}
|
|
1729
|
+
// Section: MainThread quadrant (scalar fields)
|
|
1730
|
+
const mainFields = ['main_q1_pct', 'main_q2_pct', 'main_q3_pct', 'main_q4a_pct', 'main_q4b_pct'];
|
|
1731
|
+
const mainData = {};
|
|
1732
|
+
let hasMainData = false;
|
|
1733
|
+
for (const f of mainFields) {
|
|
1734
|
+
if (row[f] != null) {
|
|
1735
|
+
mainData[f.replace('main_', '').replace('_pct', '%')] = row[f] + '%';
|
|
1736
|
+
hasMainData = true;
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
if (hasMainData) {
|
|
1740
|
+
sections['主线程四象限'] = { title: '主线程四象限 (Q1大核运行/Q2小核运行/Q3调度等待/Q4a IO阻塞/Q4b 锁等待)', data: [mainData] };
|
|
1741
|
+
}
|
|
1742
|
+
// Section: RenderThread quadrant (scalar fields)
|
|
1743
|
+
const renderFields = ['render_q1_pct', 'render_q2_pct', 'render_q3_pct', 'render_q4a_pct', 'render_q4b_pct'];
|
|
1744
|
+
const renderData = {};
|
|
1745
|
+
let hasRenderData = false;
|
|
1746
|
+
for (const f of renderFields) {
|
|
1747
|
+
if (row[f] != null) {
|
|
1748
|
+
renderData[f.replace('render_', 'RT_').replace('_pct', '%')] = row[f] + '%';
|
|
1749
|
+
hasRenderData = true;
|
|
1750
|
+
}
|
|
1751
|
+
}
|
|
1752
|
+
if (hasRenderData) {
|
|
1753
|
+
sections['渲染线程四象限'] = { title: '渲染线程四象限 (Q1大核运行/Q2小核运行/Q3调度等待/Q4a IO阻塞/Q4b 锁等待)', data: [renderData] };
|
|
1754
|
+
}
|
|
1755
|
+
// Section: CPU frequency fallback (scalar, when cpu_freq_clusters_json is absent)
|
|
1756
|
+
if (!row['cpu_freq_clusters_json'] || row['cpu_freq_clusters_json'] === '[]') {
|
|
1757
|
+
const cpuData = {};
|
|
1758
|
+
let hasCpuData = false;
|
|
1759
|
+
for (const f of ['big_avg_freq_mhz', 'big_max_freq_mhz', 'ramp_ms']) {
|
|
1760
|
+
if (row[f] != null) {
|
|
1761
|
+
cpuData[f] = row[f];
|
|
1762
|
+
hasCpuData = true;
|
|
1763
|
+
}
|
|
1764
|
+
}
|
|
1765
|
+
if (hasCpuData) {
|
|
1766
|
+
sections['CPU 频率'] = { title: 'CPU 频率', data: [cpuData] };
|
|
1767
|
+
}
|
|
1768
|
+
}
|
|
1769
|
+
// Section: Top Slice CPU mix
|
|
1770
|
+
const cpuMixFields = ['top_slice_little_pct', 'top_slice_big_pct', 'top_slice_runnable_pct'];
|
|
1771
|
+
const cpuMixData = {};
|
|
1772
|
+
let hasCpuMix = false;
|
|
1773
|
+
for (const f of cpuMixFields) {
|
|
1774
|
+
if (row[f] != null && Number(row[f]) > 0) {
|
|
1775
|
+
cpuMixData[f.replace('top_slice_', '')] = row[f] + '%';
|
|
1776
|
+
hasCpuMix = true;
|
|
1777
|
+
}
|
|
1778
|
+
}
|
|
1779
|
+
if (hasCpuMix) {
|
|
1780
|
+
sections['关键操作 CPU 分布'] = { title: '关键操作 CPU 分布 (大核/小核/Runnable)', data: [cpuMixData] };
|
|
1781
|
+
}
|
|
1782
|
+
// Section: GPU / Shader
|
|
1783
|
+
const gpuFields = ['gpu_fence_ms', 'gpu_fence_total_ms', 'shader_count', 'shader_ms'];
|
|
1784
|
+
const gpuData = {};
|
|
1785
|
+
let hasGpu = false;
|
|
1786
|
+
for (const f of gpuFields) {
|
|
1787
|
+
if (row[f] != null && Number(row[f]) > 0) {
|
|
1788
|
+
gpuData[f] = row[f];
|
|
1789
|
+
hasGpu = true;
|
|
1790
|
+
}
|
|
1791
|
+
}
|
|
1792
|
+
if (hasGpu) {
|
|
1793
|
+
sections['GPU / Shader'] = { title: 'GPU / Shader', data: [gpuData] };
|
|
1794
|
+
}
|
|
1795
|
+
// Section: Interference factors (Binder + GC)
|
|
1796
|
+
const interferenceData = {};
|
|
1797
|
+
let hasInterference = false;
|
|
1798
|
+
if (row['binder_overlap_ms'] != null && Number(row['binder_overlap_ms']) > 0) {
|
|
1799
|
+
interferenceData['binder_overlap_ms'] = row['binder_overlap_ms'];
|
|
1800
|
+
hasInterference = true;
|
|
1801
|
+
}
|
|
1802
|
+
if (row['gc_overlap_ms'] != null && Number(row['gc_overlap_ms']) > 0) {
|
|
1803
|
+
interferenceData['gc_overlap_ms'] = row['gc_overlap_ms'];
|
|
1804
|
+
hasInterference = true;
|
|
1805
|
+
}
|
|
1806
|
+
if (row['gc_count'] != null && Number(row['gc_count']) > 0) {
|
|
1807
|
+
interferenceData['gc_count'] = row['gc_count'];
|
|
1808
|
+
hasInterference = true;
|
|
1809
|
+
}
|
|
1810
|
+
if (hasInterference) {
|
|
1811
|
+
sections['干扰因素'] = { title: '干扰因素 (Binder/GC)', data: [interferenceData] };
|
|
1812
|
+
}
|
|
1813
|
+
// Section: Frame budget reference
|
|
1814
|
+
if (row['frame_budget_ms'] != null) {
|
|
1815
|
+
sections['帧预算'] = { title: '帧预算参考', data: [{ frame_budget_ms: row['frame_budget_ms'] + 'ms' }] };
|
|
1816
|
+
}
|
|
1817
|
+
// ── Apply JSON column registry ───────────────────────────────────────
|
|
1818
|
+
for (const entry of jsonSectionRegistry) {
|
|
1819
|
+
const items = this.parseJsonColumn(row, entry.column);
|
|
1820
|
+
if (items.length > 0) {
|
|
1821
|
+
sections[entry.key] = { title: entry.title, data: entry.transform(items) };
|
|
1822
|
+
}
|
|
1823
|
+
}
|
|
1824
|
+
return sections;
|
|
1825
|
+
}
|
|
1826
|
+
/** Safely parse a JSON string column from a batch row. */
|
|
1827
|
+
parseJsonColumn(row, columnName) {
|
|
1828
|
+
const raw = row[columnName];
|
|
1829
|
+
if (!raw || raw === '[]')
|
|
1830
|
+
return [];
|
|
1831
|
+
try {
|
|
1832
|
+
const parsed = typeof raw === 'string' ? JSON.parse(raw) : raw;
|
|
1833
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
1834
|
+
}
|
|
1835
|
+
catch {
|
|
1836
|
+
return [];
|
|
1837
|
+
}
|
|
1838
|
+
}
|
|
1839
|
+
/**
|
|
1840
|
+
* Execute composite skill and return layered results
|
|
1841
|
+
* This is an alternative execution path that organizes output by layers (overview/list/session/deep)
|
|
1842
|
+
*/
|
|
1843
|
+
async executeCompositeSkill(skill, inputs, context) {
|
|
1844
|
+
const startTime = Date.now();
|
|
1845
|
+
// Validate input
|
|
1846
|
+
if (!skill) {
|
|
1847
|
+
throw new Error('Skill definition is required');
|
|
1848
|
+
}
|
|
1849
|
+
if (!skill.steps || skill.steps.length === 0) {
|
|
1850
|
+
return {
|
|
1851
|
+
layers: {
|
|
1852
|
+
overview: {}, list: {}, session: {}, deep: {}, diagnosis: {},
|
|
1853
|
+
},
|
|
1854
|
+
defaultExpanded: ['overview', 'list'],
|
|
1855
|
+
stepResults: [],
|
|
1856
|
+
metadata: {
|
|
1857
|
+
skillName: skill.name,
|
|
1858
|
+
version: skill.version || '1.0.0',
|
|
1859
|
+
executedAt: new Date().toISOString()
|
|
1860
|
+
}
|
|
1861
|
+
};
|
|
1862
|
+
}
|
|
1863
|
+
const traceId = context.traceId || '';
|
|
1864
|
+
const gate = await this.applyIdentityGate(skill, traceId, inputs, context.inherited || {});
|
|
1865
|
+
if (!gate.allowed) {
|
|
1866
|
+
throw new Error(gate.error || `Process identity gate blocked skill: ${skill.name}`);
|
|
1867
|
+
}
|
|
1868
|
+
const prerequisiteModules = this.resolvePrerequisiteModules(skill.prerequisites?.modules);
|
|
1869
|
+
const validated = (0, skillValidator_1.validateSkillInputs)(skill.name, skill.inputs, gate.params);
|
|
1870
|
+
for (const w of validated.warnings) {
|
|
1871
|
+
logger_1.default.warn('SkillExecutor', `[${skill.name}] ${w.paramName}: ${w.message}`);
|
|
1872
|
+
}
|
|
1873
|
+
if (validated.errors.length > 0) {
|
|
1874
|
+
const msg = validated.errors.map(e => `${e.paramName}: ${e.message}`).join('; ');
|
|
1875
|
+
logger_1.default.error('SkillExecutor', `[${skill.name}] Input validation failed: ${msg}`);
|
|
1876
|
+
throw new Error(`Input validation failed: ${msg}`);
|
|
1877
|
+
}
|
|
1878
|
+
// Create execution context
|
|
1879
|
+
const execContext = {
|
|
1880
|
+
traceId,
|
|
1881
|
+
params: validated.params,
|
|
1882
|
+
inherited: gate.inherited,
|
|
1883
|
+
results: {},
|
|
1884
|
+
variables: {},
|
|
1885
|
+
moduleIncludes: prerequisiteModules,
|
|
1886
|
+
};
|
|
1887
|
+
if (execContext.traceId && prerequisiteModules.length > 0) {
|
|
1888
|
+
execContext.moduleIncludes = await this.resolveAvailableModules(execContext.traceId, prerequisiteModules);
|
|
1889
|
+
}
|
|
1890
|
+
// Execute all steps and collect synthesize-marked data
|
|
1891
|
+
const stepResults = [];
|
|
1892
|
+
const synthesizeData = [];
|
|
1893
|
+
if (skill.steps) {
|
|
1894
|
+
for (let i = 0; i < skill.steps.length; i++) {
|
|
1895
|
+
const step = skill.steps[i];
|
|
1896
|
+
const stepResult = await this.executeStep(step, execContext, skill.name);
|
|
1897
|
+
// Save result to context
|
|
1898
|
+
if (stepResult.success) {
|
|
1899
|
+
execContext.results[step.id] = stepResult;
|
|
1900
|
+
// Save to variables if save_as is specified
|
|
1901
|
+
if ('save_as' in step && step.save_as) {
|
|
1902
|
+
execContext.variables[step.save_as] = this.extractSaveAsValue(stepResult);
|
|
1903
|
+
}
|
|
1904
|
+
}
|
|
1905
|
+
// IMPORTANT: Add display config from step definition to stepResult
|
|
1906
|
+
// This is needed for organizeByLayer to correctly place results in layers
|
|
1907
|
+
// Process display config with template variable substitution (e.g., ${frame_id})
|
|
1908
|
+
if ('display' in step && typeof step.display === 'object') {
|
|
1909
|
+
stepResult.display = processDisplayConfig(step.display, execContext);
|
|
1910
|
+
}
|
|
1911
|
+
// 收集标记为 synthesize 的步骤数据
|
|
1912
|
+
// 支持两种格式:
|
|
1913
|
+
// 1. synthesize: true (旧格式,向后兼容)
|
|
1914
|
+
// 2. synthesize: { role: ..., fields: ... } (新格式,数据驱动)
|
|
1915
|
+
if ('synthesize' in step && step.synthesize) {
|
|
1916
|
+
const synthesizeValue = step.synthesize;
|
|
1917
|
+
const displayConfig = step.display && typeof step.display === 'object' ? step.display : {};
|
|
1918
|
+
// 解析 synthesize 配置
|
|
1919
|
+
let config;
|
|
1920
|
+
if (typeof synthesizeValue === 'object' && synthesizeValue.role) {
|
|
1921
|
+
// 新格式:完整的配置对象
|
|
1922
|
+
config = synthesizeValue;
|
|
1923
|
+
}
|
|
1924
|
+
// 旧格式 (synthesize: true) 不设置 config,由 analysisWorker 使用默认处理
|
|
1925
|
+
synthesizeData.push({
|
|
1926
|
+
stepId: step.id,
|
|
1927
|
+
stepName: ('name' in step ? step.name : step.id) || step.id,
|
|
1928
|
+
stepType: typeof step.type === 'string' ? step.type : 'skill',
|
|
1929
|
+
layer: displayConfig.layer,
|
|
1930
|
+
data: stepResult.data,
|
|
1931
|
+
success: stepResult.success,
|
|
1932
|
+
config, // 包含 YAML 中定义的配置(如果有)
|
|
1933
|
+
});
|
|
1934
|
+
}
|
|
1935
|
+
stepResults.push(stepResult);
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
// Iterator 结果绑回源列表:将 expandableData 绑定到 source step 的 StepResult
|
|
1939
|
+
// 这样 convertDisplayResultsToSections 可以在源步骤的 data 上找到 expandableData
|
|
1940
|
+
if (skill.steps) {
|
|
1941
|
+
for (let i = 0; i < skill.steps.length; i++) {
|
|
1942
|
+
const step = skill.steps[i];
|
|
1943
|
+
if (step.type === 'iterator' && 'source' in step && step.source) {
|
|
1944
|
+
const sourceName = step.source;
|
|
1945
|
+
// source 引用的是 save_as 名称,需要找到对应的 step.id
|
|
1946
|
+
const sourceStep = skill.steps.find((s) => s.save_as === sourceName || s.id === sourceName);
|
|
1947
|
+
const sourceStepId = sourceStep ? sourceStep.id : sourceName;
|
|
1948
|
+
const sourceResult = stepResults.find(sr => sr.stepId === sourceStepId);
|
|
1949
|
+
const iteratorResult = stepResults[i];
|
|
1950
|
+
// 在 executeCompositeSkill 路径中,iterator 的 data 是原始 [{itemIndex, item, result}, ...]
|
|
1951
|
+
// 需要将其转换为 expandableData 格式
|
|
1952
|
+
if (sourceResult?.data && iteratorResult?.success && Array.isArray(iteratorResult.data)) {
|
|
1953
|
+
const expandableData = iteratorResult.data.map((iterItem) => ({
|
|
1954
|
+
item: iterItem.item,
|
|
1955
|
+
result: {
|
|
1956
|
+
success: iterItem.result?.success ?? false,
|
|
1957
|
+
sections: this.convertDisplayResultsToSections(iterItem.result?.displayResults || []),
|
|
1958
|
+
error: iterItem.result?.error,
|
|
1959
|
+
},
|
|
1960
|
+
}));
|
|
1961
|
+
// 直接在 data 上挂载 expandableData(JS 数组/对象都支持额外属性)
|
|
1962
|
+
sourceResult.data.expandableData = expandableData;
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
1965
|
+
}
|
|
1966
|
+
}
|
|
1967
|
+
// Batch-to-expandable binding for executeCompositeSkill path (object-array variant)
|
|
1968
|
+
if (skill.steps) {
|
|
1969
|
+
for (const step of skill.steps) {
|
|
1970
|
+
const display = step.display && typeof step.display === 'object' ? step.display : undefined;
|
|
1971
|
+
const bindSource = display?.expandableBindSource;
|
|
1972
|
+
if (!bindSource)
|
|
1973
|
+
continue;
|
|
1974
|
+
const sourceData = execContext.variables[bindSource];
|
|
1975
|
+
const targetResult = stepResults.find(sr => sr.stepId === step.id);
|
|
1976
|
+
if (!Array.isArray(sourceData) || sourceData.length === 0)
|
|
1977
|
+
continue;
|
|
1978
|
+
if (!targetResult?.data || !Array.isArray(targetResult.data) || targetResult.data.length === 0)
|
|
1979
|
+
continue;
|
|
1980
|
+
if (typeof targetResult.data[0] !== 'object' || targetResult.data[0] === null)
|
|
1981
|
+
continue;
|
|
1982
|
+
const expandableData = this.buildExpandableFromBatch(null, null, sourceData, targetResult.data);
|
|
1983
|
+
targetResult.data.expandableData = expandableData;
|
|
1984
|
+
}
|
|
1985
|
+
}
|
|
1986
|
+
// Return layered structure
|
|
1987
|
+
try {
|
|
1988
|
+
const layers = organizeByLayer(stepResults);
|
|
1989
|
+
const result = {
|
|
1990
|
+
layers,
|
|
1991
|
+
defaultExpanded: ['overview', 'list'],
|
|
1992
|
+
metadata: {
|
|
1993
|
+
skillName: skill.name,
|
|
1994
|
+
version: skill.version || '1.0.0',
|
|
1995
|
+
executedAt: new Date().toISOString()
|
|
1996
|
+
},
|
|
1997
|
+
stepResults,
|
|
1998
|
+
// 添加收集的 synthesize 数据
|
|
1999
|
+
synthesizeData: synthesizeData.length > 0 ? synthesizeData : undefined,
|
|
2000
|
+
};
|
|
2001
|
+
// synthesizeData collected for final summary (debug logging removed)
|
|
2002
|
+
return result;
|
|
2003
|
+
}
|
|
2004
|
+
catch (error) {
|
|
2005
|
+
console.error('[executeCompositeSkill] organizeByLayer failed:', error);
|
|
2006
|
+
throw error;
|
|
2007
|
+
}
|
|
2008
|
+
}
|
|
2009
|
+
/**
|
|
2010
|
+
* 执行原子 skill(单个 SQL)
|
|
2011
|
+
*/
|
|
2012
|
+
async executeAtomicSkill(skill, context) {
|
|
2013
|
+
const startTime = Date.now();
|
|
2014
|
+
if (!skill.sql) {
|
|
2015
|
+
return {
|
|
2016
|
+
stepId: 'root',
|
|
2017
|
+
stepType: 'atomic',
|
|
2018
|
+
success: false,
|
|
2019
|
+
error: 'No SQL defined for atomic skill',
|
|
2020
|
+
executionTimeMs: Date.now() - startTime,
|
|
2021
|
+
};
|
|
2022
|
+
}
|
|
2023
|
+
const sql = this.buildSqlWithModuleIncludes(substituteVariables(skill.sql, context), context);
|
|
2024
|
+
try {
|
|
2025
|
+
const result = await this.traceProcessor.query(context.traceId, sql);
|
|
2026
|
+
if (result.error) {
|
|
2027
|
+
return {
|
|
2028
|
+
stepId: 'root',
|
|
2029
|
+
stepType: 'atomic',
|
|
2030
|
+
success: false,
|
|
2031
|
+
error: result.error,
|
|
2032
|
+
executionTimeMs: Date.now() - startTime,
|
|
2033
|
+
};
|
|
2034
|
+
}
|
|
2035
|
+
return {
|
|
2036
|
+
stepId: 'root',
|
|
2037
|
+
stepType: 'atomic',
|
|
2038
|
+
success: true,
|
|
2039
|
+
data: this.rowsToObjects(result.columns, result.rows),
|
|
2040
|
+
executionTimeMs: Date.now() - startTime,
|
|
2041
|
+
display: skill.output?.display ? processDisplayConfig(skill.output.display, context) : undefined,
|
|
2042
|
+
};
|
|
2043
|
+
}
|
|
2044
|
+
catch (error) {
|
|
2045
|
+
return {
|
|
2046
|
+
stepId: 'root',
|
|
2047
|
+
stepType: 'atomic',
|
|
2048
|
+
success: false,
|
|
2049
|
+
error: error.message,
|
|
2050
|
+
executionTimeMs: Date.now() - startTime,
|
|
2051
|
+
};
|
|
2052
|
+
}
|
|
2053
|
+
}
|
|
2054
|
+
/**
|
|
2055
|
+
* 执行单个步骤
|
|
2056
|
+
*/
|
|
2057
|
+
async executeStep(step, context, parentSkillId) {
|
|
2058
|
+
const startTime = Date.now();
|
|
2059
|
+
// 检查步骤的条件限制
|
|
2060
|
+
if ('condition' in step && typeof step.condition === 'string') {
|
|
2061
|
+
const conditionStr = step.condition;
|
|
2062
|
+
const conditionResult = ExpressionEvaluator.evaluateCondition(conditionStr, context);
|
|
2063
|
+
if (!conditionResult) {
|
|
2064
|
+
const isOptional = Boolean(step.optional);
|
|
2065
|
+
this.emit({
|
|
2066
|
+
type: 'step_completed',
|
|
2067
|
+
skillId: parentSkillId,
|
|
2068
|
+
stepId: step.id,
|
|
2069
|
+
data: { skipped: true, reason: 'condition_not_met', optional: isOptional },
|
|
2070
|
+
});
|
|
2071
|
+
return {
|
|
2072
|
+
stepId: step.id,
|
|
2073
|
+
stepType: step.type,
|
|
2074
|
+
success: isOptional,
|
|
2075
|
+
data: isOptional ? [] : undefined,
|
|
2076
|
+
error: isOptional ? undefined : 'Condition not met',
|
|
2077
|
+
executionTimeMs: Date.now() - startTime,
|
|
2078
|
+
};
|
|
2079
|
+
}
|
|
2080
|
+
}
|
|
2081
|
+
this.emit({
|
|
2082
|
+
type: 'step_started',
|
|
2083
|
+
skillId: parentSkillId,
|
|
2084
|
+
stepId: step.id,
|
|
2085
|
+
data: { stepType: step.type },
|
|
2086
|
+
});
|
|
2087
|
+
let result;
|
|
2088
|
+
try {
|
|
2089
|
+
switch (step.type) {
|
|
2090
|
+
case 'atomic':
|
|
2091
|
+
result = await this.executeAtomicStep(step, context);
|
|
2092
|
+
break;
|
|
2093
|
+
case 'iterator':
|
|
2094
|
+
result = await this.executeIteratorStep(step, context, parentSkillId);
|
|
2095
|
+
break;
|
|
2096
|
+
case 'parallel':
|
|
2097
|
+
result = await this.executeParallelStep(step, context, parentSkillId);
|
|
2098
|
+
break;
|
|
2099
|
+
case 'diagnostic':
|
|
2100
|
+
result = await this.executeDiagnosticStep(step, context);
|
|
2101
|
+
break;
|
|
2102
|
+
case 'ai_decision':
|
|
2103
|
+
result = await this.executeAIDecisionStep(step, context);
|
|
2104
|
+
break;
|
|
2105
|
+
case 'ai_summary':
|
|
2106
|
+
result = await this.executeAISummaryStep(step, context);
|
|
2107
|
+
break;
|
|
2108
|
+
case 'conditional':
|
|
2109
|
+
result = await this.executeConditionalStep(step, context, parentSkillId);
|
|
2110
|
+
break;
|
|
2111
|
+
case 'pipeline':
|
|
2112
|
+
result = await this.executePipelineStep(step, context);
|
|
2113
|
+
break;
|
|
2114
|
+
default:
|
|
2115
|
+
// 默认作为 skill 引用处理
|
|
2116
|
+
const unknownStep = step;
|
|
2117
|
+
if ('skill' in unknownStep) {
|
|
2118
|
+
result = await this.executeSkillRefStep(unknownStep, context);
|
|
2119
|
+
}
|
|
2120
|
+
else {
|
|
2121
|
+
result = {
|
|
2122
|
+
stepId: unknownStep.id,
|
|
2123
|
+
stepType: 'atomic',
|
|
2124
|
+
success: false,
|
|
2125
|
+
error: `Unknown step type: ${unknownStep.type}`,
|
|
2126
|
+
executionTimeMs: Date.now() - startTime,
|
|
2127
|
+
};
|
|
2128
|
+
}
|
|
2129
|
+
}
|
|
2130
|
+
}
|
|
2131
|
+
catch (error) {
|
|
2132
|
+
const failedStep = step;
|
|
2133
|
+
result = {
|
|
2134
|
+
stepId: failedStep.id,
|
|
2135
|
+
stepType: failedStep.type || 'skill',
|
|
2136
|
+
success: false,
|
|
2137
|
+
error: error.message,
|
|
2138
|
+
executionTimeMs: Date.now() - startTime,
|
|
2139
|
+
};
|
|
2140
|
+
}
|
|
2141
|
+
this.emit({
|
|
2142
|
+
type: 'step_completed',
|
|
2143
|
+
skillId: parentSkillId,
|
|
2144
|
+
stepId: step.id,
|
|
2145
|
+
data: { success: result.success, error: result.error },
|
|
2146
|
+
});
|
|
2147
|
+
return result;
|
|
2148
|
+
}
|
|
2149
|
+
/**
|
|
2150
|
+
* 执行原子步骤
|
|
2151
|
+
*/
|
|
2152
|
+
async executeAtomicStep(step, context) {
|
|
2153
|
+
const startTime = Date.now();
|
|
2154
|
+
let substitutedSql = substituteVariables(step.sql, context);
|
|
2155
|
+
// Inject SQL fragments if declared on this step
|
|
2156
|
+
if (step.sql_fragments?.length) {
|
|
2157
|
+
substitutedSql = this.injectSqlFragments(substitutedSql, step.sql_fragments, context);
|
|
2158
|
+
}
|
|
2159
|
+
const sql = this.buildSqlWithModuleIncludes(substitutedSql, context);
|
|
2160
|
+
try {
|
|
2161
|
+
const result = await this.traceProcessor.query(context.traceId, sql);
|
|
2162
|
+
if (result.error) {
|
|
2163
|
+
if (step.optional) {
|
|
2164
|
+
return {
|
|
2165
|
+
stepId: step.id,
|
|
2166
|
+
stepType: 'atomic',
|
|
2167
|
+
success: true,
|
|
2168
|
+
data: [],
|
|
2169
|
+
executionTimeMs: Date.now() - startTime,
|
|
2170
|
+
};
|
|
2171
|
+
}
|
|
2172
|
+
return {
|
|
2173
|
+
stepId: step.id,
|
|
2174
|
+
stepType: 'atomic',
|
|
2175
|
+
success: false,
|
|
2176
|
+
error: result.error,
|
|
2177
|
+
executionTimeMs: Date.now() - startTime,
|
|
2178
|
+
};
|
|
2179
|
+
}
|
|
2180
|
+
const data = this.rowsToObjects(result.columns, result.rows);
|
|
2181
|
+
return {
|
|
2182
|
+
stepId: step.id,
|
|
2183
|
+
stepType: 'atomic',
|
|
2184
|
+
success: true,
|
|
2185
|
+
data,
|
|
2186
|
+
executionTimeMs: Date.now() - startTime,
|
|
2187
|
+
};
|
|
2188
|
+
}
|
|
2189
|
+
catch (error) {
|
|
2190
|
+
if (step.optional) {
|
|
2191
|
+
return {
|
|
2192
|
+
stepId: step.id,
|
|
2193
|
+
stepType: 'atomic',
|
|
2194
|
+
success: true,
|
|
2195
|
+
data: [],
|
|
2196
|
+
executionTimeMs: Date.now() - startTime,
|
|
2197
|
+
};
|
|
2198
|
+
}
|
|
2199
|
+
throw error;
|
|
2200
|
+
}
|
|
2201
|
+
}
|
|
2202
|
+
/**
|
|
2203
|
+
* 检查 prerequisites 条件 (required_tables, optional_tables)
|
|
2204
|
+
*/
|
|
2205
|
+
async checkPrerequisites(skill, traceId) {
|
|
2206
|
+
if (!skill.prerequisites)
|
|
2207
|
+
return { success: true };
|
|
2208
|
+
const { required_tables } = skill.prerequisites;
|
|
2209
|
+
if (!required_tables || required_tables.length === 0) {
|
|
2210
|
+
return { success: true };
|
|
2211
|
+
}
|
|
2212
|
+
try {
|
|
2213
|
+
// Perfetto trace_processor uses virtual tables that may not appear in sqlite_master.
|
|
2214
|
+
// These core tables are ALWAYS present in any valid Perfetto trace:
|
|
2215
|
+
const CORE_TABLES = new Set(['thread', 'process', 'slice', 'counter', 'track', 'thread_track', 'counter_track']);
|
|
2216
|
+
// Filter out core tables - they're guaranteed to exist
|
|
2217
|
+
const tablesToCheck = required_tables.filter(t => !CORE_TABLES.has(t));
|
|
2218
|
+
if (tablesToCheck.length === 0) {
|
|
2219
|
+
// All required tables are core tables - they always exist
|
|
2220
|
+
return { success: true };
|
|
2221
|
+
}
|
|
2222
|
+
// For non-core tables, query sqlite_master (include views for Perfetto's virtual tables)
|
|
2223
|
+
const tableList = tablesToCheck.map(t => `'${t}'`).join(',');
|
|
2224
|
+
const query = `
|
|
2225
|
+
SELECT name
|
|
2226
|
+
FROM sqlite_master
|
|
2227
|
+
WHERE type IN ('table', 'view') AND name IN (${tableList})
|
|
2228
|
+
`;
|
|
2229
|
+
const result = await this.traceProcessor.query(traceId, query);
|
|
2230
|
+
const existingTables = new Set();
|
|
2231
|
+
// 处理查询结果(兼容多种返回结构)
|
|
2232
|
+
if (result) {
|
|
2233
|
+
if (result.columns && Array.isArray(result.rows)) {
|
|
2234
|
+
const nameIdx = result.columns.indexOf('name');
|
|
2235
|
+
if (nameIdx >= 0) {
|
|
2236
|
+
for (const row of result.rows) {
|
|
2237
|
+
if (Array.isArray(row) && row[nameIdx]) {
|
|
2238
|
+
existingTables.add(String(row[nameIdx]));
|
|
2239
|
+
}
|
|
2240
|
+
else if (row && typeof row === 'object' && row['name']) {
|
|
2241
|
+
existingTables.add(String(row['name']));
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2244
|
+
}
|
|
2245
|
+
}
|
|
2246
|
+
else if (Array.isArray(result)) {
|
|
2247
|
+
result.forEach((row) => {
|
|
2248
|
+
if (row?.name) {
|
|
2249
|
+
existingTables.add(String(row.name));
|
|
2250
|
+
}
|
|
2251
|
+
});
|
|
2252
|
+
}
|
|
2253
|
+
}
|
|
2254
|
+
// 检查缺少的表 (only check non-core tables)
|
|
2255
|
+
const missingTables = tablesToCheck.filter(t => !existingTables.has(t));
|
|
2256
|
+
if (missingTables.length > 0) {
|
|
2257
|
+
return {
|
|
2258
|
+
success: false,
|
|
2259
|
+
error: `Trace is missing required tables: ${missingTables.join(', ')}`
|
|
2260
|
+
};
|
|
2261
|
+
}
|
|
2262
|
+
return { success: true };
|
|
2263
|
+
}
|
|
2264
|
+
catch (e) {
|
|
2265
|
+
console.error(`[SkillExecutor] Failed to check prerequisites: ${e.message}`);
|
|
2266
|
+
//为了健壮性,查询失败时不阻止执行,可能是 traceProcessor 问题
|
|
2267
|
+
return { success: true };
|
|
2268
|
+
}
|
|
2269
|
+
}
|
|
2270
|
+
/**
|
|
2271
|
+
* 执行 skill 引用步骤
|
|
2272
|
+
*/
|
|
2273
|
+
async executeSkillRefStep(step, context) {
|
|
2274
|
+
const startTime = Date.now();
|
|
2275
|
+
// 构建子 skill 的参数
|
|
2276
|
+
const params = {};
|
|
2277
|
+
if (step.params) {
|
|
2278
|
+
for (const [key, value] of Object.entries(step.params)) {
|
|
2279
|
+
if (typeof value === 'string' && value.startsWith('${')) {
|
|
2280
|
+
params[key] = ExpressionEvaluator.evaluate(value, context);
|
|
2281
|
+
}
|
|
2282
|
+
else {
|
|
2283
|
+
params[key] = value;
|
|
2284
|
+
}
|
|
2285
|
+
}
|
|
2286
|
+
}
|
|
2287
|
+
// 执行子 skill
|
|
2288
|
+
const result = await this.execute(step.skill, context.traceId, params, { ...context.inherited, ...context.variables });
|
|
2289
|
+
return {
|
|
2290
|
+
stepId: step.id,
|
|
2291
|
+
stepType: 'skill',
|
|
2292
|
+
success: result.success,
|
|
2293
|
+
data: result,
|
|
2294
|
+
error: result.error,
|
|
2295
|
+
executionTimeMs: Date.now() - startTime,
|
|
2296
|
+
};
|
|
2297
|
+
}
|
|
2298
|
+
/**
|
|
2299
|
+
* 执行迭代步骤
|
|
2300
|
+
*/
|
|
2301
|
+
async executeIteratorStep(step, context, parentSkillId) {
|
|
2302
|
+
const startTime = Date.now();
|
|
2303
|
+
const itemSkillName = typeof step.item_skill === 'string'
|
|
2304
|
+
? String(step.item_skill)
|
|
2305
|
+
: (typeof step.skill === 'string' ? String(step.skill) : '');
|
|
2306
|
+
if (!itemSkillName) {
|
|
2307
|
+
return {
|
|
2308
|
+
stepId: step.id,
|
|
2309
|
+
stepType: 'iterator',
|
|
2310
|
+
success: false,
|
|
2311
|
+
error: `Iterator item_skill is missing: ${step.id}`,
|
|
2312
|
+
executionTimeMs: Date.now() - startTime,
|
|
2313
|
+
};
|
|
2314
|
+
}
|
|
2315
|
+
// 获取数据源
|
|
2316
|
+
const source = context.variables[step.source] || context.results[step.source]?.data;
|
|
2317
|
+
if (!source || !Array.isArray(source)) {
|
|
2318
|
+
return {
|
|
2319
|
+
stepId: step.id,
|
|
2320
|
+
stepType: 'iterator',
|
|
2321
|
+
success: false,
|
|
2322
|
+
error: `Iterator source not found or not an array: ${step.source}`,
|
|
2323
|
+
executionTimeMs: Date.now() - startTime,
|
|
2324
|
+
};
|
|
2325
|
+
}
|
|
2326
|
+
const results = [];
|
|
2327
|
+
const maxItems = step.max_items || 100; // 性能保护
|
|
2328
|
+
let items = [...source];
|
|
2329
|
+
// Optional iterator filter (best-effort): allows skills to analyze only a subset of items.
|
|
2330
|
+
// Example in YAML: filter: "jank_level == 'severe' OR jank_level == 'bad'"
|
|
2331
|
+
const filterExprRaw = typeof step.filter === 'string' ? String(step.filter).trim() : '';
|
|
2332
|
+
if (filterExprRaw) {
|
|
2333
|
+
const filterExpr = filterExprRaw
|
|
2334
|
+
.replace(/\bOR\b/gi, '||')
|
|
2335
|
+
.replace(/\bAND\b/gi, '&&');
|
|
2336
|
+
try {
|
|
2337
|
+
items = items.filter((item) => {
|
|
2338
|
+
const itemObj = (item && typeof item === 'object') ? item : {};
|
|
2339
|
+
const filterCtx = {
|
|
2340
|
+
...context,
|
|
2341
|
+
// Expose item fields at root-level for convenience in filter expressions.
|
|
2342
|
+
inherited: { ...(context.inherited || {}), ...itemObj },
|
|
2343
|
+
currentItem: itemObj,
|
|
2344
|
+
};
|
|
2345
|
+
return ExpressionEvaluator.evaluateCondition(filterExpr, filterCtx);
|
|
2346
|
+
});
|
|
2347
|
+
}
|
|
2348
|
+
catch {
|
|
2349
|
+
// Ignore filter evaluation errors (iterator still runs).
|
|
2350
|
+
}
|
|
2351
|
+
}
|
|
2352
|
+
items = items.slice(0, maxItems);
|
|
2353
|
+
for (let i = 0; i < items.length; i++) {
|
|
2354
|
+
const item = items[i];
|
|
2355
|
+
// 构建子 skill 的参数
|
|
2356
|
+
const params = {};
|
|
2357
|
+
if (step.item_params) {
|
|
2358
|
+
for (const [key, path] of Object.entries(step.item_params)) {
|
|
2359
|
+
// 仅在字段不存在(=== undefined)时才回退为常量字符串;保留 null(常用于 SQL NULL)
|
|
2360
|
+
const v = item?.[path];
|
|
2361
|
+
params[key] = v !== undefined ? v : path;
|
|
2362
|
+
}
|
|
2363
|
+
}
|
|
2364
|
+
else {
|
|
2365
|
+
// 默认将 item 的所有字段作为参数
|
|
2366
|
+
Object.assign(params, item);
|
|
2367
|
+
}
|
|
2368
|
+
// 设置当前迭代项
|
|
2369
|
+
const iterContext = { ...context };
|
|
2370
|
+
iterContext.currentItem = item;
|
|
2371
|
+
iterContext.currentItemIndex = i;
|
|
2372
|
+
// 执行子 skill
|
|
2373
|
+
const itemResult = await this.execute(itemSkillName, context.traceId, params, { ...context.inherited, ...context.variables, item });
|
|
2374
|
+
// Always record the per-item result, even if it failed (so UI/Agents can see errors).
|
|
2375
|
+
results.push({
|
|
2376
|
+
itemIndex: i,
|
|
2377
|
+
item,
|
|
2378
|
+
result: itemResult,
|
|
2379
|
+
});
|
|
2380
|
+
}
|
|
2381
|
+
return {
|
|
2382
|
+
stepId: step.id,
|
|
2383
|
+
stepType: 'iterator',
|
|
2384
|
+
success: true,
|
|
2385
|
+
data: results,
|
|
2386
|
+
executionTimeMs: Date.now() - startTime,
|
|
2387
|
+
};
|
|
2388
|
+
}
|
|
2389
|
+
/**
|
|
2390
|
+
* 执行并行步骤
|
|
2391
|
+
*/
|
|
2392
|
+
async executeParallelStep(step, context, parentSkillId) {
|
|
2393
|
+
const startTime = Date.now();
|
|
2394
|
+
const promises = step.steps.map(subStep => this.executeStep(subStep, context, parentSkillId));
|
|
2395
|
+
const results = await Promise.all(promises);
|
|
2396
|
+
const allSuccess = results.every(r => r.success);
|
|
2397
|
+
// 将结果存入 context
|
|
2398
|
+
const data = {};
|
|
2399
|
+
for (let i = 0; i < step.steps.length; i++) {
|
|
2400
|
+
const subStep = step.steps[i];
|
|
2401
|
+
data[subStep.id] = results[i].data;
|
|
2402
|
+
context.results[subStep.id] = results[i];
|
|
2403
|
+
}
|
|
2404
|
+
return {
|
|
2405
|
+
stepId: step.id,
|
|
2406
|
+
stepType: 'parallel',
|
|
2407
|
+
success: allSuccess,
|
|
2408
|
+
data,
|
|
2409
|
+
executionTimeMs: Date.now() - startTime,
|
|
2410
|
+
};
|
|
2411
|
+
}
|
|
2412
|
+
/**
|
|
2413
|
+
* 执行诊断步骤
|
|
2414
|
+
*/
|
|
2415
|
+
async executeDiagnosticStep(step, context) {
|
|
2416
|
+
const startTime = Date.now();
|
|
2417
|
+
const diagnostics = [];
|
|
2418
|
+
// 收集输入数据
|
|
2419
|
+
const inputs = {};
|
|
2420
|
+
for (const inputName of step.inputs) {
|
|
2421
|
+
inputs[inputName] = context.variables[inputName] || context.results[inputName]?.data;
|
|
2422
|
+
}
|
|
2423
|
+
// 评估规则
|
|
2424
|
+
for (const rule of step.rules) {
|
|
2425
|
+
const conditionResult = ExpressionEvaluator.evaluateCondition(rule.condition, context);
|
|
2426
|
+
if (conditionResult) {
|
|
2427
|
+
const confidence = typeof rule.confidence === 'number'
|
|
2428
|
+
? rule.confidence
|
|
2429
|
+
: rule.confidence === 'high' ? 0.9 : rule.confidence === 'medium' ? 0.7 : 0.5;
|
|
2430
|
+
const severityFromRule = rule.severity === 'critical' || rule.severity === 'warning' || rule.severity === 'info'
|
|
2431
|
+
? rule.severity
|
|
2432
|
+
: undefined;
|
|
2433
|
+
// Substitute variables in diagnosis message
|
|
2434
|
+
const diagnosis = ExpressionEvaluator.evaluate(rule.diagnosis, context);
|
|
2435
|
+
// 收集 evidence 数据
|
|
2436
|
+
const evidence = this.collectDiagnosticEvidence(rule, context, inputs);
|
|
2437
|
+
// Evaluate suggestions templates (e.g., "${root_cause.data[0].secondary_info}")
|
|
2438
|
+
const evaluatedSuggestions = rule.suggestions?.map((s) => typeof s === 'string' ? ExpressionEvaluator.evaluate(s, context) : s);
|
|
2439
|
+
diagnostics.push({
|
|
2440
|
+
id: `${step.id}_${diagnostics.length}`,
|
|
2441
|
+
diagnosis,
|
|
2442
|
+
confidence,
|
|
2443
|
+
severity: severityFromRule ?? (confidence >= 0.8 ? 'critical' : confidence >= 0.6 ? 'warning' : 'info'),
|
|
2444
|
+
suggestions: evaluatedSuggestions,
|
|
2445
|
+
evidence,
|
|
2446
|
+
source: 'rule',
|
|
2447
|
+
});
|
|
2448
|
+
}
|
|
2449
|
+
}
|
|
2450
|
+
// 如果没有匹配的规则且配置了 AI 辅助,调用 AI
|
|
2451
|
+
if (diagnostics.length === 0 && step.ai_assist && step.fallback && this.aiService) {
|
|
2452
|
+
const aiResult = await this.callAI(step.fallback.prompt, context);
|
|
2453
|
+
if (aiResult) {
|
|
2454
|
+
diagnostics.push({
|
|
2455
|
+
id: `${step.id}_ai`,
|
|
2456
|
+
diagnosis: aiResult,
|
|
2457
|
+
confidence: 0.6,
|
|
2458
|
+
severity: 'info',
|
|
2459
|
+
source: 'ai',
|
|
2460
|
+
});
|
|
2461
|
+
}
|
|
2462
|
+
}
|
|
2463
|
+
return {
|
|
2464
|
+
stepId: step.id,
|
|
2465
|
+
stepType: 'diagnostic',
|
|
2466
|
+
success: true,
|
|
2467
|
+
data: { diagnostics, inputs },
|
|
2468
|
+
executionTimeMs: Date.now() - startTime,
|
|
2469
|
+
};
|
|
2470
|
+
}
|
|
2471
|
+
/**
|
|
2472
|
+
* 收集诊断结论的数据依据
|
|
2473
|
+
* 从 rule.evidence_fields 或自动从 condition 解析引用的数据源
|
|
2474
|
+
*/
|
|
2475
|
+
collectDiagnosticEvidence(rule, context, inputs) {
|
|
2476
|
+
const evidence = {};
|
|
2477
|
+
// 1. 如果规则定义了 evidence_fields,使用它们
|
|
2478
|
+
if (rule.evidence_fields && Array.isArray(rule.evidence_fields)) {
|
|
2479
|
+
for (const field of rule.evidence_fields) {
|
|
2480
|
+
const value = this.resolveEvidenceField(field, context, inputs);
|
|
2481
|
+
if (value !== undefined) {
|
|
2482
|
+
evidence[field] = value;
|
|
2483
|
+
}
|
|
2484
|
+
}
|
|
2485
|
+
}
|
|
2486
|
+
// 2. 自动从 condition 中提取数据源引用
|
|
2487
|
+
const conditionSources = this.extractDataSources(rule.condition);
|
|
2488
|
+
for (const source of conditionSources) {
|
|
2489
|
+
// 只提取第一行数据作为 evidence(避免数据过大)
|
|
2490
|
+
const sourceData = inputs[source];
|
|
2491
|
+
if (sourceData && !evidence[source]) {
|
|
2492
|
+
if (Array.isArray(sourceData) && sourceData.length > 0) {
|
|
2493
|
+
// 只取第一条记录的关键字段
|
|
2494
|
+
const firstRow = sourceData[0];
|
|
2495
|
+
evidence[source] = {
|
|
2496
|
+
_summary: `共 ${sourceData.length} 条记录`,
|
|
2497
|
+
_firstRow: this.extractKeyFields(firstRow),
|
|
2498
|
+
};
|
|
2499
|
+
}
|
|
2500
|
+
else if (typeof sourceData === 'object') {
|
|
2501
|
+
evidence[source] = this.extractKeyFields(sourceData);
|
|
2502
|
+
}
|
|
2503
|
+
}
|
|
2504
|
+
}
|
|
2505
|
+
// 3. 添加时间戳用于 Perfetto 跳转
|
|
2506
|
+
const tsField = this.findTimestampField(inputs, conditionSources);
|
|
2507
|
+
if (tsField) {
|
|
2508
|
+
evidence._perfettoTs = tsField;
|
|
2509
|
+
}
|
|
2510
|
+
return Object.keys(evidence).length > 0 ? evidence : undefined;
|
|
2511
|
+
}
|
|
2512
|
+
/**
|
|
2513
|
+
* 从表达式中提取数据源名称
|
|
2514
|
+
* 例如: "lock_data.data[0]?.wait_ms > 2" => ["lock_data"]
|
|
2515
|
+
*/
|
|
2516
|
+
extractDataSources(expression) {
|
|
2517
|
+
const sources = new Set();
|
|
2518
|
+
// 匹配 xxx.data 或 xxx.xxx 形式的数据源引用
|
|
2519
|
+
const matches = expression.match(/(\w+)\.data/g);
|
|
2520
|
+
if (matches) {
|
|
2521
|
+
for (const match of matches) {
|
|
2522
|
+
const source = match.replace('.data', '');
|
|
2523
|
+
sources.add(source);
|
|
2524
|
+
}
|
|
2525
|
+
}
|
|
2526
|
+
return Array.from(sources);
|
|
2527
|
+
}
|
|
2528
|
+
/**
|
|
2529
|
+
* 解析 evidence_fields 中的字段路径
|
|
2530
|
+
* 支持格式: "source.field" 或 "source.data[0].field"
|
|
2531
|
+
*/
|
|
2532
|
+
resolveEvidenceField(field, context, inputs) {
|
|
2533
|
+
try {
|
|
2534
|
+
// 尝试从 inputs 中解析
|
|
2535
|
+
const parts = field.split('.');
|
|
2536
|
+
let value = inputs;
|
|
2537
|
+
for (const part of parts) {
|
|
2538
|
+
if (value === undefined)
|
|
2539
|
+
return undefined;
|
|
2540
|
+
// 处理数组索引,如 data[0]
|
|
2541
|
+
const arrayMatch = part.match(/^(\w+)\[(\d+)\]$/);
|
|
2542
|
+
if (arrayMatch) {
|
|
2543
|
+
value = value[arrayMatch[1]]?.[parseInt(arrayMatch[2])];
|
|
2544
|
+
}
|
|
2545
|
+
else {
|
|
2546
|
+
value = value[part];
|
|
2547
|
+
}
|
|
2548
|
+
}
|
|
2549
|
+
return value;
|
|
2550
|
+
}
|
|
2551
|
+
catch {
|
|
2552
|
+
return undefined;
|
|
2553
|
+
}
|
|
2554
|
+
}
|
|
2555
|
+
/**
|
|
2556
|
+
* 从对象中提取关键字段(排除大型嵌套对象)
|
|
2557
|
+
*/
|
|
2558
|
+
extractKeyFields(obj) {
|
|
2559
|
+
if (!obj || typeof obj !== 'object')
|
|
2560
|
+
return obj;
|
|
2561
|
+
const result = {};
|
|
2562
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
2563
|
+
// 跳过大型数组和深层嵌套对象
|
|
2564
|
+
if (Array.isArray(value)) {
|
|
2565
|
+
result[key] = `[Array(${value.length})]`;
|
|
2566
|
+
}
|
|
2567
|
+
else if (value && typeof value === 'object') {
|
|
2568
|
+
// 只保留一层深度
|
|
2569
|
+
result[key] = '[Object]';
|
|
2570
|
+
}
|
|
2571
|
+
else {
|
|
2572
|
+
result[key] = value;
|
|
2573
|
+
}
|
|
2574
|
+
}
|
|
2575
|
+
return result;
|
|
2576
|
+
}
|
|
2577
|
+
/**
|
|
2578
|
+
* 从输入数据中找到时间戳字段用于 Perfetto 跳转
|
|
2579
|
+
*/
|
|
2580
|
+
findTimestampField(inputs, sources) {
|
|
2581
|
+
for (const source of sources) {
|
|
2582
|
+
const data = inputs[source];
|
|
2583
|
+
if (Array.isArray(data) && data.length > 0) {
|
|
2584
|
+
const firstRow = data[0];
|
|
2585
|
+
// 常见的时间戳字段名
|
|
2586
|
+
const tsFields = ['ts', 'start_ts', 'timestamp', 'begin_ts'];
|
|
2587
|
+
for (const field of tsFields) {
|
|
2588
|
+
if (firstRow[field] !== undefined && firstRow[field] !== null) {
|
|
2589
|
+
return String(firstRow[field]);
|
|
2590
|
+
}
|
|
2591
|
+
}
|
|
2592
|
+
}
|
|
2593
|
+
}
|
|
2594
|
+
return undefined;
|
|
2595
|
+
}
|
|
2596
|
+
/**
|
|
2597
|
+
* 执行 AI 决策步骤
|
|
2598
|
+
*/
|
|
2599
|
+
async executeAIDecisionStep(step, context) {
|
|
2600
|
+
const startTime = Date.now();
|
|
2601
|
+
if (!this.aiService) {
|
|
2602
|
+
return {
|
|
2603
|
+
stepId: step.id,
|
|
2604
|
+
stepType: 'ai_decision',
|
|
2605
|
+
success: false,
|
|
2606
|
+
error: 'AI service not available',
|
|
2607
|
+
executionTimeMs: Date.now() - startTime,
|
|
2608
|
+
};
|
|
2609
|
+
}
|
|
2610
|
+
const basePrompt = ExpressionEvaluator.evaluate(step.prompt, context);
|
|
2611
|
+
const inputsPayloadRaw = this.buildAIInputsPayload(step.inputs, context);
|
|
2612
|
+
const inputsPayload = inputsPayloadRaw ? (0, llmPrivacy_1.redactObjectForLLM)(inputsPayloadRaw).value : null;
|
|
2613
|
+
const promptRaw = this.buildStructuredAIPrompt(basePrompt, inputsPayload, 'decision');
|
|
2614
|
+
const prompt = (0, llmPrivacy_1.redactTextForLLM)(promptRaw).text;
|
|
2615
|
+
this.emit({
|
|
2616
|
+
type: 'ai_thinking',
|
|
2617
|
+
skillId: '',
|
|
2618
|
+
stepId: step.id,
|
|
2619
|
+
data: { prompt },
|
|
2620
|
+
});
|
|
2621
|
+
const response = await this.callAI(prompt, context, 'evaluation');
|
|
2622
|
+
const normalizedDecision = this.extractStructuredAIField(response, 'decision');
|
|
2623
|
+
this.emit({
|
|
2624
|
+
type: 'ai_response',
|
|
2625
|
+
skillId: '',
|
|
2626
|
+
stepId: step.id,
|
|
2627
|
+
data: { response: normalizedDecision, rawResponse: response },
|
|
2628
|
+
});
|
|
2629
|
+
return {
|
|
2630
|
+
stepId: step.id,
|
|
2631
|
+
stepType: 'ai_decision',
|
|
2632
|
+
success: true,
|
|
2633
|
+
data: { decision: normalizedDecision },
|
|
2634
|
+
executionTimeMs: Date.now() - startTime,
|
|
2635
|
+
};
|
|
2636
|
+
}
|
|
2637
|
+
/**
|
|
2638
|
+
* 执行 AI 总结步骤
|
|
2639
|
+
*/
|
|
2640
|
+
async executeAISummaryStep(step, context) {
|
|
2641
|
+
const startTime = Date.now();
|
|
2642
|
+
if (!this.aiService) {
|
|
2643
|
+
return {
|
|
2644
|
+
stepId: step.id,
|
|
2645
|
+
stepType: 'ai_summary',
|
|
2646
|
+
success: false,
|
|
2647
|
+
error: 'AI service not available',
|
|
2648
|
+
executionTimeMs: Date.now() - startTime,
|
|
2649
|
+
};
|
|
2650
|
+
}
|
|
2651
|
+
const basePrompt = ExpressionEvaluator.evaluate(step.prompt, context);
|
|
2652
|
+
const inputsPayloadRaw = this.buildAIInputsPayload(step.inputs, context);
|
|
2653
|
+
const inputsPayload = inputsPayloadRaw ? (0, llmPrivacy_1.redactObjectForLLM)(inputsPayloadRaw).value : null;
|
|
2654
|
+
const promptRaw = this.buildStructuredAIPrompt(basePrompt, inputsPayload, 'summary');
|
|
2655
|
+
const prompt = (0, llmPrivacy_1.redactTextForLLM)(promptRaw).text;
|
|
2656
|
+
this.emit({
|
|
2657
|
+
type: 'ai_thinking',
|
|
2658
|
+
skillId: '',
|
|
2659
|
+
stepId: step.id,
|
|
2660
|
+
data: { prompt },
|
|
2661
|
+
});
|
|
2662
|
+
const response = await this.callAI(prompt, context, 'synthesis');
|
|
2663
|
+
const normalizedSummary = this.extractStructuredAIField(response, 'summary');
|
|
2664
|
+
this.emit({
|
|
2665
|
+
type: 'ai_response',
|
|
2666
|
+
skillId: '',
|
|
2667
|
+
stepId: step.id,
|
|
2668
|
+
data: { response: normalizedSummary, rawResponse: response },
|
|
2669
|
+
});
|
|
2670
|
+
return {
|
|
2671
|
+
stepId: step.id,
|
|
2672
|
+
stepType: 'ai_summary',
|
|
2673
|
+
success: true,
|
|
2674
|
+
data: { summary: normalizedSummary },
|
|
2675
|
+
executionTimeMs: Date.now() - startTime,
|
|
2676
|
+
};
|
|
2677
|
+
}
|
|
2678
|
+
/**
|
|
2679
|
+
* 执行条件步骤
|
|
2680
|
+
*/
|
|
2681
|
+
async executeConditionalStep(step, context, parentSkillId) {
|
|
2682
|
+
const startTime = Date.now();
|
|
2683
|
+
// 评估条件
|
|
2684
|
+
for (const condition of step.conditions) {
|
|
2685
|
+
if (ExpressionEvaluator.evaluateCondition(condition.when, context)) {
|
|
2686
|
+
if (typeof condition.then === 'string') {
|
|
2687
|
+
// skill 引用
|
|
2688
|
+
return this.executeSkillRefStep({
|
|
2689
|
+
id: step.id,
|
|
2690
|
+
skill: condition.then,
|
|
2691
|
+
}, context);
|
|
2692
|
+
}
|
|
2693
|
+
else {
|
|
2694
|
+
// 内联步骤
|
|
2695
|
+
return this.executeStep(condition.then, context, parentSkillId);
|
|
2696
|
+
}
|
|
2697
|
+
}
|
|
2698
|
+
}
|
|
2699
|
+
// 默认分支
|
|
2700
|
+
if (step.else) {
|
|
2701
|
+
if (typeof step.else === 'string') {
|
|
2702
|
+
return this.executeSkillRefStep({
|
|
2703
|
+
id: step.id,
|
|
2704
|
+
skill: step.else,
|
|
2705
|
+
}, context);
|
|
2706
|
+
}
|
|
2707
|
+
else {
|
|
2708
|
+
return this.executeStep(step.else, context, parentSkillId);
|
|
2709
|
+
}
|
|
2710
|
+
}
|
|
2711
|
+
return {
|
|
2712
|
+
stepId: step.id,
|
|
2713
|
+
stepType: 'conditional',
|
|
2714
|
+
success: true,
|
|
2715
|
+
data: null,
|
|
2716
|
+
executionTimeMs: Date.now() - startTime,
|
|
2717
|
+
};
|
|
2718
|
+
}
|
|
2719
|
+
/**
|
|
2720
|
+
* 执行 pipeline 步骤
|
|
2721
|
+
*
|
|
2722
|
+
* 将渲染管线检测结果聚合为教学内容 + Pin 指令,作为 SkillEngine 一等步骤类型输出。
|
|
2723
|
+
*/
|
|
2724
|
+
async executePipelineStep(step, context) {
|
|
2725
|
+
const startTime = Date.now();
|
|
2726
|
+
try {
|
|
2727
|
+
await (0, pipelineSkillLoader_1.ensurePipelineSkillsInitialized)();
|
|
2728
|
+
const pipelineSource = step.pipeline_source || 'pipeline_result';
|
|
2729
|
+
const activeProcessesSource = step.active_processes_source || 'active_rendering_processes';
|
|
2730
|
+
const traceRequirementsSource = step.trace_requirements_source || 'trace_requirements';
|
|
2731
|
+
const pipelineRow = this.resolveFirstObjectRowFromSource(pipelineSource, context);
|
|
2732
|
+
const explicitPipelineIdRaw = typeof step.pipeline_id === 'string' && step.pipeline_id.trim().length > 0
|
|
2733
|
+
? ExpressionEvaluator.evaluate(step.pipeline_id, context)
|
|
2734
|
+
: undefined;
|
|
2735
|
+
const explicitPipelineId = explicitPipelineIdRaw !== undefined && explicitPipelineIdRaw !== null
|
|
2736
|
+
? String(explicitPipelineIdRaw).trim()
|
|
2737
|
+
: '';
|
|
2738
|
+
const primaryPipelineId = (explicitPipelineId ||
|
|
2739
|
+
String(pipelineRow?.primary_pipeline_id ?? '').trim() ||
|
|
2740
|
+
teaching_config_1.TEACHING_DEFAULTS.pipelineId);
|
|
2741
|
+
const primaryConfidence = (0, teaching_types_1.validateConfidence)(pipelineRow?.primary_confidence, teaching_config_1.TEACHING_DEFAULTS.confidence);
|
|
2742
|
+
const candidatesList = pipelineRow?.candidates_list || '';
|
|
2743
|
+
const featuresList = pipelineRow?.features_list || '';
|
|
2744
|
+
const docPath = String(pipelineRow?.doc_path || teaching_config_1.TEACHING_DEFAULTS.docPath);
|
|
2745
|
+
const candidates = candidatesList
|
|
2746
|
+
? (0, teaching_types_1.parseCandidates)(candidatesList, teaching_config_1.TEACHING_LIMITS.maxCandidates)
|
|
2747
|
+
: [{ id: primaryPipelineId, confidence: primaryConfidence }];
|
|
2748
|
+
const features = (0, teaching_types_1.parseFeatures)(featuresList);
|
|
2749
|
+
const traceRequirementsMissing = this.extractTraceRequirementHints(this.resolveFirstObjectRowFromSource(traceRequirementsSource, context));
|
|
2750
|
+
const activeRenderingProcesses = (0, teaching_types_1.validateActiveProcesses)(this.resolveStepResultFromSource(activeProcessesSource, context));
|
|
2751
|
+
const yamlTeaching = pipelineSkillLoader_1.pipelineSkillLoader.getTeachingContent(primaryPipelineId);
|
|
2752
|
+
const mdTeaching = (0, pipelineDocService_1.getPipelineDocService)().getTeachingContent(primaryPipelineId);
|
|
2753
|
+
const teachingContent = yamlTeaching
|
|
2754
|
+
? (0, teaching_types_1.transformTeachingContent)(yamlTeaching, pipelineSkillLoader_1.pipelineSkillLoader.getPipelineMeta(primaryPipelineId)?.doc_path || docPath)
|
|
2755
|
+
: mdTeaching
|
|
2756
|
+
? {
|
|
2757
|
+
title: mdTeaching.title,
|
|
2758
|
+
summary: mdTeaching.summary,
|
|
2759
|
+
mermaidBlocks: mdTeaching.mermaidBlocks,
|
|
2760
|
+
threadRoles: mdTeaching.threadRoles,
|
|
2761
|
+
keySlices: mdTeaching.keySlices,
|
|
2762
|
+
docPath: mdTeaching.docPath,
|
|
2763
|
+
}
|
|
2764
|
+
: null;
|
|
2765
|
+
const basePinInstructions = pipelineSkillLoader_1.pipelineSkillLoader
|
|
2766
|
+
.getAutoPinInstructions(primaryPipelineId)
|
|
2767
|
+
.slice(0, teaching_config_1.TEACHING_LIMITS.maxPinInstructions);
|
|
2768
|
+
const smartFilterConfigs = pipelineSkillLoader_1.pipelineSkillLoader.getSmartFilterConfigs(primaryPipelineId);
|
|
2769
|
+
const pinInstructions = basePinInstructions.map((inst) => {
|
|
2770
|
+
const hasSmartFilter = inst.smart_filter?.enabled ?? smartFilterConfigs.has(inst.pattern);
|
|
2771
|
+
const rawInstruction = {
|
|
2772
|
+
pattern: inst.pattern,
|
|
2773
|
+
match_by: inst.match_by,
|
|
2774
|
+
priority: inst.priority,
|
|
2775
|
+
reason: inst.reason,
|
|
2776
|
+
expand: inst.expand,
|
|
2777
|
+
main_thread_only: inst.main_thread_only,
|
|
2778
|
+
smart_filter: hasSmartFilter
|
|
2779
|
+
? (inst.smart_filter || { enabled: true })
|
|
2780
|
+
: undefined,
|
|
2781
|
+
};
|
|
2782
|
+
const transformed = (0, teaching_types_1.transformPinInstruction)(rawInstruction, activeRenderingProcesses);
|
|
2783
|
+
if (transformed.smartPin && !transformed.skipPin) {
|
|
2784
|
+
transformed.reason = `${inst.reason} (${activeRenderingProcesses.length} 活跃进程)`;
|
|
2785
|
+
}
|
|
2786
|
+
return transformed;
|
|
2787
|
+
});
|
|
2788
|
+
return {
|
|
2789
|
+
stepId: step.id,
|
|
2790
|
+
stepType: 'pipeline',
|
|
2791
|
+
success: true,
|
|
2792
|
+
data: {
|
|
2793
|
+
detection: {
|
|
2794
|
+
detected: !!pipelineRow || !!explicitPipelineId,
|
|
2795
|
+
primaryPipelineId,
|
|
2796
|
+
primaryConfidence,
|
|
2797
|
+
candidates,
|
|
2798
|
+
features,
|
|
2799
|
+
traceRequirementsMissing,
|
|
2800
|
+
},
|
|
2801
|
+
teachingContent,
|
|
2802
|
+
pinInstructions,
|
|
2803
|
+
activeRenderingProcesses,
|
|
2804
|
+
docPath,
|
|
2805
|
+
},
|
|
2806
|
+
executionTimeMs: Date.now() - startTime,
|
|
2807
|
+
};
|
|
2808
|
+
}
|
|
2809
|
+
catch (error) {
|
|
2810
|
+
return {
|
|
2811
|
+
stepId: step.id,
|
|
2812
|
+
stepType: 'pipeline',
|
|
2813
|
+
success: false,
|
|
2814
|
+
error: error?.message || 'Pipeline step execution failed',
|
|
2815
|
+
executionTimeMs: Date.now() - startTime,
|
|
2816
|
+
};
|
|
2817
|
+
}
|
|
2818
|
+
}
|
|
2819
|
+
resolveStepResultFromSource(source, context) {
|
|
2820
|
+
if (context.results[source])
|
|
2821
|
+
return context.results[source];
|
|
2822
|
+
if (context.variables[source] !== undefined) {
|
|
2823
|
+
return { data: context.variables[source] };
|
|
2824
|
+
}
|
|
2825
|
+
return undefined;
|
|
2826
|
+
}
|
|
2827
|
+
resolveFirstObjectRowFromSource(source, context) {
|
|
2828
|
+
const sourceResult = this.resolveStepResultFromSource(source, context);
|
|
2829
|
+
const sourceData = sourceResult?.data;
|
|
2830
|
+
if (Array.isArray(sourceData)) {
|
|
2831
|
+
const row = sourceData.find((item) => item && typeof item === 'object' && !Array.isArray(item));
|
|
2832
|
+
return row ? row : null;
|
|
2833
|
+
}
|
|
2834
|
+
if (sourceData && typeof sourceData === 'object' && !Array.isArray(sourceData)) {
|
|
2835
|
+
return sourceData;
|
|
2836
|
+
}
|
|
2837
|
+
return null;
|
|
2838
|
+
}
|
|
2839
|
+
extractTraceRequirementHints(row) {
|
|
2840
|
+
if (!row)
|
|
2841
|
+
return [];
|
|
2842
|
+
const hints = [];
|
|
2843
|
+
for (const value of Object.values(row)) {
|
|
2844
|
+
if (typeof value !== 'string')
|
|
2845
|
+
continue;
|
|
2846
|
+
const trimmed = value.trim();
|
|
2847
|
+
if (trimmed.length > 0)
|
|
2848
|
+
hints.push(trimmed);
|
|
2849
|
+
}
|
|
2850
|
+
return hints;
|
|
2851
|
+
}
|
|
2852
|
+
/**
|
|
2853
|
+
* 调用 AI 服务
|
|
2854
|
+
*/
|
|
2855
|
+
async callAI(prompt, _context, taskType = 'general') {
|
|
2856
|
+
if (!this.aiService) {
|
|
2857
|
+
return '';
|
|
2858
|
+
}
|
|
2859
|
+
const safePrompt = (0, llmPrivacy_1.redactTextForLLM)(prompt).text;
|
|
2860
|
+
try {
|
|
2861
|
+
if (typeof this.aiService.chat === 'function') {
|
|
2862
|
+
return await this.aiService.chat(safePrompt);
|
|
2863
|
+
}
|
|
2864
|
+
if (typeof this.aiService.callWithFallback === 'function') {
|
|
2865
|
+
const result = await this.aiService.callWithFallback(safePrompt, taskType, { temperature: 0 });
|
|
2866
|
+
return result?.response || result?.content || '';
|
|
2867
|
+
}
|
|
2868
|
+
throw new Error('AI service does not implement chat');
|
|
2869
|
+
}
|
|
2870
|
+
catch (error) {
|
|
2871
|
+
console.error('[SkillExecutor] AI call failed:', error.message);
|
|
2872
|
+
return '';
|
|
2873
|
+
}
|
|
2874
|
+
}
|
|
2875
|
+
/**
|
|
2876
|
+
* Build a compact, deterministic payload for ai_summary/ai_decision steps.
|
|
2877
|
+
*
|
|
2878
|
+
* Note: step.inputs uses save_as names (preferred) or step ids.
|
|
2879
|
+
* We intentionally sample rows to avoid prompt bloat.
|
|
2880
|
+
*/
|
|
2881
|
+
buildAIInputsPayload(inputs, context) {
|
|
2882
|
+
if (!inputs || inputs.length === 0)
|
|
2883
|
+
return null;
|
|
2884
|
+
const payload = {};
|
|
2885
|
+
const maxSampleRows = 5;
|
|
2886
|
+
const maxColumns = 64;
|
|
2887
|
+
for (const inputName of inputs) {
|
|
2888
|
+
const value = this.resolveAIInputValue(inputName, context);
|
|
2889
|
+
if (value === undefined) {
|
|
2890
|
+
payload[inputName] = { missing: true };
|
|
2891
|
+
continue;
|
|
2892
|
+
}
|
|
2893
|
+
if (Array.isArray(value)) {
|
|
2894
|
+
const count = value.length;
|
|
2895
|
+
const firstRow = count > 0 ? value[0] : undefined;
|
|
2896
|
+
const columns = firstRow && typeof firstRow === 'object' && !Array.isArray(firstRow)
|
|
2897
|
+
? Object.keys(firstRow).slice(0, maxColumns)
|
|
2898
|
+
: undefined;
|
|
2899
|
+
const sample = value.slice(0, Math.min(count, maxSampleRows)).map((row) => {
|
|
2900
|
+
if (row && typeof row === 'object')
|
|
2901
|
+
return this.extractKeyFields(row);
|
|
2902
|
+
return row;
|
|
2903
|
+
});
|
|
2904
|
+
payload[inputName] = {
|
|
2905
|
+
type: 'array',
|
|
2906
|
+
count,
|
|
2907
|
+
columns,
|
|
2908
|
+
sample,
|
|
2909
|
+
truncated: count > maxSampleRows,
|
|
2910
|
+
};
|
|
2911
|
+
continue;
|
|
2912
|
+
}
|
|
2913
|
+
if (value && typeof value === 'object') {
|
|
2914
|
+
payload[inputName] = {
|
|
2915
|
+
type: 'object',
|
|
2916
|
+
value: this.extractKeyFields(value),
|
|
2917
|
+
};
|
|
2918
|
+
continue;
|
|
2919
|
+
}
|
|
2920
|
+
payload[inputName] = {
|
|
2921
|
+
type: typeof value,
|
|
2922
|
+
value,
|
|
2923
|
+
};
|
|
2924
|
+
}
|
|
2925
|
+
return payload;
|
|
2926
|
+
}
|
|
2927
|
+
resolveAIInputValue(inputName, context) {
|
|
2928
|
+
if (context.variables[inputName] !== undefined) {
|
|
2929
|
+
return context.variables[inputName];
|
|
2930
|
+
}
|
|
2931
|
+
if (context.results[inputName]?.data !== undefined) {
|
|
2932
|
+
return context.results[inputName].data;
|
|
2933
|
+
}
|
|
2934
|
+
if (context.params && context.params[inputName] !== undefined) {
|
|
2935
|
+
return context.params[inputName];
|
|
2936
|
+
}
|
|
2937
|
+
if (context.inherited && context.inherited[inputName] !== undefined) {
|
|
2938
|
+
return context.inherited[inputName];
|
|
2939
|
+
}
|
|
2940
|
+
if (context.currentItem && context.currentItem[inputName] !== undefined) {
|
|
2941
|
+
return context.currentItem[inputName];
|
|
2942
|
+
}
|
|
2943
|
+
return undefined;
|
|
2944
|
+
}
|
|
2945
|
+
buildStructuredAIPrompt(basePrompt, inputsPayload, mode) {
|
|
2946
|
+
const schema = mode === 'decision'
|
|
2947
|
+
? '{"decision":"string","reasoning":"string","confidence":"high|medium|low","missing_data":["string"]}'
|
|
2948
|
+
: '{"summary":"string","key_points":["string"],"confidence":"high|medium|low","missing_data":["string"],"next_steps":["string"]}';
|
|
2949
|
+
const inputBlock = inputsPayload
|
|
2950
|
+
? `\n\n[INPUT_DATA_JSON]\n${JSON.stringify(inputsPayload, null, 2)}\n[/INPUT_DATA_JSON]`
|
|
2951
|
+
: '';
|
|
2952
|
+
const groundingRule = mode === 'decision'
|
|
2953
|
+
? '严格要求:只根据 INPUT_DATA_JSON 中提供的数据做判断;缺数据就明确说明缺口。'
|
|
2954
|
+
: '严格要求:只基于 INPUT_DATA_JSON 中的实际数据分析;不要编造数值。若字段不存在/为空,请明确说明无法判断,并给出下一步建议。';
|
|
2955
|
+
return `${basePrompt}${inputBlock}\n\n${groundingRule}\n输出要求:只返回一个 JSON 对象,不要输出 markdown、代码块或额外解释。\nJSON Schema: ${schema}`;
|
|
2956
|
+
}
|
|
2957
|
+
extractStructuredAIField(response, field) {
|
|
2958
|
+
const fallback = String(response || '').trim();
|
|
2959
|
+
if (!fallback)
|
|
2960
|
+
return '';
|
|
2961
|
+
try {
|
|
2962
|
+
const parsed = (0, llmJson_1.parseLlmJson)(fallback);
|
|
2963
|
+
if (parsed && typeof parsed === 'object') {
|
|
2964
|
+
if (typeof parsed[field] === 'string' && parsed[field].trim()) {
|
|
2965
|
+
return parsed[field].trim();
|
|
2966
|
+
}
|
|
2967
|
+
if (field === 'decision' && typeof parsed.reasoning === 'string' && parsed.reasoning.trim()) {
|
|
2968
|
+
return parsed.reasoning.trim();
|
|
2969
|
+
}
|
|
2970
|
+
}
|
|
2971
|
+
}
|
|
2972
|
+
catch {
|
|
2973
|
+
// Fall back to raw response if structured parse fails.
|
|
2974
|
+
}
|
|
2975
|
+
return fallback;
|
|
2976
|
+
}
|
|
2977
|
+
/**
|
|
2978
|
+
* 判断步骤是否需要展示
|
|
2979
|
+
*/
|
|
2980
|
+
shouldDisplay(step) {
|
|
2981
|
+
if (!('display' in step))
|
|
2982
|
+
return false;
|
|
2983
|
+
const display = step.display;
|
|
2984
|
+
if (display === false)
|
|
2985
|
+
return false;
|
|
2986
|
+
if (display === true)
|
|
2987
|
+
return true;
|
|
2988
|
+
if (typeof display === 'object') {
|
|
2989
|
+
return display.show !== false && display.level !== 'none';
|
|
2990
|
+
}
|
|
2991
|
+
return false;
|
|
2992
|
+
}
|
|
2993
|
+
/**
|
|
2994
|
+
* 获取步骤的展示配置
|
|
2995
|
+
*/
|
|
2996
|
+
getDisplayConfig(step) {
|
|
2997
|
+
if (!('display' in step))
|
|
2998
|
+
return undefined;
|
|
2999
|
+
const display = step.display;
|
|
3000
|
+
if (typeof display === 'boolean') {
|
|
3001
|
+
return display ? { show: true, level: 'summary' } : undefined;
|
|
3002
|
+
}
|
|
3003
|
+
return display;
|
|
3004
|
+
}
|
|
3005
|
+
/**
|
|
3006
|
+
* 创建展示结果
|
|
3007
|
+
*/
|
|
3008
|
+
createDisplayResult(stepId, title, stepResult, displayConfig, sql) {
|
|
3009
|
+
const rawConfig = displayConfig || { level: 'summary', format: 'table' };
|
|
3010
|
+
const { config, issues } = (0, displayContractValidator_1.sanitizeDisplayConfigForRuntime)(rawConfig, {
|
|
3011
|
+
stepId,
|
|
3012
|
+
defaultLevel: 'detail',
|
|
3013
|
+
defaultLayer: 'list',
|
|
3014
|
+
defaultFormat: 'table',
|
|
3015
|
+
});
|
|
3016
|
+
for (const issue of issues) {
|
|
3017
|
+
logger_1.default.warn('SkillExecutor', `Sanitized invalid runtime display config: ${(0, displayContractValidator_1.formatDisplayContractIssue)(issue)}`);
|
|
3018
|
+
}
|
|
3019
|
+
// Skill 引用步骤返回的是嵌套 SkillExecutionResult,展示时需要先解包到真实数据。
|
|
3020
|
+
const data = stepResult.stepType === 'skill'
|
|
3021
|
+
? this.extractSaveAsValue(stepResult)
|
|
3022
|
+
: stepResult.data;
|
|
3023
|
+
// Extract column definitions from config (runtime data may be ColumnDefinition[] even though type says string[])
|
|
3024
|
+
// This happens because skill YAML is loaded dynamically and contains full column definitions
|
|
3025
|
+
const columnDefinitions = Array.isArray(config.columns)
|
|
3026
|
+
? config.columns.filter((c) => typeof c === 'object' && c.name)
|
|
3027
|
+
: undefined;
|
|
3028
|
+
// 根据数据类型确定展示格式
|
|
3029
|
+
let displayData;
|
|
3030
|
+
// Special handling for diagnostic step data - preserve the structure
|
|
3031
|
+
// so that transformDeepFrameAnalysis can extract diagnostics
|
|
3032
|
+
if (typeof data === 'object' && data !== null && 'diagnostics' in data && Array.isArray(data.diagnostics)) {
|
|
3033
|
+
// Preserve diagnostic structure for later extraction
|
|
3034
|
+
displayData = data;
|
|
3035
|
+
}
|
|
3036
|
+
else if (Array.isArray(data) && data.length > 0) {
|
|
3037
|
+
// 检查是否是 iterator 结果(包含 itemIndex, item, result)
|
|
3038
|
+
if (this.isIteratorResult(data)) {
|
|
3039
|
+
displayData = this.flattenIteratorResults(data, stepResult.stepType === 'iterator', columnDefinitions);
|
|
3040
|
+
}
|
|
3041
|
+
else {
|
|
3042
|
+
// 普通数组 - 转换为表格格式
|
|
3043
|
+
const firstItem = data[0];
|
|
3044
|
+
if (typeof firstItem === 'object' && firstItem !== null) {
|
|
3045
|
+
// If display.columns is provided, project data to configured columns only.
|
|
3046
|
+
// This keeps UI tables concise and avoids leaking internal helper fields.
|
|
3047
|
+
const configuredColumns = Array.isArray(columnDefinitions)
|
|
3048
|
+
? columnDefinitions
|
|
3049
|
+
.map((d) => d?.name)
|
|
3050
|
+
.filter((name, idx, arr) => typeof name === 'string' &&
|
|
3051
|
+
name.length > 0 &&
|
|
3052
|
+
arr.indexOf(name) === idx)
|
|
3053
|
+
: [];
|
|
3054
|
+
const columns = configuredColumns.length > 0 ? configuredColumns : Object.keys(firstItem);
|
|
3055
|
+
const rows = data.map(row => columns.map(col => this.formatCellValue(row[col])));
|
|
3056
|
+
displayData = { columns, rows };
|
|
3057
|
+
}
|
|
3058
|
+
else {
|
|
3059
|
+
// 简单数组
|
|
3060
|
+
displayData = { columns: ['value'], rows: data.map(v => [this.formatCellValue(v)]) };
|
|
3061
|
+
}
|
|
3062
|
+
}
|
|
3063
|
+
}
|
|
3064
|
+
else if (typeof data === 'string') {
|
|
3065
|
+
displayData = { text: data };
|
|
3066
|
+
}
|
|
3067
|
+
else if (data === null || data === undefined) {
|
|
3068
|
+
displayData = { text: '无数据' };
|
|
3069
|
+
}
|
|
3070
|
+
else if (typeof data === 'object') {
|
|
3071
|
+
// 单个对象 - 转换为键值对表格
|
|
3072
|
+
const columns = ['属性', '值'];
|
|
3073
|
+
const rows = Object.entries(data).map(([key, value]) => [key, this.formatCellValue(value)]);
|
|
3074
|
+
displayData = { columns, rows };
|
|
3075
|
+
}
|
|
3076
|
+
else {
|
|
3077
|
+
displayData = { text: String(data) };
|
|
3078
|
+
}
|
|
3079
|
+
return {
|
|
3080
|
+
stepId,
|
|
3081
|
+
title: config.title || title,
|
|
3082
|
+
level: config.level || 'summary',
|
|
3083
|
+
layer: config.layer, // 分层展示层级
|
|
3084
|
+
format: config.format || 'table',
|
|
3085
|
+
data: displayData,
|
|
3086
|
+
highlight: config.highlight,
|
|
3087
|
+
sql, // 保存原始 SQL
|
|
3088
|
+
expandable: config.expandable, // 是否支持展开查看详细分析
|
|
3089
|
+
metadataFields: config.metadataFields, // 提取到元数据的字段
|
|
3090
|
+
hidden_columns: config.hidden_columns, // 隐藏的列
|
|
3091
|
+
columnDefinitions, // 完整的列定义(包含 hidden 等属性)
|
|
3092
|
+
collapsible: config.collapsible, // 是否可折叠
|
|
3093
|
+
defaultCollapsed: config.defaultCollapsed, // 是否默认折叠
|
|
3094
|
+
};
|
|
3095
|
+
}
|
|
3096
|
+
/**
|
|
3097
|
+
* Build a deterministic "insight summary" DisplayResult from synthesize configs.
|
|
3098
|
+
*
|
|
3099
|
+
* Motivation:
|
|
3100
|
+
* - Skills already carry `synthesize:` configs (role/fields/insights)
|
|
3101
|
+
* - Agents need compact, citeable KPIs + insights without relying on ai_summary
|
|
3102
|
+
*
|
|
3103
|
+
* Current scope (v2):
|
|
3104
|
+
* - Processes config.role in {'overview', 'conclusion', 'list', 'clusters'}
|
|
3105
|
+
* - overview/conclusion: uses first row/object as the KPI row
|
|
3106
|
+
* - list/clusters: summarizes group distributions + top items (best-effort)
|
|
3107
|
+
*/
|
|
3108
|
+
buildSynthesizeSummaryDisplayResult(synthesizeData) {
|
|
3109
|
+
if (!Array.isArray(synthesizeData) || synthesizeData.length === 0)
|
|
3110
|
+
return null;
|
|
3111
|
+
const keyRoleItems = synthesizeData.filter(item => item?.success === true &&
|
|
3112
|
+
item?.config &&
|
|
3113
|
+
typeof item.config === 'object' &&
|
|
3114
|
+
['overview', 'conclusion', 'list', 'clusters'].includes(String(item.config.role)));
|
|
3115
|
+
if (keyRoleItems.length === 0)
|
|
3116
|
+
return null;
|
|
3117
|
+
const metrics = [];
|
|
3118
|
+
const insights = [];
|
|
3119
|
+
const resolvePath = (ctx, path) => {
|
|
3120
|
+
if (!path || !ctx)
|
|
3121
|
+
return undefined;
|
|
3122
|
+
if (!path.includes('.'))
|
|
3123
|
+
return ctx[path];
|
|
3124
|
+
const parts = path.split('.');
|
|
3125
|
+
let cur = ctx;
|
|
3126
|
+
for (const p of parts) {
|
|
3127
|
+
if (cur === null || cur === undefined)
|
|
3128
|
+
return undefined;
|
|
3129
|
+
cur = cur[p];
|
|
3130
|
+
}
|
|
3131
|
+
return cur;
|
|
3132
|
+
};
|
|
3133
|
+
const applyTemplate = (template, ctx) => {
|
|
3134
|
+
const t = String(template || '');
|
|
3135
|
+
if (!t.includes('{{'))
|
|
3136
|
+
return t;
|
|
3137
|
+
return t.replace(/\{\{\s*([a-zA-Z0-9_\\.]+)\s*\}\}/g, (_m, key) => {
|
|
3138
|
+
const v = resolvePath(ctx, String(key || '').trim());
|
|
3139
|
+
if (v === undefined || v === null)
|
|
3140
|
+
return '';
|
|
3141
|
+
if (typeof v === 'object') {
|
|
3142
|
+
try {
|
|
3143
|
+
return JSON.stringify(v);
|
|
3144
|
+
}
|
|
3145
|
+
catch {
|
|
3146
|
+
return String(v);
|
|
3147
|
+
}
|
|
3148
|
+
}
|
|
3149
|
+
return String(v);
|
|
3150
|
+
});
|
|
3151
|
+
};
|
|
3152
|
+
const evalConditionOnRow = (condition, rowCtx) => {
|
|
3153
|
+
const expr = String(condition || '').trim();
|
|
3154
|
+
if (!expr)
|
|
3155
|
+
return true;
|
|
3156
|
+
try {
|
|
3157
|
+
// YAML-defined expressions are trusted (skill author controlled).
|
|
3158
|
+
const fn = new Function('ctx', `with (ctx) { return (${expr}); }`);
|
|
3159
|
+
return Boolean(fn(rowCtx));
|
|
3160
|
+
}
|
|
3161
|
+
catch {
|
|
3162
|
+
return false;
|
|
3163
|
+
}
|
|
3164
|
+
};
|
|
3165
|
+
const isPlainObject = (v) => {
|
|
3166
|
+
return typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
3167
|
+
};
|
|
3168
|
+
const toNumber = (v) => {
|
|
3169
|
+
if (typeof v === 'number' && Number.isFinite(v))
|
|
3170
|
+
return v;
|
|
3171
|
+
if (typeof v === 'string') {
|
|
3172
|
+
const s = v.trim();
|
|
3173
|
+
if (!s)
|
|
3174
|
+
return null;
|
|
3175
|
+
const n = Number(s);
|
|
3176
|
+
return Number.isFinite(n) ? n : null;
|
|
3177
|
+
}
|
|
3178
|
+
return null;
|
|
3179
|
+
};
|
|
3180
|
+
const isIteratorData = (data) => {
|
|
3181
|
+
if (!Array.isArray(data) || data.length === 0)
|
|
3182
|
+
return false;
|
|
3183
|
+
const first = data[0];
|
|
3184
|
+
return isPlainObject(first) && 'itemIndex' in first && 'item' in first && 'result' in first;
|
|
3185
|
+
};
|
|
3186
|
+
const collectTemplateKeys = (template) => {
|
|
3187
|
+
const keys = [];
|
|
3188
|
+
const t = String(template || '');
|
|
3189
|
+
const re = /\{\{\s*([a-zA-Z0-9_\\.]+)\s*\}\}/g;
|
|
3190
|
+
let m;
|
|
3191
|
+
while ((m = re.exec(t)) !== null) {
|
|
3192
|
+
const key = String(m[1] || '').trim();
|
|
3193
|
+
if (!key)
|
|
3194
|
+
continue;
|
|
3195
|
+
// Only keep root path segment (we don't build nested objects in iterator extraction)
|
|
3196
|
+
const root = key.includes('.') ? key.split('.')[0] : key;
|
|
3197
|
+
if (root)
|
|
3198
|
+
keys.push(root);
|
|
3199
|
+
}
|
|
3200
|
+
return keys;
|
|
3201
|
+
};
|
|
3202
|
+
const resolveFieldFromSkillResult = (skillResult, field) => {
|
|
3203
|
+
if (!skillResult || !field)
|
|
3204
|
+
return undefined;
|
|
3205
|
+
// 1) Prefer diagnostics for common fields
|
|
3206
|
+
if (field === 'diagnosis' && Array.isArray(skillResult.diagnostics) && skillResult.diagnostics.length > 0) {
|
|
3207
|
+
const d = skillResult.diagnostics[0];
|
|
3208
|
+
if (d && typeof d.diagnosis === 'string' && d.diagnosis.trim())
|
|
3209
|
+
return d.diagnosis;
|
|
3210
|
+
}
|
|
3211
|
+
if (field === 'confidence' && Array.isArray(skillResult.diagnostics) && skillResult.diagnostics.length > 0) {
|
|
3212
|
+
const d = skillResult.diagnostics[0];
|
|
3213
|
+
if (d && typeof d.confidence === 'number' && Number.isFinite(d.confidence))
|
|
3214
|
+
return d.confidence;
|
|
3215
|
+
}
|
|
3216
|
+
// 2) Search rawResults step outputs for a field match (first row/object only)
|
|
3217
|
+
const raw = skillResult.rawResults;
|
|
3218
|
+
if (raw && typeof raw === 'object') {
|
|
3219
|
+
for (const stepResult of Object.values(raw)) {
|
|
3220
|
+
const data = stepResult?.data;
|
|
3221
|
+
if (Array.isArray(data) && data.length > 0) {
|
|
3222
|
+
const first = data[0];
|
|
3223
|
+
if (isPlainObject(first) && field in first)
|
|
3224
|
+
return first[field];
|
|
3225
|
+
}
|
|
3226
|
+
else if (isPlainObject(data) && field in data) {
|
|
3227
|
+
return data[field];
|
|
3228
|
+
}
|
|
3229
|
+
}
|
|
3230
|
+
}
|
|
3231
|
+
return undefined;
|
|
3232
|
+
};
|
|
3233
|
+
const resolveClusterBy = (clusterBy) => {
|
|
3234
|
+
if (!clusterBy)
|
|
3235
|
+
return null;
|
|
3236
|
+
if (typeof clusterBy === 'string') {
|
|
3237
|
+
const field = clusterBy.trim();
|
|
3238
|
+
return field ? { field } : null;
|
|
3239
|
+
}
|
|
3240
|
+
if (typeof clusterBy === 'object') {
|
|
3241
|
+
const fieldRaw = clusterBy?.field;
|
|
3242
|
+
const field = typeof fieldRaw === 'string' ? fieldRaw.trim() : '';
|
|
3243
|
+
if (!field)
|
|
3244
|
+
return null;
|
|
3245
|
+
const labelRaw = clusterBy?.label;
|
|
3246
|
+
const label = typeof labelRaw === 'string' && labelRaw.trim() ? labelRaw.trim() : undefined;
|
|
3247
|
+
return { field, label };
|
|
3248
|
+
}
|
|
3249
|
+
return null;
|
|
3250
|
+
};
|
|
3251
|
+
const extractRowsForListLikeRole = (data, config) => {
|
|
3252
|
+
if (!data)
|
|
3253
|
+
return [];
|
|
3254
|
+
// Determine which fields we may need to synthesize summaries.
|
|
3255
|
+
const needed = new Set();
|
|
3256
|
+
if (config.role === 'clusters') {
|
|
3257
|
+
const c = resolveClusterBy(config.clusterBy);
|
|
3258
|
+
if (c?.field)
|
|
3259
|
+
needed.add(c.field);
|
|
3260
|
+
}
|
|
3261
|
+
if (Array.isArray(config.groupBy)) {
|
|
3262
|
+
for (const g of config.groupBy) {
|
|
3263
|
+
if (g?.field)
|
|
3264
|
+
needed.add(String(g.field));
|
|
3265
|
+
}
|
|
3266
|
+
}
|
|
3267
|
+
if (Array.isArray(config.fields)) {
|
|
3268
|
+
for (const f of config.fields) {
|
|
3269
|
+
if (f?.key)
|
|
3270
|
+
needed.add(String(f.key));
|
|
3271
|
+
if (typeof f?.format === 'string') {
|
|
3272
|
+
for (const k of collectTemplateKeys(f.format))
|
|
3273
|
+
needed.add(k);
|
|
3274
|
+
}
|
|
3275
|
+
}
|
|
3276
|
+
}
|
|
3277
|
+
if (Array.isArray(config.insights)) {
|
|
3278
|
+
for (const i of config.insights) {
|
|
3279
|
+
if (typeof i?.template === 'string') {
|
|
3280
|
+
for (const k of collectTemplateKeys(i.template))
|
|
3281
|
+
needed.add(k);
|
|
3282
|
+
}
|
|
3283
|
+
}
|
|
3284
|
+
}
|
|
3285
|
+
// Iterator results: [{ itemIndex, item, result }]
|
|
3286
|
+
if (isIteratorData(data)) {
|
|
3287
|
+
const rows = [];
|
|
3288
|
+
for (const it of data) {
|
|
3289
|
+
const row = isPlainObject(it?.item) ? { ...it.item } : {};
|
|
3290
|
+
// Fill missing fields from nested SkillExecutionResult
|
|
3291
|
+
for (const key of needed) {
|
|
3292
|
+
if (row[key] !== undefined)
|
|
3293
|
+
continue;
|
|
3294
|
+
const v = resolveFieldFromSkillResult(it?.result, key);
|
|
3295
|
+
if (v !== undefined)
|
|
3296
|
+
row[key] = v;
|
|
3297
|
+
}
|
|
3298
|
+
rows.push(row);
|
|
3299
|
+
}
|
|
3300
|
+
return rows;
|
|
3301
|
+
}
|
|
3302
|
+
if (Array.isArray(data)) {
|
|
3303
|
+
return data.filter(isPlainObject);
|
|
3304
|
+
}
|
|
3305
|
+
if (isPlainObject(data))
|
|
3306
|
+
return [data];
|
|
3307
|
+
return [];
|
|
3308
|
+
};
|
|
3309
|
+
const extractRowObject = (data) => {
|
|
3310
|
+
if (!data)
|
|
3311
|
+
return null;
|
|
3312
|
+
// Handle columnar format: { columns: string[], rows: any[][] }
|
|
3313
|
+
// This is the DataEnvelope v2.0 format returned by trace_processor_shell.
|
|
3314
|
+
if (data.columns && Array.isArray(data.columns) &&
|
|
3315
|
+
Array.isArray(data.rows) && data.rows.length > 0) {
|
|
3316
|
+
const row = {};
|
|
3317
|
+
const cols = data.columns;
|
|
3318
|
+
const firstRow = data.rows[0];
|
|
3319
|
+
for (let i = 0; i < cols.length && i < firstRow.length; i++) {
|
|
3320
|
+
row[cols[i]] = firstRow[i];
|
|
3321
|
+
}
|
|
3322
|
+
return row;
|
|
3323
|
+
}
|
|
3324
|
+
if (Array.isArray(data) && data.length > 0) {
|
|
3325
|
+
const first = data[0];
|
|
3326
|
+
if (first && typeof first === 'object' && !Array.isArray(first)) {
|
|
3327
|
+
return first;
|
|
3328
|
+
}
|
|
3329
|
+
return null;
|
|
3330
|
+
}
|
|
3331
|
+
if (typeof data === 'object' && !Array.isArray(data)) {
|
|
3332
|
+
return data;
|
|
3333
|
+
}
|
|
3334
|
+
return null;
|
|
3335
|
+
};
|
|
3336
|
+
for (const item of keyRoleItems) {
|
|
3337
|
+
const config = item.config;
|
|
3338
|
+
const role = config?.role;
|
|
3339
|
+
// list/clusters: summarize distribution + top items, best-effort
|
|
3340
|
+
if (role === 'list' || role === 'clusters') {
|
|
3341
|
+
const rows = extractRowsForListLikeRole(item.data, config);
|
|
3342
|
+
if (rows.length === 0)
|
|
3343
|
+
continue;
|
|
3344
|
+
const stepName = item.stepName || item.stepId;
|
|
3345
|
+
const itemPrefix = keyRoleItems.length > 1 ? `${stepName}: ` : `${stepName}: `;
|
|
3346
|
+
// Group distributions
|
|
3347
|
+
const groupBy = [];
|
|
3348
|
+
if (role === 'clusters') {
|
|
3349
|
+
const c = resolveClusterBy(config.clusterBy);
|
|
3350
|
+
if (c?.field) {
|
|
3351
|
+
groupBy.push({ field: c.field, title: `聚类(${c.label || c.field})` });
|
|
3352
|
+
}
|
|
3353
|
+
}
|
|
3354
|
+
if (Array.isArray(config.groupBy)) {
|
|
3355
|
+
for (const g of config.groupBy) {
|
|
3356
|
+
if (!g || typeof g.field !== 'string' || typeof g.title !== 'string')
|
|
3357
|
+
continue;
|
|
3358
|
+
groupBy.push({ field: g.field, title: g.title });
|
|
3359
|
+
}
|
|
3360
|
+
}
|
|
3361
|
+
const pickDistributionMode = () => {
|
|
3362
|
+
// If rows contain a numeric percent-like field, aggregate percentages (common for breakdown tables).
|
|
3363
|
+
const percentKeys = ['percent', 'pct', 'percentage'];
|
|
3364
|
+
for (const k of percentKeys) {
|
|
3365
|
+
if (rows.some(r => toNumber(r?.[k]) !== null)) {
|
|
3366
|
+
return { mode: 'percent', valueKey: k };
|
|
3367
|
+
}
|
|
3368
|
+
}
|
|
3369
|
+
return { mode: 'count' };
|
|
3370
|
+
};
|
|
3371
|
+
const distMode = pickDistributionMode();
|
|
3372
|
+
for (const g of groupBy) {
|
|
3373
|
+
const field = g.field;
|
|
3374
|
+
const totalCount = rows.length;
|
|
3375
|
+
const buckets = new Map();
|
|
3376
|
+
for (const r of rows) {
|
|
3377
|
+
const rawKey = r?.[field];
|
|
3378
|
+
const key = rawKey === undefined || rawKey === null || String(rawKey).trim() === ''
|
|
3379
|
+
? 'unknown'
|
|
3380
|
+
: String(rawKey);
|
|
3381
|
+
if (!buckets.has(key)) {
|
|
3382
|
+
buckets.set(key, { count: 0, sum: 0 });
|
|
3383
|
+
}
|
|
3384
|
+
const b = buckets.get(key);
|
|
3385
|
+
b.count += 1;
|
|
3386
|
+
if (distMode.mode === 'percent' && distMode.valueKey) {
|
|
3387
|
+
const n = toNumber(r?.[distMode.valueKey]);
|
|
3388
|
+
if (n !== null)
|
|
3389
|
+
b.sum = (b.sum || 0) + n;
|
|
3390
|
+
}
|
|
3391
|
+
}
|
|
3392
|
+
const entries = Array.from(buckets.entries()).map(([k, v]) => ({ k, ...v }));
|
|
3393
|
+
entries.sort((a, b) => {
|
|
3394
|
+
if (distMode.mode === 'percent')
|
|
3395
|
+
return (b.sum || 0) - (a.sum || 0);
|
|
3396
|
+
return b.count - a.count;
|
|
3397
|
+
});
|
|
3398
|
+
const top = entries.slice(0, 3);
|
|
3399
|
+
const segs = [];
|
|
3400
|
+
for (const e of top) {
|
|
3401
|
+
if (distMode.mode === 'percent') {
|
|
3402
|
+
segs.push(`${e.k} ${(e.sum || 0).toFixed(1).replace(/\.0$/, '')}%`);
|
|
3403
|
+
}
|
|
3404
|
+
else {
|
|
3405
|
+
const pct = totalCount > 0 ? Math.round(100 * e.count / totalCount) : 0;
|
|
3406
|
+
segs.push(`${e.k} ${e.count} (${pct}%)`);
|
|
3407
|
+
}
|
|
3408
|
+
}
|
|
3409
|
+
if (segs.length > 0) {
|
|
3410
|
+
insights.push(`${g.title}: ${segs.join(',')}`);
|
|
3411
|
+
}
|
|
3412
|
+
}
|
|
3413
|
+
// Top items: when fields define a (name,value) mapping
|
|
3414
|
+
if (Array.isArray(config.fields) && config.fields.length >= 2) {
|
|
3415
|
+
const nameField = config.fields[0];
|
|
3416
|
+
const valueField = config.fields[1];
|
|
3417
|
+
if (nameField?.key && valueField?.key) {
|
|
3418
|
+
const items = rows.slice(0, 3).map(r => {
|
|
3419
|
+
const name = r?.[nameField.key];
|
|
3420
|
+
const raw = r?.[valueField.key];
|
|
3421
|
+
const ctx = { ...(r || {}), value: raw };
|
|
3422
|
+
const formatted = valueField.format ? applyTemplate(valueField.format, ctx).trim() : undefined;
|
|
3423
|
+
const value = formatted !== undefined && formatted !== null && formatted !== ''
|
|
3424
|
+
? formatted
|
|
3425
|
+
: (raw === undefined || raw === null ? '' : String(raw));
|
|
3426
|
+
const nameStr = name === undefined || name === null ? '' : String(name);
|
|
3427
|
+
const s = nameStr ? `${nameStr}: ${value}` : value;
|
|
3428
|
+
return s.length > 90 ? s.slice(0, 90) + '…' : s;
|
|
3429
|
+
}).filter(s => typeof s === 'string' && s.trim().length > 0);
|
|
3430
|
+
if (items.length > 0) {
|
|
3431
|
+
insights.push(`${itemPrefix}Top: ${items.join(';')}`);
|
|
3432
|
+
}
|
|
3433
|
+
}
|
|
3434
|
+
}
|
|
3435
|
+
// Optional row-level insights (evaluate on first row only to keep summary compact)
|
|
3436
|
+
if (Array.isArray(config.insights) && config.insights.length > 0) {
|
|
3437
|
+
const row0 = rows[0];
|
|
3438
|
+
if (row0) {
|
|
3439
|
+
for (const insight of config.insights) {
|
|
3440
|
+
if (!insight || typeof insight.template !== 'string')
|
|
3441
|
+
continue;
|
|
3442
|
+
const ok = insight.condition ? evalConditionOnRow(insight.condition, row0) : true;
|
|
3443
|
+
if (!ok)
|
|
3444
|
+
continue;
|
|
3445
|
+
const rendered = applyTemplate(insight.template, row0).trim();
|
|
3446
|
+
if (rendered)
|
|
3447
|
+
insights.push(`${itemPrefix}${rendered}`);
|
|
3448
|
+
}
|
|
3449
|
+
}
|
|
3450
|
+
}
|
|
3451
|
+
// Light metric: list size (helps citation and sanity checks)
|
|
3452
|
+
metrics.push({
|
|
3453
|
+
label: `${stepName} 条目数`,
|
|
3454
|
+
value: rows.length,
|
|
3455
|
+
});
|
|
3456
|
+
continue;
|
|
3457
|
+
}
|
|
3458
|
+
const row = extractRowObject(item.data);
|
|
3459
|
+
if (!row)
|
|
3460
|
+
continue;
|
|
3461
|
+
// Fields → metrics
|
|
3462
|
+
if (Array.isArray(config.fields)) {
|
|
3463
|
+
for (const field of config.fields) {
|
|
3464
|
+
if (!field || typeof field.key !== 'string' || typeof field.label !== 'string')
|
|
3465
|
+
continue;
|
|
3466
|
+
const raw = row[field.key];
|
|
3467
|
+
if (raw === undefined || raw === null)
|
|
3468
|
+
continue;
|
|
3469
|
+
const ctx = { ...row, value: raw };
|
|
3470
|
+
const formatted = field.format ? applyTemplate(field.format, ctx) : undefined;
|
|
3471
|
+
const value = formatted !== undefined && formatted !== null && String(formatted).trim() !== ''
|
|
3472
|
+
? String(formatted)
|
|
3473
|
+
: (typeof raw === 'number' || typeof raw === 'string' ? raw : String(raw));
|
|
3474
|
+
metrics.push({
|
|
3475
|
+
label: field.label,
|
|
3476
|
+
value,
|
|
3477
|
+
});
|
|
3478
|
+
}
|
|
3479
|
+
}
|
|
3480
|
+
// Insights → short bullet lines
|
|
3481
|
+
if (Array.isArray(config.insights)) {
|
|
3482
|
+
for (const insight of config.insights) {
|
|
3483
|
+
if (!insight || typeof insight.template !== 'string')
|
|
3484
|
+
continue;
|
|
3485
|
+
const ok = insight.condition ? evalConditionOnRow(insight.condition, row) : true;
|
|
3486
|
+
if (!ok)
|
|
3487
|
+
continue;
|
|
3488
|
+
const rendered = applyTemplate(insight.template, row).trim();
|
|
3489
|
+
if (!rendered)
|
|
3490
|
+
continue;
|
|
3491
|
+
const prefix = keyRoleItems.length > 1
|
|
3492
|
+
? `${item.stepName || item.stepId}: `
|
|
3493
|
+
: '';
|
|
3494
|
+
insights.push(`${prefix}${rendered}`);
|
|
3495
|
+
}
|
|
3496
|
+
}
|
|
3497
|
+
}
|
|
3498
|
+
// Dedupe while preserving order
|
|
3499
|
+
const seenMetric = new Set();
|
|
3500
|
+
const dedupedMetrics = metrics.filter(m => {
|
|
3501
|
+
const k = `${m.label}::${String(m.value)}`;
|
|
3502
|
+
if (seenMetric.has(k))
|
|
3503
|
+
return false;
|
|
3504
|
+
seenMetric.add(k);
|
|
3505
|
+
return true;
|
|
3506
|
+
}).slice(0, 12);
|
|
3507
|
+
const seenInsight = new Set();
|
|
3508
|
+
const dedupedInsights = insights.filter(s => {
|
|
3509
|
+
const k = s.trim();
|
|
3510
|
+
if (!k)
|
|
3511
|
+
return false;
|
|
3512
|
+
if (seenInsight.has(k))
|
|
3513
|
+
return false;
|
|
3514
|
+
seenInsight.add(k);
|
|
3515
|
+
return true;
|
|
3516
|
+
}).slice(0, 8);
|
|
3517
|
+
if (dedupedMetrics.length === 0 && dedupedInsights.length === 0)
|
|
3518
|
+
return null;
|
|
3519
|
+
const content = dedupedInsights.length > 0
|
|
3520
|
+
? dedupedInsights.map(s => `- ${s}`).join('\n')
|
|
3521
|
+
: '(无显式洞见,见指标)';
|
|
3522
|
+
return {
|
|
3523
|
+
stepId: '__synthesize_summary__',
|
|
3524
|
+
title: '洞见摘要',
|
|
3525
|
+
level: 'key',
|
|
3526
|
+
layer: 'overview',
|
|
3527
|
+
format: 'summary',
|
|
3528
|
+
data: {
|
|
3529
|
+
summary: {
|
|
3530
|
+
title: '洞见摘要',
|
|
3531
|
+
content,
|
|
3532
|
+
metrics: dedupedMetrics,
|
|
3533
|
+
},
|
|
3534
|
+
},
|
|
3535
|
+
};
|
|
3536
|
+
}
|
|
3537
|
+
/**
|
|
3538
|
+
* 创建 DataEnvelope (v2.0 数据契约格式)
|
|
3539
|
+
*
|
|
3540
|
+
* DataEnvelope 是自描述的数据容器,包含:
|
|
3541
|
+
* - meta: 数据来源和版本信息
|
|
3542
|
+
* - data: 实际数据内容
|
|
3543
|
+
* - display: 显示配置(包括列定义)
|
|
3544
|
+
*
|
|
3545
|
+
* 前端可以根据 display.columns 配置进行通用渲染,无需硬编码字段名。
|
|
3546
|
+
*/
|
|
3547
|
+
buildDataEnvelope(skillId, stepId, title, stepResult, displayConfig, sql) {
|
|
3548
|
+
// First create the DisplayResult using existing logic
|
|
3549
|
+
const displayResult = this.createDisplayResult(stepId, title, stepResult, displayConfig, sql);
|
|
3550
|
+
// Extract column definitions from config or infer from data
|
|
3551
|
+
const explicitColumns = displayConfig?.columns;
|
|
3552
|
+
// Build the DataEnvelope
|
|
3553
|
+
return (0, dataContract_1.displayResultToEnvelope)(displayResult, skillId, explicitColumns);
|
|
3554
|
+
}
|
|
3555
|
+
/**
|
|
3556
|
+
* 将 SkillExecutionResult 转换为 DataEnvelope 数组
|
|
3557
|
+
*
|
|
3558
|
+
* 用于 v2.0 数据契约,统一 SSE 事件格式
|
|
3559
|
+
*/
|
|
3560
|
+
static toDataEnvelopes(result, columnDefinitions) {
|
|
3561
|
+
return result.displayResults.map(dr => {
|
|
3562
|
+
// Prefer external columnDefinitions, fallback to embedded columnDefinitions in DisplayResult
|
|
3563
|
+
const explicitColumns = columnDefinitions?.[dr.stepId] ?? dr.columnDefinitions;
|
|
3564
|
+
// Bridge skillEngine DisplayResult -> dataContract DisplayResult:
|
|
3565
|
+
// dataContract expects metadataConfig.fields, while skillEngine uses metadataFields.
|
|
3566
|
+
const drAny = dr;
|
|
3567
|
+
const drForEnvelope = {
|
|
3568
|
+
...drAny,
|
|
3569
|
+
metadataConfig: drAny.metadataConfig || (Array.isArray(drAny.metadataFields) ? { fields: drAny.metadataFields } : undefined),
|
|
3570
|
+
};
|
|
3571
|
+
return (0, dataContract_1.displayResultToEnvelope)(drForEnvelope, result.skillId, explicitColumns);
|
|
3572
|
+
});
|
|
3573
|
+
}
|
|
3574
|
+
/**
|
|
3575
|
+
* 检查数据是否是迭代器结果
|
|
3576
|
+
*/
|
|
3577
|
+
isIteratorResult(data) {
|
|
3578
|
+
if (data.length === 0)
|
|
3579
|
+
return false;
|
|
3580
|
+
const first = data[0];
|
|
3581
|
+
return typeof first === 'object' && first !== null &&
|
|
3582
|
+
'itemIndex' in first && 'item' in first && 'result' in first;
|
|
3583
|
+
}
|
|
3584
|
+
/**
|
|
3585
|
+
* 将迭代器结果展平为可显示的表格
|
|
3586
|
+
*/
|
|
3587
|
+
flattenIteratorResults(data, _isIterator, columnDefinitions) {
|
|
3588
|
+
if (data.length === 0) {
|
|
3589
|
+
return { text: '无迭代结果' };
|
|
3590
|
+
}
|
|
3591
|
+
const resolveFieldFromSkillResult = (skillResult, field) => {
|
|
3592
|
+
if (!skillResult || !field)
|
|
3593
|
+
return undefined;
|
|
3594
|
+
// Prefer diagnostics for common fields
|
|
3595
|
+
if (Array.isArray(skillResult.diagnostics) && skillResult.diagnostics.length > 0) {
|
|
3596
|
+
const d = skillResult.diagnostics[0];
|
|
3597
|
+
if (field === 'diagnosis' && d && typeof d.diagnosis === 'string' && d.diagnosis.trim()) {
|
|
3598
|
+
return d.diagnosis;
|
|
3599
|
+
}
|
|
3600
|
+
if (field === 'confidence' && d && typeof d.confidence === 'number' && Number.isFinite(d.confidence)) {
|
|
3601
|
+
return d.confidence;
|
|
3602
|
+
}
|
|
3603
|
+
if (field === 'severity' && d && typeof d.severity === 'string' && d.severity.trim()) {
|
|
3604
|
+
return d.severity;
|
|
3605
|
+
}
|
|
3606
|
+
}
|
|
3607
|
+
// Search rawResults step outputs for a field match (first row/object only)
|
|
3608
|
+
const raw = skillResult.rawResults;
|
|
3609
|
+
if (raw && typeof raw === 'object') {
|
|
3610
|
+
for (const stepResult of Object.values(raw)) {
|
|
3611
|
+
const stepData = stepResult?.data;
|
|
3612
|
+
if (Array.isArray(stepData) && stepData.length > 0) {
|
|
3613
|
+
const first = stepData[0];
|
|
3614
|
+
if (first && typeof first === 'object' && !Array.isArray(first) && field in first) {
|
|
3615
|
+
return first[field];
|
|
3616
|
+
}
|
|
3617
|
+
}
|
|
3618
|
+
else if (stepData && typeof stepData === 'object' && !Array.isArray(stepData) && field in stepData) {
|
|
3619
|
+
return stepData[field];
|
|
3620
|
+
}
|
|
3621
|
+
}
|
|
3622
|
+
}
|
|
3623
|
+
return undefined;
|
|
3624
|
+
};
|
|
3625
|
+
const explicitColumns = Array.isArray(columnDefinitions) && columnDefinitions.length > 0
|
|
3626
|
+
? columnDefinitions.map(c => c.name).filter((n) => typeof n === 'string' && n.trim().length > 0)
|
|
3627
|
+
: [];
|
|
3628
|
+
// If step defines explicit columns, prefer them and attempt to extract values
|
|
3629
|
+
// from both `item` and nested `result` (SkillExecutionResult).
|
|
3630
|
+
if (explicitColumns.length > 0) {
|
|
3631
|
+
const columns = explicitColumns;
|
|
3632
|
+
const rows = data.map((iterItem) => {
|
|
3633
|
+
const item = iterItem.item || {};
|
|
3634
|
+
const skillResult = iterItem.result;
|
|
3635
|
+
return columns.map((col) => {
|
|
3636
|
+
const v = (item && typeof item === 'object' && col in item)
|
|
3637
|
+
? item[col]
|
|
3638
|
+
: resolveFieldFromSkillResult(skillResult, col);
|
|
3639
|
+
return this.formatCellValue(v);
|
|
3640
|
+
});
|
|
3641
|
+
});
|
|
3642
|
+
const expandableData = data.map((iterItem) => ({
|
|
3643
|
+
item: iterItem.item,
|
|
3644
|
+
result: {
|
|
3645
|
+
success: iterItem.result?.success ?? false,
|
|
3646
|
+
sections: this.convertDisplayResultsToSections(iterItem.result?.displayResults || []),
|
|
3647
|
+
error: iterItem.result?.error,
|
|
3648
|
+
},
|
|
3649
|
+
}));
|
|
3650
|
+
const summary = this.generateIteratorSummary(data, expandableData);
|
|
3651
|
+
return { columns, rows, expandableData, summary };
|
|
3652
|
+
}
|
|
3653
|
+
// 从 item 中提取关键字段用于显示
|
|
3654
|
+
const firstItem = data[0].item;
|
|
3655
|
+
const itemKeys = Object.keys(firstItem).filter(key => {
|
|
3656
|
+
// 过滤掉太长的字段(如 ts_str 可以保留,但很长的 JSON 字段不要)
|
|
3657
|
+
const value = firstItem[key];
|
|
3658
|
+
if (typeof value === 'string' && value.length > 200)
|
|
3659
|
+
return false;
|
|
3660
|
+
if (typeof value === 'object' && value !== null)
|
|
3661
|
+
return false;
|
|
3662
|
+
return true;
|
|
3663
|
+
}).slice(0, 6); // 最多显示 6 列
|
|
3664
|
+
// 添加一个"状态"列
|
|
3665
|
+
const columns = ['#', ...itemKeys, '分析状态'];
|
|
3666
|
+
const rows = data.map((iterItem, idx) => {
|
|
3667
|
+
const row = [idx + 1];
|
|
3668
|
+
for (const key of itemKeys) {
|
|
3669
|
+
row.push(this.formatCellValue(iterItem.item[key]));
|
|
3670
|
+
}
|
|
3671
|
+
// 添加状态
|
|
3672
|
+
row.push(iterItem.result?.success ? '✓ 完成' : '✗ 失败');
|
|
3673
|
+
return row;
|
|
3674
|
+
});
|
|
3675
|
+
// 提取可展开的详细数据 - 使用 displayResults 而不是 sections
|
|
3676
|
+
const expandableData = data.map((iterItem, idx) => ({
|
|
3677
|
+
item: iterItem.item,
|
|
3678
|
+
result: {
|
|
3679
|
+
success: iterItem.result?.success ?? false,
|
|
3680
|
+
// 将 displayResults 转换为 sections 格式
|
|
3681
|
+
sections: this.convertDisplayResultsToSections(iterItem.result?.displayResults || []),
|
|
3682
|
+
error: iterItem.result?.error,
|
|
3683
|
+
},
|
|
3684
|
+
}));
|
|
3685
|
+
// 生成汇总报告
|
|
3686
|
+
const summary = this.generateIteratorSummary(data, expandableData);
|
|
3687
|
+
return { columns, rows, expandableData, summary };
|
|
3688
|
+
}
|
|
3689
|
+
/**
|
|
3690
|
+
* 生成迭代器结果的汇总报告
|
|
3691
|
+
*/
|
|
3692
|
+
generateIteratorSummary(data, expandableData) {
|
|
3693
|
+
if (data.length === 0)
|
|
3694
|
+
return undefined;
|
|
3695
|
+
const successCount = expandableData.filter(d => d.result.success).length;
|
|
3696
|
+
const failCount = data.length - successCount;
|
|
3697
|
+
const firstItem = expandableData[0]?.item || {};
|
|
3698
|
+
const isJankLike = ('frame_id' in firstItem) ||
|
|
3699
|
+
('jank_type' in firstItem) ||
|
|
3700
|
+
('vsync_missed' in firstItem);
|
|
3701
|
+
const isStartupLike = ('startup_id' in firstItem) ||
|
|
3702
|
+
('startup_type' in firstItem) ||
|
|
3703
|
+
('ttid_ms' in firstItem) ||
|
|
3704
|
+
('ttfd_ms' in firstItem);
|
|
3705
|
+
// Try to extract key indicators from sections to generate a summary.
|
|
3706
|
+
// Prefer domain-specific summaries; fall back to a generic iterator summary.
|
|
3707
|
+
const summaryLines = [];
|
|
3708
|
+
if (!isJankLike && !isStartupLike) {
|
|
3709
|
+
summaryLines.push(`**迭代分析汇总**`);
|
|
3710
|
+
summaryLines.push('');
|
|
3711
|
+
summaryLines.push(`共分析 ${data.length} 项,成功 ${successCount} 项${failCount > 0 ? `,失败 ${failCount} 项` : ''}。`);
|
|
3712
|
+
return {
|
|
3713
|
+
title: '汇总报告',
|
|
3714
|
+
content: summaryLines.join('\n'),
|
|
3715
|
+
};
|
|
3716
|
+
}
|
|
3717
|
+
if (isStartupLike) {
|
|
3718
|
+
summaryLines.push(`**启动事件分析汇总**`);
|
|
3719
|
+
summaryLines.push('');
|
|
3720
|
+
summaryLines.push(`共分析 ${data.length} 个启动事件,成功 ${successCount} 个${failCount > 0 ? `,失败 ${failCount} 个` : ''}。`);
|
|
3721
|
+
// Startup type distribution (best-effort)
|
|
3722
|
+
const typeCounts = new Map();
|
|
3723
|
+
for (const { item } of expandableData) {
|
|
3724
|
+
const t = item?.startup_type;
|
|
3725
|
+
const k = t === undefined || t === null || String(t).trim() === '' ? 'unknown' : String(t);
|
|
3726
|
+
typeCounts.set(k, (typeCounts.get(k) || 0) + 1);
|
|
3727
|
+
}
|
|
3728
|
+
const typeTop = Array.from(typeCounts.entries()).sort((a, b) => b[1] - a[1]).slice(0, 3);
|
|
3729
|
+
if (typeTop.length > 0) {
|
|
3730
|
+
summaryLines.push('');
|
|
3731
|
+
summaryLines.push(`启动类型分布: ${typeTop.map(([k, v]) => `${k} ${v}`).join(',')}`);
|
|
3732
|
+
}
|
|
3733
|
+
// Top slow startups by dur_ms
|
|
3734
|
+
const withDur = expandableData
|
|
3735
|
+
.map(({ item }) => ({
|
|
3736
|
+
startup_id: item?.startup_id,
|
|
3737
|
+
startup_type: item?.startup_type,
|
|
3738
|
+
dur_ms: Number(item?.dur_ms),
|
|
3739
|
+
}))
|
|
3740
|
+
.filter(r => Number.isFinite(r.dur_ms));
|
|
3741
|
+
withDur.sort((a, b) => b.dur_ms - a.dur_ms);
|
|
3742
|
+
const slowTop = withDur.slice(0, 3);
|
|
3743
|
+
if (slowTop.length > 0) {
|
|
3744
|
+
summaryLines.push('');
|
|
3745
|
+
summaryLines.push('最慢启动:');
|
|
3746
|
+
for (const s of slowTop) {
|
|
3747
|
+
summaryLines.push(`- startup_id=${s.startup_id ?? '?'} (${s.startup_type ?? 'unknown'}) ${s.dur_ms.toFixed(0)}ms`);
|
|
3748
|
+
}
|
|
3749
|
+
}
|
|
3750
|
+
return {
|
|
3751
|
+
title: '汇总报告',
|
|
3752
|
+
content: summaryLines.join('\n'),
|
|
3753
|
+
};
|
|
3754
|
+
}
|
|
3755
|
+
// Jank/frame iterator summary (existing behavior)
|
|
3756
|
+
summaryLines.push(`**掉帧分析汇总**`);
|
|
3757
|
+
summaryLines.push('');
|
|
3758
|
+
summaryLines.push(`共分析 ${data.length} 个掉帧帧,成功 ${successCount} 个${failCount > 0 ? `,失败 ${failCount} 个` : ''}。`);
|
|
3759
|
+
summaryLines.push('');
|
|
3760
|
+
// 收集所有帧的关键发现
|
|
3761
|
+
const keyFindings = [];
|
|
3762
|
+
for (const { item, result } of expandableData) {
|
|
3763
|
+
if (!result.success || !result.sections)
|
|
3764
|
+
continue;
|
|
3765
|
+
const frameId = item.frame_id || item.id || '?';
|
|
3766
|
+
const jankType = item.jank_type || 'Unknown';
|
|
3767
|
+
const durMs = item.dur_ms || 0;
|
|
3768
|
+
// 从各个 section 中提取关键信息
|
|
3769
|
+
const frameFindings = [];
|
|
3770
|
+
// 主线程耗时操作
|
|
3771
|
+
const mainSlices = result.sections.main_slices || result.sections['主线程耗时操作'];
|
|
3772
|
+
if (mainSlices?.data && mainSlices.data.length > 0) {
|
|
3773
|
+
const topSlice = mainSlices.data[0];
|
|
3774
|
+
frameFindings.push(`主线程 "${topSlice.name}" 耗时 ${topSlice.total_ms}ms`);
|
|
3775
|
+
}
|
|
3776
|
+
// CPU 频率变化时间线
|
|
3777
|
+
const freqTimeline = result.sections.freq_timeline || result.sections['主线程操作CPU频率变化'];
|
|
3778
|
+
if (freqTimeline?.data && freqTimeline.data.length > 0) {
|
|
3779
|
+
const topFreq = freqTimeline.data[0];
|
|
3780
|
+
if (topFreq.freq_timeline && topFreq.state_count > 2) {
|
|
3781
|
+
frameFindings.push(`${topFreq.slice_name}(${topFreq.total_dur_ms}ms): ${topFreq.freq_timeline}`);
|
|
3782
|
+
}
|
|
3783
|
+
}
|
|
3784
|
+
// 大小核占比
|
|
3785
|
+
const coreAnalysis = result.sections.core_analysis || result.sections['大小核分析'];
|
|
3786
|
+
if (coreAnalysis?.data && coreAnalysis.data.length > 0) {
|
|
3787
|
+
const mainCore = coreAnalysis.data[0];
|
|
3788
|
+
if (mainCore.big_core_pct !== undefined) {
|
|
3789
|
+
frameFindings.push(`大核占比 ${mainCore.big_core_pct}%`);
|
|
3790
|
+
}
|
|
3791
|
+
}
|
|
3792
|
+
// 四大象限
|
|
3793
|
+
const quadrant = result.sections.quadrant || result.sections['四象限分析'];
|
|
3794
|
+
if (quadrant?.data && quadrant.data.length > 0) {
|
|
3795
|
+
const q = quadrant.data[0];
|
|
3796
|
+
if (q.q3_runnable_ms > 5) {
|
|
3797
|
+
frameFindings.push(`Runnable 等待 ${q.q3_runnable_ms}ms`);
|
|
3798
|
+
}
|
|
3799
|
+
}
|
|
3800
|
+
// Binder 调用
|
|
3801
|
+
const binder = result.sections.binder_analysis || result.sections['Binder 调用'];
|
|
3802
|
+
if (binder?.data && binder.data.length > 0) {
|
|
3803
|
+
const topBinder = binder.data[0];
|
|
3804
|
+
if (topBinder.total_ms > 5) {
|
|
3805
|
+
frameFindings.push(`Binder 调用耗时 ${topBinder.total_ms}ms`);
|
|
3806
|
+
}
|
|
3807
|
+
}
|
|
3808
|
+
// 诊断结果
|
|
3809
|
+
const diagnosis = result.sections.frame_diagnosis || result.sections['帧诊断'];
|
|
3810
|
+
if (diagnosis?.diagnostics && diagnosis.diagnostics.length > 0) {
|
|
3811
|
+
const diag = diagnosis.diagnostics[0];
|
|
3812
|
+
if (diag.message) {
|
|
3813
|
+
frameFindings.push(`诊断: ${diag.message}`);
|
|
3814
|
+
}
|
|
3815
|
+
}
|
|
3816
|
+
if (frameFindings.length > 0) {
|
|
3817
|
+
keyFindings.push(`**帧 #${frameId}** (${jankType}, ${durMs.toFixed(1)}ms): ${frameFindings.join(', ')}`);
|
|
3818
|
+
}
|
|
3819
|
+
}
|
|
3820
|
+
if (keyFindings.length > 0) {
|
|
3821
|
+
summaryLines.push('**关键发现:**');
|
|
3822
|
+
summaryLines.push(...keyFindings.slice(0, 10)); // 最多显示 10 个帧的发现
|
|
3823
|
+
if (keyFindings.length > 10) {
|
|
3824
|
+
summaryLines.push(`... (还有 ${keyFindings.length - 10} 个帧)`);
|
|
3825
|
+
}
|
|
3826
|
+
summaryLines.push('');
|
|
3827
|
+
}
|
|
3828
|
+
summaryLines.push('---');
|
|
3829
|
+
summaryLines.push('*点击每行可展开查看详细分析*');
|
|
3830
|
+
return {
|
|
3831
|
+
title: '掉帧帧详细分析',
|
|
3832
|
+
content: summaryLines.join('\n'),
|
|
3833
|
+
};
|
|
3834
|
+
}
|
|
3835
|
+
/**
|
|
3836
|
+
* 将 displayResults 转换为 sections 格式(用于 iterator 结果)
|
|
3837
|
+
*/
|
|
3838
|
+
convertDisplayResultsToSections(displayResults) {
|
|
3839
|
+
const sections = {};
|
|
3840
|
+
for (const dr of displayResults) {
|
|
3841
|
+
// 从 displayResult 的 data 字段中提取实际数据
|
|
3842
|
+
const drData = dr.data;
|
|
3843
|
+
const dataRows = drData?.rows || [];
|
|
3844
|
+
const dataColumns = drData?.columns || [];
|
|
3845
|
+
// 将 rows 转换为对象数组(像 adapter 中的 rowsToObjects)
|
|
3846
|
+
const objects = dataRows.map((row) => {
|
|
3847
|
+
const obj = {};
|
|
3848
|
+
dataColumns.forEach((col, idx) => {
|
|
3849
|
+
obj[col] = row[idx];
|
|
3850
|
+
});
|
|
3851
|
+
return obj;
|
|
3852
|
+
});
|
|
3853
|
+
sections[dr.stepId] = {
|
|
3854
|
+
title: dr.title,
|
|
3855
|
+
data: objects,
|
|
3856
|
+
};
|
|
3857
|
+
}
|
|
3858
|
+
return sections;
|
|
3859
|
+
}
|
|
3860
|
+
/**
|
|
3861
|
+
* 格式化单元格值用于显示
|
|
3862
|
+
*/
|
|
3863
|
+
formatCellValue(value) {
|
|
3864
|
+
if (value === null || value === undefined) {
|
|
3865
|
+
return '-';
|
|
3866
|
+
}
|
|
3867
|
+
if (typeof value === 'number') {
|
|
3868
|
+
return value;
|
|
3869
|
+
}
|
|
3870
|
+
if (typeof value === 'bigint') {
|
|
3871
|
+
return value.toString();
|
|
3872
|
+
}
|
|
3873
|
+
if (typeof value === 'string') {
|
|
3874
|
+
// 截断过长的字符串
|
|
3875
|
+
if (value.length > 100) {
|
|
3876
|
+
return value.substring(0, 97) + '...';
|
|
3877
|
+
}
|
|
3878
|
+
return value;
|
|
3879
|
+
}
|
|
3880
|
+
if (typeof value === 'boolean') {
|
|
3881
|
+
return value ? '是' : '否';
|
|
3882
|
+
}
|
|
3883
|
+
if (typeof value === 'object') {
|
|
3884
|
+
// 对象/数组简化显示
|
|
3885
|
+
const str = JSON.stringify(value);
|
|
3886
|
+
if (str.length > 50) {
|
|
3887
|
+
return str.substring(0, 47) + '...';
|
|
3888
|
+
}
|
|
3889
|
+
return str;
|
|
3890
|
+
}
|
|
3891
|
+
return String(value);
|
|
3892
|
+
}
|
|
3893
|
+
/**
|
|
3894
|
+
* 将行数组转换为对象数组
|
|
3895
|
+
*/
|
|
3896
|
+
rowsToObjects(columns, rows) {
|
|
3897
|
+
return rows.map(row => {
|
|
3898
|
+
const obj = {};
|
|
3899
|
+
columns.forEach((col, idx) => {
|
|
3900
|
+
obj[col] = row[idx];
|
|
3901
|
+
});
|
|
3902
|
+
return obj;
|
|
3903
|
+
});
|
|
3904
|
+
}
|
|
3905
|
+
}
|
|
3906
|
+
exports.SkillExecutor = SkillExecutor;
|
|
3907
|
+
/**
|
|
3908
|
+
* Extract findings from skill execution results based on findingsSchema
|
|
3909
|
+
*/
|
|
3910
|
+
function extractFindings(skillName, findingsSchema, executionContext, stepResults) {
|
|
3911
|
+
if (!findingsSchema || findingsSchema.length === 0) {
|
|
3912
|
+
return [];
|
|
3913
|
+
}
|
|
3914
|
+
const findings = [];
|
|
3915
|
+
for (const schema of findingsSchema) {
|
|
3916
|
+
// Check if this finding type was detected
|
|
3917
|
+
// The condition is implicitly "data exists and has values"
|
|
3918
|
+
// More sophisticated rules can be added later
|
|
3919
|
+
const evidenceData = {};
|
|
3920
|
+
let hasEvidence = false;
|
|
3921
|
+
// Collect evidence from specified fields
|
|
3922
|
+
if (schema.evidenceFields) {
|
|
3923
|
+
for (const fieldPath of schema.evidenceFields) {
|
|
3924
|
+
const value = resolveFieldPath(fieldPath, executionContext, stepResults);
|
|
3925
|
+
if (value !== undefined && value !== null) {
|
|
3926
|
+
evidenceData[fieldPath] = value;
|
|
3927
|
+
hasEvidence = true;
|
|
3928
|
+
}
|
|
3929
|
+
}
|
|
3930
|
+
}
|
|
3931
|
+
// Only create finding if we have evidence
|
|
3932
|
+
if (hasEvidence) {
|
|
3933
|
+
// Substitute template placeholders
|
|
3934
|
+
const title = substituteTemplate(schema.titleTemplate, evidenceData);
|
|
3935
|
+
const description = schema.descriptionTemplate
|
|
3936
|
+
? substituteTemplate(schema.descriptionTemplate, evidenceData)
|
|
3937
|
+
: undefined;
|
|
3938
|
+
findings.push({
|
|
3939
|
+
id: `${skillName}_${schema.id}`,
|
|
3940
|
+
severity: schema.severity,
|
|
3941
|
+
title,
|
|
3942
|
+
description,
|
|
3943
|
+
evidence: evidenceData,
|
|
3944
|
+
sourceModule: skillName,
|
|
3945
|
+
confidence: calculateConfidence(evidenceData, schema.evidenceFields),
|
|
3946
|
+
});
|
|
3947
|
+
}
|
|
3948
|
+
}
|
|
3949
|
+
return findings;
|
|
3950
|
+
}
|
|
3951
|
+
/**
|
|
3952
|
+
* Extract suggestions from skill execution results based on suggestionsSchema
|
|
3953
|
+
*/
|
|
3954
|
+
function extractSuggestions(skillName, suggestionsSchema, executionContext, stepResults) {
|
|
3955
|
+
if (!suggestionsSchema || suggestionsSchema.length === 0) {
|
|
3956
|
+
return [];
|
|
3957
|
+
}
|
|
3958
|
+
const suggestions = [];
|
|
3959
|
+
for (const schema of suggestionsSchema) {
|
|
3960
|
+
// Evaluate the condition to see if this suggestion applies
|
|
3961
|
+
const conditionMet = evaluateSuggestionCondition(schema.condition, executionContext, stepResults);
|
|
3962
|
+
if (conditionMet) {
|
|
3963
|
+
// Map parameters from current results to target params
|
|
3964
|
+
const params = {};
|
|
3965
|
+
if (schema.paramsMapping) {
|
|
3966
|
+
for (const [targetKey, sourcePath] of Object.entries(schema.paramsMapping)) {
|
|
3967
|
+
const value = resolveFieldPath(sourcePath, executionContext, stepResults);
|
|
3968
|
+
if (value !== undefined) {
|
|
3969
|
+
params[targetKey] = value;
|
|
3970
|
+
}
|
|
3971
|
+
}
|
|
3972
|
+
}
|
|
3973
|
+
// Substitute template placeholders in question
|
|
3974
|
+
const questionTemplate = substituteTemplate(schema.questionTemplate, params);
|
|
3975
|
+
suggestions.push({
|
|
3976
|
+
id: `${skillName}_${schema.id}`,
|
|
3977
|
+
targetModule: schema.targetModule,
|
|
3978
|
+
questionTemplate,
|
|
3979
|
+
params,
|
|
3980
|
+
priority: schema.priority ?? 100,
|
|
3981
|
+
reason: `Triggered by condition: ${schema.condition}`,
|
|
3982
|
+
});
|
|
3983
|
+
}
|
|
3984
|
+
}
|
|
3985
|
+
// Sort by priority (lower = higher priority)
|
|
3986
|
+
suggestions.sort((a, b) => a.priority - b.priority);
|
|
3987
|
+
return suggestions;
|
|
3988
|
+
}
|
|
3989
|
+
/**
|
|
3990
|
+
* Resolve a field path to get its value from context or step results
|
|
3991
|
+
* Supports paths like: "step_id.field_name", "params.value", "variables.name"
|
|
3992
|
+
*/
|
|
3993
|
+
function resolveFieldPath(path, context, stepResults) {
|
|
3994
|
+
const parts = path.split('.');
|
|
3995
|
+
if (parts.length === 0)
|
|
3996
|
+
return undefined;
|
|
3997
|
+
const root = parts[0];
|
|
3998
|
+
const rest = parts.slice(1);
|
|
3999
|
+
let value;
|
|
4000
|
+
// Try to resolve from different sources
|
|
4001
|
+
if (stepResults[root]?.data !== undefined) {
|
|
4002
|
+
value = stepResults[root].data;
|
|
4003
|
+
}
|
|
4004
|
+
else if (context.variables[root] !== undefined) {
|
|
4005
|
+
value = context.variables[root];
|
|
4006
|
+
}
|
|
4007
|
+
else if (context.params[root] !== undefined) {
|
|
4008
|
+
value = context.params[root];
|
|
4009
|
+
}
|
|
4010
|
+
else if (context.inherited[root] !== undefined) {
|
|
4011
|
+
value = context.inherited[root];
|
|
4012
|
+
}
|
|
4013
|
+
else {
|
|
4014
|
+
return undefined;
|
|
4015
|
+
}
|
|
4016
|
+
// Navigate the rest of the path
|
|
4017
|
+
for (const part of rest) {
|
|
4018
|
+
if (value === undefined || value === null)
|
|
4019
|
+
return undefined;
|
|
4020
|
+
// Handle array index
|
|
4021
|
+
const arrayMatch = part.match(/^(\w+)\[(\d+)\]$/);
|
|
4022
|
+
if (arrayMatch) {
|
|
4023
|
+
value = value[arrayMatch[1]]?.[parseInt(arrayMatch[2])];
|
|
4024
|
+
}
|
|
4025
|
+
else if (Array.isArray(value) && !isNaN(parseInt(part))) {
|
|
4026
|
+
value = value[parseInt(part)];
|
|
4027
|
+
}
|
|
4028
|
+
else {
|
|
4029
|
+
value = value[part];
|
|
4030
|
+
}
|
|
4031
|
+
}
|
|
4032
|
+
return value;
|
|
4033
|
+
}
|
|
4034
|
+
/**
|
|
4035
|
+
* Substitute template placeholders {field_name} with actual values
|
|
4036
|
+
*/
|
|
4037
|
+
function substituteTemplate(template, values) {
|
|
4038
|
+
return template.replace(/\{(\w+)\}/g, (_, key) => {
|
|
4039
|
+
const value = values[key];
|
|
4040
|
+
if (value === undefined || value === null)
|
|
4041
|
+
return `{${key}}`;
|
|
4042
|
+
if (typeof value === 'object')
|
|
4043
|
+
return JSON.stringify(value);
|
|
4044
|
+
return String(value);
|
|
4045
|
+
});
|
|
4046
|
+
}
|
|
4047
|
+
/**
|
|
4048
|
+
* Evaluate a suggestion condition expression
|
|
4049
|
+
* Supports simple comparisons like: "field != value", "field > value"
|
|
4050
|
+
*/
|
|
4051
|
+
function evaluateSuggestionCondition(condition, context, stepResults) {
|
|
4052
|
+
try {
|
|
4053
|
+
// Parse simple conditions: "field operator value"
|
|
4054
|
+
const operators = ['!=', '==', '>=', '<=', '>', '<', '===', '!=='];
|
|
4055
|
+
for (const op of operators) {
|
|
4056
|
+
const parts = condition.split(op).map(s => s.trim());
|
|
4057
|
+
if (parts.length === 2) {
|
|
4058
|
+
const leftPath = parts[0];
|
|
4059
|
+
const rightValue = parts[1];
|
|
4060
|
+
const leftValue = resolveFieldPath(leftPath, context, stepResults);
|
|
4061
|
+
// Handle quoted string values
|
|
4062
|
+
let right = rightValue;
|
|
4063
|
+
if (rightValue.startsWith('"') && rightValue.endsWith('"')) {
|
|
4064
|
+
right = rightValue.slice(1, -1);
|
|
4065
|
+
}
|
|
4066
|
+
else if (rightValue.startsWith("'") && rightValue.endsWith("'")) {
|
|
4067
|
+
right = rightValue.slice(1, -1);
|
|
4068
|
+
}
|
|
4069
|
+
else if (!isNaN(Number(rightValue))) {
|
|
4070
|
+
right = Number(rightValue);
|
|
4071
|
+
}
|
|
4072
|
+
else if (rightValue === 'true') {
|
|
4073
|
+
right = true;
|
|
4074
|
+
}
|
|
4075
|
+
else if (rightValue === 'false') {
|
|
4076
|
+
right = false;
|
|
4077
|
+
}
|
|
4078
|
+
else if (rightValue === 'null' || rightValue === 'undefined') {
|
|
4079
|
+
right = null;
|
|
4080
|
+
}
|
|
4081
|
+
else {
|
|
4082
|
+
// It might be a field path
|
|
4083
|
+
right = resolveFieldPath(rightValue, context, stepResults);
|
|
4084
|
+
}
|
|
4085
|
+
// Perform comparison
|
|
4086
|
+
switch (op) {
|
|
4087
|
+
case '!=':
|
|
4088
|
+
case '!==':
|
|
4089
|
+
return leftValue !== right;
|
|
4090
|
+
case '==':
|
|
4091
|
+
case '===':
|
|
4092
|
+
return leftValue === right;
|
|
4093
|
+
case '>':
|
|
4094
|
+
return leftValue > right;
|
|
4095
|
+
case '<':
|
|
4096
|
+
return leftValue < right;
|
|
4097
|
+
case '>=':
|
|
4098
|
+
return leftValue >= right;
|
|
4099
|
+
case '<=':
|
|
4100
|
+
return leftValue <= right;
|
|
4101
|
+
}
|
|
4102
|
+
}
|
|
4103
|
+
}
|
|
4104
|
+
// If no operator found, treat as truthy check
|
|
4105
|
+
const value = resolveFieldPath(condition, context, stepResults);
|
|
4106
|
+
return Boolean(value);
|
|
4107
|
+
}
|
|
4108
|
+
catch (e) {
|
|
4109
|
+
console.warn(`[extractSuggestions] Failed to evaluate condition: ${condition}`, e);
|
|
4110
|
+
return false;
|
|
4111
|
+
}
|
|
4112
|
+
}
|
|
4113
|
+
/**
|
|
4114
|
+
* Calculate confidence score based on evidence completeness
|
|
4115
|
+
*/
|
|
4116
|
+
function calculateConfidence(evidence, expectedFields) {
|
|
4117
|
+
if (!expectedFields || expectedFields.length === 0) {
|
|
4118
|
+
return Object.keys(evidence).length > 0 ? 0.7 : 0;
|
|
4119
|
+
}
|
|
4120
|
+
const foundFields = expectedFields.filter(f => evidence[f] !== undefined);
|
|
4121
|
+
return foundFields.length / expectedFields.length;
|
|
4122
|
+
}
|
|
4123
|
+
// =============================================================================
|
|
4124
|
+
// 工厂函数
|
|
4125
|
+
// =============================================================================
|
|
4126
|
+
function createSkillExecutor(traceProcessor, aiService, eventEmitter) {
|
|
4127
|
+
return new SkillExecutor(traceProcessor, aiService, eventEmitter);
|
|
4128
|
+
}
|
|
4129
|
+
//# sourceMappingURL=skillExecutor.js.map
|