At agent-eval 0.171.0 createTraceAnalyst(definition, options) requires options.engine: TraceAnalysisEngine, and that field is not optional (dist/default-registry-B0s2zU-s.d.ts:79).
Grepping the whole installed dist for a constructor returns exactly one:
$ grep -h "): TraceAnalysisEngine" dist/*.d.ts
dist/index-DT73JraI.d.ts:178 declare function createDspyRlmTraceEngine(options: DspyRlmTraceEngineOptions): TraceAnalysisEngine;
DspyRlmTraceEngineOptions needs runner?: ExternalOptimizerRunnerCommand ("Python command used to load agent-eval-rpc[dspy]. Default: python", index-DT73JraI.d.ts:172) plus a caller-owned ExternalOptimizerModelCall and a recordExecution sink.
Measured consequence, run against the installed packages:
buildDefaultAnalystRegistry().list()
-> [{ id: "efficiency-behavioral", version: "2.0.0", cost: { kind: "deterministic" } }]
analystsFromRegistry(thatRegistry) // @tangle-network/agent-runtime/kernel 0.185.2
-> throws: analystsFromRegistry: "failure-mode", "intent-divergence", "knowledge-gap",
"knowledge-poisoning", "improvement" are not registered;
the registry has "efficiency-behavioral"
So a consumer that already has a model seam — an AgentProfile on a bridge or a sandbox seat, driven through agent-runtime streamAgentTurn — cannot build a registry that satisfies analystsFromRegistry, and cannot reach any of the five DEFAULT_TRACE_ANALYST_KINDS. The documented composition supervise(profile, task, { analysts: analystsFromRegistry(registry) }) (agent-runtime docs/canonical-api.md line 183) has no reachable path unless the consumer stands up Python.
Ask
Export a TraceAnalysisEngine constructor whose model seam is a plain call — an LlmCallRequest -> LlmCallResult function, or a ChatClient — so a consumer can supply its own executor. Something equivalent to:
declare function createCallTraceEngine(opts: {
call: (req: LlmCallRequest) => Promise<LlmCallResult>
recordExecution?: (row: unknown) => void
}): TraceAnalysisEngine
Then buildDefaultAnalystRegistry({ engine }) registers the five default kinds, analystsFromRegistry stops throwing, and a consumer deletes its hand-rolled lens.
Why we care, with the number
discovery-lab carries tools/analysts.mjs, 496 lines, whose createTraceBehaviorAnalyst hand-builds the { kinds, run } lens shape because of exactly this. About 150 of those lines are a prompt renderer over toolSpansToTraceAnalysisStore output that the engine would own. It is the last blocker on deleting the file.
Second, smaller gap in the same area
The one deterministic analyst that IS reachable, behavioralAnalyst, emits only monotonic-input-growth | output-length-decay | single-tool-dependency | no-self-verification (default-registry-B0s2zU-s.d.ts:7). There is no repeated-call / stuck-loop signal on the lens path. repeatedActionDetector has that invariant but is a StreamingDetector over pre-hashed fingerprints, not a store reader; computeToolUseMetrics and toolWasteView take a TraceStore while the lens contract hands a TraceAnalysisStore, and their duplicateRate is set membership, not a consecutive run. A deterministic, $0 loop panel over a TraceAnalysisStore would let a consumer delete another ~110 lines.
At agent-eval 0.171.0
createTraceAnalyst(definition, options)requiresoptions.engine: TraceAnalysisEngine, and that field is not optional (dist/default-registry-B0s2zU-s.d.ts:79).Grepping the whole installed dist for a constructor returns exactly one:
DspyRlmTraceEngineOptionsneedsrunner?: ExternalOptimizerRunnerCommand("Python command used to load agent-eval-rpc[dspy]. Default: python",index-DT73JraI.d.ts:172) plus a caller-ownedExternalOptimizerModelCalland arecordExecutionsink.Measured consequence, run against the installed packages:
So a consumer that already has a model seam — an
AgentProfileon a bridge or a sandbox seat, driven through agent-runtimestreamAgentTurn— cannot build a registry that satisfiesanalystsFromRegistry, and cannot reach any of the fiveDEFAULT_TRACE_ANALYST_KINDS. The documented compositionsupervise(profile, task, { analysts: analystsFromRegistry(registry) })(agent-runtimedocs/canonical-api.mdline 183) has no reachable path unless the consumer stands up Python.Ask
Export a
TraceAnalysisEngineconstructor whose model seam is a plain call — anLlmCallRequest -> LlmCallResultfunction, or aChatClient— so a consumer can supply its own executor. Something equivalent to:Then
buildDefaultAnalystRegistry({ engine })registers the five default kinds,analystsFromRegistrystops throwing, and a consumer deletes its hand-rolled lens.Why we care, with the number
discovery-lab carries
tools/analysts.mjs, 496 lines, whosecreateTraceBehaviorAnalysthand-builds the{ kinds, run }lens shape because of exactly this. About 150 of those lines are a prompt renderer overtoolSpansToTraceAnalysisStoreoutput that the engine would own. It is the last blocker on deleting the file.Second, smaller gap in the same area
The one deterministic analyst that IS reachable,
behavioralAnalyst, emits onlymonotonic-input-growth | output-length-decay | single-tool-dependency | no-self-verification(default-registry-B0s2zU-s.d.ts:7). There is no repeated-call / stuck-loop signal on the lens path.repeatedActionDetectorhas that invariant but is aStreamingDetectorover pre-hashed fingerprints, not a store reader;computeToolUseMetricsandtoolWasteViewtake aTraceStorewhile the lens contract hands aTraceAnalysisStore, and theirduplicateRateis set membership, not a consecutive run. A deterministic, $0 loop panel over aTraceAnalysisStorewould let a consumer delete another ~110 lines.