@agentguard-run/spend 0.3.0 → 0.4.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/CHANGELOG.md +5 -0
- package/README.es-419.md +11 -0
- package/README.md +11 -0
- package/README.pt-BR.md +11 -0
- package/dist/cli/coach.d.ts +5 -0
- package/dist/cli/coach.d.ts.map +1 -0
- package/dist/cli/coach.js +257 -0
- package/dist/cli/coach.js.map +1 -0
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +6 -0
- package/dist/cli/main.js.map +1 -1
- package/dist/coach/anomaly.d.ts +26 -0
- package/dist/coach/anomaly.d.ts.map +1 -0
- package/dist/coach/anomaly.js +119 -0
- package/dist/coach/anomaly.js.map +1 -0
- package/dist/coach/conversation.d.ts +69 -0
- package/dist/coach/conversation.d.ts.map +1 -0
- package/dist/coach/conversation.js +228 -0
- package/dist/coach/conversation.js.map +1 -0
- package/dist/coach/forecast.d.ts +19 -0
- package/dist/coach/forecast.d.ts.map +1 -0
- package/dist/coach/forecast.js +57 -0
- package/dist/coach/forecast.js.map +1 -0
- package/dist/coach/llm-client.d.ts +41 -0
- package/dist/coach/llm-client.d.ts.map +1 -0
- package/dist/coach/llm-client.js +248 -0
- package/dist/coach/llm-client.js.map +1 -0
- package/dist/coach/output.d.ts +41 -0
- package/dist/coach/output.d.ts.map +1 -0
- package/dist/coach/output.js +173 -0
- package/dist/coach/output.js.map +1 -0
- package/dist/coach/system-prompt.d.ts +20 -0
- package/dist/coach/system-prompt.d.ts.map +1 -0
- package/dist/coach/system-prompt.js +177 -0
- package/dist/coach/system-prompt.js.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -2
- package/dist/index.js.map +1 -1
- package/dist/telemetry.js +1 -1
- package/package.json +9 -2
- package/src/cli/coach.ts +249 -0
- package/src/coach/anomaly.ts +98 -0
- package/src/coach/conversation.ts +248 -0
- package/src/coach/forecast.ts +64 -0
- package/src/coach/llm-client.ts +247 -0
- package/src/coach/output.ts +172 -0
- package/src/coach/system-prompt.ts +181 -0
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* AgentGuard(TM) Spend: Coach conversation state.
|
|
4
|
+
*
|
|
5
|
+
* Patent notice: Protected by U.S. patent-pending technology
|
|
6
|
+
* (App. Nos. 63/983,615; 63/983,621; 63/983,843; 63/984,626;
|
|
7
|
+
* 64/071,781; 64/071,789).
|
|
8
|
+
*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
+
}) : function(o, v) {
|
|
23
|
+
o["default"] = v;
|
|
24
|
+
});
|
|
25
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
26
|
+
var ownKeys = function(o) {
|
|
27
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
28
|
+
var ar = [];
|
|
29
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30
|
+
return ar;
|
|
31
|
+
};
|
|
32
|
+
return ownKeys(o);
|
|
33
|
+
};
|
|
34
|
+
return function (mod) {
|
|
35
|
+
if (mod && mod.__esModule) return mod;
|
|
36
|
+
var result = {};
|
|
37
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
38
|
+
__setModuleDefault(result, mod);
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
})();
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.CoachConversation = exports.COACH_QUESTIONS = void 0;
|
|
44
|
+
exports.buildBusinessProfile = buildBusinessProfile;
|
|
45
|
+
exports.buildPolicyFromProfile = buildPolicyFromProfile;
|
|
46
|
+
exports.projectedSavings = projectedSavings;
|
|
47
|
+
exports.formatCents = formatCents;
|
|
48
|
+
exports.detectProjectLanguage = detectProjectLanguage;
|
|
49
|
+
const fs = __importStar(require("fs"));
|
|
50
|
+
const path = __importStar(require("path"));
|
|
51
|
+
exports.COACH_QUESTIONS = [
|
|
52
|
+
{ id: 'building', prompt: 'What are you building or running? Include your business type and the agent workflow.' },
|
|
53
|
+
{ id: 'scale', prompt: 'How big is the team and roughly how many AI calls, tickets, orders, encounters, matters, or jobs happen per month?' },
|
|
54
|
+
{ id: 'tasks', prompt: 'What are the top 3 AI tasks this agent will perform?' },
|
|
55
|
+
{ id: 'budget', prompt: 'What monthly AI budget or per-task ceiling should this stay under?' },
|
|
56
|
+
{ id: 'confirm', prompt: 'Confirm the setup or list any refinements before I write policy.yaml and quickstart code.' },
|
|
57
|
+
];
|
|
58
|
+
const VERTICAL_HINTS = [
|
|
59
|
+
{ vertical: 'law-firm', needles: ['law', 'legal', 'attorney', 'paralegal', 'contract', 'matter', 'discovery'], scopeLabel: 'matter', capability: 'data_write', primary: 'anthropic/claude-sonnet-4-6', fallback: 'anthropic/claude-haiku-4-5', perCall: 300 },
|
|
60
|
+
{ vertical: 'healthcare', needles: ['health', 'medical', 'dental', 'clinic', 'patient', 'chart', 'hipaa', 'encounter'], scopeLabel: 'encounter', capability: 'data_write', primary: 'anthropic.claude-sonnet-4-v1:0', fallback: 'amazon.nova-lite-v1:0', perCall: 300 },
|
|
61
|
+
{ vertical: 'ecommerce', needles: ['shopify', 'commerce', 'store', 'order', 'refund', 'chargeback', 'fraud', 'returns'], scopeLabel: 'order', capability: 'payment_initiate', primary: 'openai/gpt-5-mini', fallback: 'openai/gpt-4o-mini', perCall: 25 },
|
|
62
|
+
{ vertical: 'accounting', needles: ['accounting', 'bookkeeping', 'tax', 'ledger', 'receipt', 'close', 'audit', 'sox'], scopeLabel: 'engagement', capability: 'data_write', primary: 'anthropic/claude-sonnet-4-6', fallback: 'anthropic/claude-haiku-4-5', perCall: 150 },
|
|
63
|
+
{ vertical: 'software', needles: ['software', 'code', 'developer', 'github', 'repo', 'pull request', 'pr'], scopeLabel: 'repo', capability: 'read_only', primary: 'google/gemini-3-flash-preview', fallback: 'openai/gpt-4o-mini', perCall: 10 },
|
|
64
|
+
{ vertical: 'real-estate', needles: ['real estate', 'broker', 'listing', 'mortgage', 'tenant', 'lease', 'property'], scopeLabel: 'transaction', capability: 'data_write', primary: 'openai/gpt-5-mini', fallback: 'openai/gpt-4o-mini', perCall: 50 },
|
|
65
|
+
{ vertical: 'marketing', needles: ['marketing', 'agency', 'content', 'campaign', 'brand'], scopeLabel: 'campaign', capability: 'data_write', primary: 'openai/gpt-5-mini', fallback: 'openai/gpt-4o-mini', perCall: 25 },
|
|
66
|
+
{ vertical: 'local-services', needles: ['salon', 'gym', 'restaurant', 'landscaping', 'construction', 'photography', 'fitness', 'pet'], scopeLabel: 'job', capability: 'data_write', primary: 'openai/gpt-5-mini', fallback: 'openai/gpt-4o-mini', perCall: 25 },
|
|
67
|
+
];
|
|
68
|
+
class CoachConversation {
|
|
69
|
+
answers = {};
|
|
70
|
+
index = 0;
|
|
71
|
+
constructor(initial) {
|
|
72
|
+
if (initial)
|
|
73
|
+
this.answers = { ...initial };
|
|
74
|
+
this.index = firstMissingIndex(this.answers);
|
|
75
|
+
}
|
|
76
|
+
currentQuestion() {
|
|
77
|
+
return exports.COACH_QUESTIONS[this.index] ?? null;
|
|
78
|
+
}
|
|
79
|
+
answer(value) {
|
|
80
|
+
const question = this.currentQuestion();
|
|
81
|
+
if (!question)
|
|
82
|
+
return;
|
|
83
|
+
this.answers[question.id] = value.trim();
|
|
84
|
+
}
|
|
85
|
+
next() {
|
|
86
|
+
this.index = Math.min(this.index + 1, exports.COACH_QUESTIONS.length);
|
|
87
|
+
return this.currentQuestion();
|
|
88
|
+
}
|
|
89
|
+
back() {
|
|
90
|
+
this.index = Math.max(0, this.index - 1);
|
|
91
|
+
return this.currentQuestion();
|
|
92
|
+
}
|
|
93
|
+
isComplete() {
|
|
94
|
+
return exports.COACH_QUESTIONS.every((question) => Boolean(this.answers[question.id]?.trim()));
|
|
95
|
+
}
|
|
96
|
+
snapshot() {
|
|
97
|
+
return { ...this.answers };
|
|
98
|
+
}
|
|
99
|
+
profile(cwd = process.cwd()) {
|
|
100
|
+
return buildBusinessProfile(this.answers, cwd);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
exports.CoachConversation = CoachConversation;
|
|
104
|
+
function buildBusinessProfile(answers, cwd = process.cwd()) {
|
|
105
|
+
const joined = `${answers.building ?? ''} ${answers.scale ?? ''} ${answers.tasks ?? ''}`.toLowerCase();
|
|
106
|
+
const hint = VERTICAL_HINTS.find((candidate) => candidate.needles.some((needle) => joined.includes(needle))) ?? VERTICAL_HINTS[0];
|
|
107
|
+
const scale = parseScale(answers.scale ?? '');
|
|
108
|
+
const budgetCents = parseBudgetCents(answers.budget ?? '', Math.max(4900, Math.ceil(scale.monthlyVolume * hint.perCall * 0.35)));
|
|
109
|
+
const tasks = parseTasks(answers.tasks ?? answers.building ?? hint.vertical);
|
|
110
|
+
const perMonthCapCents = Math.max(1000, budgetCents);
|
|
111
|
+
const perDayCapCents = Math.max(hint.perCall * 10, Math.ceil(perMonthCapCents / 20));
|
|
112
|
+
return {
|
|
113
|
+
vertical: hint.vertical,
|
|
114
|
+
tenantId: tenantIdFromBusiness(answers.building ?? hint.vertical),
|
|
115
|
+
teamSize: scale.teamSize,
|
|
116
|
+
monthlyVolume: scale.monthlyVolume,
|
|
117
|
+
tasks,
|
|
118
|
+
monthlyBudgetCents: perMonthCapCents,
|
|
119
|
+
requiredCapability: capabilityFor(joined, hint.capability),
|
|
120
|
+
primaryModel: hint.primary,
|
|
121
|
+
fallbackModel: hint.fallback,
|
|
122
|
+
perCallCapCents: hint.perCall,
|
|
123
|
+
perDayCapCents,
|
|
124
|
+
perMonthCapCents,
|
|
125
|
+
scopeLabel: hint.scopeLabel,
|
|
126
|
+
language: answers.language ?? detectProjectLanguage(cwd),
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
function buildPolicyFromProfile(profile) {
|
|
130
|
+
const caps = [
|
|
131
|
+
{
|
|
132
|
+
amountCents: profile.perCallCapCents,
|
|
133
|
+
window: 'per_call',
|
|
134
|
+
action: 'downgrade',
|
|
135
|
+
downgradeTo: profile.fallbackModel,
|
|
136
|
+
reason: 'Per-call budget reached, route to fallback model',
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
amountCents: profile.perDayCapCents,
|
|
140
|
+
window: 'per_day',
|
|
141
|
+
action: 'block',
|
|
142
|
+
reason: 'Daily budget reached',
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
amountCents: profile.perMonthCapCents,
|
|
146
|
+
window: 'per_month',
|
|
147
|
+
action: 'block',
|
|
148
|
+
reason: 'Monthly budget reached',
|
|
149
|
+
},
|
|
150
|
+
];
|
|
151
|
+
return {
|
|
152
|
+
id: `coach-${profile.vertical}-v1`,
|
|
153
|
+
name: `Coach generated ${profile.vertical} policy`,
|
|
154
|
+
scope: { tenantId: profile.tenantId },
|
|
155
|
+
caps,
|
|
156
|
+
mode: 'enforce',
|
|
157
|
+
requiredCapability: profile.requiredCapability,
|
|
158
|
+
version: 1,
|
|
159
|
+
effectiveFrom: new Date().toISOString(),
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
function projectedSavings(profile) {
|
|
163
|
+
const heavyPerCall = Math.max(profile.perCallCapCents * 4, 100);
|
|
164
|
+
const routedPerCall = Math.max(1, Math.ceil(profile.perCallCapCents * 0.45));
|
|
165
|
+
const monthlyBeforeCents = profile.monthlyVolume * heavyPerCall;
|
|
166
|
+
const monthlyAfterCents = Math.min(profile.perMonthCapCents, profile.monthlyVolume * routedPerCall);
|
|
167
|
+
const monthlySavingsCents = Math.max(0, monthlyBeforeCents - monthlyAfterCents);
|
|
168
|
+
return {
|
|
169
|
+
rows: [
|
|
170
|
+
{ label: 'All traffic on premium model', beforeCents: monthlyBeforeCents, afterCents: 0, savingsCents: 0 },
|
|
171
|
+
{ label: 'Task routed with AgentGuard caps', beforeCents: 0, afterCents: monthlyAfterCents, savingsCents: monthlySavingsCents },
|
|
172
|
+
],
|
|
173
|
+
monthlyBeforeCents,
|
|
174
|
+
monthlyAfterCents,
|
|
175
|
+
monthlySavingsCents,
|
|
176
|
+
savingsPercent: monthlyBeforeCents > 0 ? Math.round((monthlySavingsCents / monthlyBeforeCents) * 100) : 0,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
function formatCents(cents) {
|
|
180
|
+
return `$${(cents / 100).toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
|
|
181
|
+
}
|
|
182
|
+
function detectProjectLanguage(cwd) {
|
|
183
|
+
try {
|
|
184
|
+
if (fs.existsSync(path.join(cwd, 'pyproject.toml')) || fs.existsSync(path.join(cwd, 'requirements.txt')))
|
|
185
|
+
return 'py';
|
|
186
|
+
if (fs.existsSync(path.join(cwd, 'package.json')))
|
|
187
|
+
return 'ts';
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
return 'ts';
|
|
191
|
+
}
|
|
192
|
+
return 'ts';
|
|
193
|
+
}
|
|
194
|
+
function firstMissingIndex(answers) {
|
|
195
|
+
const index = exports.COACH_QUESTIONS.findIndex((question) => !answers[question.id]?.trim());
|
|
196
|
+
return index === -1 ? exports.COACH_QUESTIONS.length : index;
|
|
197
|
+
}
|
|
198
|
+
function parseScale(value) {
|
|
199
|
+
const numbers = (value.match(/\d[\d,]*/g) ?? []).map((part) => Number(part.replace(/,/g, ''))).filter(Number.isFinite);
|
|
200
|
+
const teamSize = Math.max(1, numbers[0] ?? 3);
|
|
201
|
+
const monthlyVolume = Math.max(25, numbers[1] ?? numbers[0] ?? 500);
|
|
202
|
+
return { teamSize, monthlyVolume };
|
|
203
|
+
}
|
|
204
|
+
function parseBudgetCents(value, fallback) {
|
|
205
|
+
const money = value.match(/\$?\s*(\d[\d,]*(?:\.\d{1,2})?)/);
|
|
206
|
+
if (!money)
|
|
207
|
+
return fallback;
|
|
208
|
+
const amount = Number(money[1].replace(/,/g, ''));
|
|
209
|
+
if (!Number.isFinite(amount) || amount <= 0)
|
|
210
|
+
return fallback;
|
|
211
|
+
return Math.round(amount * 100);
|
|
212
|
+
}
|
|
213
|
+
function parseTasks(value) {
|
|
214
|
+
const parts = value.split(/,|\n|;| and /i).map((part) => part.trim()).filter(Boolean);
|
|
215
|
+
return parts.length > 0 ? parts.slice(0, 3) : ['review requests', 'route models', 'write audit receipts'];
|
|
216
|
+
}
|
|
217
|
+
function tenantIdFromBusiness(value) {
|
|
218
|
+
const cleaned = value.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '').slice(0, 40);
|
|
219
|
+
return cleaned || 'local-business';
|
|
220
|
+
}
|
|
221
|
+
function capabilityFor(text, fallback) {
|
|
222
|
+
if (/refund|payment|charge|dispute|money|invoice/.test(text))
|
|
223
|
+
return 'payment_initiate';
|
|
224
|
+
if (/write|update|ledger|chart|patient|health|phi|sox|legal|contract|tax|student|employment/.test(text))
|
|
225
|
+
return 'data_write';
|
|
226
|
+
return fallback;
|
|
227
|
+
}
|
|
228
|
+
//# sourceMappingURL=conversation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation.js","sourceRoot":"","sources":["../../src/coach/conversation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentGuard(TM) Spend: local Coach forecast skeleton.
|
|
3
|
+
*
|
|
4
|
+
* Reads local decision logs only. No network calls are made.
|
|
5
|
+
*
|
|
6
|
+
* Patent notice: Protected by U.S. patent-pending technology
|
|
7
|
+
* (App. Nos. 63/983,615; 63/983,621; 63/983,843; 63/984,626;
|
|
8
|
+
* 64/071,781; 64/071,789).
|
|
9
|
+
*/
|
|
10
|
+
import type { CoachSpendPoint } from './anomaly';
|
|
11
|
+
export interface CoachForecast {
|
|
12
|
+
daysObserved: number;
|
|
13
|
+
monthEndCents: number;
|
|
14
|
+
capCents: number | null;
|
|
15
|
+
overCap: boolean;
|
|
16
|
+
message: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function forecastMonthEnd(points: CoachSpendPoint[], capCents?: number | null, now?: Date): CoachForecast;
|
|
19
|
+
//# sourceMappingURL=forecast.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forecast.d.ts","sourceRoot":"","sources":["../../src/coach/forecast.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAEjD,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,eAAe,EAAE,EAAE,QAAQ,GAAE,MAAM,GAAG,IAAW,EAAE,GAAG,OAAa,GAAG,aAAa,CAoB3H"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* AgentGuard(TM) Spend: local Coach forecast skeleton.
|
|
4
|
+
*
|
|
5
|
+
* Reads local decision logs only. No network calls are made.
|
|
6
|
+
*
|
|
7
|
+
* Patent notice: Protected by U.S. patent-pending technology
|
|
8
|
+
* (App. Nos. 63/983,615; 63/983,621; 63/983,843; 63/984,626;
|
|
9
|
+
* 64/071,781; 64/071,789).
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.forecastMonthEnd = forecastMonthEnd;
|
|
13
|
+
function forecastMonthEnd(points, capCents = null, now = new Date()) {
|
|
14
|
+
const daily = lastThirtyDaily(points, now);
|
|
15
|
+
if (daily.length === 0) {
|
|
16
|
+
return { daysObserved: 0, monthEndCents: 0, capCents, overCap: false, message: 'No local spend history found.' };
|
|
17
|
+
}
|
|
18
|
+
const slope = linearSlope(daily.map((row, index) => ({ x: index + 1, y: row.cents })));
|
|
19
|
+
const monthDays = new Date(now.getFullYear(), now.getMonth() + 1, 0).getDate();
|
|
20
|
+
const elapsed = now.getDate();
|
|
21
|
+
const observedTotal = daily.reduce((sum, row) => sum + row.cents, 0);
|
|
22
|
+
const avg = observedTotal / Math.max(1, daily.length);
|
|
23
|
+
const projectedRemaining = Math.max(0, monthDays - elapsed) * Math.max(0, avg + slope);
|
|
24
|
+
const monthEndCents = Math.round(observedTotal + projectedRemaining);
|
|
25
|
+
const overCap = capCents !== null && monthEndCents > capCents;
|
|
26
|
+
return {
|
|
27
|
+
daysObserved: daily.length,
|
|
28
|
+
monthEndCents,
|
|
29
|
+
capCents,
|
|
30
|
+
overCap,
|
|
31
|
+
message: overCap ? 'Projected spend is above cap. Consider a lower fallback model or a tighter per_day cap.' : 'Projected spend is within the current cap.',
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function lastThirtyDaily(points, now) {
|
|
35
|
+
const cutoff = now.getTime() - 30 * 24 * 60 * 60 * 1000;
|
|
36
|
+
const buckets = new Map();
|
|
37
|
+
for (const point of points) {
|
|
38
|
+
const t = Date.parse(point.ts);
|
|
39
|
+
if (!Number.isFinite(t) || t < cutoff)
|
|
40
|
+
continue;
|
|
41
|
+
const day = new Date(t).toISOString().slice(0, 10);
|
|
42
|
+
buckets.set(day, (buckets.get(day) ?? 0) + point.cents);
|
|
43
|
+
}
|
|
44
|
+
return [...buckets.entries()].map(([day, cents]) => ({ day, cents })).sort((a, b) => a.day.localeCompare(b.day));
|
|
45
|
+
}
|
|
46
|
+
function linearSlope(points) {
|
|
47
|
+
if (points.length < 2)
|
|
48
|
+
return 0;
|
|
49
|
+
const n = points.length;
|
|
50
|
+
const sx = points.reduce((sum, point) => sum + point.x, 0);
|
|
51
|
+
const sy = points.reduce((sum, point) => sum + point.y, 0);
|
|
52
|
+
const sxx = points.reduce((sum, point) => sum + point.x * point.x, 0);
|
|
53
|
+
const sxy = points.reduce((sum, point) => sum + point.x * point.y, 0);
|
|
54
|
+
const denom = n * sxx - sx * sx;
|
|
55
|
+
return denom === 0 ? 0 : (n * sxy - sx * sy) / denom;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=forecast.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forecast.js","sourceRoot":"","sources":["../../src/coach/forecast.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentGuard(TM) Spend: local Coach LLM client.
|
|
3
|
+
*
|
|
4
|
+
* All provider calls go from the customer terminal to the configured provider.
|
|
5
|
+
* No AgentGuard service is contacted for prompts or completions.
|
|
6
|
+
*
|
|
7
|
+
* Patent notice: Protected by U.S. patent-pending technology
|
|
8
|
+
* (App. Nos. 63/983,615; 63/983,621; 63/983,843; 63/984,626;
|
|
9
|
+
* 64/071,781; 64/071,789).
|
|
10
|
+
*/
|
|
11
|
+
export type CoachProvider = 'openrouter' | 'openai' | 'anthropic' | 'compatible' | 'mock';
|
|
12
|
+
export interface CoachChatMessage {
|
|
13
|
+
role: 'system' | 'user' | 'assistant';
|
|
14
|
+
content: string;
|
|
15
|
+
}
|
|
16
|
+
export interface CoachClientOptions {
|
|
17
|
+
provider?: CoachProvider;
|
|
18
|
+
apiKey?: string;
|
|
19
|
+
baseUrl?: string;
|
|
20
|
+
model?: string;
|
|
21
|
+
timeoutMs?: number;
|
|
22
|
+
fetchImpl?: FetchLike;
|
|
23
|
+
}
|
|
24
|
+
export interface CoachClient {
|
|
25
|
+
provider: CoachProvider;
|
|
26
|
+
model: string;
|
|
27
|
+
baseUrl: string;
|
|
28
|
+
streamChat(messages: CoachChatMessage[], signal?: AbortSignalLike): AsyncIterable<string>;
|
|
29
|
+
}
|
|
30
|
+
type FetchLike = (url: string, init: Record<string, unknown>) => Promise<any>;
|
|
31
|
+
type AbortSignalLike = {
|
|
32
|
+
aborted?: boolean;
|
|
33
|
+
addEventListener?: (type: 'abort', listener: () => void, options?: {
|
|
34
|
+
once?: boolean;
|
|
35
|
+
}) => void;
|
|
36
|
+
};
|
|
37
|
+
export declare function resolveCoachApiKey(provider?: CoachProvider, explicit?: string): string | null;
|
|
38
|
+
export declare function createCoachClient(options?: CoachClientOptions): CoachClient;
|
|
39
|
+
export declare function parseSseResponse(response: any, pickText: (json: any) => string): AsyncIterable<string>;
|
|
40
|
+
export {};
|
|
41
|
+
//# sourceMappingURL=llm-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-client.d.ts","sourceRoot":"","sources":["../../src/coach/llm-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,QAAQ,GAAG,WAAW,GAAG,YAAY,GAAG,MAAM,CAAC;AAE1F,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,aAAa,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,QAAQ,EAAE,gBAAgB,EAAE,EAAE,MAAM,CAAC,EAAE,eAAe,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;CAC3F;AAED,KAAK,SAAS,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;AAE9E,KAAK,eAAe,GAAG;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,EAAE,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;CAChG,CAAC;AAYF,wBAAgB,kBAAkB,CAAC,QAAQ,GAAE,aAA4B,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAY3G;AAED,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,kBAAuB,GAAG,WAAW,CAwB/E;AAiED,wBAAuB,gBAAgB,CAAC,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,CAmB7G"}
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* AgentGuard(TM) Spend: local Coach LLM client.
|
|
4
|
+
*
|
|
5
|
+
* All provider calls go from the customer terminal to the configured provider.
|
|
6
|
+
* No AgentGuard service is contacted for prompts or completions.
|
|
7
|
+
*
|
|
8
|
+
* Patent notice: Protected by U.S. patent-pending technology
|
|
9
|
+
* (App. Nos. 63/983,615; 63/983,621; 63/983,843; 63/984,626;
|
|
10
|
+
* 64/071,781; 64/071,789).
|
|
11
|
+
*/
|
|
12
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
15
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
16
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
17
|
+
}
|
|
18
|
+
Object.defineProperty(o, k2, desc);
|
|
19
|
+
}) : (function(o, m, k, k2) {
|
|
20
|
+
if (k2 === undefined) k2 = k;
|
|
21
|
+
o[k2] = m[k];
|
|
22
|
+
}));
|
|
23
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
24
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
25
|
+
}) : function(o, v) {
|
|
26
|
+
o["default"] = v;
|
|
27
|
+
});
|
|
28
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
29
|
+
var ownKeys = function(o) {
|
|
30
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
31
|
+
var ar = [];
|
|
32
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
33
|
+
return ar;
|
|
34
|
+
};
|
|
35
|
+
return ownKeys(o);
|
|
36
|
+
};
|
|
37
|
+
return function (mod) {
|
|
38
|
+
if (mod && mod.__esModule) return mod;
|
|
39
|
+
var result = {};
|
|
40
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
41
|
+
__setModuleDefault(result, mod);
|
|
42
|
+
return result;
|
|
43
|
+
};
|
|
44
|
+
})();
|
|
45
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
+
exports.resolveCoachApiKey = resolveCoachApiKey;
|
|
47
|
+
exports.createCoachClient = createCoachClient;
|
|
48
|
+
exports.parseSseResponse = parseSseResponse;
|
|
49
|
+
const fs = __importStar(require("fs"));
|
|
50
|
+
const os = __importStar(require("os"));
|
|
51
|
+
const path = __importStar(require("path"));
|
|
52
|
+
const DEFAULT_OPENROUTER_BASE_URL = 'https://openrouter.ai/api/v1';
|
|
53
|
+
const DEFAULT_OPENAI_BASE_URL = 'https://api.openai.com/v1';
|
|
54
|
+
const DEFAULT_ANTHROPIC_BASE_URL = 'https://api.anthropic.com/v1';
|
|
55
|
+
const DEFAULT_MODEL = 'openai/gpt-4o-mini';
|
|
56
|
+
function resolveCoachApiKey(provider = 'openrouter', explicit) {
|
|
57
|
+
if (explicit?.trim())
|
|
58
|
+
return explicit.trim();
|
|
59
|
+
if (provider === 'openai' && process.env.OPENAI_API_KEY)
|
|
60
|
+
return process.env.OPENAI_API_KEY;
|
|
61
|
+
if (provider === 'anthropic' && process.env.ANTHROPIC_API_KEY)
|
|
62
|
+
return process.env.ANTHROPIC_API_KEY;
|
|
63
|
+
if ((provider === 'openrouter' || provider === 'compatible') && process.env.OPENROUTER_API_KEY)
|
|
64
|
+
return process.env.OPENROUTER_API_KEY;
|
|
65
|
+
if (process.env.AGENTGUARD_COACH_API_KEY)
|
|
66
|
+
return process.env.AGENTGUARD_COACH_API_KEY;
|
|
67
|
+
try {
|
|
68
|
+
const key = fs.readFileSync(path.join(agentguardHome(), 'openrouter-key'), 'utf8').trim();
|
|
69
|
+
return key.length > 0 ? key : null;
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function createCoachClient(options = {}) {
|
|
76
|
+
const provider = options.provider ?? providerFromBaseUrl(options.baseUrl) ?? 'openrouter';
|
|
77
|
+
const model = options.model ?? (provider === 'anthropic' ? 'claude-sonnet-4-6' : DEFAULT_MODEL);
|
|
78
|
+
const baseUrl = normalizeBaseUrl(options.baseUrl ?? defaultBaseUrl(provider));
|
|
79
|
+
const fetchImpl = options.fetchImpl ?? globalFetch;
|
|
80
|
+
const apiKey = resolveCoachApiKey(provider, options.apiKey);
|
|
81
|
+
return {
|
|
82
|
+
provider,
|
|
83
|
+
model,
|
|
84
|
+
baseUrl,
|
|
85
|
+
async *streamChat(messages, signal) {
|
|
86
|
+
if (provider === 'mock') {
|
|
87
|
+
yield 'Mock coach response.';
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (!apiKey)
|
|
91
|
+
throw new Error('No Coach API key configured');
|
|
92
|
+
if (provider === 'anthropic') {
|
|
93
|
+
yield* streamAnthropic({ fetchImpl, baseUrl, model, apiKey, messages, signal, timeoutMs: options.timeoutMs });
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
yield* streamOpenAICompatible({ fetchImpl, baseUrl, model, apiKey, messages, signal, timeoutMs: options.timeoutMs });
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
async function* streamOpenAICompatible(args) {
|
|
102
|
+
const controller = createAbortController();
|
|
103
|
+
const timer = setTimeout(() => controller.abort(), args.timeoutMs ?? 120_000);
|
|
104
|
+
const signal = mergeSignal(args.signal, controller.signal);
|
|
105
|
+
try {
|
|
106
|
+
const response = await args.fetchImpl(`${args.baseUrl}/chat/completions`, {
|
|
107
|
+
method: 'POST',
|
|
108
|
+
headers: {
|
|
109
|
+
authorization: `Bearer ${args.apiKey}`,
|
|
110
|
+
'content-type': 'application/json',
|
|
111
|
+
accept: 'text/event-stream',
|
|
112
|
+
},
|
|
113
|
+
body: JSON.stringify({ model: args.model, messages: args.messages, stream: true }),
|
|
114
|
+
signal,
|
|
115
|
+
});
|
|
116
|
+
if (!response.ok)
|
|
117
|
+
throw new Error(`Coach provider HTTP ${response.status}`);
|
|
118
|
+
yield* parseSseResponse(response, (json) => json?.choices?.[0]?.delta?.content ?? json?.choices?.[0]?.message?.content ?? '');
|
|
119
|
+
}
|
|
120
|
+
finally {
|
|
121
|
+
clearTimeout(timer);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
async function* streamAnthropic(args) {
|
|
125
|
+
const controller = createAbortController();
|
|
126
|
+
const timer = setTimeout(() => controller.abort(), args.timeoutMs ?? 120_000);
|
|
127
|
+
const signal = mergeSignal(args.signal, controller.signal);
|
|
128
|
+
try {
|
|
129
|
+
const system = args.messages.find((m) => m.role === 'system')?.content ?? '';
|
|
130
|
+
const messages = args.messages.filter((m) => m.role !== 'system').map((m) => ({ role: m.role === 'assistant' ? 'assistant' : 'user', content: m.content }));
|
|
131
|
+
const response = await args.fetchImpl(`${args.baseUrl}/messages`, {
|
|
132
|
+
method: 'POST',
|
|
133
|
+
headers: {
|
|
134
|
+
'x-api-key': args.apiKey,
|
|
135
|
+
'anthropic-version': '2023-06-01',
|
|
136
|
+
'content-type': 'application/json',
|
|
137
|
+
accept: 'text/event-stream',
|
|
138
|
+
},
|
|
139
|
+
body: JSON.stringify({ model: args.model, system, messages, max_tokens: 1200, stream: true }),
|
|
140
|
+
signal,
|
|
141
|
+
});
|
|
142
|
+
if (!response.ok)
|
|
143
|
+
throw new Error(`Coach provider HTTP ${response.status}`);
|
|
144
|
+
yield* parseSseResponse(response, (json) => json?.delta?.text ?? json?.content_block?.text ?? '');
|
|
145
|
+
}
|
|
146
|
+
finally {
|
|
147
|
+
clearTimeout(timer);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
async function* parseSseResponse(response, pickText) {
|
|
151
|
+
let buffer = '';
|
|
152
|
+
for await (const chunk of responseBodyIterable(response)) {
|
|
153
|
+
buffer += chunk;
|
|
154
|
+
const parts = buffer.split('\n\n');
|
|
155
|
+
buffer = parts.pop() ?? '';
|
|
156
|
+
for (const part of parts) {
|
|
157
|
+
const dataLines = part.split('\n').filter((line) => line.startsWith('data:')).map((line) => line.slice(5).trim());
|
|
158
|
+
for (const data of dataLines) {
|
|
159
|
+
if (!data || data === '[DONE]')
|
|
160
|
+
continue;
|
|
161
|
+
try {
|
|
162
|
+
const token = pickText(JSON.parse(data));
|
|
163
|
+
if (token)
|
|
164
|
+
yield token;
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
async function* responseBodyIterable(response) {
|
|
174
|
+
const body = response.body;
|
|
175
|
+
if (!body)
|
|
176
|
+
return;
|
|
177
|
+
if (typeof body[Symbol.asyncIterator] === 'function') {
|
|
178
|
+
for await (const chunk of body)
|
|
179
|
+
yield chunkToString(chunk);
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
if (typeof body.getReader === 'function') {
|
|
183
|
+
const reader = body.getReader();
|
|
184
|
+
const decoder = new TextDecoder();
|
|
185
|
+
while (true) {
|
|
186
|
+
const { done, value } = await reader.read();
|
|
187
|
+
if (done)
|
|
188
|
+
break;
|
|
189
|
+
yield decoder.decode(value, { stream: true });
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
function chunkToString(chunk) {
|
|
194
|
+
if (typeof chunk === 'string')
|
|
195
|
+
return chunk;
|
|
196
|
+
if (chunk instanceof Uint8Array)
|
|
197
|
+
return Buffer.from(chunk).toString('utf8');
|
|
198
|
+
return String(chunk ?? '');
|
|
199
|
+
}
|
|
200
|
+
function defaultBaseUrl(provider) {
|
|
201
|
+
if (provider === 'openai')
|
|
202
|
+
return DEFAULT_OPENAI_BASE_URL;
|
|
203
|
+
if (provider === 'anthropic')
|
|
204
|
+
return DEFAULT_ANTHROPIC_BASE_URL;
|
|
205
|
+
return DEFAULT_OPENROUTER_BASE_URL;
|
|
206
|
+
}
|
|
207
|
+
function normalizeBaseUrl(value) {
|
|
208
|
+
return value.replace(/\/+$/, '');
|
|
209
|
+
}
|
|
210
|
+
function providerFromBaseUrl(baseUrl) {
|
|
211
|
+
if (!baseUrl)
|
|
212
|
+
return null;
|
|
213
|
+
if (baseUrl.includes('anthropic.com'))
|
|
214
|
+
return 'anthropic';
|
|
215
|
+
if (baseUrl.includes('openai.com'))
|
|
216
|
+
return 'openai';
|
|
217
|
+
if (baseUrl.includes('openrouter.ai'))
|
|
218
|
+
return 'openrouter';
|
|
219
|
+
return 'compatible';
|
|
220
|
+
}
|
|
221
|
+
function agentguardHome() {
|
|
222
|
+
return process.env.AGENTGUARD_HOME || path.join(os.homedir(), '.agentguard');
|
|
223
|
+
}
|
|
224
|
+
function globalFetch(url, init) {
|
|
225
|
+
const fetchImpl = globalThis.fetch;
|
|
226
|
+
if (typeof fetchImpl !== 'function')
|
|
227
|
+
throw new Error('Global fetch is not available. Use Node 20 or newer.');
|
|
228
|
+
return fetchImpl(url, init);
|
|
229
|
+
}
|
|
230
|
+
function createAbortController() {
|
|
231
|
+
const Controller = globalThis.AbortController;
|
|
232
|
+
if (Controller)
|
|
233
|
+
return new Controller();
|
|
234
|
+
const signal = { aborted: false, addEventListener: () => undefined };
|
|
235
|
+
return { signal, abort: () => { signal.aborted = true; } };
|
|
236
|
+
}
|
|
237
|
+
function mergeSignal(a, b) {
|
|
238
|
+
if (!a)
|
|
239
|
+
return b;
|
|
240
|
+
if (a.aborted)
|
|
241
|
+
return a;
|
|
242
|
+
const controller = createAbortController();
|
|
243
|
+
const abort = () => controller.abort();
|
|
244
|
+
a.addEventListener?.('abort', abort, { once: true });
|
|
245
|
+
b.addEventListener?.('abort', abort, { once: true });
|
|
246
|
+
return controller.signal;
|
|
247
|
+
}
|
|
248
|
+
//# sourceMappingURL=llm-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-client.js","sourceRoot":"","sources":["../../src/coach/llm-client.ts"],"names":[],"mappings":"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"}
|