podwatch 1.1.0 → 1.1.1

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.
@@ -1,20 +1,15 @@
1
1
  /**
2
- * Budget hard stop hooks — before_model_resolve and before_prompt_build.
2
+ * Budget hard stop hooks — before_prompt_build + before_tool_call.
3
3
  *
4
4
  * When the server signals a hard stop (budget exceeded + hard stop enabled),
5
5
  * these hooks:
6
- * 1. Try to downgrade to a cheaper model (best-effort)
7
- * 2. Prepend context telling the LLM to inform the user about the budget limit
6
+ * 1. Prepend context telling the LLM to inform the user about the budget limit
7
+ * 2. Block all tool calls (via before_tool_call in security.ts)
8
+ *
9
+ * No model downgrade — we can't know what providers the user has configured,
10
+ * so forcing a "cheaper" model would break setups with a single provider.
8
11
  */
9
12
  import type { PodwatchConfig } from "../index.js";
10
13
  import type { PluginApi } from "../types.js";
11
- /**
12
- * Find the cheapest available model from the gateway config.
13
- * Returns { model, provider } or null if only one model is configured.
14
- */
15
- export declare function findCheapestModel(config: Record<string, unknown>): {
16
- model: string;
17
- provider: string;
18
- } | null;
19
14
  export declare function registerBudgetHooks(api: PluginApi, config: PodwatchConfig): void;
20
15
  //# sourceMappingURL=budget.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"budget.d.ts","sourceRoot":"","sources":["../../src/hooks/budget.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AA6B7C;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA0D5C;AAMD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CA6ChF"}
