@rlynjb/aptkit-core 0.1.0 → 0.2.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 +1 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/node_modules/@aptkit/provider-synthetic/dist/src/fixture-data-source.d.ts +18 -0
- package/node_modules/@aptkit/provider-synthetic/dist/src/fixture-data-source.js +120 -0
- package/node_modules/@aptkit/provider-synthetic/dist/src/index.d.ts +5 -0
- package/node_modules/@aptkit/provider-synthetic/dist/src/index.js +5 -0
- package/node_modules/@aptkit/provider-synthetic/dist/src/openai-synthetic-data-source.d.ts +22 -0
- package/node_modules/@aptkit/provider-synthetic/dist/src/openai-synthetic-data-source.js +181 -0
- package/node_modules/@aptkit/provider-synthetic/dist/src/tool-definitions.d.ts +2 -0
- package/node_modules/@aptkit/provider-synthetic/dist/src/tool-definitions.js +59 -0
- package/node_modules/@aptkit/provider-synthetic/dist/src/tool-registry.d.ts +15 -0
- package/node_modules/@aptkit/provider-synthetic/dist/src/tool-registry.js +28 -0
- package/node_modules/@aptkit/provider-synthetic/dist/src/types.d.ts +94 -0
- package/node_modules/@aptkit/provider-synthetic/dist/src/types.js +1 -0
- package/node_modules/@aptkit/provider-synthetic/package.json +28 -0
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ The package is published to npmjs as `@rlynjb/aptkit-core`.
|
|
|
13
13
|
Blooming keeps its existing imports by installing this package through an npm alias:
|
|
14
14
|
|
|
15
15
|
```sh
|
|
16
|
-
npm install @aptkit/core@npm:@rlynjb/aptkit-core@0.
|
|
16
|
+
npm install @aptkit/core@npm:@rlynjb/aptkit-core@0.2.0
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
Because the package is public on npmjs, consumers do not need a package registry token.
|
package/dist/src/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export * from '@aptkit/tools';
|
|
|
3
3
|
export * from '@aptkit/context';
|
|
4
4
|
export * from '@aptkit/prompts';
|
|
5
5
|
export * from '@aptkit/evals';
|
|
6
|
+
export * from '@aptkit/provider-synthetic';
|
|
6
7
|
export * from '@aptkit/agent-recommendation';
|
|
7
8
|
export { ANOMALY_MONITORING_CAPABILITY_ID, AnomalyMonitoringAgent, ECOMMERCE_ANOMALY_CATEGORIES, anomalyMonitoringToolPolicy, coverageReport, formatCategoryChecklist, runnableCategories, schemaCapabilities, tryParseAnomalies, validateAnomalies, } from '@aptkit/agent-anomaly-monitoring';
|
|
8
9
|
export type { Anomaly as MonitoringAnomaly, AnomalyCategory as MonitoringAnomalyCategory, } from '@aptkit/agent-anomaly-monitoring';
|
package/dist/src/index.js
CHANGED
|
@@ -3,6 +3,7 @@ export * from '@aptkit/tools';
|
|
|
3
3
|
export * from '@aptkit/context';
|
|
4
4
|
export * from '@aptkit/prompts';
|
|
5
5
|
export * from '@aptkit/evals';
|
|
6
|
+
export * from '@aptkit/provider-synthetic';
|
|
6
7
|
export * from '@aptkit/agent-recommendation';
|
|
7
8
|
export { ANOMALY_MONITORING_CAPABILITY_ID, AnomalyMonitoringAgent, ECOMMERCE_ANOMALY_CATEGORIES, anomalyMonitoringToolPolicy, coverageReport, formatCategoryChecklist, runnableCategories, schemaCapabilities, tryParseAnomalies, validateAnomalies, } from '@aptkit/agent-anomaly-monitoring';
|
|
8
9
|
export { DIAGNOSTIC_INVESTIGATION_CAPABILITY_ID, DiagnosticInvestigationAgent, diagnosticInvestigationToolPolicy, diagnosisConfidence, tryParseDiagnosis, validateDiagnosis, } from '@aptkit/agent-diagnostic-investigation';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { WorkspaceDescriptor } from '@aptkit/context';
|
|
2
|
+
import type { AnomalyContextArgs, AnomalyContextResult, MetricTimeseriesArgs, MetricTimeseriesResult, ProjectOverview, SyntheticEcommerceDataSource } from './types.js';
|
|
3
|
+
export declare const syntheticEcommerceWorkspace: WorkspaceDescriptor;
|
|
4
|
+
export type FixtureSyntheticEcommerceDataSourceOptions = {
|
|
5
|
+
scenarioId?: string;
|
|
6
|
+
workspace?: WorkspaceDescriptor;
|
|
7
|
+
};
|
|
8
|
+
/** Deterministic synthetic ecommerce data source for Studio, tests, and repeatable demos. */
|
|
9
|
+
export declare class FixtureSyntheticEcommerceDataSource implements SyntheticEcommerceDataSource {
|
|
10
|
+
readonly mode: "fixture";
|
|
11
|
+
readonly scenarioId: string;
|
|
12
|
+
readonly workspace: WorkspaceDescriptor;
|
|
13
|
+
constructor(options?: FixtureSyntheticEcommerceDataSourceOptions);
|
|
14
|
+
getProjectOverview(): ProjectOverview;
|
|
15
|
+
getMetricTimeseries(args?: MetricTimeseriesArgs): MetricTimeseriesResult;
|
|
16
|
+
getAnomalyContext(args?: AnomalyContextArgs): AnomalyContextResult;
|
|
17
|
+
private providerMetadata;
|
|
18
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
const DEFAULT_RECENT_WINDOW = { from: '2026-05-04', to: '2026-06-01' };
|
|
2
|
+
const DEFAULT_BASELINE_WINDOW = { from: '2026-02-09', to: '2026-05-04' };
|
|
3
|
+
export const syntheticEcommerceWorkspace = {
|
|
4
|
+
projectId: 'synthetic-ecommerce',
|
|
5
|
+
projectName: 'Synthetic ecommerce analytics workspace',
|
|
6
|
+
events: [
|
|
7
|
+
{ name: 'purchase', properties: ['state', 'category', 'payment_type', 'total_price'], eventCount: 50000 },
|
|
8
|
+
{ name: 'session_start', properties: ['utm_source', 'device'], eventCount: 80000 },
|
|
9
|
+
{ name: 'checkout', properties: ['state', 'payment_type'], eventCount: 35000 },
|
|
10
|
+
{ name: 'view_item', properties: ['category'], eventCount: 120000 },
|
|
11
|
+
],
|
|
12
|
+
customerProperties: ['state', 'city', 'loyalty_tier'],
|
|
13
|
+
catalogs: [{ id: 'products', name: 'Products' }],
|
|
14
|
+
totalCustomers: 125000,
|
|
15
|
+
totalEvents: 285000,
|
|
16
|
+
oldestTimestamp: Date.UTC(2025, 11, 1),
|
|
17
|
+
dataHorizon: { from: '2025-12-01', to: '2026-06-01', durationDays: 182 },
|
|
18
|
+
};
|
|
19
|
+
/** Deterministic synthetic ecommerce data source for Studio, tests, and repeatable demos. */
|
|
20
|
+
export class FixtureSyntheticEcommerceDataSource {
|
|
21
|
+
mode = 'fixture';
|
|
22
|
+
scenarioId;
|
|
23
|
+
workspace;
|
|
24
|
+
constructor(options = {}) {
|
|
25
|
+
this.scenarioId = options.scenarioId ?? 'sp-revenue-drop';
|
|
26
|
+
this.workspace = options.workspace ?? syntheticEcommerceWorkspace;
|
|
27
|
+
}
|
|
28
|
+
getProjectOverview() {
|
|
29
|
+
return {
|
|
30
|
+
provider: this.providerMetadata(),
|
|
31
|
+
workspace: this.workspace,
|
|
32
|
+
highlights: [
|
|
33
|
+
'SP revenue is down 30.0245% over the recent four-week window.',
|
|
34
|
+
'RJ and MG remain approximately flat, making the movement region-specific.',
|
|
35
|
+
'The fixture is deterministic and safe for replay promotion.',
|
|
36
|
+
],
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
getMetricTimeseries(args = {}) {
|
|
40
|
+
const metric = args.metric ?? 'revenue';
|
|
41
|
+
const dimension = args.dimension ?? 'state';
|
|
42
|
+
const segment = args.segment ?? 'SP';
|
|
43
|
+
const recentWindow = requiredRange(args.time_range, DEFAULT_RECENT_WINDOW);
|
|
44
|
+
return {
|
|
45
|
+
provider: this.providerMetadata(),
|
|
46
|
+
periodComparison: {
|
|
47
|
+
metric,
|
|
48
|
+
dimension,
|
|
49
|
+
segment,
|
|
50
|
+
recentWindow,
|
|
51
|
+
baselineWindow: DEFAULT_BASELINE_WINDOW,
|
|
52
|
+
recentValue: 28550000,
|
|
53
|
+
baselineAverage: 40800000,
|
|
54
|
+
pctChange: -0.300245,
|
|
55
|
+
relatedSegments: [
|
|
56
|
+
{ name: 'RJ', pctChange: -0.02 },
|
|
57
|
+
{ name: 'MG', pctChange: 0.01 },
|
|
58
|
+
],
|
|
59
|
+
},
|
|
60
|
+
points: [
|
|
61
|
+
{ ts: '2026-05-04', segment: 'SP', value: 7400000 },
|
|
62
|
+
{ ts: '2026-05-11', segment: 'SP', value: 7200000 },
|
|
63
|
+
{ ts: '2026-05-18', segment: 'SP', value: 7050000 },
|
|
64
|
+
{ ts: '2026-05-25', segment: 'SP', value: 6900000 },
|
|
65
|
+
{ ts: '2026-05-04', segment: 'RJ', value: 4300000 },
|
|
66
|
+
{ ts: '2026-05-11', segment: 'RJ', value: 4350000 },
|
|
67
|
+
{ ts: '2026-05-04', segment: 'MG', value: 3900000 },
|
|
68
|
+
{ ts: '2026-05-11', segment: 'MG', value: 3940000 },
|
|
69
|
+
],
|
|
70
|
+
totalCount: 4200,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
getAnomalyContext(args = {}) {
|
|
74
|
+
const metric = args.metric ?? 'revenue';
|
|
75
|
+
const segment = args.segment ?? 'SP';
|
|
76
|
+
return {
|
|
77
|
+
provider: this.providerMetadata(),
|
|
78
|
+
anomaly_summary: {
|
|
79
|
+
metric,
|
|
80
|
+
segment,
|
|
81
|
+
anomaly_value: 28550000,
|
|
82
|
+
baseline_avg: 40800000,
|
|
83
|
+
pct_change: -0.300245,
|
|
84
|
+
},
|
|
85
|
+
related_segments: [
|
|
86
|
+
{ name: 'RJ', pct_change: -0.02 },
|
|
87
|
+
{ name: 'MG', pct_change: 0.01 },
|
|
88
|
+
],
|
|
89
|
+
drivers: [
|
|
90
|
+
{
|
|
91
|
+
name: 'electronics',
|
|
92
|
+
contribution: -0.62,
|
|
93
|
+
detail: 'Electronics orders in SP account for most of the recent revenue loss.',
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
name: 'paid_search',
|
|
97
|
+
contribution: -0.21,
|
|
98
|
+
detail: 'Paid search sessions declined during the same window.',
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
sample_orders: [
|
|
102
|
+
{ order_id: 'syn-sp-101', purchase_ts: '2026-05-10', status: 'delivered', price_brl: 42000 },
|
|
103
|
+
{ order_id: 'syn-sp-102', purchase_ts: '2026-05-23', status: 'delivered', price_brl: 31000 },
|
|
104
|
+
],
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
providerMetadata() {
|
|
108
|
+
return {
|
|
109
|
+
id: 'synthetic-ecommerce',
|
|
110
|
+
mode: this.mode,
|
|
111
|
+
scenarioId: this.scenarioId,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
function requiredRange(input, fallback) {
|
|
116
|
+
return {
|
|
117
|
+
from: input?.from ?? fallback.from,
|
|
118
|
+
to: input?.to ?? fallback.to,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type ModelProvider } from '@aptkit/runtime';
|
|
2
|
+
import type { AnomalyContextArgs, AnomalyContextResult, MetricTimeseriesArgs, MetricTimeseriesResult, ProjectOverview, SyntheticEcommerceDataSource } from './types.js';
|
|
3
|
+
import type { WorkspaceDescriptor } from '@aptkit/context';
|
|
4
|
+
export type OpenAISyntheticEcommerceDataSourceOptions = {
|
|
5
|
+
model: ModelProvider;
|
|
6
|
+
scenarioId?: string;
|
|
7
|
+
workspace?: WorkspaceDescriptor;
|
|
8
|
+
systemPrompt?: string;
|
|
9
|
+
};
|
|
10
|
+
/** Model-backed synthetic data source. Use with OpenAIModelProvider or any ModelProvider adapter. */
|
|
11
|
+
export declare class OpenAISyntheticEcommerceDataSource implements SyntheticEcommerceDataSource {
|
|
12
|
+
readonly mode: "openai";
|
|
13
|
+
readonly scenarioId: string;
|
|
14
|
+
readonly workspace: WorkspaceDescriptor;
|
|
15
|
+
private readonly model;
|
|
16
|
+
private readonly systemPrompt;
|
|
17
|
+
constructor(options: OpenAISyntheticEcommerceDataSourceOptions);
|
|
18
|
+
getProjectOverview(): Promise<ProjectOverview>;
|
|
19
|
+
getMetricTimeseries(args?: MetricTimeseriesArgs): Promise<MetricTimeseriesResult>;
|
|
20
|
+
getAnomalyContext(args?: AnomalyContextArgs): Promise<AnomalyContextResult>;
|
|
21
|
+
private completeJson;
|
|
22
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { parseAgentJson } from '@aptkit/runtime';
|
|
2
|
+
import { syntheticEcommerceWorkspace } from './fixture-data-source.js';
|
|
3
|
+
/** Model-backed synthetic data source. Use with OpenAIModelProvider or any ModelProvider adapter. */
|
|
4
|
+
export class OpenAISyntheticEcommerceDataSource {
|
|
5
|
+
mode = 'openai';
|
|
6
|
+
scenarioId;
|
|
7
|
+
workspace;
|
|
8
|
+
model;
|
|
9
|
+
systemPrompt;
|
|
10
|
+
constructor(options) {
|
|
11
|
+
this.model = options.model;
|
|
12
|
+
this.scenarioId = options.scenarioId ?? 'sp-revenue-drop';
|
|
13
|
+
this.workspace = options.workspace ?? syntheticEcommerceWorkspace;
|
|
14
|
+
this.systemPrompt = options.systemPrompt ?? [
|
|
15
|
+
'You generate synthetic ecommerce analytics tool results for AptKit.',
|
|
16
|
+
'Return only JSON. Do not include prose or markdown fences.',
|
|
17
|
+
'Keep outputs internally consistent for the requested scenario and workspace.',
|
|
18
|
+
'Always include provider metadata: {"id":"synthetic-ecommerce","mode":"openai","scenarioId": string}.',
|
|
19
|
+
].join('\n');
|
|
20
|
+
}
|
|
21
|
+
async getProjectOverview() {
|
|
22
|
+
const value = await this.completeJson('get_project_overview', {});
|
|
23
|
+
return assertProjectOverview(value, this.scenarioId);
|
|
24
|
+
}
|
|
25
|
+
async getMetricTimeseries(args = {}) {
|
|
26
|
+
const value = await this.completeJson('get_metric_timeseries', args);
|
|
27
|
+
return assertMetricTimeseries(value, this.scenarioId);
|
|
28
|
+
}
|
|
29
|
+
async getAnomalyContext(args = {}) {
|
|
30
|
+
const value = await this.completeJson('get_anomaly_context', args);
|
|
31
|
+
return assertAnomalyContext(value, this.scenarioId);
|
|
32
|
+
}
|
|
33
|
+
async completeJson(toolName, args) {
|
|
34
|
+
const response = await this.model.complete({
|
|
35
|
+
system: this.systemPrompt,
|
|
36
|
+
messages: [
|
|
37
|
+
{
|
|
38
|
+
role: 'user',
|
|
39
|
+
content: JSON.stringify({
|
|
40
|
+
toolName,
|
|
41
|
+
scenarioId: this.scenarioId,
|
|
42
|
+
workspace: this.workspace,
|
|
43
|
+
args,
|
|
44
|
+
}),
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
maxTokens: 1400,
|
|
48
|
+
temperature: 0.2,
|
|
49
|
+
});
|
|
50
|
+
const text = response.content
|
|
51
|
+
.filter((block) => block.type === 'text')
|
|
52
|
+
.map((block) => block.text)
|
|
53
|
+
.join('\n');
|
|
54
|
+
return parseAgentJson(text);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function assertProjectOverview(value, scenarioId) {
|
|
58
|
+
const object = assertObject(value, 'project overview');
|
|
59
|
+
if (!isObject(object.workspace))
|
|
60
|
+
throw new Error('project overview workspace is missing');
|
|
61
|
+
return {
|
|
62
|
+
provider: providerMetadata(object.provider, scenarioId, 'openai'),
|
|
63
|
+
workspace: object.workspace,
|
|
64
|
+
highlights: stringArray(object.highlights, 'highlights'),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function assertMetricTimeseries(value, scenarioId) {
|
|
68
|
+
const object = assertObject(value, 'metric timeseries');
|
|
69
|
+
const comparison = assertObject(object.periodComparison, 'periodComparison');
|
|
70
|
+
return {
|
|
71
|
+
provider: providerMetadata(object.provider, scenarioId, 'openai'),
|
|
72
|
+
periodComparison: {
|
|
73
|
+
metric: stringValue(comparison.metric, 'periodComparison.metric'),
|
|
74
|
+
dimension: stringValue(comparison.dimension, 'periodComparison.dimension'),
|
|
75
|
+
segment: stringValue(comparison.segment, 'periodComparison.segment'),
|
|
76
|
+
recentWindow: timeRange(comparison.recentWindow, 'periodComparison.recentWindow'),
|
|
77
|
+
baselineWindow: timeRange(comparison.baselineWindow, 'periodComparison.baselineWindow'),
|
|
78
|
+
recentValue: numberValue(comparison.recentValue, 'periodComparison.recentValue'),
|
|
79
|
+
baselineAverage: numberValue(comparison.baselineAverage, 'periodComparison.baselineAverage'),
|
|
80
|
+
pctChange: numberValue(comparison.pctChange, 'periodComparison.pctChange'),
|
|
81
|
+
relatedSegments: relatedSegments(comparison.relatedSegments),
|
|
82
|
+
},
|
|
83
|
+
points: metricPoints(object.points),
|
|
84
|
+
totalCount: numberValue(object.totalCount, 'totalCount'),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function assertAnomalyContext(value, scenarioId) {
|
|
88
|
+
const object = assertObject(value, 'anomaly context');
|
|
89
|
+
const summary = assertObject(object.anomaly_summary, 'anomaly_summary');
|
|
90
|
+
return {
|
|
91
|
+
provider: providerMetadata(object.provider, scenarioId, 'openai'),
|
|
92
|
+
anomaly_summary: {
|
|
93
|
+
metric: stringValue(summary.metric, 'anomaly_summary.metric'),
|
|
94
|
+
segment: stringValue(summary.segment, 'anomaly_summary.segment'),
|
|
95
|
+
anomaly_value: numberValue(summary.anomaly_value, 'anomaly_summary.anomaly_value'),
|
|
96
|
+
baseline_avg: numberValue(summary.baseline_avg, 'anomaly_summary.baseline_avg'),
|
|
97
|
+
pct_change: numberValue(summary.pct_change, 'anomaly_summary.pct_change'),
|
|
98
|
+
},
|
|
99
|
+
related_segments: relatedSegments(object.related_segments).map((segment) => ({
|
|
100
|
+
name: segment.name,
|
|
101
|
+
pct_change: segment.pctChange,
|
|
102
|
+
})),
|
|
103
|
+
drivers: arrayValue(object.drivers, 'drivers').map((driver, index) => {
|
|
104
|
+
const objectDriver = assertObject(driver, `drivers.${index}`);
|
|
105
|
+
return {
|
|
106
|
+
name: stringValue(objectDriver.name, `drivers.${index}.name`),
|
|
107
|
+
contribution: numberValue(objectDriver.contribution, `drivers.${index}.contribution`),
|
|
108
|
+
detail: stringValue(objectDriver.detail, `drivers.${index}.detail`),
|
|
109
|
+
};
|
|
110
|
+
}),
|
|
111
|
+
sample_orders: arrayValue(object.sample_orders, 'sample_orders').map((order, index) => {
|
|
112
|
+
const objectOrder = assertObject(order, `sample_orders.${index}`);
|
|
113
|
+
return {
|
|
114
|
+
order_id: stringValue(objectOrder.order_id, `sample_orders.${index}.order_id`),
|
|
115
|
+
purchase_ts: stringValue(objectOrder.purchase_ts, `sample_orders.${index}.purchase_ts`),
|
|
116
|
+
status: stringValue(objectOrder.status, `sample_orders.${index}.status`),
|
|
117
|
+
price_brl: numberValue(objectOrder.price_brl, `sample_orders.${index}.price_brl`),
|
|
118
|
+
};
|
|
119
|
+
}),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
function providerMetadata(value, scenarioId, mode) {
|
|
123
|
+
const provider = isObject(value) ? value : {};
|
|
124
|
+
return {
|
|
125
|
+
id: 'synthetic-ecommerce',
|
|
126
|
+
mode,
|
|
127
|
+
scenarioId: typeof provider.scenarioId === 'string' ? provider.scenarioId : scenarioId,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
function relatedSegments(value) {
|
|
131
|
+
return arrayValue(value, 'relatedSegments').map((segment, index) => {
|
|
132
|
+
const object = assertObject(segment, `relatedSegments.${index}`);
|
|
133
|
+
return {
|
|
134
|
+
name: stringValue(object.name, `relatedSegments.${index}.name`),
|
|
135
|
+
pctChange: numberValue(object.pctChange ?? object.pct_change, `relatedSegments.${index}.pctChange`),
|
|
136
|
+
};
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
function metricPoints(value) {
|
|
140
|
+
return arrayValue(value, 'points').map((point, index) => {
|
|
141
|
+
const object = assertObject(point, `points.${index}`);
|
|
142
|
+
return {
|
|
143
|
+
ts: stringValue(object.ts, `points.${index}.ts`),
|
|
144
|
+
segment: stringValue(object.segment, `points.${index}.segment`),
|
|
145
|
+
value: numberValue(object.value, `points.${index}.value`),
|
|
146
|
+
};
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
function timeRange(value, path) {
|
|
150
|
+
const object = assertObject(value, path);
|
|
151
|
+
return {
|
|
152
|
+
from: stringValue(object.from, `${path}.from`),
|
|
153
|
+
to: stringValue(object.to, `${path}.to`),
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
function assertObject(value, path) {
|
|
157
|
+
if (!isObject(value))
|
|
158
|
+
throw new Error(`${path} must be an object`);
|
|
159
|
+
return value;
|
|
160
|
+
}
|
|
161
|
+
function isObject(value) {
|
|
162
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
163
|
+
}
|
|
164
|
+
function arrayValue(value, path) {
|
|
165
|
+
if (!Array.isArray(value))
|
|
166
|
+
throw new Error(`${path} must be an array`);
|
|
167
|
+
return value;
|
|
168
|
+
}
|
|
169
|
+
function stringArray(value, path) {
|
|
170
|
+
return arrayValue(value, path).map((item, index) => stringValue(item, `${path}.${index}`));
|
|
171
|
+
}
|
|
172
|
+
function stringValue(value, path) {
|
|
173
|
+
if (typeof value !== 'string')
|
|
174
|
+
throw new Error(`${path} must be a string`);
|
|
175
|
+
return value;
|
|
176
|
+
}
|
|
177
|
+
function numberValue(value, path) {
|
|
178
|
+
if (typeof value !== 'number' || !Number.isFinite(value))
|
|
179
|
+
throw new Error(`${path} must be a number`);
|
|
180
|
+
return value;
|
|
181
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export const syntheticEcommerceToolDefinitions = [
|
|
2
|
+
{
|
|
3
|
+
name: 'get_project_overview',
|
|
4
|
+
description: 'Return synthetic ecommerce workspace metadata and data horizon.',
|
|
5
|
+
inputSchema: {
|
|
6
|
+
type: 'object',
|
|
7
|
+
properties: {},
|
|
8
|
+
additionalProperties: false,
|
|
9
|
+
},
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
name: 'get_metric_timeseries',
|
|
13
|
+
description: 'Return synthetic ecommerce metric timeseries for an optional dimension and segment.',
|
|
14
|
+
inputSchema: {
|
|
15
|
+
type: 'object',
|
|
16
|
+
properties: {
|
|
17
|
+
metric: { type: 'string' },
|
|
18
|
+
dimension: { type: 'string' },
|
|
19
|
+
segment: { type: 'string' },
|
|
20
|
+
time_range: {
|
|
21
|
+
type: 'object',
|
|
22
|
+
properties: {
|
|
23
|
+
from: { type: 'string' },
|
|
24
|
+
to: { type: 'string' },
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
granularity: { type: 'string' },
|
|
28
|
+
},
|
|
29
|
+
required: ['metric'],
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: 'get_anomaly_context',
|
|
34
|
+
description: 'Return synthetic ecommerce anomaly context, related segments, and sample records.',
|
|
35
|
+
inputSchema: {
|
|
36
|
+
type: 'object',
|
|
37
|
+
properties: {
|
|
38
|
+
metric: { type: 'string' },
|
|
39
|
+
dimension: { type: 'string' },
|
|
40
|
+
segment: { type: 'string' },
|
|
41
|
+
anomaly_window: {
|
|
42
|
+
type: 'object',
|
|
43
|
+
properties: {
|
|
44
|
+
from: { type: 'string' },
|
|
45
|
+
to: { type: 'string' },
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
baseline_window: {
|
|
49
|
+
type: 'object',
|
|
50
|
+
properties: {
|
|
51
|
+
from: { type: 'string' },
|
|
52
|
+
to: { type: 'string' },
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
required: ['metric', 'dimension', 'segment'],
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ToolCallOptions, ToolCallResult, ToolDefinition, ToolRegistry } from '@aptkit/tools';
|
|
2
|
+
import type { SyntheticEcommerceDataSource } from './types.js';
|
|
3
|
+
export type SyntheticEcommerceToolRegistryOptions = {
|
|
4
|
+
dataSource: SyntheticEcommerceDataSource;
|
|
5
|
+
tools?: readonly ToolDefinition[];
|
|
6
|
+
};
|
|
7
|
+
/** ToolRegistry adapter that exposes synthetic ecommerce data through normal agent tools. */
|
|
8
|
+
export declare class SyntheticEcommerceToolRegistry implements ToolRegistry {
|
|
9
|
+
private readonly dataSource;
|
|
10
|
+
private readonly tools;
|
|
11
|
+
constructor(options: SyntheticEcommerceToolRegistryOptions);
|
|
12
|
+
listTools(): ToolDefinition[];
|
|
13
|
+
callTool(name: string, args: Record<string, unknown>, options?: ToolCallOptions): Promise<ToolCallResult>;
|
|
14
|
+
private dispatch;
|
|
15
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { syntheticEcommerceToolDefinitions } from './tool-definitions.js';
|
|
2
|
+
/** ToolRegistry adapter that exposes synthetic ecommerce data through normal agent tools. */
|
|
3
|
+
export class SyntheticEcommerceToolRegistry {
|
|
4
|
+
dataSource;
|
|
5
|
+
tools;
|
|
6
|
+
constructor(options) {
|
|
7
|
+
this.dataSource = options.dataSource;
|
|
8
|
+
this.tools = options.tools ?? syntheticEcommerceToolDefinitions;
|
|
9
|
+
}
|
|
10
|
+
listTools() {
|
|
11
|
+
return [...this.tools];
|
|
12
|
+
}
|
|
13
|
+
async callTool(name, args, options) {
|
|
14
|
+
options?.signal?.throwIfAborted();
|
|
15
|
+
const start = performance.now();
|
|
16
|
+
const result = await this.dispatch(name, args);
|
|
17
|
+
return { result, durationMs: Math.round(performance.now() - start) };
|
|
18
|
+
}
|
|
19
|
+
dispatch(name, args) {
|
|
20
|
+
if (name === 'get_project_overview')
|
|
21
|
+
return this.dataSource.getProjectOverview();
|
|
22
|
+
if (name === 'get_metric_timeseries')
|
|
23
|
+
return this.dataSource.getMetricTimeseries(args);
|
|
24
|
+
if (name === 'get_anomaly_context')
|
|
25
|
+
return this.dataSource.getAnomalyContext(args);
|
|
26
|
+
throw new Error(`synthetic ecommerce tool not found: ${name}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { WorkspaceDescriptor } from '@aptkit/context';
|
|
2
|
+
export type SyntheticProviderMode = 'fixture' | 'openai';
|
|
3
|
+
export type TimeRange = {
|
|
4
|
+
from?: string;
|
|
5
|
+
to?: string;
|
|
6
|
+
};
|
|
7
|
+
export type ProjectOverview = {
|
|
8
|
+
provider: {
|
|
9
|
+
id: 'synthetic-ecommerce';
|
|
10
|
+
mode: SyntheticProviderMode;
|
|
11
|
+
scenarioId: string;
|
|
12
|
+
};
|
|
13
|
+
workspace: WorkspaceDescriptor;
|
|
14
|
+
highlights: string[];
|
|
15
|
+
};
|
|
16
|
+
export type MetricTimeseriesArgs = {
|
|
17
|
+
metric?: string;
|
|
18
|
+
dimension?: string;
|
|
19
|
+
segment?: string;
|
|
20
|
+
time_range?: TimeRange;
|
|
21
|
+
granularity?: 'day' | 'week' | 'month' | string;
|
|
22
|
+
};
|
|
23
|
+
export type MetricPoint = {
|
|
24
|
+
ts: string;
|
|
25
|
+
segment: string;
|
|
26
|
+
value: number;
|
|
27
|
+
};
|
|
28
|
+
export type MetricTimeseriesResult = {
|
|
29
|
+
provider: {
|
|
30
|
+
id: 'synthetic-ecommerce';
|
|
31
|
+
mode: SyntheticProviderMode;
|
|
32
|
+
scenarioId: string;
|
|
33
|
+
};
|
|
34
|
+
periodComparison: {
|
|
35
|
+
metric: string;
|
|
36
|
+
dimension: string;
|
|
37
|
+
segment: string;
|
|
38
|
+
recentWindow: Required<TimeRange>;
|
|
39
|
+
baselineWindow: Required<TimeRange>;
|
|
40
|
+
recentValue: number;
|
|
41
|
+
baselineAverage: number;
|
|
42
|
+
pctChange: number;
|
|
43
|
+
relatedSegments: {
|
|
44
|
+
name: string;
|
|
45
|
+
pctChange: number;
|
|
46
|
+
}[];
|
|
47
|
+
};
|
|
48
|
+
points: MetricPoint[];
|
|
49
|
+
totalCount: number;
|
|
50
|
+
};
|
|
51
|
+
export type AnomalyContextArgs = {
|
|
52
|
+
metric?: string;
|
|
53
|
+
dimension?: string;
|
|
54
|
+
segment?: string;
|
|
55
|
+
anomaly_window?: TimeRange;
|
|
56
|
+
baseline_window?: TimeRange;
|
|
57
|
+
};
|
|
58
|
+
export type AnomalyContextResult = {
|
|
59
|
+
provider: {
|
|
60
|
+
id: 'synthetic-ecommerce';
|
|
61
|
+
mode: SyntheticProviderMode;
|
|
62
|
+
scenarioId: string;
|
|
63
|
+
};
|
|
64
|
+
anomaly_summary: {
|
|
65
|
+
metric: string;
|
|
66
|
+
segment: string;
|
|
67
|
+
anomaly_value: number;
|
|
68
|
+
baseline_avg: number;
|
|
69
|
+
pct_change: number;
|
|
70
|
+
};
|
|
71
|
+
related_segments: {
|
|
72
|
+
name: string;
|
|
73
|
+
pct_change: number;
|
|
74
|
+
}[];
|
|
75
|
+
drivers: {
|
|
76
|
+
name: string;
|
|
77
|
+
contribution: number;
|
|
78
|
+
detail: string;
|
|
79
|
+
}[];
|
|
80
|
+
sample_orders: {
|
|
81
|
+
order_id: string;
|
|
82
|
+
purchase_ts: string;
|
|
83
|
+
status: string;
|
|
84
|
+
price_brl: number;
|
|
85
|
+
}[];
|
|
86
|
+
};
|
|
87
|
+
export type SyntheticEcommerceDataSource = {
|
|
88
|
+
readonly mode: SyntheticProviderMode;
|
|
89
|
+
readonly scenarioId: string;
|
|
90
|
+
readonly workspace: WorkspaceDescriptor;
|
|
91
|
+
getProjectOverview(): Promise<ProjectOverview> | ProjectOverview;
|
|
92
|
+
getMetricTimeseries(args?: MetricTimeseriesArgs): Promise<MetricTimeseriesResult> | MetricTimeseriesResult;
|
|
93
|
+
getAnomalyContext(args?: AnomalyContextArgs): Promise<AnomalyContextResult> | AnomalyContextResult;
|
|
94
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@aptkit/provider-synthetic",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/src/index.js",
|
|
6
|
+
"types": "./dist/src/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist/src"
|
|
9
|
+
],
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/src/index.d.ts",
|
|
13
|
+
"import": "./dist/src/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsc -p tsconfig.json",
|
|
18
|
+
"test": "npm run build && node --test dist/test/*.test.js"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@aptkit/context": "0.0.0",
|
|
22
|
+
"@aptkit/runtime": "0.0.0",
|
|
23
|
+
"@aptkit/tools": "0.0.0"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@types/node": "^20.0.0"
|
|
27
|
+
}
|
|
28
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rlynjb/aptkit-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Standalone AptKit core bundle for extracted agent capabilities.",
|
|
6
6
|
"main": "./dist/src/index.js",
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
"@aptkit/context": "0.0.0",
|
|
37
37
|
"@aptkit/evals": "0.0.0",
|
|
38
38
|
"@aptkit/prompts": "0.0.0",
|
|
39
|
+
"@aptkit/provider-synthetic": "0.0.0",
|
|
39
40
|
"@aptkit/runtime": "0.0.0",
|
|
40
41
|
"@aptkit/tools": "0.0.0"
|
|
41
42
|
},
|
|
@@ -47,6 +48,7 @@
|
|
|
47
48
|
"@aptkit/context",
|
|
48
49
|
"@aptkit/evals",
|
|
49
50
|
"@aptkit/prompts",
|
|
51
|
+
"@aptkit/provider-synthetic",
|
|
50
52
|
"@aptkit/runtime",
|
|
51
53
|
"@aptkit/tools"
|
|
52
54
|
]
|