@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.
Files changed (115) hide show
  1. package/CHANGELOG.md +14 -1
  2. package/LICENSE +1 -1
  3. package/README.es-419.md +37 -100
  4. package/README.md +58 -121
  5. package/README.pt-BR.md +37 -100
  6. package/dist/bindings/anthropic.d.ts +11 -0
  7. package/dist/bindings/anthropic.d.ts.map +1 -0
  8. package/dist/bindings/anthropic.js +116 -0
  9. package/dist/bindings/anthropic.js.map +1 -0
  10. package/dist/bindings/bedrock.d.ts +11 -0
  11. package/dist/bindings/bedrock.d.ts.map +1 -0
  12. package/dist/bindings/bedrock.js +177 -0
  13. package/dist/bindings/bedrock.js.map +1 -0
  14. package/dist/cli/auth.d.ts +7 -0
  15. package/dist/cli/auth.d.ts.map +1 -0
  16. package/dist/cli/auth.js +189 -0
  17. package/dist/cli/auth.js.map +1 -0
  18. package/dist/cli/coach.d.ts +5 -0
  19. package/dist/cli/coach.d.ts.map +1 -0
  20. package/dist/cli/coach.js +257 -0
  21. package/dist/cli/coach.js.map +1 -0
  22. package/dist/cli/colors.d.ts +8 -3
  23. package/dist/cli/colors.d.ts.map +1 -1
  24. package/dist/cli/colors.js +93 -4
  25. package/dist/cli/colors.js.map +1 -1
  26. package/dist/cli/demo.d.ts.map +1 -1
  27. package/dist/cli/demo.js +23 -2
  28. package/dist/cli/demo.js.map +1 -1
  29. package/dist/cli/main.d.ts +0 -6
  30. package/dist/cli/main.d.ts.map +1 -1
  31. package/dist/cli/main.js +42 -16
  32. package/dist/cli/main.js.map +1 -1
  33. package/dist/cli/models.d.ts +18 -0
  34. package/dist/cli/models.d.ts.map +1 -0
  35. package/dist/cli/models.js +277 -0
  36. package/dist/cli/models.js.map +1 -0
  37. package/dist/cli/tips.d.ts +21 -0
  38. package/dist/cli/tips.d.ts.map +1 -0
  39. package/dist/cli/tips.js +191 -0
  40. package/dist/cli/tips.js.map +1 -0
  41. package/dist/cli/wizard.d.ts +27 -0
  42. package/dist/cli/wizard.d.ts.map +1 -0
  43. package/dist/cli/wizard.js +182 -0
  44. package/dist/cli/wizard.js.map +1 -0
  45. package/dist/coach/anomaly.d.ts +26 -0
  46. package/dist/coach/anomaly.d.ts.map +1 -0
  47. package/dist/coach/anomaly.js +119 -0
  48. package/dist/coach/anomaly.js.map +1 -0
  49. package/dist/coach/conversation.d.ts +69 -0
  50. package/dist/coach/conversation.d.ts.map +1 -0
  51. package/dist/coach/conversation.js +228 -0
  52. package/dist/coach/conversation.js.map +1 -0
  53. package/dist/coach/forecast.d.ts +19 -0
  54. package/dist/coach/forecast.d.ts.map +1 -0
  55. package/dist/coach/forecast.js +57 -0
  56. package/dist/coach/forecast.js.map +1 -0
  57. package/dist/coach/llm-client.d.ts +41 -0
  58. package/dist/coach/llm-client.d.ts.map +1 -0
  59. package/dist/coach/llm-client.js +248 -0
  60. package/dist/coach/llm-client.js.map +1 -0
  61. package/dist/coach/output.d.ts +41 -0
  62. package/dist/coach/output.d.ts.map +1 -0
  63. package/dist/coach/output.js +173 -0
  64. package/dist/coach/output.js.map +1 -0
  65. package/dist/coach/system-prompt.d.ts +20 -0
  66. package/dist/coach/system-prompt.d.ts.map +1 -0
  67. package/dist/coach/system-prompt.js +177 -0
  68. package/dist/coach/system-prompt.js.map +1 -0
  69. package/dist/cost-table.d.ts +11 -36
  70. package/dist/cost-table.d.ts.map +1 -1
  71. package/dist/cost-table.js +114 -45
  72. package/dist/cost-table.js.map +1 -1
  73. package/dist/index.d.ts +9 -3
  74. package/dist/index.d.ts.map +1 -1
  75. package/dist/index.js +30 -2
  76. package/dist/index.js.map +1 -1
  77. package/dist/openrouter-catalog.d.ts +56 -0
  78. package/dist/openrouter-catalog.d.ts.map +1 -0
  79. package/dist/openrouter-catalog.js +183 -0
  80. package/dist/openrouter-catalog.js.map +1 -0
  81. package/dist/spend-guard.d.ts +38 -55
  82. package/dist/spend-guard.d.ts.map +1 -1
  83. package/dist/spend-guard.js +268 -83
  84. package/dist/spend-guard.js.map +1 -1
  85. package/dist/telemetry.d.ts.map +1 -1
  86. package/dist/telemetry.js +52 -21
  87. package/dist/telemetry.js.map +1 -1
  88. package/dist/templates/index.d.ts +17 -0
  89. package/dist/templates/index.d.ts.map +1 -0
  90. package/dist/templates/index.js +100 -0
  91. package/dist/templates/index.js.map +1 -0
  92. package/dist/types.d.ts +18 -3
  93. package/dist/types.d.ts.map +1 -1
  94. package/package.json +39 -4
  95. package/src/bindings/anthropic.ts +142 -0
  96. package/src/bindings/bedrock.ts +200 -0
  97. package/src/cli/auth.ts +145 -0
  98. package/src/cli/coach.ts +249 -0
  99. package/src/cli/models.ts +236 -0
  100. package/src/cli/tips.ts +161 -0
  101. package/src/cli/wizard.ts +160 -0
  102. package/src/coach/anomaly.ts +98 -0
  103. package/src/coach/conversation.ts +248 -0
  104. package/src/coach/forecast.ts +64 -0
  105. package/src/coach/llm-client.ts +247 -0
  106. package/src/coach/output.ts +172 -0
  107. package/src/coach/system-prompt.ts +181 -0
  108. package/src/openrouter-catalog.ts +180 -0
  109. package/src/templates/agent-support.yaml +30 -0
  110. package/src/templates/chargeback-evidence.yaml +30 -0
  111. package/src/templates/code-scan.yaml +30 -0
  112. package/src/templates/index.ts +109 -0
  113. package/src/templates/payment-approval.yaml +30 -0
  114. package/src/templates/risk-review.yaml +30 -0
  115. package/tests/fixtures/openrouter-catalog.json +1 -0