1
+ {"version":3,"file":"budget.d.ts","sourceRoot":"","sources":["../../src/hooks/budget.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAO7C,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CAuBhF"}
@@ -1,119 +1,22 @@
1
1
  "use strict";
2
2
  /**
3
- * Budget hard stop hooks — before_model_resolve and before_prompt_build.
3
+ * Budget hard stop hooks — before_prompt_build + before_tool_call.
4
4
  *
5
5
  * When the server signals a hard stop (budget exceeded + hard stop enabled),
6
6
  * these hooks:
7
- * 1. Try to downgrade to a cheaper model (best-effort)
8
- * 2. Prepend context telling the LLM to inform the user about the budget limit
7
+ * 1. Prepend context telling the LLM to inform the user about the budget limit
8
+ * 2. Block all tool calls (via before_tool_call in security.ts)
9
+ *
10
+ * No model downgrade — we can't know what providers the user has configured,
11
+ * so forcing a "cheaper" model would break setups with a single provider.
9
12
  */
10
13
  Object.defineProperty(exports, "__esModule", { value: true });
11
- exports.findCheapestModel = findCheapestModel;
12
14
  exports.registerBudgetHooks = registerBudgetHooks;
13
15
  const transmitter_js_1 = require("../transmitter.js");
14
16
  // ---------------------------------------------------------------------------
15
- // Model cost heuristic — cheaper models first
16
- // ---------------------------------------------------------------------------
17
- /** Known cheap model patterns (ordered cheapest first). */
18
- const CHEAP_MODEL_PATTERNS = [
19
- "haiku",
20
- "flash",
21
- "mini",
22
- "nano",
23
- "lite",
24
- "sonnet",
25
- ];
26
- /**
27
- * Score a model name by cost (lower = cheaper).
28
- * Known cheap patterns get low scores, unknown models get a high default.
29
- */
30
- function modelCostScore(modelName) {
31
- const lower = modelName.toLowerCase();
32
- for (let i = 0; i < CHEAP_MODEL_PATTERNS.length; i++) {
33
- if (lower.includes(CHEAP_MODEL_PATTERNS[i]))
34
- return i;
35
- }
36
- return 100; // unknown = expensive
37
- }
38
- /**
39
- * Find the cheapest available model from the gateway config.
40
- * Returns { model, provider } or null if only one model is configured.
41
- */
42
- function findCheapestModel(config) {
43
- const candidates = [];
44
- // Check models.providers for available models
45
- const providers = config?.models?.providers;
46
- if (providers && typeof providers === "object") {
47
- for (const [providerName, providerCfg] of Object.entries(providers)) {
48
- const cfg = providerCfg;
49
- const models = cfg.models;
50
- if (Array.isArray(models)) {
51
- for (const m of models) {
52
- if (typeof m === "string") {
53
- candidates.push({
54
- model: `${providerName}/${m}`,
55
- provider: providerName,
56
- score: modelCostScore(m),
57
- });
58
- }
59
- }
60
- }
61
- }
62
- }
63
- // Also check agents.defaults.models for configured model aliases
64
- const agentModels = config?.agents?.defaults?.models;
65
- if (agentModels && typeof agentModels === "object") {
66
- for (const modelId of Object.keys(agentModels)) {
67
- if (typeof modelId === "string") {
68
- const parts = modelId.split("/");
69
- const modelName = parts[parts.length - 1] ?? modelId;
70
- const provider = parts.length > 1 ? parts[0] : "";
71
- candidates.push({
72
- model: modelId,
73
- provider,
74
- score: modelCostScore(modelName),
75
- });
76
- }
77
- }
78
- }
79
- // Deduplicate by model name
80
- const seen = new Set();
81
- const unique = candidates.filter((c) => {
82
- if (seen.has(c.model))
83
- return false;
84
- seen.add(c.model);
85
- return true;
86
- });
87
- if (unique.length <= 1)
88
- return null;
89
- // Sort by score (cheapest first) and pick the cheapest
90
- unique.sort((a, b) => a.score - b.score);
91
- // Get the current primary model to avoid returning the same one
92
- const primaryModel = config?.agents?.defaults?.model?.primary;
93
- const cheapest = unique.find((c) => c.model !== primaryModel) ?? unique[0];
94
- return { model: cheapest.model, provider: cheapest.provider };
95
- }
96
- // ---------------------------------------------------------------------------
97
17
  // Hook registration
98
18
  // ---------------------------------------------------------------------------
99
19
  function registerBudgetHooks(api, config) {
100
- // -----------------------------------------------------------------------
101
- // before_model_resolve — downgrade to cheaper model on hard stop
102
- // -----------------------------------------------------------------------
103
- api.registerHook("before_model_resolve", async () => {
104
- if (!config.enableBudgetEnforcement)
105
- return;
106
- const budget = transmitter_js_1.transmitter.getCachedBudget();
107
- if (!budget?.hardStopActive)
108
- return;
109
- const cheaper = findCheapestModel(api.config);
110
- if (!cheaper)
111
- return; // only one model configured, skip
112
- return {
113
- modelOverride: cheaper.model,
114
- providerOverride: cheaper.provider,
115
- };
116
- }, { name: "podwatch-budget-model-resolve" });
117
20
  // -----------------------------------------------------------------------
118
21
  // before_prompt_build — inject budget warning into prompt
119
22
  // -----------------------------------------------------------------------
@@ -1 +1 @@
1
- {"version":3,"file":"budget.js","sourceRoot":"","sources":["../../src/hooks/budget.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"budget.js","sourceRoot":"","sources":["../../src/hooks/budget.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;AAUH,kDAuBC;AA7BD,sDAAgD;AAEhD,8EAA8E;AAC9E,oBAAoB;AACpB,8EAA8E;AAE9E,SAAgB,mBAAmB,CAAC,GAAc,EAAE,MAAsB;IACxE,0EAA0E;IAC1E,0DAA0D;IAC1D,0EAA0E;IAC1E,GAAG,CAAC,YAAY,CACd,qBAAqB,EACrB,KAAK,IAAiD,EAAE;QACtD,IAAI,CAAC,MAAM,CAAC,uBAAuB;YAAE,OAAO;QAE5C,MAAM,MAAM,GAAG,4BAAW,CAAC,eAAe,EAAE,CAAC;QAC7C,IAAI,CAAC,MAAM,EAAE,cAAc;YAAE,OAAO;QAEpC,OAAO;YACL,cAAc,EACZ,iEAAiE;gBACjE,4EAA4E;gBAC5E,+FAA+F;SAClG,CAAC;IACJ,CAAC,EACD,EAAE,IAAI,EAAE,8BAA8B,EAAE,CACzC,CAAC;IAEF,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;AAClE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "podwatch",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Security monitoring, cost tracking, and observability for AI agents",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",