@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
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "revenue-by-state-query-fixture-promoted",
|
|
3
|
+
"description": "Promoted deterministic query fixture from fixture replay artifact. Source fixture: revenue-by-state-query. Replay created at: 2026-06-18T19:29:11.225Z.",
|
|
4
|
+
"question": "What was revenue by state in the last 30 days?",
|
|
5
|
+
"intent": "monitoring",
|
|
6
|
+
"workspace": {
|
|
7
|
+
"projectId": "olist",
|
|
8
|
+
"projectName": "Olist Brazilian ecommerce fixture",
|
|
9
|
+
"events": [
|
|
10
|
+
{
|
|
11
|
+
"name": "purchase",
|
|
12
|
+
"properties": [
|
|
13
|
+
"state",
|
|
14
|
+
"category",
|
|
15
|
+
"total_price"
|
|
16
|
+
],
|
|
17
|
+
"eventCount": 50000
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"name": "session_start",
|
|
21
|
+
"properties": [
|
|
22
|
+
"utm_source"
|
|
23
|
+
],
|
|
24
|
+
"eventCount": 80000
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"name": "checkout",
|
|
28
|
+
"properties": [
|
|
29
|
+
"state"
|
|
30
|
+
],
|
|
31
|
+
"eventCount": 35000
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"name": "view_item",
|
|
35
|
+
"properties": [
|
|
36
|
+
"category"
|
|
37
|
+
],
|
|
38
|
+
"eventCount": 120000
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"customerProperties": [
|
|
42
|
+
"state",
|
|
43
|
+
"city"
|
|
44
|
+
],
|
|
45
|
+
"catalogs": [],
|
|
46
|
+
"totalCustomers": 125000,
|
|
47
|
+
"totalEvents": 285000,
|
|
48
|
+
"oldestTimestamp": 1764547200000,
|
|
49
|
+
"dataHorizon": {
|
|
50
|
+
"from": "2025-12-01",
|
|
51
|
+
"to": "2026-06-01",
|
|
52
|
+
"durationDays": 182
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"tools": [
|
|
56
|
+
{
|
|
57
|
+
"name": "get_metric_timeseries",
|
|
58
|
+
"description": "Return metric timeseries for an optional dimension.",
|
|
59
|
+
"inputSchema": {
|
|
60
|
+
"type": "object",
|
|
61
|
+
"properties": {
|
|
62
|
+
"metric": {
|
|
63
|
+
"type": "string"
|
|
64
|
+
},
|
|
65
|
+
"dimension": {
|
|
66
|
+
"type": "string"
|
|
67
|
+
},
|
|
68
|
+
"time_range": {
|
|
69
|
+
"type": "object"
|
|
70
|
+
},
|
|
71
|
+
"granularity": {
|
|
72
|
+
"type": "string"
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
"required": [
|
|
76
|
+
"metric",
|
|
77
|
+
"time_range"
|
|
78
|
+
]
|
|
79
|
+
},
|
|
80
|
+
"result": {
|
|
81
|
+
"points": [
|
|
82
|
+
{
|
|
83
|
+
"ts": "2026-05-04",
|
|
84
|
+
"segment": "SP",
|
|
85
|
+
"value": 28550000
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"ts": "2026-05-04",
|
|
89
|
+
"segment": "RJ",
|
|
90
|
+
"value": 12100000
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"ts": "2026-05-04",
|
|
94
|
+
"segment": "MG",
|
|
95
|
+
"value": 9800000
|
|
96
|
+
}
|
|
97
|
+
],
|
|
98
|
+
"totalCount": 4200,
|
|
99
|
+
"unit": "brl_cents"
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
],
|
|
103
|
+
"modelResponses": [
|
|
104
|
+
{
|
|
105
|
+
"content": [
|
|
106
|
+
{
|
|
107
|
+
"type": "text",
|
|
108
|
+
"text": "For the last 30 days in the populated fixture window, SP had the most revenue at BRL 285,500, followed by RJ at BRL 121,000 and MG at BRL 98,000. The ranking is SP, RJ, then MG, based on the get_metric_timeseries result for revenue by state from 2026-05-04 to 2026-06-01."
|
|
109
|
+
}
|
|
110
|
+
],
|
|
111
|
+
"usage": {
|
|
112
|
+
"inputTokens": 1680,
|
|
113
|
+
"outputTokens": 165,
|
|
114
|
+
"estimated": true
|
|
115
|
+
},
|
|
116
|
+
"model": "promoted-fixture-replay"
|
|
117
|
+
}
|
|
118
|
+
],
|
|
119
|
+
"expectations": {
|
|
120
|
+
"requiredAnswerText": [
|
|
121
|
+
"BRL 121,000",
|
|
122
|
+
"BRL 285,500",
|
|
123
|
+
"BRL 98,000",
|
|
124
|
+
"MG",
|
|
125
|
+
"RJ",
|
|
126
|
+
"SP"
|
|
127
|
+
]
|
|
128
|
+
},
|
|
129
|
+
"promotion": {
|
|
130
|
+
"sourceArtifact": "artifacts/replays/2026-06-18T19-29-11-225Z-revenue-by-state-query-fixture-studio.json",
|
|
131
|
+
"sourceProvider": {
|
|
132
|
+
"id": "fixture",
|
|
133
|
+
"model": "fixture-model"
|
|
134
|
+
},
|
|
135
|
+
"promotedAt": "2026-06-18T19:37:13.692Z",
|
|
136
|
+
"note": "This fixture captures the final query replay answer deterministically; it does not reconstruct the live provider tool loop."
|
|
137
|
+
}
|
|
138
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "revenue-by-state-query",
|
|
3
|
+
"description": "Answer a free-form revenue-by-state question from deterministic Olist-style timeseries data.",
|
|
4
|
+
"question": "What was revenue by state in the last 30 days?",
|
|
5
|
+
"intent": "monitoring",
|
|
6
|
+
"workspace": {
|
|
7
|
+
"projectId": "olist",
|
|
8
|
+
"projectName": "Olist Brazilian ecommerce fixture",
|
|
9
|
+
"events": [
|
|
10
|
+
{ "name": "purchase", "properties": ["state", "category", "total_price"], "eventCount": 50000 },
|
|
11
|
+
{ "name": "session_start", "properties": ["utm_source"], "eventCount": 80000 },
|
|
12
|
+
{ "name": "checkout", "properties": ["state"], "eventCount": 35000 },
|
|
13
|
+
{ "name": "view_item", "properties": ["category"], "eventCount": 120000 }
|
|
14
|
+
],
|
|
15
|
+
"customerProperties": ["state", "city"],
|
|
16
|
+
"catalogs": [],
|
|
17
|
+
"totalCustomers": 125000,
|
|
18
|
+
"totalEvents": 285000,
|
|
19
|
+
"oldestTimestamp": 1764547200000,
|
|
20
|
+
"dataHorizon": { "from": "2025-12-01", "to": "2026-06-01", "durationDays": 182 }
|
|
21
|
+
},
|
|
22
|
+
"tools": [
|
|
23
|
+
{
|
|
24
|
+
"name": "get_metric_timeseries",
|
|
25
|
+
"description": "Return metric timeseries for an optional dimension.",
|
|
26
|
+
"inputSchema": {
|
|
27
|
+
"type": "object",
|
|
28
|
+
"properties": {
|
|
29
|
+
"metric": { "type": "string" },
|
|
30
|
+
"dimension": { "type": "string" },
|
|
31
|
+
"time_range": { "type": "object" },
|
|
32
|
+
"granularity": { "type": "string" }
|
|
33
|
+
},
|
|
34
|
+
"required": ["metric", "time_range"]
|
|
35
|
+
},
|
|
36
|
+
"result": {
|
|
37
|
+
"points": [
|
|
38
|
+
{ "ts": "2026-05-04", "segment": "SP", "value": 28550000 },
|
|
39
|
+
{ "ts": "2026-05-04", "segment": "RJ", "value": 12100000 },
|
|
40
|
+
{ "ts": "2026-05-04", "segment": "MG", "value": 9800000 }
|
|
41
|
+
],
|
|
42
|
+
"totalCount": 4200,
|
|
43
|
+
"unit": "brl_cents"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
],
|
|
47
|
+
"modelResponses": [
|
|
48
|
+
{
|
|
49
|
+
"content": [
|
|
50
|
+
{
|
|
51
|
+
"type": "tool_use",
|
|
52
|
+
"id": "query-tool-1",
|
|
53
|
+
"name": "get_metric_timeseries",
|
|
54
|
+
"input": {
|
|
55
|
+
"metric": "revenue",
|
|
56
|
+
"dimension": "state",
|
|
57
|
+
"time_range": { "from": "2026-05-04", "to": "2026-06-01" },
|
|
58
|
+
"granularity": "week"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
],
|
|
62
|
+
"usage": { "inputTokens": 900, "outputTokens": 70 },
|
|
63
|
+
"model": "fixture-model"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"content": [
|
|
67
|
+
{
|
|
68
|
+
"type": "text",
|
|
69
|
+
"text": "For the last 30 days in the populated fixture window, SP had the most revenue at BRL 285,500, followed by RJ at BRL 121,000 and MG at BRL 98,000. The ranking is SP, RJ, then MG, based on the get_metric_timeseries result for revenue by state from 2026-05-04 to 2026-06-01."
|
|
70
|
+
}
|
|
71
|
+
],
|
|
72
|
+
"usage": { "inputTokens": 780, "outputTokens": 95 },
|
|
73
|
+
"model": "fixture-model"
|
|
74
|
+
}
|
|
75
|
+
],
|
|
76
|
+
"expectations": {
|
|
77
|
+
"requiredAnswerText": ["SP", "BRL 285,500", "RJ", "BRL 121,000", "MG", "BRL 98,000"]
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@aptkit/agent-query",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/src/index.js",
|
|
6
|
+
"types": "./dist/src/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"README.md",
|
|
9
|
+
"dist/src",
|
|
10
|
+
"fixtures"
|
|
11
|
+
],
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/src/index.d.ts",
|
|
15
|
+
"import": "./dist/src/index.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsc -p tsconfig.json",
|
|
20
|
+
"test": "npm run build && node --test dist/test/*.test.js",
|
|
21
|
+
"replay:fixture": "npm run build && node dist/scripts/replay-fixture.js",
|
|
22
|
+
"replay:promoted": "npm run build && node ../../../scripts/replay-promoted-fixtures.mjs --count answerPresent --empty \"no promoted query fixtures found\""
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@aptkit/context": "0.0.0",
|
|
26
|
+
"@aptkit/prompts": "0.0.0",
|
|
27
|
+
"@aptkit/runtime": "0.0.0",
|
|
28
|
+
"@aptkit/tools": "0.0.0"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/node": "^20.0.0"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# @aptkit/agent-recommendation
|
|
2
|
+
|
|
3
|
+
Extracted recommendation capability from the Blooming Insights workflow.
|
|
4
|
+
|
|
5
|
+
The package proposes 1-3 marketer-facing actions from an anomaly and diagnosis. It is provider-neutral: callers inject a `ModelProvider`, `ToolRegistry`, workspace descriptor, optional action taxonomy, and optional trace sink.
|
|
6
|
+
|
|
7
|
+
## Install In Workspace
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npm install
|
|
11
|
+
npm run build
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Fixture Replay
|
|
15
|
+
|
|
16
|
+
Run the default recorded fixture without network or secrets:
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
npm run replay:fixture -w @aptkit/agent-recommendation
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The default fixture is `fixtures/sp-revenue-drop.json`, derived from the Blooming Insights `06-recommendation-sp` regression case.
|
|
23
|
+
|
|
24
|
+
Additional fixtures:
|
|
25
|
+
|
|
26
|
+
- `fixtures/electronics-spike.json`
|
|
27
|
+
- `fixtures/voucher-dropoff.json`
|
|
28
|
+
|
|
29
|
+
Run a specific fixture:
|
|
30
|
+
|
|
31
|
+
```sh
|
|
32
|
+
npm run replay:fixture -w @aptkit/agent-recommendation -- fixtures/electronics-spike.json
|
|
33
|
+
npm run replay:fixture -w @aptkit/agent-recommendation -- fixtures/voucher-dropoff.json
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Basic Usage
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
import { RecommendationAgent } from '@aptkit/agent-recommendation';
|
|
40
|
+
import { InMemoryToolRegistry } from '@aptkit/tools';
|
|
41
|
+
|
|
42
|
+
const agent = new RecommendationAgent({
|
|
43
|
+
model,
|
|
44
|
+
tools,
|
|
45
|
+
workspace,
|
|
46
|
+
trace: { emit: console.log },
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const recommendations = await agent.propose(anomaly, diagnosis);
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Live Anthropic Usage
|
|
53
|
+
|
|
54
|
+
The agent does not import Anthropic directly. Use `@aptkit/provider-anthropic` at the app boundary:
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
import { AnthropicModelProvider } from '@aptkit/provider-anthropic';
|
|
58
|
+
import { RecommendationAgent } from '@aptkit/agent-recommendation';
|
|
59
|
+
|
|
60
|
+
const model = new AnthropicModelProvider({
|
|
61
|
+
apiKey: process.env.ANTHROPIC_API_KEY,
|
|
62
|
+
model: 'claude-sonnet-4-6',
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
const agent = new RecommendationAgent({ model, tools, workspace });
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Live provider tests should stay opt-in and must not run in CI without explicit credentials.
|
|
69
|
+
|
|
70
|
+
## Live OpenAI Usage
|
|
71
|
+
|
|
72
|
+
Use `@aptkit/provider-openai` at the app boundary:
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
import { OpenAIModelProvider } from '@aptkit/provider-openai';
|
|
76
|
+
import { RecommendationAgent } from '@aptkit/agent-recommendation';
|
|
77
|
+
|
|
78
|
+
const model = new OpenAIModelProvider({
|
|
79
|
+
apiKey: process.env.OPENAI_API_KEY,
|
|
80
|
+
model: process.env.OPENAI_MODEL ?? 'gpt-4.1',
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
const agent = new RecommendationAgent({ model, tools, workspace });
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
The OpenAI adapter uses Chat Completions function tools because AptKit's current runtime contract is chat/tool-loop shaped. A Responses API adapter can be added later if AptKit needs OpenAI-native response state, richer built-in tools, or streaming event parity.
|
|
87
|
+
|
|
88
|
+
## Contract
|
|
89
|
+
|
|
90
|
+
Input:
|
|
91
|
+
|
|
92
|
+
- `Anomaly`
|
|
93
|
+
- `Diagnosis`
|
|
94
|
+
- `WorkspaceDescriptor`
|
|
95
|
+
- Optional `ActionTaxonomy`
|
|
96
|
+
|
|
97
|
+
Output:
|
|
98
|
+
|
|
99
|
+
- `Recommendation[]`
|
|
100
|
+
|
|
101
|
+
The model is asked to emit recommendations without `id`; this package validates the id-less shape, caps the output at three recommendations, then assigns ids through `idGenerator`.
|
|
102
|
+
|
|
103
|
+
## What Stayed Out
|
|
104
|
+
|
|
105
|
+
- Bloomreach OAuth and cookies.
|
|
106
|
+
- Next.js route handlers.
|
|
107
|
+
- UI streaming state.
|
|
108
|
+
- Concrete Bloomreach and Olist adapters.
|
|
109
|
+
- Source-app state files and live provider logs.
|
|
@@ -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,30 @@
|
|
|
1
|
+
import { type CapabilityTraceSink, type ModelProvider } from '@aptkit/runtime';
|
|
2
|
+
import { type ToolRegistry } from '@aptkit/tools';
|
|
3
|
+
import { type ActionTaxonomy, type Anomaly, type Diagnosis, type Recommendation, type WorkspaceDescriptor } from './types.js';
|
|
4
|
+
export declare const RECOMMENDATION_CAPABILITY_ID = "recommendation-agent";
|
|
5
|
+
/** Least-privilege tool grant for read-only recommendation generation. */
|
|
6
|
+
export declare const recommendationToolPolicy: {
|
|
7
|
+
capabilityId: string;
|
|
8
|
+
allowedTools: readonly ["list_scenarios", "get_scenario", "list_initiatives", "get_initiative_items", "list_recommendations", "get_recommendation", "list_segmentations", "list_email_campaigns", "list_voucher_pools", "get_frequency_policies", "get_metric_timeseries", "get_segments", "get_anomaly_context"];
|
|
9
|
+
};
|
|
10
|
+
export type RecommendationAgentOptions = {
|
|
11
|
+
model: ModelProvider;
|
|
12
|
+
tools: ToolRegistry;
|
|
13
|
+
workspace: WorkspaceDescriptor;
|
|
14
|
+
actionTaxonomy?: ActionTaxonomy;
|
|
15
|
+
trace?: CapabilityTraceSink;
|
|
16
|
+
idGenerator?: () => string;
|
|
17
|
+
prompt?: string;
|
|
18
|
+
};
|
|
19
|
+
export type RecommendationRunOptions = {
|
|
20
|
+
signal?: AbortSignal;
|
|
21
|
+
};
|
|
22
|
+
export declare class RecommendationAgent {
|
|
23
|
+
private readonly options;
|
|
24
|
+
private readonly taxonomy;
|
|
25
|
+
private readonly idGenerator;
|
|
26
|
+
private readonly prompt;
|
|
27
|
+
constructor(options: RecommendationAgentOptions);
|
|
28
|
+
/** Produces validated, id-assigned recommendations grounded in an anomaly diagnosis. */
|
|
29
|
+
propose(anomaly: Anomaly, diagnosis: Diagnosis, runOptions?: RecommendationRunOptions): Promise<Recommendation[]>;
|
|
30
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { recommendationPromptPackage, renderPromptTemplate } from '@aptkit/prompts';
|
|
2
|
+
import { buildSynthesisInstruction, runAgentLoop } from '@aptkit/runtime';
|
|
3
|
+
import { filterToolsForPolicy } from '@aptkit/tools';
|
|
4
|
+
import { schemaSummary } from './schema-summary.js';
|
|
5
|
+
import { DEFAULT_ACTION_TAXONOMY, } from './types.js';
|
|
6
|
+
import { tryParseRecommendations } from './validate.js';
|
|
7
|
+
export const RECOMMENDATION_CAPABILITY_ID = 'recommendation-agent';
|
|
8
|
+
/** Least-privilege tool grant for read-only recommendation generation. */
|
|
9
|
+
export const recommendationToolPolicy = {
|
|
10
|
+
capabilityId: RECOMMENDATION_CAPABILITY_ID,
|
|
11
|
+
allowedTools: [
|
|
12
|
+
'list_scenarios',
|
|
13
|
+
'get_scenario',
|
|
14
|
+
'list_initiatives',
|
|
15
|
+
'get_initiative_items',
|
|
16
|
+
'list_recommendations',
|
|
17
|
+
'get_recommendation',
|
|
18
|
+
'list_segmentations',
|
|
19
|
+
'list_email_campaigns',
|
|
20
|
+
'list_voucher_pools',
|
|
21
|
+
'get_frequency_policies',
|
|
22
|
+
'get_metric_timeseries',
|
|
23
|
+
'get_segments',
|
|
24
|
+
'get_anomaly_context',
|
|
25
|
+
],
|
|
26
|
+
};
|
|
27
|
+
export class RecommendationAgent {
|
|
28
|
+
options;
|
|
29
|
+
taxonomy;
|
|
30
|
+
idGenerator;
|
|
31
|
+
prompt;
|
|
32
|
+
constructor(options) {
|
|
33
|
+
this.options = options;
|
|
34
|
+
this.taxonomy = options.actionTaxonomy ?? DEFAULT_ACTION_TAXONOMY;
|
|
35
|
+
this.idGenerator = options.idGenerator ?? (() => crypto.randomUUID());
|
|
36
|
+
this.prompt = options.prompt ?? recommendationPromptPackage.system;
|
|
37
|
+
}
|
|
38
|
+
/** Produces validated, id-assigned recommendations grounded in an anomaly diagnosis. */
|
|
39
|
+
async propose(anomaly, diagnosis, runOptions = {}) {
|
|
40
|
+
const allTools = await this.options.tools.listTools();
|
|
41
|
+
const toolSchemas = filterToolsForPolicy(allTools, recommendationToolPolicy);
|
|
42
|
+
const system = renderPromptTemplate(this.prompt, {
|
|
43
|
+
schema: schemaSummary(this.options.workspace),
|
|
44
|
+
project_id: this.options.workspace.projectId,
|
|
45
|
+
diagnosis: JSON.stringify(diagnosis),
|
|
46
|
+
});
|
|
47
|
+
const { parsed } = await runAgentLoop({
|
|
48
|
+
capabilityId: RECOMMENDATION_CAPABILITY_ID,
|
|
49
|
+
model: this.options.model,
|
|
50
|
+
tools: this.options.tools,
|
|
51
|
+
system,
|
|
52
|
+
userPrompt: 'Propose recommendations for this diagnosis and return the JSON array.',
|
|
53
|
+
toolSchemas,
|
|
54
|
+
trace: this.options.trace,
|
|
55
|
+
signal: runOptions.signal,
|
|
56
|
+
maxTurns: 6,
|
|
57
|
+
maxToolCalls: 4,
|
|
58
|
+
synthesisInstruction: buildSynthesisInstruction('Stop querying now and output your final answer. Respond with ONLY a JSON array of at most 3 recommendation objects in a json fence, or [] if you cannot propose grounded actions, based on the diagnosis and the data you have already gathered. Do NOT include an id field.'),
|
|
59
|
+
parseResult: (text) => tryParseRecommendations(text, this.taxonomy),
|
|
60
|
+
recoveryPrompt: (toolCalls) => buildRecoveryPrompt(anomaly, diagnosis, toolCalls),
|
|
61
|
+
});
|
|
62
|
+
if (!parsed)
|
|
63
|
+
return [];
|
|
64
|
+
return parsed.slice(0, 3).map((recommendation) => ({
|
|
65
|
+
id: this.idGenerator(),
|
|
66
|
+
...recommendation,
|
|
67
|
+
}));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function buildRecoveryPrompt(anomaly, diagnosis, toolCalls) {
|
|
71
|
+
const evidence = toolCalls
|
|
72
|
+
.map((call, index) => {
|
|
73
|
+
const payload = call.error ? { error: call.error } : call.result;
|
|
74
|
+
return `Query ${index + 1}: ${call.toolName} ${JSON.stringify(call.args).slice(0, 200)}\nResult: ${JSON.stringify(payload).slice(0, 900)}`;
|
|
75
|
+
})
|
|
76
|
+
.join('\n\n') || '(no existing-feature queries were completed)';
|
|
77
|
+
return [
|
|
78
|
+
`Anomaly that was diagnosed:\n${JSON.stringify(anomaly)}`,
|
|
79
|
+
`Diagnosis to act on:\n${JSON.stringify(diagnosis)}`,
|
|
80
|
+
`Existing-feature queries run and their results:\n${evidence}`,
|
|
81
|
+
'Based on the diagnosis above, output your best 2-3 recommendations as a single JSON array in a json fence.',
|
|
82
|
+
'Each object must include title, rationale, bloomreachFeature, steps, estimatedImpact, confidence, and any useful setup fields.',
|
|
83
|
+
'Do NOT include an id field. If you cannot propose grounded actions, return []. Do NOT request more queries.',
|
|
84
|
+
].join('\n\n');
|
|
85
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { schemaSummary } from '@aptkit/context';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { schemaSummary } from '@aptkit/context';
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export type { WorkspaceDescriptor } from '@aptkit/context';
|
|
2
|
+
export type Severity = 'critical' | 'warning' | 'info' | 'positive';
|
|
3
|
+
export type Anomaly = {
|
|
4
|
+
metric: string;
|
|
5
|
+
scope: string[];
|
|
6
|
+
change: {
|
|
7
|
+
value: number;
|
|
8
|
+
direction: 'up' | 'down';
|
|
9
|
+
baseline: string;
|
|
10
|
+
};
|
|
11
|
+
severity: Severity;
|
|
12
|
+
evidence: {
|
|
13
|
+
tool: string;
|
|
14
|
+
result: unknown;
|
|
15
|
+
}[];
|
|
16
|
+
impact?: string;
|
|
17
|
+
history?: number[];
|
|
18
|
+
category?: string;
|
|
19
|
+
};
|
|
20
|
+
export type Diagnosis = {
|
|
21
|
+
conclusion: string;
|
|
22
|
+
evidence: string[];
|
|
23
|
+
hypothesesConsidered: {
|
|
24
|
+
hypothesis: string;
|
|
25
|
+
supported: boolean;
|
|
26
|
+
reasoning: string;
|
|
27
|
+
}[];
|
|
28
|
+
affectedCustomers?: {
|
|
29
|
+
count: number;
|
|
30
|
+
segmentDescription: string;
|
|
31
|
+
};
|
|
32
|
+
confidence?: 'high' | 'medium' | 'low';
|
|
33
|
+
timeSeries?: {
|
|
34
|
+
day: string;
|
|
35
|
+
value: number;
|
|
36
|
+
}[];
|
|
37
|
+
};
|
|
38
|
+
export type ActionFeature = 'scenario' | 'segment' | 'campaign' | 'voucher' | 'experiment';
|
|
39
|
+
export type EstimatedImpact = string | {
|
|
40
|
+
range: string;
|
|
41
|
+
rangeUsd?: {
|
|
42
|
+
low: number;
|
|
43
|
+
high: number;
|
|
44
|
+
};
|
|
45
|
+
assumption: string;
|
|
46
|
+
};
|
|
47
|
+
export type Recommendation = {
|
|
48
|
+
id: string;
|
|
49
|
+
title: string;
|
|
50
|
+
rationale: string;
|
|
51
|
+
bloomreachFeature: ActionFeature;
|
|
52
|
+
steps: string[];
|
|
53
|
+
estimatedImpact: EstimatedImpact;
|
|
54
|
+
confidence: 'high' | 'medium' | 'low';
|
|
55
|
+
effort?: 'low' | 'medium' | 'high';
|
|
56
|
+
timeToSetUpMinutes?: number;
|
|
57
|
+
readResultInDays?: number;
|
|
58
|
+
prerequisites?: {
|
|
59
|
+
label: string;
|
|
60
|
+
satisfied: boolean;
|
|
61
|
+
}[];
|
|
62
|
+
successMetric?: string;
|
|
63
|
+
};
|
|
64
|
+
export type IdlessRecommendation = Omit<Recommendation, 'id'>;
|
|
65
|
+
export type ActionTaxonomy = {
|
|
66
|
+
features: readonly ActionFeature[];
|
|
67
|
+
};
|
|
68
|
+
export declare const DEFAULT_ACTION_TAXONOMY: ActionTaxonomy;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { ActionTaxonomy, IdlessRecommendation } from './types.js';
|
|
2
|
+
export declare function isRecommendationArray(value: unknown, taxonomy: ActionTaxonomy): value is IdlessRecommendation[];
|
|
3
|
+
export declare function tryParseRecommendations(text: string, taxonomy: ActionTaxonomy): IdlessRecommendation[] | null;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { parseAgentJson } from '@aptkit/runtime';
|
|
2
|
+
const CONFIDENCE = ['high', 'medium', 'low'];
|
|
3
|
+
const EFFORT = ['low', 'medium', 'high'];
|
|
4
|
+
function isRecord(value) {
|
|
5
|
+
return !!value && typeof value === 'object' && !Array.isArray(value);
|
|
6
|
+
}
|
|
7
|
+
function isEstimatedImpact(value) {
|
|
8
|
+
if (typeof value === 'string')
|
|
9
|
+
return true;
|
|
10
|
+
return isRecord(value) && typeof value.range === 'string';
|
|
11
|
+
}
|
|
12
|
+
function isPrerequisite(value) {
|
|
13
|
+
return isRecord(value) && typeof value.label === 'string' && typeof value.satisfied === 'boolean';
|
|
14
|
+
}
|
|
15
|
+
export function isRecommendationArray(value, taxonomy) {
|
|
16
|
+
return Array.isArray(value) && value.every((item) => {
|
|
17
|
+
if (!isRecord(item))
|
|
18
|
+
return false;
|
|
19
|
+
if (typeof item.title !== 'string')
|
|
20
|
+
return false;
|
|
21
|
+
if (typeof item.rationale !== 'string')
|
|
22
|
+
return false;
|
|
23
|
+
if (!taxonomy.features.includes(item.bloomreachFeature))
|
|
24
|
+
return false;
|
|
25
|
+
if (!Array.isArray(item.steps) || !item.steps.every((step) => typeof step === 'string'))
|
|
26
|
+
return false;
|
|
27
|
+
if (!isEstimatedImpact(item.estimatedImpact))
|
|
28
|
+
return false;
|
|
29
|
+
if (!CONFIDENCE.includes(String(item.confidence)))
|
|
30
|
+
return false;
|
|
31
|
+
if (item.effort !== undefined && !EFFORT.includes(String(item.effort)))
|
|
32
|
+
return false;
|
|
33
|
+
if (item.timeToSetUpMinutes !== undefined && typeof item.timeToSetUpMinutes !== 'number')
|
|
34
|
+
return false;
|
|
35
|
+
if (item.readResultInDays !== undefined && typeof item.readResultInDays !== 'number')
|
|
36
|
+
return false;
|
|
37
|
+
if (item.prerequisites !== undefined &&
|
|
38
|
+
(!Array.isArray(item.prerequisites) || !item.prerequisites.every(isPrerequisite))) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
if (item.successMetric !== undefined && typeof item.successMetric !== 'string')
|
|
42
|
+
return false;
|
|
43
|
+
return true;
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
export function tryParseRecommendations(text, taxonomy) {
|
|
47
|
+
try {
|
|
48
|
+
const parsed = parseAgentJson(text);
|
|
49
|
+
return isRecommendationArray(parsed, taxonomy) ? parsed : null;
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
}
|