package/dist/telemetry.js CHANGED
@@ -43,35 +43,36 @@ const https = __importStar(require("https"));
43
43
  const os = __importStar(require("os"));
44
44
  const path = __importStar(require("path"));
45
45
  const crypto_1 = require("crypto");
46
- const AGENTGUARD_SPEND_VERSION = '0.2.2';
46
+ const AGENTGUARD_SPEND_VERSION = '0.4.0';
47
47
  const STATE_DIR = path.join(os.homedir(), '.agentguard');
48
- const STATE_PATH = path.join(STATE_DIR, 'telemetry.json');
48
+ const INSTALL_PATH = path.join(STATE_DIR, 'install.json');
49
49
  const BEACON_URL = 'https://agentguard.run/api/beacon';
50
50
  const sentEvents = new Set();
51
51
  function telemetryStatus() {
52
52
  const state = loadState();
53
53
  return {
54
54
  enabled: telemetryEnabled(state),
55
- anonymousInstallId: state.anonymousInstallId ?? null,
56
- statePath: STATE_PATH,
55
+ anonymousInstallId: normalizedInstallId(state) ?? envInstallId(),
56
+ statePath: INSTALL_PATH,
57
57
  };
58
58
  }
59
59
  function enableTelemetry() {
60
- const state = ensureInstallId(loadState());
61
- state.enabled = true;
62
- saveState(state);
60
+ const state = loadState();
61
+ const installId = getOrCreateInstallId(state);
62
+ const next = { ...state, enabled: true };
63
+ if (installId)
64
+ next.anonymousInstallId = installId;
65
+ saveState(next);
63
66
  return telemetryStatus();
64
67
  }
65
68
  function disableTelemetry() {
66
69
  const state = loadState();
67
- state.enabled = false;
68
- saveState(state);
70
+ saveState({ ...state, enabled: false });
69
71
  return telemetryStatus();
70
72
  }
71
73
  function resetTelemetryInstallId() {
72
74
  const state = loadState();
73
- state.anonymousInstallId = (0, crypto_1.randomUUID)();
74
- saveState(state);
75
+ saveState({ ...state, anonymousInstallId: (0, crypto_1.randomUUID)() });
75
76
  return telemetryStatus();
76
77
  }
