@agentguard-run/spend 0.2.2 → 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 +14 -1
- package/LICENSE +1 -1
- package/README.es-419.md +37 -100
- package/README.md +58 -121
- package/README.pt-BR.md +37 -100
- package/dist/bindings/anthropic.d.ts +11 -0
- package/dist/bindings/anthropic.d.ts.map +1 -0
- package/dist/bindings/anthropic.js +116 -0
- package/dist/bindings/anthropic.js.map +1 -0
- package/dist/bindings/bedrock.d.ts +11 -0
- package/dist/bindings/bedrock.d.ts.map +1 -0
- package/dist/bindings/bedrock.js +177 -0
- package/dist/bindings/bedrock.js.map +1 -0
- package/dist/cli/auth.d.ts +7 -0
- package/dist/cli/auth.d.ts.map +1 -0
- package/dist/cli/auth.js +189 -0
- package/dist/cli/auth.js.map +1 -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/colors.d.ts +8 -3
- package/dist/cli/colors.d.ts.map +1 -1
- package/dist/cli/colors.js +93 -4
- package/dist/cli/colors.js.map +1 -1
- package/dist/cli/demo.d.ts.map +1 -1
- package/dist/cli/demo.js +23 -2
- package/dist/cli/demo.js.map +1 -1
- package/dist/cli/main.d.ts +0 -6
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +42 -16
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/models.d.ts +18 -0
- package/dist/cli/models.d.ts.map +1 -0
- package/dist/cli/models.js +277 -0
- package/dist/cli/models.js.map +1 -0
- package/dist/cli/tips.d.ts +21 -0
- package/dist/cli/tips.d.ts.map +1 -0
- package/dist/cli/tips.js +191 -0
- package/dist/cli/tips.js.map +1 -0
- package/dist/cli/wizard.d.ts +27 -0
- package/dist/cli/wizard.d.ts.map +1 -0
- package/dist/cli/wizard.js +182 -0
- package/dist/cli/wizard.js.map +1 -0
- 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/cost-table.d.ts +11 -36
- package/dist/cost-table.d.ts.map +1 -1
- package/dist/cost-table.js +114 -45
- package/dist/cost-table.js.map +1 -1
- package/dist/index.d.ts +9 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -2
- package/dist/index.js.map +1 -1
- package/dist/openrouter-catalog.d.ts +56 -0
- package/dist/openrouter-catalog.d.ts.map +1 -0
- package/dist/openrouter-catalog.js +183 -0
- package/dist/openrouter-catalog.js.map +1 -0
- package/dist/spend-guard.d.ts +38 -55
- package/dist/spend-guard.d.ts.map +1 -1
- package/dist/spend-guard.js +268 -83
- package/dist/spend-guard.js.map +1 -1
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +52 -21
- package/dist/telemetry.js.map +1 -1
- package/dist/templates/index.d.ts +17 -0
- package/dist/templates/index.d.ts.map +1 -0
- package/dist/templates/index.js +100 -0
- package/dist/templates/index.js.map +1 -0
- package/dist/types.d.ts +18 -3
- package/dist/types.d.ts.map +1 -1
- package/package.json +39 -4
- package/src/bindings/anthropic.ts +142 -0
- package/src/bindings/bedrock.ts +200 -0
- package/src/cli/auth.ts +145 -0
- package/src/cli/coach.ts +249 -0
- package/src/cli/models.ts +236 -0
- package/src/cli/tips.ts +161 -0
- package/src/cli/wizard.ts +160 -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
- package/src/openrouter-catalog.ts +180 -0
- package/src/templates/agent-support.yaml +30 -0
- package/src/templates/chargeback-evidence.yaml +30 -0
- package/src/templates/code-scan.yaml +30 -0
- package/src/templates/index.ts +109 -0
- package/src/templates/payment-approval.yaml +30 -0
- package/src/templates/risk-review.yaml +30 -0
- package/tests/fixtures/openrouter-catalog.json +1 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.WizardStateMachine = void 0;
|
|
37
|
+
exports.runWizard = runWizard;
|
|
38
|
+
exports.defaultAnswers = defaultAnswers;
|
|
39
|
+
exports.writeWizardOutputs = writeWizardOutputs;
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const readline = __importStar(require("readline"));
|
|
43
|
+
const index_1 = require("../index");
|
|
44
|
+
const templates_1 = require("../templates");
|
|
45
|
+
const colors_1 = require("./colors");
|
|
46
|
+
const BUILD_TYPES = ['chatbot', 'agent', 'batch job', 'API endpoint'];
|
|
47
|
+
const CAPABILITY_TIERS = [
|
|
48
|
+
['read_only', 'Read records and produce findings'],
|
|
49
|
+
['data_write', 'Write allowed fields after policy checks'],
|
|
50
|
+
['payment_initiate', 'Create or recommend payment intents'],
|
|
51
|
+
['payment_execute', 'Execute money movement only with verified attestation'],
|
|
52
|
+
];
|
|
53
|
+
class WizardStateMachine {
|
|
54
|
+
step = 0;
|
|
55
|
+
totalSteps = 7;
|
|
56
|
+
next(answer) {
|
|
57
|
+
if (!this.validate(this.step, answer))
|
|
58
|
+
return false;
|
|
59
|
+
this.step = Math.min(this.step + 1, this.totalSteps - 1);
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
back() {
|
|
63
|
+
this.step = Math.max(0, this.step - 1);
|
|
64
|
+
}
|
|
65
|
+
validate(step, answer) {
|
|
66
|
+
if (step === 0)
|
|
67
|
+
return BUILD_TYPES.includes(answer);
|
|
68
|
+
if (step === 1)
|
|
69
|
+
return Boolean(templates_1.TASK_TEMPLATES[answer]);
|
|
70
|
+
if (step === 2)
|
|
71
|
+
return CAPABILITY_TIERS.some(([tier]) => tier === answer);
|
|
72
|
+
if (step === 3)
|
|
73
|
+
return answer.split(',').map((item) => item.trim()).filter(Boolean).length > 0;
|
|
74
|
+
if (step === 4)
|
|
75
|
+
return answer.trim().length > 0;
|
|
76
|
+
if (step === 5)
|
|
77
|
+
return answer.split(',').every((item) => Number.isSafeInteger(Number(item.trim())) && Number(item.trim()) >= 0);
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.WizardStateMachine = WizardStateMachine;
|
|
82
|
+
async function runWizard(argv) {
|
|
83
|
+
if (argv.includes('--help') || argv.includes('-h')) {
|
|
84
|
+
console.log('agentguard wizard [--defaults] [--template <name>]');
|
|
85
|
+
return 0;
|
|
86
|
+
}
|
|
87
|
+
const templateSlug = valueAfter(argv, '--template') ?? 'risk-review';
|
|
88
|
+
const useDefaults = argv.includes('--defaults') || !process.stdin.isTTY;
|
|
89
|
+
const answers = useDefaults ? defaultAnswers(templateSlug) : await promptAnswers(templateSlug);
|
|
90
|
+
const outputs = writeWizardOutputs(answers);
|
|
91
|
+
console.log('');
|
|
92
|
+
console.log(' ' + (0, colors_1.banner)(index_1.AGENTGUARD_SPEND_VERSION));
|
|
93
|
+
console.log('');
|
|
94
|
+
console.log(` ${(0, colors_1.green)('created')} ${outputs.policyPath}`);
|
|
95
|
+
console.log(` ${(0, colors_1.green)('created')} ${outputs.quickstartTsPath}`);
|
|
96
|
+
console.log(` ${(0, colors_1.green)('created')} ${outputs.quickstartPyPath}`);
|
|
97
|
+
console.log('');
|
|
98
|
+
console.log((0, colors_1.cyanBold)('Quickstart snippet'));
|
|
99
|
+
console.log('');
|
|
100
|
+
console.log(outputs.snippet);
|
|
101
|
+
console.log('');
|
|
102
|
+
console.log(' ' + (0, colors_1.statusBar)());
|
|
103
|
+
console.log('');
|
|
104
|
+
return 0;
|
|
105
|
+
}
|
|
106
|
+
function defaultAnswers(templateSlug = 'risk-review') {
|
|
107
|
+
const template = (0, templates_1.getTaskTemplate)(templateSlug) ?? (0, templates_1.getTaskTemplate)('risk-review');
|
|
108
|
+
const perCall = template.caps.find((cap) => cap.window === 'per_call')?.amountCents ?? 100;
|
|
109
|
+
const perDay = template.caps.find((cap) => cap.window === 'per_day')?.amountCents ?? 2500;
|
|
110
|
+
return {
|
|
111
|
+
building: 'agent',
|
|
112
|
+
template: template.slug,
|
|
113
|
+
capability: template.requiredCapability,
|
|
114
|
+
allowedModels: [...template.allowedModels],
|
|
115
|
+
fallbackModel: template.fallbackModel,
|
|
116
|
+
perCallCents: perCall,
|
|
117
|
+
perDayCents: perDay,
|
|
118
|
+
perMonthCents: perDay * 20,
|
|
119
|
+
systemInstructions: template.systemInstructions,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
function writeWizardOutputs(answers, home = (0, colors_1.agentguardHome)()) {
|
|
123
|
+
fs.mkdirSync(home, { recursive: true });
|
|
124
|
+
const policyPath = path.join(home, 'policy.yaml');
|
|
125
|
+
const quickstartTsPath = path.join(home, 'quickstart.ts');
|
|
126
|
+
const quickstartPyPath = path.join(home, 'quickstart.py');
|
|
127
|
+
const policy = policyYaml(answers);
|
|
128
|
+
const ts = quickstartTs(answers);
|
|
129
|
+
const py = quickstartPy(answers);
|
|
130
|
+
fs.writeFileSync(policyPath, policy);
|
|
131
|
+
fs.writeFileSync(quickstartTsPath, ts);
|
|
132
|
+
fs.writeFileSync(quickstartPyPath, py);
|
|
133
|
+
return { policyPath, quickstartTsPath, quickstartPyPath, snippet: tsSnippet(answers) };
|
|
134
|
+
}
|
|
135
|
+
async function promptAnswers(templateSlug) {
|
|
136
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
137
|
+
const ask = (question, fallback) => new Promise((resolve) => {
|
|
138
|
+
rl.question(`${question} (${fallback}): `, (answer) => resolve(answer.trim() || fallback));
|
|
139
|
+
});
|
|
140
|
+
try {
|
|
141
|
+
const seed = defaultAnswers(templateSlug);
|
|
142
|
+
console.log('');
|
|
143
|
+
console.log(' ' + (0, colors_1.banner)(index_1.AGENTGUARD_SPEND_VERSION));
|
|
144
|
+
console.log('');
|
|
145
|
+
const building = await ask(`What are you building? ${BUILD_TYPES.join(', ')}`, seed.building);
|
|
146
|
+
const template = await ask(`Pick a task template: ${(0, templates_1.listTaskTemplates)().map((item) => item.slug).join(', ')}`, seed.template);
|
|
147
|
+
const capability = await ask(`Capability tier: ${CAPABILITY_TIERS.map(([tier, label]) => tier + ' (' + label + ')').join(', ')}`, seed.capability);
|
|
148
|
+
const templateDef = (0, templates_1.getTaskTemplate)(template) ?? (0, templates_1.getTaskTemplate)(seed.template);
|
|
149
|
+
const allowedModels = (await ask('Allowed models, comma separated', templateDef.allowedModels.join(','))).split(',').map((item) => item.trim()).filter(Boolean);
|
|
150
|
+
const fallbackModel = await ask('Fallback on downgrade', templateDef.fallbackModel);
|
|
151
|
+
const caps = await ask('Caps in cents: per-call, per-day, per-month', `${seed.perCallCents},${seed.perDayCents},${seed.perMonthCents}`);
|
|
152
|
+
const [perCallCents, perDayCents, perMonthCents] = caps.split(',').map((item) => Number(item.trim()));
|
|
153
|
+
const systemInstructions = await ask('System instructions', templateDef.systemInstructions);
|
|
154
|
+
return { building, template, capability, allowedModels, fallbackModel, perCallCents, perDayCents, perMonthCents, systemInstructions };
|
|
155
|
+
}
|
|
156
|
+
finally {
|
|
157
|
+
rl.close();
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
function policyYaml(answers) {
|
|
161
|
+
const id = `agentguard-${answers.template}-v1`;
|
|
162
|
+
const allowed = answers.allowedModels.map((model) => ` - ${model}`).join('\n');
|
|
163
|
+
return `# AgentGuard Spend policy generated by agentguard wizard\nid: ${id}\nname: ${answers.template} policy\nversion: 1\neffectiveFrom: "${new Date().toISOString()}"\nmode: enforce\nrequiredCapability: ${answers.capability}\nscope:\n tenantId: my-tenant\nmodels:\n allowed:\n${allowed}\n fallback: ${answers.fallbackModel}\ncaps:\n # WHY: Per-call cap bounds one agent action.\n - amountCents: ${answers.perCallCents}\n window: per_call\n action: downgrade\n downgradeTo: ${answers.fallbackModel}\n reason: "Per-call budget reached, routing to fallback model"\n # WHY: Daily cap catches runaway loops and unexpected volume.\n - amountCents: ${answers.perDayCents}\n window: per_day\n action: block\n reason: "Daily budget reached"\n # WHY: Monthly cap keeps the finance view predictable.\n - amountCents: ${answers.perMonthCents}\n window: per_month\n action: block\n reason: "Monthly budget reached"\nsystemInstructions: |\n${indent(answers.systemInstructions, 2)}\n`;
|
|
164
|
+
}
|
|
165
|
+
function quickstartTs(answers) {
|
|
166
|
+
return `import OpenAI from 'openai';\nimport { withSpendGuard, type SpendPolicy } from '@agentguard-run/spend';\n\nconst policy: SpendPolicy = {\n id: 'agentguard-${answers.template}-v1',\n name: '${answers.template} policy',\n scope: { tenantId: 'my-tenant' },\n caps: [\n { amountCents: ${answers.perCallCents}, window: 'per_call', action: 'downgrade', downgradeTo: '${answers.fallbackModel}' },\n { amountCents: ${answers.perDayCents}, window: 'per_day', action: 'block' },\n { amountCents: ${answers.perMonthCents}, window: 'per_month', action: 'block' },\n ],\n mode: 'enforce',\n requiredCapability: '${answers.capability}',\n version: 1,\n effectiveFrom: new Date().toISOString(),\n};\n\nconst openrouter = new OpenAI({\n baseURL: 'https://openrouter.ai/api/v1',\n apiKey: process.env.OPENROUTER_API_KEY,\n});\n\nexport const guardedClient = withSpendGuard(openrouter, {\n policy,\n scope: { tenantId: 'my-tenant', agentId: '${answers.template}' },\n capabilityClaim: '${answers.capability}',\n});\n`;
|
|
167
|
+
}
|
|
168
|
+
function quickstartPy(answers) {
|
|
169
|
+
return `from openai import OpenAI\nfrom agentguard_spend import with_spend_guard\nfrom agentguard_spend.types import SpendPolicy, SpendCap\n\npolicy = SpendPolicy(\n id='agentguard-${answers.template}-v1', name='${answers.template} policy',\n scope={'tenantId': 'my-tenant'},\n caps=[\n SpendCap(amountCents=${answers.perCallCents}, window='per_call', action='downgrade', downgradeTo='${answers.fallbackModel}'),\n SpendCap(amountCents=${answers.perDayCents}, window='per_day', action='block'),\n SpendCap(amountCents=${answers.perMonthCents}, window='per_month', action='block'),\n ],\n mode='enforce', requiredCapability='${answers.capability}',\n version=1, effectiveFrom='2026-05-27T00:00:00Z',\n)\n\nopenrouter = OpenAI(base_url='https://openrouter.ai/api/v1')\nguarded_client = with_spend_guard(openrouter, policy=policy, scope={'tenantId': 'my-tenant', 'agentId': '${answers.template}'}, capability_claim='${answers.capability}')\n`;
|
|
170
|
+
}
|
|
171
|
+
function tsSnippet(answers) {
|
|
172
|
+
return `const response = await guardedClient.chat.completions.create({\n model: '${answers.allowedModels[0] ?? 'openai/gpt-4o-mini'}',\n messages: [{ role: 'user', content: 'Run the governed task.' }],\n});`;
|
|
173
|
+
}
|
|
174
|
+
function indent(value, spaces) {
|
|
175
|
+
const prefix = ' '.repeat(spaces);
|
|
176
|
+
return value.split('\n').map((line) => prefix + line).join('\n');
|
|
177
|
+
}
|
|
178
|
+
function valueAfter(argv, flag) {
|
|
179
|
+
const index = argv.indexOf(flag);
|
|
180
|
+
return index >= 0 ? argv[index + 1] : undefined;
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=wizard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wizard.js","sourceRoot":"","sources":["../../src/cli/wizard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentGuard(TM) Spend: local Coach anomaly review 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
|
+
export interface CoachSpendPoint {
|
|
11
|
+
ts: string;
|
|
12
|
+
scope: string;
|
|
13
|
+
agentId: string;
|
|
14
|
+
cents: number;
|
|
15
|
+
}
|
|
16
|
+
export interface CoachAnomaly {
|
|
17
|
+
scope: string;
|
|
18
|
+
agentId: string;
|
|
19
|
+
last24hCents: number;
|
|
20
|
+
baselineCents: number;
|
|
21
|
+
sigmaCents: number;
|
|
22
|
+
suggestion: string;
|
|
23
|
+
}
|
|
24
|
+
export declare function readDecisionSpend(scope?: string, home?: string): CoachSpendPoint[];
|
|
25
|
+
export declare function reviewAnomalies(points: CoachSpendPoint[], now?: Date): CoachAnomaly[];
|
|
26
|
+
//# sourceMappingURL=anomaly.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anomaly.d.ts","sourceRoot":"","sources":["../../src/coach/anomaly.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,iBAAiB,CAAC,KAAK,SAAY,EAAE,IAAI,SAAmB,GAAG,eAAe,EAAE,CAuB/F;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,EAAE,EAAE,GAAG,OAAa,GAAG,YAAY,EAAE,CA6B3F"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* AgentGuard(TM) Spend: local Coach anomaly review 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
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
14
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
15
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
16
|
+
}
|
|
17
|
+
Object.defineProperty(o, k2, desc);
|
|
18
|
+
}) : (function(o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
o[k2] = m[k];
|
|
21
|
+
}));
|
|
22
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
23
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
24
|
+
}) : function(o, v) {
|
|
25
|
+
o["default"] = v;
|
|
26
|
+
});
|
|
27
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
28
|
+
var ownKeys = function(o) {
|
|
29
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
30
|
+
var ar = [];
|
|
31
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
32
|
+
return ar;
|
|
33
|
+
};
|
|
34
|
+
return ownKeys(o);
|
|
35
|
+
};
|
|
36
|
+
return function (mod) {
|
|
37
|
+
if (mod && mod.__esModule) return mod;
|
|
38
|
+
var result = {};
|
|
39
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
40
|
+
__setModuleDefault(result, mod);
|
|
41
|
+
return result;
|
|
42
|
+
};
|
|
43
|
+
})();
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.readDecisionSpend = readDecisionSpend;
|
|
46
|
+
exports.reviewAnomalies = reviewAnomalies;
|
|
47
|
+
const fs = __importStar(require("fs"));
|
|
48
|
+
const path = __importStar(require("path"));
|
|
49
|
+
const output_1 = require("./output");
|
|
50
|
+
function readDecisionSpend(scope = 'default', home = (0, output_1.agentguardHome)()) {
|
|
51
|
+
const file = path.join(home, scope, 'decisions.ndjson');
|
|
52
|
+
if (!fs.existsSync(file))
|
|
53
|
+
return [];
|
|
54
|
+
const points = [];
|
|
55
|
+
for (const line of fs.readFileSync(file, 'utf8').split('\n')) {
|
|
56
|
+
if (!line.trim())
|
|
57
|
+
continue;
|
|
58
|
+
try {
|
|
59
|
+
const parsed = JSON.parse(line);
|
|
60
|
+
const decision = parsed.decision ?? parsed;
|
|
61
|
+
const cents = Number(decision.actualCents ?? decision.projectedCents ?? 0);
|
|
62
|
+
const ts = String(decision.timestamp ?? parsed.timestamp ?? new Date(0).toISOString());
|
|
63
|
+
const scopeObj = decision.scope ?? {};
|
|
64
|
+
points.push({
|
|
65
|
+
ts,
|
|
66
|
+
scope: String(scopeObj.tenantId ?? decision.triggeredScopeKey ?? scope),
|
|
67
|
+
agentId: String(scopeObj.agentId ?? decision.agentId ?? 'unknown'),
|
|
68
|
+
cents: Number.isFinite(cents) ? cents : 0,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return points;
|
|
76
|
+
}
|
|
77
|
+
function reviewAnomalies(points, now = new Date()) {
|
|
78
|
+
const cutoff = now.getTime() - 24 * 60 * 60 * 1000;
|
|
79
|
+
const byAgent = new Map();
|
|
80
|
+
for (const point of points) {
|
|
81
|
+
const key = `${point.scope}\t${point.agentId}`;
|
|
82
|
+
byAgent.set(key, [...(byAgent.get(key) ?? []), point]);
|
|
83
|
+
}
|
|
84
|
+
const anomalies = [];
|
|
85
|
+
for (const [key, rows] of byAgent) {
|
|
86
|
+
const [scope, agentId] = key.split('\t');
|
|
87
|
+
const daily = bucketDaily(rows);
|
|
88
|
+
const historical = daily.filter((row) => row.day < dayKey(new Date(cutoff))).map((row) => row.cents);
|
|
89
|
+
const recent = rows.filter((row) => Date.parse(row.ts) >= cutoff).reduce((sum, row) => sum + row.cents, 0);
|
|
90
|
+
if (historical.length < 3 || recent <= 0)
|
|
91
|
+
continue;
|
|
92
|
+
const mean = historical.reduce((sum, value) => sum + value, 0) / historical.length;
|
|
93
|
+
const variance = historical.reduce((sum, value) => sum + Math.pow(value - mean, 2), 0) / historical.length;
|
|
94
|
+
const sigma = Math.sqrt(variance);
|
|
95
|
+
if (recent > mean + 3 * sigma) {
|
|
96
|
+
anomalies.push({
|
|
97
|
+
scope: scope ?? 'unknown',
|
|
98
|
+
agentId: agentId ?? 'unknown',
|
|
99
|
+
last24hCents: recent,
|
|
100
|
+
baselineCents: Math.round(mean),
|
|
101
|
+
sigmaCents: Math.round(sigma),
|
|
102
|
+
suggestion: 'Lower the per_day cap or add a per_minute block cap for this agent.',
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return anomalies.sort((a, b) => b.last24hCents - a.last24hCents);
|
|
107
|
+
}
|
|
108
|
+
function bucketDaily(points) {
|
|
109
|
+
const buckets = new Map();
|
|
110
|
+
for (const point of points) {
|
|
111
|
+
const day = dayKey(new Date(point.ts));
|
|
112
|
+
buckets.set(day, (buckets.get(day) ?? 0) + point.cents);
|
|
113
|
+
}
|
|
114
|
+
return [...buckets.entries()].map(([day, cents]) => ({ day, cents })).sort((a, b) => a.day.localeCompare(b.day));
|
|
115
|
+
}
|
|
116
|
+
function dayKey(date) {
|
|
117
|
+
return date.toISOString().slice(0, 10);
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=anomaly.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anomaly.js","sourceRoot":"","sources":["../../src/coach/anomaly.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentGuard(TM) Spend: Coach conversation state.
|
|
3
|
+
*
|
|
4
|
+
* Patent notice: Protected by U.S. patent-pending technology
|
|
5
|
+
* (App. Nos. 63/983,615; 63/983,621; 63/983,843; 63/984,626;
|
|
6
|
+
* 64/071,781; 64/071,789).
|
|
7
|
+
*/
|
|
8
|
+
import type { CapabilityTier, SpendPolicy } from '../types';
|
|
9
|
+
export type CoachQuestionId = 'building' | 'scale' | 'tasks' | 'budget' | 'confirm';
|
|
10
|
+
export interface CoachQuestion {
|
|
11
|
+
id: CoachQuestionId;
|
|
12
|
+
prompt: string;
|
|
13
|
+
}
|
|
14
|
+
export interface CoachAnswers {
|
|
15
|
+
building?: string;
|
|
16
|
+
scale?: string;
|
|
17
|
+
tasks?: string;
|
|
18
|
+
budget?: string;
|
|
19
|
+
confirm?: string;
|
|
20
|
+
language?: 'ts' | 'py';
|
|
21
|
+
}
|
|
22
|
+
export interface CoachBusinessProfile {
|
|
23
|
+
vertical: string;
|
|
24
|
+
tenantId: string;
|
|
25
|
+
teamSize: number;
|
|
26
|
+
monthlyVolume: number;
|
|
27
|
+
tasks: string[];
|
|
28
|
+
monthlyBudgetCents: number;
|
|
29
|
+
requiredCapability: CapabilityTier;
|
|
30
|
+
primaryModel: string;
|
|
31
|
+
fallbackModel: string;
|
|
32
|
+
perCallCapCents: number;
|
|
33
|
+
perDayCapCents: number;
|
|
34
|
+
perMonthCapCents: number;
|
|
35
|
+
scopeLabel: string;
|
|
36
|
+
language: 'ts' | 'py';
|
|
37
|
+
}
|
|
38
|
+
export interface ProjectedSavingsRow {
|
|
39
|
+
label: string;
|
|
40
|
+
beforeCents: number;
|
|
41
|
+
afterCents: number;
|
|
42
|
+
savingsCents: number;
|
|
43
|
+
}
|
|
44
|
+
export interface ProjectedSavings {
|
|
45
|
+
rows: ProjectedSavingsRow[];
|
|
46
|
+
monthlyBeforeCents: number;
|
|
47
|
+
monthlyAfterCents: number;
|
|
48
|
+
monthlySavingsCents: number;
|
|
49
|
+
savingsPercent: number;
|
|
50
|
+
}
|
|
51
|
+
export declare const COACH_QUESTIONS: CoachQuestion[];
|
|
52
|
+
export declare class CoachConversation {
|
|
53
|
+
private answers;
|
|
54
|
+
private index;
|
|
55
|
+
constructor(initial?: CoachAnswers);
|
|
56
|
+
currentQuestion(): CoachQuestion | null;
|
|
57
|
+
answer(value: string): void;
|
|
58
|
+
next(): CoachQuestion | null;
|
|
59
|
+
back(): CoachQuestion | null;
|
|
60
|
+
isComplete(): boolean;
|
|
61
|
+
snapshot(): CoachAnswers;
|
|
62
|
+
profile(cwd?: string): CoachBusinessProfile;
|
|
63
|
+
}
|
|
64
|
+
export declare function buildBusinessProfile(answers: CoachAnswers, cwd?: string): CoachBusinessProfile;
|
|
65
|
+
export declare function buildPolicyFromProfile(profile: CoachBusinessProfile): SpendPolicy;
|
|
66
|
+
export declare function projectedSavings(profile: CoachBusinessProfile): ProjectedSavings;
|
|
67
|
+
export declare function formatCents(cents: number): string;
|
|
68
|
+
export declare function detectProjectLanguage(cwd: string): 'ts' | 'py';
|
|
69
|
+
//# sourceMappingURL=conversation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../src/coach/conversation.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAY,WAAW,EAAE,MAAM,UAAU,CAAC;AAEtE,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEpF,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,eAAe,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,cAAc,CAAC;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,mBAAmB,EAAE,CAAC;IAC5B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,eAAe,EAAE,aAAa,EAM1C,CAAC;AAaF,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,KAAK,CAAK;gBAEN,OAAO,CAAC,EAAE,YAAY;IAKlC,eAAe,IAAI,aAAa,GAAG,IAAI;IAIvC,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAM3B,IAAI,IAAI,aAAa,GAAG,IAAI;IAK5B,IAAI,IAAI,aAAa,GAAG,IAAI;IAK5B,UAAU,IAAI,OAAO;IAIrB,QAAQ,IAAI,YAAY;IAIxB,OAAO,CAAC,GAAG,SAAgB,GAAG,oBAAoB;CAGnD;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,SAAgB,GAAG,oBAAoB,CAwBrG;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,oBAAoB,GAAG,WAAW,CAgCjF;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,oBAAoB,GAAG,gBAAgB,CAgBhF;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAQ9D"}
|