@rlynjb/aptkit-core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -0
- package/dist/src/index.d.ts +12 -0
- package/dist/src/index.js +9 -0
- package/node_modules/@aptkit/agent-anomaly-monitoring/README.md +13 -0
- package/node_modules/@aptkit/agent-anomaly-monitoring/dist/src/categories.d.ts +11 -0
- package/node_modules/@aptkit/agent-anomaly-monitoring/dist/src/categories.js +100 -0
- package/node_modules/@aptkit/agent-anomaly-monitoring/dist/src/fixture-provider.d.ts +10 -0
- package/node_modules/@aptkit/agent-anomaly-monitoring/dist/src/fixture-provider.js +18 -0
- package/node_modules/@aptkit/agent-anomaly-monitoring/dist/src/index.d.ts +6 -0
- package/node_modules/@aptkit/agent-anomaly-monitoring/dist/src/index.js +6 -0
- package/node_modules/@aptkit/agent-anomaly-monitoring/dist/src/monitoring-agent.d.ts +32 -0
- package/node_modules/@aptkit/agent-anomaly-monitoring/dist/src/monitoring-agent.js +88 -0
- package/node_modules/@aptkit/agent-anomaly-monitoring/dist/src/schema-summary.d.ts +2 -0
- package/node_modules/@aptkit/agent-anomaly-monitoring/dist/src/schema-summary.js +7 -0
- package/node_modules/@aptkit/agent-anomaly-monitoring/dist/src/types.d.ts +32 -0
- package/node_modules/@aptkit/agent-anomaly-monitoring/dist/src/types.js +1 -0
- package/node_modules/@aptkit/agent-anomaly-monitoring/dist/src/validate.d.ts +9 -0
- package/node_modules/@aptkit/agent-anomaly-monitoring/dist/src/validate.js +34 -0
- package/node_modules/@aptkit/agent-anomaly-monitoring/fixtures/promoted/sp-revenue-monitoring-fixture-promoted-2026-06-18-18-37-26.json +229 -0
- package/node_modules/@aptkit/agent-anomaly-monitoring/fixtures/sp-revenue-monitoring.json +136 -0
- package/node_modules/@aptkit/agent-anomaly-monitoring/package.json +33 -0
- package/node_modules/@aptkit/agent-diagnostic-investigation/README.md +11 -0
- package/node_modules/@aptkit/agent-diagnostic-investigation/dist/src/diagnostic-agent.d.ts +27 -0
- package/node_modules/@aptkit/agent-diagnostic-investigation/dist/src/diagnostic-agent.js +95 -0
- package/node_modules/@aptkit/agent-diagnostic-investigation/dist/src/fixture-provider.d.ts +10 -0
- package/node_modules/@aptkit/agent-diagnostic-investigation/dist/src/fixture-provider.js +18 -0
- package/node_modules/@aptkit/agent-diagnostic-investigation/dist/src/index.d.ts +5 -0
- package/node_modules/@aptkit/agent-diagnostic-investigation/dist/src/index.js +5 -0
- package/node_modules/@aptkit/agent-diagnostic-investigation/dist/src/schema-summary.d.ts +1 -0
- package/node_modules/@aptkit/agent-diagnostic-investigation/dist/src/schema-summary.js +1 -0
- package/node_modules/@aptkit/agent-diagnostic-investigation/dist/src/types.d.ts +37 -0
- package/node_modules/@aptkit/agent-diagnostic-investigation/dist/src/types.js +1 -0
- package/node_modules/@aptkit/agent-diagnostic-investigation/dist/src/validate.d.ts +10 -0
- package/node_modules/@aptkit/agent-diagnostic-investigation/dist/src/validate.js +49 -0
- package/node_modules/@aptkit/agent-diagnostic-investigation/fixtures/promoted/sp-revenue-diagnostic-fixture-promoted-2026-06-18-19-04-28.json +230 -0
- package/node_modules/@aptkit/agent-diagnostic-investigation/fixtures/sp-revenue-diagnostic.json +148 -0
- package/node_modules/@aptkit/agent-diagnostic-investigation/package.json +33 -0
- package/node_modules/@aptkit/agent-query/README.md +11 -0
- package/node_modules/@aptkit/agent-query/dist/src/fixture-provider.d.ts +10 -0
- package/node_modules/@aptkit/agent-query/dist/src/fixture-provider.js +18 -0
- package/node_modules/@aptkit/agent-query/dist/src/index.d.ts +6 -0
- package/node_modules/@aptkit/agent-query/dist/src/index.js +6 -0
- package/node_modules/@aptkit/agent-query/dist/src/intent.d.ts +6 -0
- package/node_modules/@aptkit/agent-query/dist/src/intent.js +23 -0
- package/node_modules/@aptkit/agent-query/dist/src/query-agent.d.ts +27 -0
- package/node_modules/@aptkit/agent-query/dist/src/query-agent.js +81 -0
- package/node_modules/@aptkit/agent-query/dist/src/schema-summary.d.ts +1 -0
- package/node_modules/@aptkit/agent-query/dist/src/schema-summary.js +1 -0
- package/node_modules/@aptkit/agent-query/dist/src/types.d.ts +5 -0
- package/node_modules/@aptkit/agent-query/dist/src/types.js +1 -0
- package/node_modules/@aptkit/agent-query/dist/src/validate.d.ts +7 -0
- package/node_modules/@aptkit/agent-query/dist/src/validate.js +9 -0
- package/node_modules/@aptkit/agent-query/fixtures/promoted/revenue-by-state-query-fixture-promoted-2026-06-18-19-29-11.json +138 -0
- package/node_modules/@aptkit/agent-query/fixtures/revenue-by-state-query.json +79 -0
- package/node_modules/@aptkit/agent-query/package.json +33 -0
- package/node_modules/@aptkit/agent-recommendation/README.md +109 -0
- package/node_modules/@aptkit/agent-recommendation/dist/src/fixture-provider.d.ts +10 -0
- package/node_modules/@aptkit/agent-recommendation/dist/src/fixture-provider.js +18 -0
- package/node_modules/@aptkit/agent-recommendation/dist/src/index.d.ts +4 -0
- package/node_modules/@aptkit/agent-recommendation/dist/src/index.js +4 -0
- package/node_modules/@aptkit/agent-recommendation/dist/src/recommendation-agent.d.ts +30 -0
- package/node_modules/@aptkit/agent-recommendation/dist/src/recommendation-agent.js +85 -0
- package/node_modules/@aptkit/agent-recommendation/dist/src/schema-summary.d.ts +1 -0
- package/node_modules/@aptkit/agent-recommendation/dist/src/schema-summary.js +1 -0
- package/node_modules/@aptkit/agent-recommendation/dist/src/types.d.ts +68 -0
- package/node_modules/@aptkit/agent-recommendation/dist/src/types.js +3 -0
- package/node_modules/@aptkit/agent-recommendation/dist/src/validate.d.ts +3 -0
- package/node_modules/@aptkit/agent-recommendation/dist/src/validate.js +54 -0
- package/node_modules/@aptkit/agent-recommendation/fixtures/electronics-spike.json +84 -0
- package/node_modules/@aptkit/agent-recommendation/fixtures/promoted/voucher-dropoff-w10-on-openai-promoted-2026-06-18-16-53-02.json +166 -0
- package/node_modules/@aptkit/agent-recommendation/fixtures/promoted/voucher-dropoff-w10-on-openai-promoted-2026-06-18-17-20-55.json +157 -0
- package/node_modules/@aptkit/agent-recommendation/fixtures/sp-revenue-drop.json +83 -0
- package/node_modules/@aptkit/agent-recommendation/fixtures/voucher-dropoff.json +84 -0
- package/node_modules/@aptkit/agent-recommendation/package.json +34 -0
- package/node_modules/@aptkit/context/README.md +15 -0
- package/node_modules/@aptkit/context/dist/src/index.d.ts +2 -0
- package/node_modules/@aptkit/context/dist/src/index.js +2 -0
- package/node_modules/@aptkit/context/dist/src/workspace-descriptor.d.ts +25 -0
- package/node_modules/@aptkit/context/dist/src/workspace-descriptor.js +1 -0
- package/node_modules/@aptkit/context/dist/src/workspace-summary.d.ts +9 -0
- package/node_modules/@aptkit/context/dist/src/workspace-summary.js +38 -0
- package/node_modules/@aptkit/context/package.json +24 -0
- package/node_modules/@aptkit/evals/dist/src/assertions.d.ts +13 -0
- package/node_modules/@aptkit/evals/dist/src/assertions.js +351 -0
- package/node_modules/@aptkit/evals/dist/src/detection-scorer.d.ts +25 -0
- package/node_modules/@aptkit/evals/dist/src/detection-scorer.js +72 -0
- package/node_modules/@aptkit/evals/dist/src/index.d.ts +3 -0
- package/node_modules/@aptkit/evals/dist/src/index.js +3 -0
- package/node_modules/@aptkit/evals/dist/src/replay-runner.d.ts +29 -0
- package/node_modules/@aptkit/evals/dist/src/replay-runner.js +72 -0
- package/node_modules/@aptkit/evals/dist/src/structural-diff.d.ts +50 -0
- package/node_modules/@aptkit/evals/dist/src/structural-diff.js +143 -0
- package/node_modules/@aptkit/evals/package.json +27 -0
- package/node_modules/@aptkit/prompts/README.md +7 -0
- package/node_modules/@aptkit/prompts/dist/src/diagnostic.d.ts +3 -0
- package/node_modules/@aptkit/prompts/dist/src/diagnostic.js +85 -0
- package/node_modules/@aptkit/prompts/dist/src/index.d.ts +5 -0
- package/node_modules/@aptkit/prompts/dist/src/index.js +5 -0
- package/node_modules/@aptkit/prompts/dist/src/monitoring.d.ts +3 -0
- package/node_modules/@aptkit/prompts/dist/src/monitoring.js +57 -0
- package/node_modules/@aptkit/prompts/dist/src/query.d.ts +3 -0
- package/node_modules/@aptkit/prompts/dist/src/query.js +86 -0
- package/node_modules/@aptkit/prompts/dist/src/recommendation.d.ts +3 -0
- package/node_modules/@aptkit/prompts/dist/src/recommendation.js +110 -0
- package/node_modules/@aptkit/prompts/dist/src/types.d.ts +21 -0
- package/node_modules/@aptkit/prompts/dist/src/types.js +6 -0
- package/node_modules/@aptkit/prompts/package.json +24 -0
- package/node_modules/@aptkit/runtime/dist/src/events.d.ts +44 -0
- package/node_modules/@aptkit/runtime/dist/src/events.js +3 -0
- package/node_modules/@aptkit/runtime/dist/src/index.d.ts +6 -0
- package/node_modules/@aptkit/runtime/dist/src/index.js +6 -0
- package/node_modules/@aptkit/runtime/dist/src/json-output.d.ts +10 -0
- package/node_modules/@aptkit/runtime/dist/src/json-output.js +32 -0
- package/node_modules/@aptkit/runtime/dist/src/model-provider.d.ts +49 -0
- package/node_modules/@aptkit/runtime/dist/src/model-provider.js +1 -0
- package/node_modules/@aptkit/runtime/dist/src/ndjson-stream.d.ts +43 -0
- package/node_modules/@aptkit/runtime/dist/src/ndjson-stream.js +128 -0
- package/node_modules/@aptkit/runtime/dist/src/run-agent-loop.d.ts +42 -0
- package/node_modules/@aptkit/runtime/dist/src/run-agent-loop.js +138 -0
- package/node_modules/@aptkit/runtime/dist/src/usage-ledger.d.ts +29 -0
- package/node_modules/@aptkit/runtime/dist/src/usage-ledger.js +61 -0
- package/node_modules/@aptkit/runtime/package.json +23 -0
- package/node_modules/@aptkit/tools/dist/src/coverage-gate.d.ts +32 -0
- package/node_modules/@aptkit/tools/dist/src/coverage-gate.js +43 -0
- package/node_modules/@aptkit/tools/dist/src/index.d.ts +3 -0
- package/node_modules/@aptkit/tools/dist/src/index.js +3 -0
- package/node_modules/@aptkit/tools/dist/src/tool-policy.d.ts +9 -0
- package/node_modules/@aptkit/tools/dist/src/tool-policy.js +11 -0
- package/node_modules/@aptkit/tools/dist/src/tool-registry.d.ts +27 -0
- package/node_modules/@aptkit/tools/dist/src/tool-registry.js +25 -0
- package/node_modules/@aptkit/tools/package.json +26 -0
- package/package.json +53 -0
package/README.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# @rlynjb/aptkit-core
|
|
2
|
+
|
|
3
|
+
Umbrella package for the stable AptKit recommendation slice.
|
|
4
|
+
|
|
5
|
+
This package re-exports the runtime, tool, context, prompt, eval, and recommendation-agent APIs that are ready to consume from another app.
|
|
6
|
+
|
|
7
|
+
Use focused packages directly when you want a smaller dependency surface. Use this package when you want a single package install while the library boundary is still evolving.
|
|
8
|
+
|
|
9
|
+
## npm
|
|
10
|
+
|
|
11
|
+
The package is published to npmjs as `@rlynjb/aptkit-core`.
|
|
12
|
+
|
|
13
|
+
Blooming keeps its existing imports by installing this package through an npm alias:
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
npm install @aptkit/core@npm:@rlynjb/aptkit-core@0.1.0
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Because the package is public on npmjs, consumers do not need a package registry token.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export * from '@aptkit/runtime';
|
|
2
|
+
export * from '@aptkit/tools';
|
|
3
|
+
export * from '@aptkit/context';
|
|
4
|
+
export * from '@aptkit/prompts';
|
|
5
|
+
export * from '@aptkit/evals';
|
|
6
|
+
export * from '@aptkit/agent-recommendation';
|
|
7
|
+
export { ANOMALY_MONITORING_CAPABILITY_ID, AnomalyMonitoringAgent, ECOMMERCE_ANOMALY_CATEGORIES, anomalyMonitoringToolPolicy, coverageReport, formatCategoryChecklist, runnableCategories, schemaCapabilities, tryParseAnomalies, validateAnomalies, } from '@aptkit/agent-anomaly-monitoring';
|
|
8
|
+
export type { Anomaly as MonitoringAnomaly, AnomalyCategory as MonitoringAnomalyCategory, } from '@aptkit/agent-anomaly-monitoring';
|
|
9
|
+
export { DIAGNOSTIC_INVESTIGATION_CAPABILITY_ID, DiagnosticInvestigationAgent, diagnosticInvestigationToolPolicy, diagnosisConfidence, tryParseDiagnosis, validateDiagnosis, } from '@aptkit/agent-diagnostic-investigation';
|
|
10
|
+
export type { Anomaly as DiagnosticAnomaly, Diagnosis as DiagnosticDiagnosis, } from '@aptkit/agent-diagnostic-investigation';
|
|
11
|
+
export { QUERY_CAPABILITY_ID, QueryAgent, classifyIntent, parseIntent, queryToolPolicy, validateQueryAnswer, } from '@aptkit/agent-query';
|
|
12
|
+
export type { Intent as QueryIntent, QueryAnswer, } from '@aptkit/agent-query';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from '@aptkit/runtime';
|
|
2
|
+
export * from '@aptkit/tools';
|
|
3
|
+
export * from '@aptkit/context';
|
|
4
|
+
export * from '@aptkit/prompts';
|
|
5
|
+
export * from '@aptkit/evals';
|
|
6
|
+
export * from '@aptkit/agent-recommendation';
|
|
7
|
+
export { ANOMALY_MONITORING_CAPABILITY_ID, AnomalyMonitoringAgent, ECOMMERCE_ANOMALY_CATEGORIES, anomalyMonitoringToolPolicy, coverageReport, formatCategoryChecklist, runnableCategories, schemaCapabilities, tryParseAnomalies, validateAnomalies, } from '@aptkit/agent-anomaly-monitoring';
|
|
8
|
+
export { DIAGNOSTIC_INVESTIGATION_CAPABILITY_ID, DiagnosticInvestigationAgent, diagnosticInvestigationToolPolicy, diagnosisConfidence, tryParseDiagnosis, validateDiagnosis, } from '@aptkit/agent-diagnostic-investigation';
|
|
9
|
+
export { QUERY_CAPABILITY_ID, QueryAgent, classifyIntent, parseIntent, queryToolPolicy, validateQueryAnswer, } from '@aptkit/agent-query';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# @aptkit/agent-anomaly-monitoring
|
|
2
|
+
|
|
3
|
+
Extracted anomaly-monitoring capability based on the Blooming Insights monitoring agent.
|
|
4
|
+
|
|
5
|
+
This package contains:
|
|
6
|
+
|
|
7
|
+
- `AnomalyMonitoringAgent`: bounded model/tool loop for anomaly detection.
|
|
8
|
+
- Ecommerce category coverage gating.
|
|
9
|
+
- Workspace schema summarization.
|
|
10
|
+
- Anomaly output validation.
|
|
11
|
+
- Fixture replay with fake tools and fake model responses.
|
|
12
|
+
|
|
13
|
+
The package is app-agnostic: host apps provide a `ModelProvider`, `ToolRegistry`, and `WorkspaceDescriptor`.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { missingCapabilities, schemaCapabilities } from '@aptkit/tools';
|
|
2
|
+
import type { AnomalyCategory, CategoryCoverage, CategoryCoverageItem } from './types.js';
|
|
3
|
+
export { missingCapabilities, schemaCapabilities };
|
|
4
|
+
/** Ecommerce-specific anomaly checks used by the monitoring agent's default category pack. */
|
|
5
|
+
export declare const ECOMMERCE_ANOMALY_CATEGORIES: AnomalyCategory[];
|
|
6
|
+
/** Compatibility wrapper for generic coverage classification from @aptkit/tools. */
|
|
7
|
+
export declare function categoryCoverage(category: AnomalyCategory, capabilities: Set<string>): CategoryCoverage;
|
|
8
|
+
/** Reports which ecommerce anomaly categories are runnable for the supplied workspace capabilities. */
|
|
9
|
+
export declare function coverageReport(categories: readonly AnomalyCategory[], capabilities: Set<string>): CategoryCoverageItem[];
|
|
10
|
+
/** Filters the default or supplied categories before the monitoring agent calls a model. */
|
|
11
|
+
export declare function runnableCategories(categories: readonly AnomalyCategory[], capabilities: Set<string>): AnomalyCategory[];
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { coverageReport as baseCoverageReport, missingCapabilities, requirementCoverage, runnableRequirements, schemaCapabilities, } from '@aptkit/tools';
|
|
2
|
+
export { missingCapabilities, schemaCapabilities };
|
|
3
|
+
const windowText = 'in last 90 days';
|
|
4
|
+
/** Ecommerce-specific anomaly checks used by the monitoring agent's default category pack. */
|
|
5
|
+
export const ECOMMERCE_ANOMALY_CATEGORIES = [
|
|
6
|
+
{
|
|
7
|
+
id: 'conversion_drop',
|
|
8
|
+
label: 'conversion rate drop',
|
|
9
|
+
requires: ['view_item', 'checkout', 'purchase'],
|
|
10
|
+
whyItMatters: 'conversion is the funnel hinge; a drop here loses completed-intent customers even at flat traffic.',
|
|
11
|
+
queryRecipe: `select count event view_item, count event checkout, count event purchase ${windowText}`,
|
|
12
|
+
thresholds: { critical: 20, warning: 10 },
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
id: 'cart_abandonment',
|
|
16
|
+
label: 'cart abandonment',
|
|
17
|
+
requires: ['cart_update', 'checkout', 'purchase'],
|
|
18
|
+
whyItMatters: 'rising abandonment means shoppers fill carts but stall before paying.',
|
|
19
|
+
queryRecipe: `select count event cart_update, count event checkout, count event purchase ${windowText}`,
|
|
20
|
+
thresholds: { critical: 20, warning: 10 },
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
id: 'product_demand',
|
|
24
|
+
label: 'product demand spike',
|
|
25
|
+
requires: ['purchase'],
|
|
26
|
+
whyItMatters: 'a sudden SKU or category velocity spike is an opportunity to protect stock and ride demand.',
|
|
27
|
+
queryRecipe: `select count event purchase by event purchase.product_id grouping top 10 ${windowText}`,
|
|
28
|
+
thresholds: { critical: 100, warning: 50 },
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: 'revenue_drop',
|
|
32
|
+
label: 'revenue drop',
|
|
33
|
+
requires: ['purchase'],
|
|
34
|
+
whyItMatters: 'revenue moves flow directly to income; isolate whether the move is demand or conversion.',
|
|
35
|
+
queryRecipe: `select sum event purchase.total_price, count event purchase ${windowText}`,
|
|
36
|
+
thresholds: { critical: 20, warning: 10 },
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: 'customer_churn',
|
|
40
|
+
label: 'customer churn',
|
|
41
|
+
requires: ['purchase', 'session_start'],
|
|
42
|
+
whyItMatters: 'falling repeat purchase reflects customers not coming back.',
|
|
43
|
+
queryRecipe: `select count event purchase, count event session_start ${windowText}`,
|
|
44
|
+
thresholds: { critical: 15, warning: 8 },
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: 'inventory',
|
|
48
|
+
label: 'inventory problems',
|
|
49
|
+
requires: ['purchase'],
|
|
50
|
+
enriches: ['catalog:inventory_level'],
|
|
51
|
+
whyItMatters: 'sell-through outrunning replenishment creates stockouts and lost sales.',
|
|
52
|
+
queryRecipe: `select count event purchase by event purchase.product_id grouping top 10 ${windowText}`,
|
|
53
|
+
thresholds: { critical: 30, warning: 15 },
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
id: 'campaign_perf',
|
|
57
|
+
label: 'campaign performance',
|
|
58
|
+
requires: ['session_start'],
|
|
59
|
+
enriches: ['session_start.utm_source'],
|
|
60
|
+
whyItMatters: 'campaign traffic swings move the top of the funnel.',
|
|
61
|
+
queryRecipe: `select count event session_start ${windowText}`,
|
|
62
|
+
thresholds: { critical: 25, warning: 12 },
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
id: 'search_failure',
|
|
66
|
+
label: 'search failure',
|
|
67
|
+
requires: ['search'],
|
|
68
|
+
whyItMatters: 'zero-result searches are demand the catalog or relevance is failing to meet.',
|
|
69
|
+
queryRecipe: `select count event search ${windowText}`,
|
|
70
|
+
thresholds: { critical: 20, warning: 10 },
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
id: 'return_spike',
|
|
74
|
+
label: 'product return spike',
|
|
75
|
+
requires: ['return'],
|
|
76
|
+
whyItMatters: 'return spikes point at quality, sizing, or expectation gaps.',
|
|
77
|
+
queryRecipe: `select count event return ${windowText}`,
|
|
78
|
+
thresholds: { critical: 25, warning: 12 },
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
id: 'fraud',
|
|
82
|
+
label: 'fraud detection',
|
|
83
|
+
requires: ['payment_failure'],
|
|
84
|
+
whyItMatters: 'clusters of failed payments or anomalous orders can signal card testing or fraud.',
|
|
85
|
+
queryRecipe: `select count event payment_failure ${windowText}`,
|
|
86
|
+
thresholds: { critical: 20, warning: 10 },
|
|
87
|
+
},
|
|
88
|
+
];
|
|
89
|
+
/** Compatibility wrapper for generic coverage classification from @aptkit/tools. */
|
|
90
|
+
export function categoryCoverage(category, capabilities) {
|
|
91
|
+
return requirementCoverage(category, capabilities);
|
|
92
|
+
}
|
|
93
|
+
/** Reports which ecommerce anomaly categories are runnable for the supplied workspace capabilities. */
|
|
94
|
+
export function coverageReport(categories, capabilities) {
|
|
95
|
+
return baseCoverageReport(categories, capabilities);
|
|
96
|
+
}
|
|
97
|
+
/** Filters the default or supplied categories before the monitoring agent calls a model. */
|
|
98
|
+
export function runnableCategories(categories, capabilities) {
|
|
99
|
+
return runnableRequirements(categories, capabilities);
|
|
100
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ModelProvider, ModelRequest, ModelResponse } from '@aptkit/runtime';
|
|
2
|
+
export declare class FixtureModelProvider implements ModelProvider {
|
|
3
|
+
private readonly responses;
|
|
4
|
+
readonly id = "fixture";
|
|
5
|
+
readonly defaultModel = "fixture-model";
|
|
6
|
+
readonly requests: ModelRequest[];
|
|
7
|
+
private index;
|
|
8
|
+
constructor(responses: ModelResponse[]);
|
|
9
|
+
complete(request: ModelRequest): Promise<ModelResponse>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export class FixtureModelProvider {
|
|
2
|
+
responses;
|
|
3
|
+
id = 'fixture';
|
|
4
|
+
defaultModel = 'fixture-model';
|
|
5
|
+
requests = [];
|
|
6
|
+
index = 0;
|
|
7
|
+
constructor(responses) {
|
|
8
|
+
this.responses = responses;
|
|
9
|
+
}
|
|
10
|
+
async complete(request) {
|
|
11
|
+
this.requests.push(request);
|
|
12
|
+
const response = this.responses[this.index];
|
|
13
|
+
this.index += 1;
|
|
14
|
+
if (!response)
|
|
15
|
+
throw new Error(`fixture model exhausted after ${this.index - 1} responses`);
|
|
16
|
+
return response;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type CapabilityTraceSink, type ModelProvider } from '@aptkit/runtime';
|
|
2
|
+
import { type ToolRegistry } from '@aptkit/tools';
|
|
3
|
+
import type { Anomaly, AnomalyCategory, WorkspaceDescriptor } from './types.js';
|
|
4
|
+
export declare const ANOMALY_MONITORING_CAPABILITY_ID = "anomaly-monitoring-agent";
|
|
5
|
+
/** Least-privilege tool grant for anomaly scanning. Provider adapters only see these tools. */
|
|
6
|
+
export declare const anomalyMonitoringToolPolicy: {
|
|
7
|
+
capabilityId: string;
|
|
8
|
+
allowedTools: readonly ["execute_analytics_eql", "get_metric_timeseries", "get_segments", "get_anomaly_context"];
|
|
9
|
+
};
|
|
10
|
+
export type MonitoringAgentOptions = {
|
|
11
|
+
model: ModelProvider;
|
|
12
|
+
tools: ToolRegistry;
|
|
13
|
+
workspace: WorkspaceDescriptor;
|
|
14
|
+
categories?: readonly AnomalyCategory[];
|
|
15
|
+
trace?: CapabilityTraceSink;
|
|
16
|
+
prompt?: string;
|
|
17
|
+
};
|
|
18
|
+
export type MonitoringRunOptions = {
|
|
19
|
+
signal?: AbortSignal;
|
|
20
|
+
};
|
|
21
|
+
export declare class AnomalyMonitoringAgent {
|
|
22
|
+
private readonly options;
|
|
23
|
+
private readonly categories;
|
|
24
|
+
private readonly prompt;
|
|
25
|
+
constructor(options: MonitoringAgentOptions);
|
|
26
|
+
/** Returns categories this workspace can scan without asking the model to guess unsupported work. */
|
|
27
|
+
runnableCategories(): AnomalyCategory[];
|
|
28
|
+
/** Runs a bounded anomaly scan and returns validated, severity-sorted anomaly objects. */
|
|
29
|
+
scan(runOptions?: MonitoringRunOptions): Promise<Anomaly[]>;
|
|
30
|
+
}
|
|
31
|
+
/** Formats runnable categories for the system prompt shown to the model. */
|
|
32
|
+
export declare function formatCategoryChecklist(categories: readonly AnomalyCategory[]): string;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { monitoringPromptPackage, renderPromptTemplate } from '@aptkit/prompts';
|
|
2
|
+
import { buildSynthesisInstruction, runAgentLoop } from '@aptkit/runtime';
|
|
3
|
+
import { filterToolsForPolicy } from '@aptkit/tools';
|
|
4
|
+
import { ECOMMERCE_ANOMALY_CATEGORIES, runnableCategories, schemaCapabilities } from './categories.js';
|
|
5
|
+
import { schemaSummary } from './schema-summary.js';
|
|
6
|
+
import { tryParseAnomalies } from './validate.js';
|
|
7
|
+
export const ANOMALY_MONITORING_CAPABILITY_ID = 'anomaly-monitoring-agent';
|
|
8
|
+
/** Least-privilege tool grant for anomaly scanning. Provider adapters only see these tools. */
|
|
9
|
+
export const anomalyMonitoringToolPolicy = {
|
|
10
|
+
capabilityId: ANOMALY_MONITORING_CAPABILITY_ID,
|
|
11
|
+
allowedTools: [
|
|
12
|
+
'execute_analytics_eql',
|
|
13
|
+
'get_metric_timeseries',
|
|
14
|
+
'get_segments',
|
|
15
|
+
'get_anomaly_context',
|
|
16
|
+
],
|
|
17
|
+
};
|
|
18
|
+
const severityRank = {
|
|
19
|
+
critical: 3,
|
|
20
|
+
warning: 2,
|
|
21
|
+
info: 1,
|
|
22
|
+
positive: 0,
|
|
23
|
+
};
|
|
24
|
+
export class AnomalyMonitoringAgent {
|
|
25
|
+
options;
|
|
26
|
+
categories;
|
|
27
|
+
prompt;
|
|
28
|
+
constructor(options) {
|
|
29
|
+
this.options = options;
|
|
30
|
+
this.categories = options.categories ?? ECOMMERCE_ANOMALY_CATEGORIES;
|
|
31
|
+
this.prompt = options.prompt ?? monitoringPromptPackage.system;
|
|
32
|
+
}
|
|
33
|
+
/** Returns categories this workspace can scan without asking the model to guess unsupported work. */
|
|
34
|
+
runnableCategories() {
|
|
35
|
+
return runnableCategories(this.categories, schemaCapabilities(this.options.workspace));
|
|
36
|
+
}
|
|
37
|
+
/** Runs a bounded anomaly scan and returns validated, severity-sorted anomaly objects. */
|
|
38
|
+
async scan(runOptions = {}) {
|
|
39
|
+
const allTools = await this.options.tools.listTools();
|
|
40
|
+
const toolSchemas = filterToolsForPolicy(allTools, anomalyMonitoringToolPolicy);
|
|
41
|
+
const categories = this.runnableCategories();
|
|
42
|
+
const system = renderPromptTemplate(this.prompt, {
|
|
43
|
+
schema: schemaSummary(this.options.workspace),
|
|
44
|
+
categories: formatCategoryChecklist(categories),
|
|
45
|
+
});
|
|
46
|
+
const { parsed } = await runAgentLoop({
|
|
47
|
+
capabilityId: ANOMALY_MONITORING_CAPABILITY_ID,
|
|
48
|
+
model: this.options.model,
|
|
49
|
+
tools: this.options.tools,
|
|
50
|
+
system,
|
|
51
|
+
userPrompt: 'Run the anomaly checklist using the available tools. Return only the anomaly JSON array in a json fence, or [] if no meaningful anomaly is found.',
|
|
52
|
+
toolSchemas,
|
|
53
|
+
trace: this.options.trace,
|
|
54
|
+
signal: runOptions.signal,
|
|
55
|
+
maxTurns: 8,
|
|
56
|
+
maxToolCalls: 6,
|
|
57
|
+
synthesisInstruction: buildSynthesisInstruction('Stop querying now and output your final answer. Respond with ONLY a JSON array of anomaly objects in a json fence, or [] if nothing meaningful was found, based on the data you have already gathered.'),
|
|
58
|
+
parseResult: tryParseAnomalies,
|
|
59
|
+
recoveryPrompt: buildRecoveryPrompt,
|
|
60
|
+
});
|
|
61
|
+
if (!parsed)
|
|
62
|
+
return [];
|
|
63
|
+
return [...parsed]
|
|
64
|
+
.sort((left, right) => severityRank[right.severity] - severityRank[left.severity])
|
|
65
|
+
.slice(0, 10);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/** Formats runnable categories for the system prompt shown to the model. */
|
|
69
|
+
export function formatCategoryChecklist(categories) {
|
|
70
|
+
if (categories.length === 0)
|
|
71
|
+
return '(no runnable checklist categories; scan core metrics broadly)';
|
|
72
|
+
return categories
|
|
73
|
+
.map((category) => `- ${category.id} (${category.label}): ${category.whyItMatters} recipe: ${category.queryRecipe}; warning >= ${category.thresholds.warning}%, critical >= ${category.thresholds.critical}%.`)
|
|
74
|
+
.join('\n');
|
|
75
|
+
}
|
|
76
|
+
function buildRecoveryPrompt(toolCalls) {
|
|
77
|
+
const evidence = toolCalls
|
|
78
|
+
.map((call, index) => {
|
|
79
|
+
const payload = call.error ? { error: call.error } : call.result;
|
|
80
|
+
return `Query ${index + 1}: ${call.toolName} ${JSON.stringify(call.args).slice(0, 200)}\nResult: ${JSON.stringify(payload).slice(0, 900)}`;
|
|
81
|
+
})
|
|
82
|
+
.join('\n\n') || '(no tool queries were completed)';
|
|
83
|
+
return [
|
|
84
|
+
'The anomaly-monitoring run is complete. Convert the evidence below into the final anomaly JSON array.',
|
|
85
|
+
evidence,
|
|
86
|
+
'Return ONLY a JSON array in a json fence. Each anomaly needs metric, scope, change, severity, evidence, and category when known. Return [] if evidence is not strong enough.',
|
|
87
|
+
].join('\n\n');
|
|
88
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export type { WorkspaceDescriptor } from '@aptkit/context';
|
|
2
|
+
export type { CoverageLevel as CategoryCoverage, CoverageReportItem as CategoryCoverageItem, CoverageRequirement, } from '@aptkit/tools';
|
|
3
|
+
export type Severity = 'critical' | 'warning' | 'info' | 'positive';
|
|
4
|
+
export type AnomalyCategory = {
|
|
5
|
+
id: string;
|
|
6
|
+
label: string;
|
|
7
|
+
requires: readonly string[];
|
|
8
|
+
enriches?: readonly string[];
|
|
9
|
+
whyItMatters: string;
|
|
10
|
+
queryRecipe: string;
|
|
11
|
+
thresholds: {
|
|
12
|
+
critical: number;
|
|
13
|
+
warning: number;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
export type Anomaly = {
|
|
17
|
+
metric: string;
|
|
18
|
+
scope: string[];
|
|
19
|
+
change: {
|
|
20
|
+
value: number;
|
|
21
|
+
direction: 'up' | 'down';
|
|
22
|
+
baseline: string;
|
|
23
|
+
};
|
|
24
|
+
severity: Severity;
|
|
25
|
+
evidence: {
|
|
26
|
+
tool: string;
|
|
27
|
+
result: unknown;
|
|
28
|
+
}[];
|
|
29
|
+
impact?: string;
|
|
30
|
+
history?: number[];
|
|
31
|
+
category?: string;
|
|
32
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { parseValidatedJson } from '@aptkit/runtime';
|
|
2
|
+
const severities = ['critical', 'warning', 'info', 'positive'];
|
|
3
|
+
export function validateAnomalies(value) {
|
|
4
|
+
if (!Array.isArray(value))
|
|
5
|
+
return { ok: false, error: 'expected anomaly array' };
|
|
6
|
+
for (const [index, anomaly] of value.entries()) {
|
|
7
|
+
if (!anomaly || typeof anomaly !== 'object')
|
|
8
|
+
return { ok: false, error: `${index}: expected object` };
|
|
9
|
+
const candidate = anomaly;
|
|
10
|
+
if (typeof candidate.metric !== 'string')
|
|
11
|
+
return { ok: false, error: `${index}.metric must be string` };
|
|
12
|
+
if (!Array.isArray(candidate.scope) || !candidate.scope.every((item) => typeof item === 'string')) {
|
|
13
|
+
return { ok: false, error: `${index}.scope must be string[]` };
|
|
14
|
+
}
|
|
15
|
+
if (!candidate.change || typeof candidate.change !== 'object')
|
|
16
|
+
return { ok: false, error: `${index}.change must be object` };
|
|
17
|
+
const change = candidate.change;
|
|
18
|
+
if (typeof change.value !== 'number')
|
|
19
|
+
return { ok: false, error: `${index}.change.value must be number` };
|
|
20
|
+
if (change.direction !== 'up' && change.direction !== 'down')
|
|
21
|
+
return { ok: false, error: `${index}.change.direction invalid` };
|
|
22
|
+
if (typeof change.baseline !== 'string')
|
|
23
|
+
return { ok: false, error: `${index}.change.baseline must be string` };
|
|
24
|
+
if (!severities.includes(candidate.severity))
|
|
25
|
+
return { ok: false, error: `${index}.severity invalid` };
|
|
26
|
+
if ('evidence' in candidate && !Array.isArray(candidate.evidence))
|
|
27
|
+
return { ok: false, error: `${index}.evidence must be array` };
|
|
28
|
+
}
|
|
29
|
+
return { ok: true, value: value };
|
|
30
|
+
}
|
|
31
|
+
export function tryParseAnomalies(text) {
|
|
32
|
+
const parsed = parseValidatedJson(text, validateAnomalies);
|
|
33
|
+
return parsed.ok ? parsed.value : null;
|
|
34
|
+
}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "sp-revenue-monitoring-fixture-promoted",
|
|
3
|
+
"description": "Promoted deterministic monitoring fixture from fixture replay artifact. Source fixture: sp-revenue-monitoring. Replay created at: 2026-06-18T18:37:26.958Z.",
|
|
4
|
+
"workspace": {
|
|
5
|
+
"projectId": "olist",
|
|
6
|
+
"projectName": "Olist Brazilian ecommerce fixture",
|
|
7
|
+
"events": [
|
|
8
|
+
{
|
|
9
|
+
"name": "purchase",
|
|
10
|
+
"properties": [
|
|
11
|
+
"state",
|
|
12
|
+
"category",
|
|
13
|
+
"total_price"
|
|
14
|
+
],
|
|
15
|
+
"eventCount": 50000
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "session_start",
|
|
19
|
+
"properties": [
|
|
20
|
+
"utm_source"
|
|
21
|
+
],
|
|
22
|
+
"eventCount": 80000
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"name": "checkout",
|
|
26
|
+
"properties": [
|
|
27
|
+
"state"
|
|
28
|
+
],
|
|
29
|
+
"eventCount": 35000
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"name": "view_item",
|
|
33
|
+
"properties": [
|
|
34
|
+
"category"
|
|
35
|
+
],
|
|
36
|
+
"eventCount": 120000
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
"customerProperties": [
|
|
40
|
+
"state",
|
|
41
|
+
"city"
|
|
42
|
+
],
|
|
43
|
+
"catalogs": [],
|
|
44
|
+
"totalCustomers": 125000,
|
|
45
|
+
"totalEvents": 285000,
|
|
46
|
+
"oldestTimestamp": 1764547200000,
|
|
47
|
+
"dataHorizon": {
|
|
48
|
+
"from": "2025-12-01",
|
|
49
|
+
"to": "2026-06-01",
|
|
50
|
+
"durationDays": 182
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"tools": [
|
|
54
|
+
{
|
|
55
|
+
"name": "get_metric_timeseries",
|
|
56
|
+
"description": "Return metric timeseries for an optional dimension.",
|
|
57
|
+
"inputSchema": {
|
|
58
|
+
"type": "object",
|
|
59
|
+
"properties": {
|
|
60
|
+
"metric": {
|
|
61
|
+
"type": "string"
|
|
62
|
+
},
|
|
63
|
+
"dimension": {
|
|
64
|
+
"type": "string"
|
|
65
|
+
},
|
|
66
|
+
"time_range": {
|
|
67
|
+
"type": "object"
|
|
68
|
+
},
|
|
69
|
+
"granularity": {
|
|
70
|
+
"type": "string"
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"required": [
|
|
74
|
+
"metric",
|
|
75
|
+
"time_range"
|
|
76
|
+
]
|
|
77
|
+
},
|
|
78
|
+
"result": {
|
|
79
|
+
"periodComparison": {
|
|
80
|
+
"metric": "revenue",
|
|
81
|
+
"dimension": "state",
|
|
82
|
+
"segment": "SP",
|
|
83
|
+
"recentWindow": {
|
|
84
|
+
"from": "2026-05-04",
|
|
85
|
+
"to": "2026-06-01"
|
|
86
|
+
},
|
|
87
|
+
"baselineWindow": {
|
|
88
|
+
"from": "2026-02-09",
|
|
89
|
+
"to": "2026-05-04"
|
|
90
|
+
},
|
|
91
|
+
"recentValue": 28550000,
|
|
92
|
+
"baselineAverage": 40800000,
|
|
93
|
+
"pctChange": -0.300245,
|
|
94
|
+
"relatedSegments": [
|
|
95
|
+
{
|
|
96
|
+
"name": "RJ",
|
|
97
|
+
"pctChange": -0.02
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"name": "MG",
|
|
101
|
+
"pctChange": 0.01
|
|
102
|
+
}
|
|
103
|
+
]
|
|
104
|
+
},
|
|
105
|
+
"points": [
|
|
106
|
+
{
|
|
107
|
+
"ts": "2026-05-04",
|
|
108
|
+
"segment": "SP",
|
|
109
|
+
"value": 7400000
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"ts": "2026-05-11",
|
|
113
|
+
"segment": "SP",
|
|
114
|
+
"value": 7200000
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"ts": "2026-05-18",
|
|
118
|
+
"segment": "SP",
|
|
119
|
+
"value": 7050000
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"ts": "2026-05-25",
|
|
123
|
+
"segment": "SP",
|
|
124
|
+
"value": 6900000
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"ts": "2026-05-04",
|
|
128
|
+
"segment": "RJ",
|
|
129
|
+
"value": 4300000
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"ts": "2026-05-11",
|
|
133
|
+
"segment": "RJ",
|
|
134
|
+
"value": 4350000
|
|
135
|
+
}
|
|
136
|
+
],
|
|
137
|
+
"totalCount": 4200
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"name": "get_anomaly_context",
|
|
142
|
+
"description": "Return context for a selected anomaly window and baseline.",
|
|
143
|
+
"inputSchema": {
|
|
144
|
+
"type": "object",
|
|
145
|
+
"properties": {
|
|
146
|
+
"metric": {
|
|
147
|
+
"type": "string"
|
|
148
|
+
},
|
|
149
|
+
"dimension": {
|
|
150
|
+
"type": "string"
|
|
151
|
+
},
|
|
152
|
+
"segment": {
|
|
153
|
+
"type": "string"
|
|
154
|
+
},
|
|
155
|
+
"anomaly_window": {
|
|
156
|
+
"type": "object"
|
|
157
|
+
},
|
|
158
|
+
"baseline_window": {
|
|
159
|
+
"type": "object"
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
"required": [
|
|
163
|
+
"metric",
|
|
164
|
+
"dimension",
|
|
165
|
+
"segment"
|
|
166
|
+
]
|
|
167
|
+
},
|
|
168
|
+
"result": {
|
|
169
|
+
"anomaly_summary": {
|
|
170
|
+
"metric": "revenue",
|
|
171
|
+
"segment": "SP",
|
|
172
|
+
"anomaly_value": 28550000,
|
|
173
|
+
"baseline_avg": 40800000,
|
|
174
|
+
"pct_change": -0.300245
|
|
175
|
+
},
|
|
176
|
+
"related_segments": [
|
|
177
|
+
{
|
|
178
|
+
"name": "RJ",
|
|
179
|
+
"pct_change": -0.02
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
"name": "MG",
|
|
183
|
+
"pct_change": 0.01
|
|
184
|
+
}
|
|
185
|
+
]
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
],
|
|
189
|
+
"modelResponses": [
|
|
190
|
+
{
|
|
191
|
+
"content": [
|
|
192
|
+
{
|
|
193
|
+
"type": "text",
|
|
194
|
+
"text": "```json\n[\n {\n \"metric\": \"revenue\",\n \"category\": \"revenue_drop\",\n \"scope\": [\n \"state:SP\"\n ],\n \"change\": {\n \"value\": 30,\n \"direction\": \"down\",\n \"baseline\": \"recent 4w vs prior 12w\"\n },\n \"severity\": \"critical\",\n \"impact\": \"Sao Paulo revenue is down about 30% while nearby states are stable, putting the largest regional topline segment at risk if the trend continues.\",\n \"evidence\": [\n {\n \"tool\": \"get_anomaly_context\",\n \"result\": {\n \"segment\": \"SP\",\n \"pct_change\": -0.300245,\n \"anomaly_value\": 28550000,\n \"baseline_avg\": 40800000\n }\n }\n ]\n }\n]\n```"
|
|
195
|
+
}
|
|
196
|
+
],
|
|
197
|
+
"usage": {
|
|
198
|
+
"inputTokens": 2680,
|
|
199
|
+
"outputTokens": 365,
|
|
200
|
+
"estimated": true
|
|
201
|
+
},
|
|
202
|
+
"model": "promoted-fixture-replay"
|
|
203
|
+
}
|
|
204
|
+
],
|
|
205
|
+
"expectations": {
|
|
206
|
+
"minAnomalyCount": 1,
|
|
207
|
+
"requiredCategories": [
|
|
208
|
+
"revenue_drop"
|
|
209
|
+
],
|
|
210
|
+
"requiredMetrics": [
|
|
211
|
+
"revenue"
|
|
212
|
+
],
|
|
213
|
+
"requiredScopes": [
|
|
214
|
+
"state:SP"
|
|
215
|
+
],
|
|
216
|
+
"requiredSeverities": [
|
|
217
|
+
"critical"
|
|
218
|
+
]
|
|
219
|
+
},
|
|
220
|
+
"promotion": {
|
|
221
|
+
"sourceArtifact": "artifacts/replays/2026-06-18T18-37-26-958Z-sp-revenue-monitoring-fixture-studio.json",
|
|
222
|
+
"sourceProvider": {
|
|
223
|
+
"id": "fixture",
|
|
224
|
+
"model": "fixture-model"
|
|
225
|
+
},
|
|
226
|
+
"promotedAt": "2026-06-18T18:37:26.963Z",
|
|
227
|
+
"note": "This fixture captures the final monitoring replay answer deterministically; it does not reconstruct the live provider tool loop."
|
|
228
|
+
}
|
|
229
|
+
}
|