77
78
  function recordTelemetryEvent(event) {
@@ -80,8 +81,9 @@ function recordTelemetryEvent(event) {
80
81
  const state = loadState();
81
82
  if (!telemetryEnabled(state))
82
83
  return;
83
- const withId = ensureInstallId(state);
84
- saveState(withId);
84
+ const installId = getOrCreateInstallId(state);
85
+ if (!installId)
86
+ return;
85
87
  sentEvents.add(event);
86
88
  const payload = JSON.stringify({
87
89
  event,
@@ -89,7 +91,7 @@ function recordTelemetryEvent(event) {
89
91
  sdk_version: AGENTGUARD_SPEND_VERSION,
90
92
  runtime: `node-${process.version}`,
91
93
  os_family: process.platform,
92
- anonymous_install_id: withId.anonymousInstallId,
94
+ anonymous_install_id: installId,
93
95
  ci_env_detected: isCI(),
94
96
  tty: Boolean(process.stdout?.isTTY),
95
97
  });
@@ -122,20 +124,49 @@ function telemetryEnabled(state) {
122
124
  }
123
125
  function loadState() {
124
126
  try {
125
- return JSON.parse(fs.readFileSync(STATE_PATH, 'utf-8'));
127
+ return JSON.parse(fs.readFileSync(INSTALL_PATH, 'utf-8'));
126
128
  }
127
129
  catch {
128
130
  return {};
129
131
  }
130
132
  }
131
133
  function saveState(state) {
132
- fs.mkdirSync(STATE_DIR, { recursive: true });
133
- fs.writeFileSync(STATE_PATH, JSON.stringify(state, null, 2) + '\n', { mode: 0o600 });
134
+ try {
135
+ const installId = normalizedInstallId(state);
136
+ const next = { ...state };
137
+ if (installId)
138
+ next.anonymousInstallId = installId;
139
+ delete next.anonymous_install_id;
140
+ fs.mkdirSync(STATE_DIR, { recursive: true });
141
+ fs.writeFileSync(INSTALL_PATH, JSON.stringify(next, null, 2) + '\n', { mode: 0o600 });
142
+ fs.chmodSync(INSTALL_PATH, 0o600);
143
+ return true;
144
+ }
145
+ catch {
146
+ return false;
147
+ }
148
+ }
149
+ function getOrCreateInstallId(state) {
150
+ const existing = normalizedInstallId(state);
151
+ if (existing) {
152
+ if (state.anonymousInstallId !== existing || state.anonymous_install_id) {
153
+ saveState({ ...state, anonymousInstallId: existing });
154
+ }
155
+ return existing;
156
+ }
157
+ const envId = envInstallId();
158
+ if (envId)
159
+ return envId;
160
+ const generated = (0, crypto_1.randomUUID)();
161
+ return saveState({ ...state, anonymousInstallId: generated }) ? generated : null;
162
+ }
163
+ function normalizedInstallId(state) {
164
+ const id = state.anonymousInstallId ?? state.anonymous_install_id;
165
+ return typeof id === 'string' && id.length > 0 ? id : null;
134
166
  }
135
- function ensureInstallId(state) {
136
- if (!state.anonymousInstallId)
137
- state.anonymousInstallId = (0, crypto_1.randomUUID)();
138
- return state;
167
+ function envInstallId() {
168
+ const id = process.env.AGENTGUARD_INSTALL_ID ?? process.env.AGENTGUARD_ANONYMOUS_INSTALL_ID;
169
+ return typeof id === 'string' && id.length > 0 ? id : null;
139
170
  }
140
171
  function isCI() {
141
172
  return Boolean(process.env.CI ||
@@ -1 +1 @@
1
- {"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwBA,0CAOC;AAED,0CAOC;AAED,4CAIC;AAED,0DAIC;AAED,oDAwCC;AA9FD,uCAAyB;AACzB,6CAA+B;AAC/B,uCAAyB;AACzB,2CAA6B;AAC7B,mCAAoC;AACpC,MAAM,wBAAwB,GAAG,OAAO,CAAC;AAEzC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAC;AACzD,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;AAC1D,MAAM,UAAU,GAAG,mCAAmC,CAAC;AACvD,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;AAcrC,SAAgB,eAAe;IAC7B,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;IAC1B,OAAO;QACL,OAAO,EAAE,gBAAgB,CAAC,KAAK,CAAC;QAChC,kBAAkB,EAAE,mBAAmB,CAAC,KAAK,CAAC,IAAI,YAAY,EAAE;QAChE,SAAS,EAAE,YAAY;KACxB,CAAC;AACJ,CAAC;AAED,SAAgB,eAAe;IAC7B,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;IAC1B,MAAM,SAAS,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,IAAI,GAAmB,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IACzD,IAAI,SAAS;QAAE,IAAI,CAAC,kBAAkB,GAAG,SAAS,CAAC;IACnD,SAAS,CAAC,IAAI,CAAC,CAAC;IAChB,OAAO,eAAe,EAAE,CAAC;AAC3B,CAAC;AAED,SAAgB,gBAAgB;IAC9B,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;IAC1B,SAAS,CAAC,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IACxC,OAAO,eAAe,EAAE,CAAC;AAC3B,CAAC;AAED,SAAgB,uBAAuB;IACrC,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;IAC1B,SAAS,CAAC,EAAE,GAAG,KAAK,EAAE,kBAAkB,EAAE,IAAA,mBAAU,GAAE,EAAE,CAAC,CAAC;IAC1D,OAAO,eAAe,EAAE,CAAC;AAC3B,CAAC;AAED,SAAgB,oBAAoB,CAAC,KAAa;IAChD,IAAI,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC;QAAE,OAAO;IAClC,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;IAC1B,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC;QAAE,OAAO;IACrC,MAAM,SAAS,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAC9C,IAAI,CAAC,SAAS;QAAE,OAAO;IACvB,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAEtB,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC;QAC7B,KAAK;QACL,QAAQ,EAAE,uBAAuB;QACjC,WAAW,EAAE,wBAAwB;QACrC,OAAO,EAAE,QAAQ,OAAO,CAAC,OAAO,EAAE;QAClC,SAAS,EAAE,OAAO,CAAC,QAAQ;QAC3B,oBAAoB,EAAE,SAAS;QAC/B,eAAe,EAAE,IAAI,EAAE;QACvB,GAAG,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC;KACpC,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;QAChC,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CACvB;YACE,MAAM,EAAE,MAAM;YACd,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,IAAI,EAAE,GAAG,CAAC,QAAQ;YAClB,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,gBAAgB,EAAE,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC;aAC7C;YACD,OAAO,EAAE,IAAI;SACd,EACD,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,CACtB,CAAC;QACF,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QACjC,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACvC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACnB,CAAC;IAAC,MAAM,CAAC;QACP,2DAA2D;IAC7D,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAqB;IAC7C,IAAI,OAAO,CAAC,GAAG,CAAC,oBAAoB,KAAK,GAAG;QAAE,OAAO,KAAK,CAAC;IAC3D,IAAI,OAAO,CAAC,GAAG,CAAC,oBAAoB,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IAC1D,OAAO,KAAK,CAAC,OAAO,KAAK,IAAI,CAAC;AAChC,CAAC;AAED,SAAS,SAAS;IAChB,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAmB,CAAC;IAC9E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,KAAqB;IACtC,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;QAC7C,MAAM,IAAI,GAAmB,EAAE,GAAG,KAAK,EAAE,CAAC;QAC1C,IAAI,SAAS;YAAE,IAAI,CAAC,kBAAkB,GAAG,SAAS,CAAC;QACnD,OAAO,IAAI,CAAC,oBAAoB,CAAC;QACjC,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7C,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACtF,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAqB;IACjD,MAAM,QAAQ,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAC5C,IAAI,QAAQ,EAAE,CAAC;QACb,IAAI,KAAK,CAAC,kBAAkB,KAAK,QAAQ,IAAI,KAAK,CAAC,oBAAoB,EAAE,CAAC;YACxE,SAAS,CAAC,EAAE,GAAG,KAAK,EAAE,kBAAkB,EAAE,QAAQ,EAAE,CAAC,CAAC;QACxD,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,KAAK,GAAG,YAAY,EAAE,CAAC;IAC7B,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC;IAExB,MAAM,SAAS,GAAG,IAAA,mBAAU,GAAE,CAAC;IAC/B,OAAO,SAAS,CAAC,EAAE,GAAG,KAAK,EAAE,kBAAkB,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AACnF,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAqB;IAChD,MAAM,EAAE,GAAG,KAAK,CAAC,kBAAkB,IAAI,KAAK,CAAC,oBAAoB,CAAC;IAClE,OAAO,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7D,CAAC;AAED,SAAS,YAAY;IACnB,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC;IAC5F,OAAO,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7D,CAAC;AAED,SAAS,IAAI;IACX,OAAO,OAAO,CACZ,OAAO,CAAC,GAAG,CAAC,EAAE;QACZ,OAAO,CAAC,GAAG,CAAC,cAAc;QAC1B,OAAO,CAAC,GAAG,CAAC,SAAS;QACrB,OAAO,CAAC,GAAG,CAAC,QAAQ;QACpB,OAAO,CAAC,GAAG,CAAC,SAAS;QACrB,OAAO,CAAC,GAAG,CAAC,MAAM;QAClB,OAAO,CAAC,GAAG,CAAC,OAAO,CACtB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { CapabilityTier, SpendPolicy } from '../types';
2
+ export interface TaskTemplate {
3
+ id: string;
4
+ slug: string;
5
+ label: string;
6
+ requiredCapability: CapabilityTier;
7
+ primaryModel: string;
8
+ fallbackModel: string;
9
+ allowedModels: string[];
10
+ caps: SpendPolicy['caps'];
11
+ systemInstructions: string;
12
+ }
13
+ export declare const TASK_TEMPLATES: Record<string, TaskTemplate>;
14
+ export declare function listTaskTemplates(): TaskTemplate[];
15
+ export declare function getTaskTemplate(slug: string): TaskTemplate | null;
16
+ export declare function policyFromTemplate(slug: string, tenantId?: string): SpendPolicy | null;
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5D,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,kBAAkB,EAAE,cAAc,CAAC;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAuEvD,CAAC;AAEF,wBAAgB,iBAAiB,IAAI,YAAY,EAAE,CAElD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAEjE;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,SAAc,GAAG,WAAW,GAAG,IAAI,CAa3F"}
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TASK_TEMPLATES = void 0;
4
+ exports.listTaskTemplates = listTaskTemplates;
5
+ exports.getTaskTemplate = getTaskTemplate;
6
+ exports.policyFromTemplate = policyFromTemplate;
7
+ exports.TASK_TEMPLATES = {
8
+ 'risk-review': {
9
+ id: 'risk-review-v1',
10
+ slug: 'risk-review',
11
+ label: 'Risk review agent',
12
+ requiredCapability: 'read_only',
13
+ primaryModel: 'openai/gpt-4o-mini',
14
+ fallbackModel: 'anthropic/claude-haiku-4-5',
15
+ allowedModels: ['openai/gpt-4o-mini', 'anthropic/claude-haiku-4-5'],
16
+ caps: [
17
+ { amountCents: 50, window: 'per_call', action: 'downgrade', downgradeTo: 'anthropic/claude-haiku-4-5', reason: 'Per-call budget reached, routing to fallback model' },
18
+ { amountCents: 2500, window: 'per_day', action: 'block', reason: 'Daily budget reached' },
19
+ ],
20
+ systemInstructions: 'Classify transaction, vendor, and account risk. Return concise findings with evidence pointers only.',
21
+ },
22
+ 'payment-approval': {
23
+ id: 'payment-approval-v1',
24
+ slug: 'payment-approval',
25
+ label: 'Payment approval agent',
26
+ requiredCapability: 'payment_initiate',
27
+ primaryModel: 'anthropic/claude-sonnet-4-6',
28
+ fallbackModel: 'openai/gpt-5-mini',
29
+ allowedModels: ['anthropic/claude-sonnet-4-6', 'openai/gpt-5-mini'],
30
+ caps: [
31
+ { amountCents: 500, window: 'per_call', action: 'downgrade', downgradeTo: 'openai/gpt-5-mini', reason: 'Per-call budget reached, routing to fallback model' },
32
+ { amountCents: 20000, window: 'per_day', action: 'block', reason: 'Daily budget reached' },
33
+ ],
34
+ systemInstructions: 'Review payment intent and policy evidence. Recommend approve, hold, or escalate. Never execute funds movement.',
35
+ },
36
+ 'chargeback-evidence': {
37
+ id: 'chargeback-evidence-v1',
38
+ slug: 'chargeback-evidence',
39
+ label: 'Chargeback evidence agent',
40
+ requiredCapability: 'read_only',
41
+ primaryModel: 'openai/gpt-5-mini',
42
+ fallbackModel: 'openai/gpt-4o-mini',
43
+ allowedModels: ['openai/gpt-5-mini', 'openai/gpt-4o-mini'],
44
+ caps: [
45
+ { amountCents: 100, window: 'per_call', action: 'downgrade', downgradeTo: 'openai/gpt-4o-mini', reason: 'Per-call budget reached, routing to fallback model' },
46
+ { amountCents: 5000, window: 'per_day', action: 'block', reason: 'Daily budget reached' },
47
+ ],
48
+ systemInstructions: 'Assemble claim evidence from provided records. Cite source IDs and keep disputed facts separate from verified records.',
49
+ },
50
+ 'agent-support': {
51
+ id: 'agent-support-v1',
52
+ slug: 'agent-support',
53
+ label: 'Agent support workflow',
54
+ requiredCapability: 'data_write',
55
+ primaryModel: 'openai/gpt-4o-mini',
56
+ fallbackModel: 'google/gemini-3-flash-preview',
57
+ allowedModels: ['openai/gpt-4o-mini', 'google/gemini-3-flash-preview'],
58
+ caps: [
59
+ { amountCents: 25, window: 'per_call', action: 'downgrade', downgradeTo: 'google/gemini-3-flash-preview', reason: 'Per-call budget reached, routing to fallback model' },
60
+ { amountCents: 10000, window: 'per_day', action: 'block', reason: 'Daily budget reached' },
61
+ ],
62
+ systemInstructions: 'Draft support replies and update allowed fields only after policy checks. Escalate billing, payment, and identity changes.',
63
+ },
64
+ 'code-scan': {
65
+ id: 'code-scan-v1',
66
+ slug: 'code-scan',
67
+ label: 'Code scan agent',
68
+ requiredCapability: 'read_only',
69
+ primaryModel: 'google/gemini-3-flash-preview',
70
+ fallbackModel: 'openai/gpt-4o-mini',
71
+ allowedModels: ['google/gemini-3-flash-preview', 'openai/gpt-4o-mini'],
72
+ caps: [
73
+ { amountCents: 10, window: 'per_call', action: 'downgrade', downgradeTo: 'openai/gpt-4o-mini', reason: 'Per-call budget reached, routing to fallback model' },
74
+ { amountCents: 3000, window: 'per_day', action: 'block', reason: 'Daily budget reached' },
75
+ ],
76
+ systemInstructions: 'Scan code for spend, audit, and integration risks. Return findings with file paths and minimal fix guidance.',
77
+ },
78
+ };
79
+ function listTaskTemplates() {
80
+ return Object.values(exports.TASK_TEMPLATES);
81
+ }
82
+ function getTaskTemplate(slug) {
83
+ return exports.TASK_TEMPLATES[slug] ?? null;
84
+ }
85
+ function policyFromTemplate(slug, tenantId = 'my-tenant') {
86
+ const template = getTaskTemplate(slug);
87
+ if (!template)
88
+ return null;
89
+ return {
90
+ id: template.id,
91
+ name: template.label,
92
+ scope: { tenantId },
93
+ caps: template.caps.map((cap) => ({ ...cap })),
94
+ mode: 'enforce',
95
+ requiredCapability: template.requiredCapability,
96
+ version: 1,
97
+ effectiveFrom: new Date().toISOString(),
98
+ };
99
+ }
100
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -123,13 +123,28 @@ export interface SpendDecision {
123
123
  modelRequested: string;
124
124
  /** Model actually used (differs from modelRequested on downgrade) */
125
125
  modelResolved: string;
126
- /** Policy ID and version this decision was made under */
126
+ /** Policy ID and version this decision was made under. */
127
127
  policyId: string;
128
128
  policyVersion: number;
129
- /** Enforcement mode in effect at the time of the decision */
129
+ /** Enforcement mode in effect at the time of the decision. */
130
130
  enforcementMode: EnforcementMode;
131
- /** Human-readable reasons */
131
+ /** Human-readable reasons. */
132
132
  reasons: string[];
133
+ /** Entry kind. Defaults to a provider enforcement decision. */
134
+ entryType?: 'decision' | 'settlement';
135
+ /** Original enforcement decision settled by this entry. */
136
+ originalDecisionId?: string;
137
+ /** Estimated tokens used for the initial reservation. */
138
+ estimatedInputTokens?: number;
139
+ estimatedOutputTokens?: number;
140
+ /** Actual tokens observed after provider completion or stream close. */
141
+ actualInputTokens?: number;
142
+ actualOutputTokens?: number;
143
+ /** Actual cents and true-up delta for settlement entries. */
144
+ actualCents?: number;
145
+ deltaCents?: number;
146
+ /** True when the stream ended before a provider completion event. */
147
+ partial?: boolean;
133
148
  }
134
149
  /**
135
150
  * A signed, hash-chained decision log entry.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentguard-run/spend",
3
- "version": "0.2.2",
3
+ "version": "0.4.0",
4
4
  "description": "Local-runtime spend caps and capability-gated model routing for AI agents. Prompts, API keys, and signing keys stay inside the customer runtime. Zero data plane involvement.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -19,6 +19,31 @@
19
19
  "types": "./dist/decision-log.d.ts",
20
20
  "require": "./dist/decision-log.js",
21
21
  "default": "./dist/decision-log.js"
22
+ },
23
+ "./bindings/anthropic": {
24
+ "types": "./dist/bindings/anthropic.d.ts",
25
+ "require": "./dist/bindings/anthropic.js",
26
+ "default": "./dist/bindings/anthropic.js"
27
+ },
28
+ "./bindings/bedrock": {
29
+ "types": "./dist/bindings/bedrock.d.ts",
30
+ "require": "./dist/bindings/bedrock.js",
31
+ "default": "./dist/bindings/bedrock.js"
32
+ },
33
+ "./openrouter-catalog": {
34
+ "types": "./dist/openrouter-catalog.d.ts",
35
+ "require": "./dist/openrouter-catalog.js",
36
+ "default": "./dist/openrouter-catalog.js"
37
+ },
38
+ "./templates": {
39
+ "types": "./dist/templates/index.d.ts",
40
+ "require": "./dist/templates/index.js",
41
+ "default": "./dist/templates/index.js"
42
+ },
43
+ "./coach": {
44
+ "types": "./dist/coach/conversation.d.ts",
45
+ "require": "./dist/coach/conversation.js",
46
+ "default": "./dist/coach/conversation.js"
22
47
  }
23
48
  },
24
49
  "bin": {
@@ -30,13 +55,23 @@
30
55
  "README.md",
31
56
  "LICENSE",
32
57
  "PATENTS.md",
33
- "CHANGELOG.md"
58
+ "CHANGELOG.md",
59
+ "src/templates",
60
+ "src/openrouter-catalog.ts",
61
+ "tests/fixtures/openrouter-catalog.json",
62
+ "src/cli/auth.ts",
63
+ "src/cli/models.ts",
64
+ "src/cli/tips.ts",
65
+ "src/cli/wizard.ts",
66
+ "src/bindings",
67
+ "src/coach",
68
+ "src/cli/coach.ts"
34
69
  ],
35
70
  "scripts": {
36
71
  "build": "tsc",
37
72
  "prepublishOnly": "npm run build",
38
- "clean": "rm -rf dist",
39
- "test": "node --test dist/**/*.test.js",
73
+ "clean": "rm -rf dist dist-test",
74
+ "test": "AGENTGUARD_HOME=./dist-test/home tsc -p tsconfig.test.json && rm -rf dist-test/home && AGENTGUARD_HOME=./dist-test/home node --test dist-test/**/*.test.js",
40
75
  "verify": "node dist/verify-test-vector.js"
41
76
  },
42
77
  "keywords": [
@@ -0,0 +1,142 @@
1
+ /** Native Anthropic binding for AgentGuard Spend. */
2
+
3
+ import type { CapabilityTier, CallContext, Provider, SpendPolicy, SpendScope } from '../types';
4
+ import {
5
+ AgentGuardBlockedError,
6
+ SpendGuard,
7
+ type SpendGuardConfig,
8
+ extractText,
9
+ outputTokensFromParams,
10
+ usageCountsFromObject,
11
+ wrapUsageStream,
12
+ type UsageCounts,
13
+ } from '../spend-guard';
14
+
15
+ export interface AnthropicBindingOptions {
16
+ policy: SpendPolicy;
17
+ scope: SpendScope;
18
+ capabilityClaim?: CapabilityTier;
19
+ config?: Omit<SpendGuardConfig, 'policy'>;
20
+ }
21
+
22
+ export function withSpendGuardAnthropic(
23
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
24
+ client: any,
25
+ opts: AnthropicBindingOptions,
26
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
27
+ ): any {
28
+ const guard = new SpendGuard({ policy: opts.policy, ...(opts.config ?? {}) });
29
+ const originalCreate = client?.messages?.create?.bind(client.messages);
30
+ if (!originalCreate) throw new Error('withSpendGuardAnthropic: expected client.messages.create');
31
+
32
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
33
+ client.messages.create = async (params: any) => {
34
+ const call = buildAnthropicCall(params, guard, opts);
35
+ const { decision } = await guard.decide(call);
36
+ if (decision.action === 'block') throw new AgentGuardBlockedError(decision, opts.scope, opts.config?.locale);
37
+
38
+ const nextParams = decision.action === 'downgrade' && decision.modelResolved !== decision.modelRequested
39
+ ? { ...params, model: decision.modelResolved }
40
+ : params;
41
+
42
+ const response = await originalCreate(nextParams);
43
+ if (nextParams?.stream === true || isAsyncIterable(response)) {
44
+ return wrapAnthropicStream(response, guard, decision.decisionId, call);
45
+ }
46
+ const usage = usageCountsFromObject((response as { usage?: unknown } | null)?.usage);
47
+ if (usage) await guard.settleStreamUsage(decision.decisionId, usage.inputTokens, usage.outputTokens);
48
+ return response;
49
+ };
50
+
51
+ const originalStream = client?.messages?.stream?.bind(client.messages);
52
+ if (originalStream) {
53
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
54
+ client.messages.stream = async (params: any) => {
55
+ const call = buildAnthropicCall({ ...params, stream: true }, guard, opts);
56
+ const { decision } = await guard.decide(call);
57
+ if (decision.action === 'block') throw new AgentGuardBlockedError(decision, opts.scope, opts.config?.locale);
58
+ const nextParams = decision.action === 'downgrade' && decision.modelResolved !== decision.modelRequested
59
+ ? { ...params, model: decision.modelResolved }
60
+ : params;
61
+ const stream = await originalStream(nextParams);
62
+ return wrapAnthropicStream(stream, guard, decision.decisionId, call);
63
+ };
64
+ }
65
+
66
+ client.__agentguard = guard;
67
+ return client;
68
+ }
69
+
70
+ function buildAnthropicCall(
71
+ params: Record<string, unknown>,
72
+ guard: SpendGuard,
73
+ opts: AnthropicBindingOptions,
74
+ ): CallContext {
75
+ const inputText = [extractText(params.system), extractText(params.messages)].filter(Boolean).join('\n');
76
+ return {
77
+ provider: 'anthropic' as Provider,
78
+ model: String(params.model ?? 'unknown'),
79
+ inputTokens: guard.estimateTokens(inputText),
80
+ outputTokens: outputTokensFromParams(params),
81
+ scope: opts.scope,
82
+ capabilityClaim: opts.capabilityClaim,
83
+ };
84
+ }
85
+
86
+ function wrapAnthropicStream(
87
+ stream: AsyncIterable<unknown>,
88
+ guard: SpendGuard,
89
+ decisionId: string,
90
+ call: CallContext,
91
+ ): AsyncIterable<unknown> {
92
+ const tracker = new AnthropicStreamUsageTracker(guard, call);
93
+ return wrapUsageStream(stream, {
94
+ onChunk: (chunk) => tracker.observe(chunk),
95
+ settle: (partial, reason) => {
96
+ const usage = tracker.usage();
97
+ return guard.settleStreamUsage(decisionId, usage.inputTokens, usage.outputTokens, { partial, reason });
98
+ },
99
+ });
100
+ }
101
+
102
+ class AnthropicStreamUsageTracker {
103
+ private input: number | null = null;
104
+ private output: number | null = null;
105
+ private content = '';
106
+
107
+ constructor(private guard: SpendGuard, private call: CallContext) {}
108
+
109
+ observe(event: unknown): void {
110
+ const obj = event as Record<string, unknown> | null;
111
+ const startUsage = ((obj?.message as Record<string, unknown> | undefined)?.usage ?? obj?.usage) as unknown;
112
+ const input = tokenField(startUsage, ['input_tokens', 'inputTokens', 'prompt_tokens']);
113
+ const output = tokenField(startUsage, ['output_tokens', 'outputTokens', 'completion_tokens']);
114
+ if (input !== null) this.input = input;
115
+ if (output !== null) this.output = output;
116
+
117
+ const delta = obj?.delta as Record<string, unknown> | undefined;
118
+ if (typeof delta?.text === 'string') this.content += delta.text;
119
+ if (typeof delta?.partial_json === 'string') this.content += delta.partial_json;
120
+ }
121
+
122
+ usage(): UsageCounts {
123
+ return {
124
+ inputTokens: this.input ?? this.call.inputTokens,
125
+ outputTokens: this.output ?? this.guard.estimateTokens(this.content),
126
+ };
127
+ }
128
+ }
129
+
130
+ function tokenField(value: unknown, names: string[]): number | null {
131
+ if (!value || typeof value !== 'object') return null;
132
+ const obj = value as Record<string, unknown>;
133
+ for (const name of names) {
134
+ const token = obj[name];
135
+ if (Number.isSafeInteger(token) && (token as number) >= 0) return token as number;
136
+ }
137
+ return null;
138
+ }
139
+
140
+ function isAsyncIterable(value: unknown): value is AsyncIterable<unknown> {
141
+ return Boolean(value && typeof (value as { [Symbol.asyncIterator]?: unknown })[Symbol.asyncIterator] === 'function');
142
+ }