govyn 0.0.1 → 0.2.5
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/LICENSE +21 -0
- package/README.md +263 -1
- package/configs/multi-provider.yaml +68 -0
- package/configs/openai-only.yaml +45 -0
- package/configs/team-setup.yaml +88 -0
- package/dist/action-logger.d.ts +128 -0
- package/dist/action-logger.js +356 -0
- package/dist/action-logger.js.map +1 -0
- package/dist/admin-cli.d.ts +2 -0
- package/dist/admin-cli.js +36 -0
- package/dist/admin-cli.js.map +1 -0
- package/dist/agents.d.ts +23 -0
- package/dist/agents.js +59 -0
- package/dist/agents.js.map +1 -0
- package/dist/alert-api.d.ts +14 -0
- package/dist/alert-api.js +355 -0
- package/dist/alert-api.js.map +1 -0
- package/dist/alert-manager.d.ts +77 -0
- package/dist/alert-manager.js +267 -0
- package/dist/alert-manager.js.map +1 -0
- package/dist/approval-api.d.ts +19 -0
- package/dist/approval-api.js +82 -0
- package/dist/approval-api.js.map +1 -0
- package/dist/approval-timeout.d.ts +29 -0
- package/dist/approval-timeout.js +45 -0
- package/dist/approval-timeout.js.map +1 -0
- package/dist/approval.d.ts +78 -0
- package/dist/approval.js +101 -0
- package/dist/approval.js.map +1 -0
- package/dist/auth.d.ts +47 -0
- package/dist/auth.js +335 -0
- package/dist/auth.js.map +1 -0
- package/dist/budget-api.d.ts +20 -0
- package/dist/budget-api.js +85 -0
- package/dist/budget-api.js.map +1 -0
- package/dist/budget-enforcer.d.ts +102 -0
- package/dist/budget-enforcer.js +294 -0
- package/dist/budget-enforcer.js.map +1 -0
- package/dist/cli.d.ts +15 -0
- package/dist/cli.js +200 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +15 -0
- package/dist/config.js +267 -0
- package/dist/config.js.map +1 -0
- package/dist/cost-aggregator.d.ts +69 -0
- package/dist/cost-aggregator.js +305 -0
- package/dist/cost-aggregator.js.map +1 -0
- package/dist/cost-api.d.ts +29 -0
- package/dist/cost-api.js +128 -0
- package/dist/cost-api.js.map +1 -0
- package/dist/database-url.d.ts +6 -0
- package/dist/database-url.js +47 -0
- package/dist/database-url.js.map +1 -0
- package/dist/db-retention.d.ts +53 -0
- package/dist/db-retention.js +82 -0
- package/dist/db-retention.js.map +1 -0
- package/dist/db-schema.d.ts +17 -0
- package/dist/db-schema.js +167 -0
- package/dist/db-schema.js.map +1 -0
- package/dist/db-writer.d.ts +55 -0
- package/dist/db-writer.js +115 -0
- package/dist/db-writer.js.map +1 -0
- package/dist/db.d.ts +33 -0
- package/dist/db.js +78 -0
- package/dist/db.js.map +1 -0
- package/dist/events.d.ts +77 -0
- package/dist/events.js +12 -0
- package/dist/events.js.map +1 -0
- package/dist/health.d.ts +14 -0
- package/dist/health.js +49 -0
- package/dist/health.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/init-wizard.d.ts +12 -0
- package/dist/init-wizard.js +206 -0
- package/dist/init-wizard.js.map +1 -0
- package/dist/log-api.d.ts +20 -0
- package/dist/log-api.js +371 -0
- package/dist/log-api.js.map +1 -0
- package/dist/log-rotator.d.ts +55 -0
- package/dist/log-rotator.js +157 -0
- package/dist/log-rotator.js.map +1 -0
- package/dist/loop-detector.d.ts +71 -0
- package/dist/loop-detector.js +122 -0
- package/dist/loop-detector.js.map +1 -0
- package/dist/persistence-types.d.ts +165 -0
- package/dist/persistence-types.js +2 -0
- package/dist/persistence-types.js.map +1 -0
- package/dist/persistence.d.ts +185 -0
- package/dist/persistence.js +785 -0
- package/dist/persistence.js.map +1 -0
- package/dist/policy-api.d.ts +25 -0
- package/dist/policy-api.js +347 -0
- package/dist/policy-api.js.map +1 -0
- package/dist/policy-engine.d.ts +76 -0
- package/dist/policy-engine.js +835 -0
- package/dist/policy-engine.js.map +1 -0
- package/dist/policy-file.d.ts +10 -0
- package/dist/policy-file.js +52 -0
- package/dist/policy-file.js.map +1 -0
- package/dist/policy-parser.d.ts +21 -0
- package/dist/policy-parser.js +560 -0
- package/dist/policy-parser.js.map +1 -0
- package/dist/policy-types.d.ts +216 -0
- package/dist/policy-types.js +8 -0
- package/dist/policy-types.js.map +1 -0
- package/dist/policy-watcher.d.ts +54 -0
- package/dist/policy-watcher.js +116 -0
- package/dist/policy-watcher.js.map +1 -0
- package/dist/pricing.d.ts +69 -0
- package/dist/pricing.js +93 -0
- package/dist/pricing.js.map +1 -0
- package/dist/prompt.d.ts +6 -0
- package/dist/prompt.js +47 -0
- package/dist/prompt.js.map +1 -0
- package/dist/providers/anthropic.d.ts +18 -0
- package/dist/providers/anthropic.js +61 -0
- package/dist/providers/anthropic.js.map +1 -0
- package/dist/providers/custom.d.ts +19 -0
- package/dist/providers/custom.js +54 -0
- package/dist/providers/custom.js.map +1 -0
- package/dist/providers/openai.d.ts +17 -0
- package/dist/providers/openai.js +48 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/proxy.d.ts +57 -0
- package/dist/proxy.js +477 -0
- package/dist/proxy.js.map +1 -0
- package/dist/router.d.ts +23 -0
- package/dist/router.js +89 -0
- package/dist/router.js.map +1 -0
- package/dist/runtime.d.ts +1 -0
- package/dist/runtime.js +139 -0
- package/dist/runtime.js.map +1 -0
- package/dist/security.d.ts +64 -0
- package/dist/security.js +422 -0
- package/dist/security.js.map +1 -0
- package/dist/server.d.ts +33 -0
- package/dist/server.js +1147 -0
- package/dist/server.js.map +1 -0
- package/dist/sqlite-schema.d.ts +6 -0
- package/dist/sqlite-schema.js +134 -0
- package/dist/sqlite-schema.js.map +1 -0
- package/dist/streaming.d.ts +24 -0
- package/dist/streaming.js +63 -0
- package/dist/streaming.js.map +1 -0
- package/dist/tokens.d.ts +45 -0
- package/dist/tokens.js +237 -0
- package/dist/tokens.js.map +1 -0
- package/dist/types.d.ts +344 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +66 -2
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Policy type definitions for the Govyn policy engine.
|
|
3
|
+
*
|
|
4
|
+
* These types define the schema for YAML policy files and the
|
|
5
|
+
* results of parsing/validating them.
|
|
6
|
+
*/
|
|
7
|
+
/** The seven policy types supported by Govyn (Phase 6 defines skeletons; Phase 7 adds evaluators; Phase 10 adds require_approval) */
|
|
8
|
+
export type PolicyType = 'block' | 'rate_limit' | 'budget_limit' | 'content_filter' | 'time_window' | 'model_route' | 'require_approval';
|
|
9
|
+
/** Policy scope — determines which requests a policy applies to */
|
|
10
|
+
export interface PolicyScope {
|
|
11
|
+
/** 'global' applies to all requests; 'agent' scopes to a specific agent; 'target' scopes to a provider */
|
|
12
|
+
level: 'global' | 'agent' | 'target';
|
|
13
|
+
/** The agent name (when level='agent') or target provider (when level='target'), undefined for global */
|
|
14
|
+
value?: string;
|
|
15
|
+
}
|
|
16
|
+
/** Base fields shared by all policy definitions */
|
|
17
|
+
export interface PolicyBase {
|
|
18
|
+
/** Unique policy name (must be unique across all loaded policies) */
|
|
19
|
+
name: string;
|
|
20
|
+
/** Human-readable description of what this policy does */
|
|
21
|
+
description?: string;
|
|
22
|
+
/** Whether this policy is active (default: true) */
|
|
23
|
+
enabled: boolean;
|
|
24
|
+
/** The type of policy rule */
|
|
25
|
+
type: PolicyType;
|
|
26
|
+
/** Scoping: who/what this policy applies to */
|
|
27
|
+
scope: PolicyScope;
|
|
28
|
+
}
|
|
29
|
+
/** Block policy — denies requests matching configured criteria with AND logic */
|
|
30
|
+
export interface BlockPolicy extends PolicyBase {
|
|
31
|
+
type: 'block';
|
|
32
|
+
match?: {
|
|
33
|
+
body?: string;
|
|
34
|
+
headers?: Record<string, string>;
|
|
35
|
+
provider?: string;
|
|
36
|
+
path?: string;
|
|
37
|
+
model?: string;
|
|
38
|
+
action_type?: string;
|
|
39
|
+
regex?: boolean;
|
|
40
|
+
};
|
|
41
|
+
message?: string;
|
|
42
|
+
}
|
|
43
|
+
/** Rate limit policy — throttles requests per sliding window */
|
|
44
|
+
export interface RateLimitPolicy extends PolicyBase {
|
|
45
|
+
type: 'rate_limit';
|
|
46
|
+
limit: number;
|
|
47
|
+
window_seconds: number;
|
|
48
|
+
}
|
|
49
|
+
/** Budget limit policy — enforces spending limits per period */
|
|
50
|
+
export interface BudgetLimitPolicy extends PolicyBase {
|
|
51
|
+
type: 'budget_limit';
|
|
52
|
+
limit: number;
|
|
53
|
+
period: 'daily' | 'weekly' | 'monthly';
|
|
54
|
+
}
|
|
55
|
+
/** Content filter policy — scans request body JSON string values for PII and custom patterns */
|
|
56
|
+
export interface ContentFilterPolicy extends PolicyBase {
|
|
57
|
+
type: 'content_filter';
|
|
58
|
+
patterns: string[];
|
|
59
|
+
reveal_pattern?: boolean;
|
|
60
|
+
}
|
|
61
|
+
/** Time window policy — schedule-based access control with timezone support */
|
|
62
|
+
export interface TimeWindowPolicy extends PolicyBase {
|
|
63
|
+
type: 'time_window';
|
|
64
|
+
start: string;
|
|
65
|
+
end: string;
|
|
66
|
+
days: string[];
|
|
67
|
+
timezone: string;
|
|
68
|
+
mode: 'allow' | 'deny';
|
|
69
|
+
}
|
|
70
|
+
/** A single routing rule with criteria and target model */
|
|
71
|
+
export interface ModelRoutingRule {
|
|
72
|
+
when?: {
|
|
73
|
+
input_tokens_estimate?: string;
|
|
74
|
+
system_prompt_contains?: string[];
|
|
75
|
+
no_system_prompt_contains?: string[];
|
|
76
|
+
user_prompt_contains?: string[];
|
|
77
|
+
no_user_prompt_contains?: string[];
|
|
78
|
+
agent?: string;
|
|
79
|
+
time_of_day?: string;
|
|
80
|
+
tool_calls_present?: boolean;
|
|
81
|
+
conversation_turns?: string;
|
|
82
|
+
provider?: string;
|
|
83
|
+
};
|
|
84
|
+
route_to: string;
|
|
85
|
+
default?: 'passthrough';
|
|
86
|
+
}
|
|
87
|
+
/** Model route policy — smart model routing per ADR-021 */
|
|
88
|
+
export interface ModelRoutePolicy extends PolicyBase {
|
|
89
|
+
type: 'model_route';
|
|
90
|
+
rules: ModelRoutingRule[];
|
|
91
|
+
model_aliases?: Record<string, string>;
|
|
92
|
+
max_downgrade_level?: string;
|
|
93
|
+
routing_opt_out_agents?: string[];
|
|
94
|
+
}
|
|
95
|
+
/** Require approval policy — flags matching requests for human approval before forwarding */
|
|
96
|
+
export interface RequireApprovalPolicy extends PolicyBase {
|
|
97
|
+
type: 'require_approval';
|
|
98
|
+
match?: {
|
|
99
|
+
provider?: string;
|
|
100
|
+
model?: string;
|
|
101
|
+
action_type?: string;
|
|
102
|
+
path?: string;
|
|
103
|
+
regex?: boolean;
|
|
104
|
+
};
|
|
105
|
+
timeout_seconds?: number;
|
|
106
|
+
store_payload?: boolean;
|
|
107
|
+
message?: string;
|
|
108
|
+
}
|
|
109
|
+
/** Union type of all policy variants */
|
|
110
|
+
export type Policy = BlockPolicy | RateLimitPolicy | BudgetLimitPolicy | ContentFilterPolicy | TimeWindowPolicy | ModelRoutePolicy | RequireApprovalPolicy;
|
|
111
|
+
/** Context about the current request, passed to the engine for evaluation */
|
|
112
|
+
export interface PolicyRequestContext {
|
|
113
|
+
/** The agent making the request */
|
|
114
|
+
agentId: string;
|
|
115
|
+
/** The target provider (e.g., 'openai', 'anthropic') */
|
|
116
|
+
provider: string;
|
|
117
|
+
/** The upstream path being requested */
|
|
118
|
+
path: string;
|
|
119
|
+
/** HTTP method */
|
|
120
|
+
method: string;
|
|
121
|
+
/** Model name from the request (for block matching on model) */
|
|
122
|
+
model?: string;
|
|
123
|
+
/** Request body as string (for content matching) */
|
|
124
|
+
body?: string;
|
|
125
|
+
/** Request headers (for header matching) */
|
|
126
|
+
headers?: Record<string, string>;
|
|
127
|
+
/** Estimated input token count (for model routing criteria) */
|
|
128
|
+
inputTokensEstimate?: number;
|
|
129
|
+
/** Whether tool/function definitions are present in the request */
|
|
130
|
+
toolCallsPresent?: boolean;
|
|
131
|
+
/** Number of conversation turns (messages) in the request */
|
|
132
|
+
conversationTurns?: number;
|
|
133
|
+
/** System prompt content (for keyword matching) */
|
|
134
|
+
systemPrompt?: string;
|
|
135
|
+
/** User message content (for keyword matching) */
|
|
136
|
+
userPrompt?: string;
|
|
137
|
+
}
|
|
138
|
+
/** Result of evaluating a single policy against a request */
|
|
139
|
+
export interface SinglePolicyResult {
|
|
140
|
+
/** The policy that was evaluated */
|
|
141
|
+
policyName: string;
|
|
142
|
+
/** The policy type */
|
|
143
|
+
policyType: PolicyType;
|
|
144
|
+
/** Whether this policy allows the request */
|
|
145
|
+
allowed: boolean;
|
|
146
|
+
/** Reason for denial (if blocked) */
|
|
147
|
+
reason?: string;
|
|
148
|
+
/** The deny message from the policy (if any) */
|
|
149
|
+
message?: string;
|
|
150
|
+
/** For rate_limit type — seconds until retry is allowed */
|
|
151
|
+
retryAfterSeconds?: number;
|
|
152
|
+
}
|
|
153
|
+
/** Result extension for model_route evaluations */
|
|
154
|
+
export interface ModelRouteResult extends SinglePolicyResult {
|
|
155
|
+
policyType: 'model_route';
|
|
156
|
+
/** The model to route to (undefined = passthrough, no rewrite) */
|
|
157
|
+
routeTo?: string;
|
|
158
|
+
/** The original model requested by the agent */
|
|
159
|
+
requestedModel?: string;
|
|
160
|
+
/** The rule index that matched (for logging) */
|
|
161
|
+
matchedRuleIndex?: number;
|
|
162
|
+
}
|
|
163
|
+
/** Result extension for require_approval evaluations */
|
|
164
|
+
export interface ApprovalPolicyResult extends SinglePolicyResult {
|
|
165
|
+
policyType: 'require_approval';
|
|
166
|
+
/** Whether this request requires human approval */
|
|
167
|
+
requiresApproval: true;
|
|
168
|
+
/** Timeout in seconds before auto-deny */
|
|
169
|
+
timeoutSeconds: number;
|
|
170
|
+
/** Whether to store the full request payload */
|
|
171
|
+
storePayload: boolean;
|
|
172
|
+
}
|
|
173
|
+
/** Aggregate result of evaluating all matching policies */
|
|
174
|
+
export interface PolicyEvaluationResult {
|
|
175
|
+
/** Whether the request is allowed (true only if ALL matching policies allow) */
|
|
176
|
+
allowed: boolean;
|
|
177
|
+
/** Number of policies that were evaluated */
|
|
178
|
+
evaluatedCount: number;
|
|
179
|
+
/** Number of policies that matched the request scope */
|
|
180
|
+
matchedCount: number;
|
|
181
|
+
/** If denied, the first denying policy result (most-restrictive-wins) */
|
|
182
|
+
denied?: SinglePolicyResult;
|
|
183
|
+
/** All individual policy results */
|
|
184
|
+
results: SinglePolicyResult[];
|
|
185
|
+
/** Time taken for evaluation in milliseconds */
|
|
186
|
+
evaluationTimeMs: number;
|
|
187
|
+
}
|
|
188
|
+
/** Top-level policy file structure */
|
|
189
|
+
export interface PolicyFile {
|
|
190
|
+
/** Schema version — must be 1 per ADR-018 */
|
|
191
|
+
version: number;
|
|
192
|
+
/** Array of policy definitions */
|
|
193
|
+
policies: Policy[];
|
|
194
|
+
}
|
|
195
|
+
/** A policy parse error with location information */
|
|
196
|
+
export interface PolicyParseError {
|
|
197
|
+
/** Human-readable error message */
|
|
198
|
+
message: string;
|
|
199
|
+
/** Line number in the YAML file (1-indexed), if available */
|
|
200
|
+
line?: number;
|
|
201
|
+
/** Column number (1-indexed), if available */
|
|
202
|
+
column?: number;
|
|
203
|
+
/** The policy name this error relates to, if applicable */
|
|
204
|
+
policyName?: string;
|
|
205
|
+
}
|
|
206
|
+
/** Result of parsing a policy file */
|
|
207
|
+
export interface PolicyParseResult {
|
|
208
|
+
/** Whether parsing succeeded without errors */
|
|
209
|
+
success: boolean;
|
|
210
|
+
/** Parsed policies (empty if success=false) */
|
|
211
|
+
policies: Policy[];
|
|
212
|
+
/** Validation errors (empty if success=true) */
|
|
213
|
+
errors: PolicyParseError[];
|
|
214
|
+
/** Non-fatal warnings */
|
|
215
|
+
warnings: PolicyParseError[];
|
|
216
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-types.js","sourceRoot":"","sources":["../src/policy-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PolicyWatcher — file-watch hot reload for policy YAML files.
|
|
3
|
+
*
|
|
4
|
+
* Watches a policy YAML file for changes using Node.js fs.watch() and
|
|
5
|
+
* reloads policies into the PolicyEngine on valid changes. Invalid
|
|
6
|
+
* changes are rejected with error logging, preserving previous policies.
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - Debounced file change detection (coalesces rapid saves)
|
|
10
|
+
* - Atomic reload via PolicyEngine.loadFromFile() (only replaces on success)
|
|
11
|
+
* - Event emission via govynEvents for observability
|
|
12
|
+
* - Clean start/stop lifecycle with no resource leaks
|
|
13
|
+
*/
|
|
14
|
+
import type { PolicyEngine } from './policy-engine.js';
|
|
15
|
+
export interface PolicyWatcherOptions {
|
|
16
|
+
/** Debounce interval in milliseconds (default: 200ms). */
|
|
17
|
+
debounceMs?: number;
|
|
18
|
+
}
|
|
19
|
+
export declare class PolicyWatcher {
|
|
20
|
+
private engine;
|
|
21
|
+
private filePath;
|
|
22
|
+
private debounceMs;
|
|
23
|
+
private watcher;
|
|
24
|
+
private debounceTimer;
|
|
25
|
+
constructor(engine: PolicyEngine, filePath: string, options?: PolicyWatcherOptions);
|
|
26
|
+
/**
|
|
27
|
+
* Begin watching the policy file for changes.
|
|
28
|
+
*
|
|
29
|
+
* Uses fs.watch() for event-driven, sub-second detection.
|
|
30
|
+
* Both 'change' and 'rename' events trigger reload (handles OS quirks
|
|
31
|
+
* where some editors fire 'rename' on save).
|
|
32
|
+
*/
|
|
33
|
+
start(): void;
|
|
34
|
+
/**
|
|
35
|
+
* Stop watching the file and clean up resources.
|
|
36
|
+
* Idempotent — safe to call multiple times.
|
|
37
|
+
*/
|
|
38
|
+
stop(): void;
|
|
39
|
+
/**
|
|
40
|
+
* Returns true if the watcher is currently active.
|
|
41
|
+
*/
|
|
42
|
+
isWatching(): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Schedule a debounced reload. Resets the timer on each call
|
|
45
|
+
* so that rapid file changes are coalesced into a single reload.
|
|
46
|
+
*/
|
|
47
|
+
private scheduleReload;
|
|
48
|
+
/**
|
|
49
|
+
* Perform the actual policy reload from the file.
|
|
50
|
+
* On success, emits policy_reloaded event.
|
|
51
|
+
* On failure, emits policy_reload_failed event and keeps previous policies.
|
|
52
|
+
*/
|
|
53
|
+
private reload;
|
|
54
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PolicyWatcher — file-watch hot reload for policy YAML files.
|
|
3
|
+
*
|
|
4
|
+
* Watches a policy YAML file for changes using Node.js fs.watch() and
|
|
5
|
+
* reloads policies into the PolicyEngine on valid changes. Invalid
|
|
6
|
+
* changes are rejected with error logging, preserving previous policies.
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - Debounced file change detection (coalesces rapid saves)
|
|
10
|
+
* - Atomic reload via PolicyEngine.loadFromFile() (only replaces on success)
|
|
11
|
+
* - Event emission via govynEvents for observability
|
|
12
|
+
* - Clean start/stop lifecycle with no resource leaks
|
|
13
|
+
*/
|
|
14
|
+
import * as fs from 'node:fs';
|
|
15
|
+
import { govynEvents } from './events.js';
|
|
16
|
+
export class PolicyWatcher {
|
|
17
|
+
engine;
|
|
18
|
+
filePath;
|
|
19
|
+
debounceMs;
|
|
20
|
+
watcher = null;
|
|
21
|
+
debounceTimer = null;
|
|
22
|
+
constructor(engine, filePath, options) {
|
|
23
|
+
this.engine = engine;
|
|
24
|
+
this.filePath = filePath;
|
|
25
|
+
this.debounceMs = options?.debounceMs ?? 200;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Begin watching the policy file for changes.
|
|
29
|
+
*
|
|
30
|
+
* Uses fs.watch() for event-driven, sub-second detection.
|
|
31
|
+
* Both 'change' and 'rename' events trigger reload (handles OS quirks
|
|
32
|
+
* where some editors fire 'rename' on save).
|
|
33
|
+
*/
|
|
34
|
+
start() {
|
|
35
|
+
if (this.watcher)
|
|
36
|
+
return; // Already watching
|
|
37
|
+
// Check file exists before starting watcher
|
|
38
|
+
if (!fs.existsSync(this.filePath)) {
|
|
39
|
+
console.log(`[govyn] Policy watcher: file not found, skipping watch: ${this.filePath}`);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
this.watcher = fs.watch(this.filePath, (_eventType) => {
|
|
44
|
+
// Treat both 'change' and 'rename' as triggers (OS quirk handling)
|
|
45
|
+
this.scheduleReload();
|
|
46
|
+
});
|
|
47
|
+
// Handle watcher errors gracefully (e.g., file deleted while watching)
|
|
48
|
+
this.watcher.on('error', (err) => {
|
|
49
|
+
console.error(`[govyn] Policy watcher error: ${err.message}`);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
54
|
+
console.error(`[govyn] Policy watcher failed to start: ${message}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Stop watching the file and clean up resources.
|
|
59
|
+
* Idempotent — safe to call multiple times.
|
|
60
|
+
*/
|
|
61
|
+
stop() {
|
|
62
|
+
if (this.debounceTimer !== null) {
|
|
63
|
+
clearTimeout(this.debounceTimer);
|
|
64
|
+
this.debounceTimer = null;
|
|
65
|
+
}
|
|
66
|
+
if (this.watcher) {
|
|
67
|
+
this.watcher.close();
|
|
68
|
+
this.watcher = null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Returns true if the watcher is currently active.
|
|
73
|
+
*/
|
|
74
|
+
isWatching() {
|
|
75
|
+
return this.watcher !== null;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Schedule a debounced reload. Resets the timer on each call
|
|
79
|
+
* so that rapid file changes are coalesced into a single reload.
|
|
80
|
+
*/
|
|
81
|
+
scheduleReload() {
|
|
82
|
+
if (this.debounceTimer !== null) {
|
|
83
|
+
clearTimeout(this.debounceTimer);
|
|
84
|
+
}
|
|
85
|
+
this.debounceTimer = setTimeout(() => {
|
|
86
|
+
this.debounceTimer = null;
|
|
87
|
+
this.reload();
|
|
88
|
+
}, this.debounceMs);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Perform the actual policy reload from the file.
|
|
92
|
+
* On success, emits policy_reloaded event.
|
|
93
|
+
* On failure, emits policy_reload_failed event and keeps previous policies.
|
|
94
|
+
*/
|
|
95
|
+
reload() {
|
|
96
|
+
const result = this.engine.loadFromFile(this.filePath);
|
|
97
|
+
if (result.success) {
|
|
98
|
+
console.log(`[govyn] Policy file reloaded: ${result.policies.length} policies loaded from ${this.filePath}`);
|
|
99
|
+
govynEvents.emit('event', {
|
|
100
|
+
type: 'policy_reloaded',
|
|
101
|
+
filePath: this.filePath,
|
|
102
|
+
policyCount: result.policies.length,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
const firstError = result.errors.length > 0 ? result.errors[0].message : 'Unknown error';
|
|
107
|
+
console.log(`[govyn] Policy reload failed (keeping previous policies): ${firstError}`);
|
|
108
|
+
govynEvents.emit('event', {
|
|
109
|
+
type: 'policy_reload_failed',
|
|
110
|
+
filePath: this.filePath,
|
|
111
|
+
error: firstError,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=policy-watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-watcher.js","sourceRoot":"","sources":["../src/policy-watcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pricing table and cost calculation engine for the Govyn proxy server.
|
|
3
|
+
*
|
|
4
|
+
* Provides built-in default pricing for major models, config overrides,
|
|
5
|
+
* and accurate cost calculation from token usage data.
|
|
6
|
+
*/
|
|
7
|
+
import type { TokenUsage } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Pricing configuration for a single model.
|
|
10
|
+
*/
|
|
11
|
+
export interface ModelPricing {
|
|
12
|
+
/** The model identifier */
|
|
13
|
+
model: string;
|
|
14
|
+
/** Price per 1,000,000 input tokens (USD) */
|
|
15
|
+
inputPricePerMillion: number;
|
|
16
|
+
/** Price per 1,000,000 output tokens (USD) */
|
|
17
|
+
outputPricePerMillion: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Pricing table: model name -> pricing configuration.
|
|
21
|
+
*/
|
|
22
|
+
export type PricingTable = Map<string, ModelPricing>;
|
|
23
|
+
/**
|
|
24
|
+
* Result of a cost calculation.
|
|
25
|
+
*/
|
|
26
|
+
export interface CostResult {
|
|
27
|
+
/** Cost for input tokens (USD) */
|
|
28
|
+
inputCost: number;
|
|
29
|
+
/** Cost for output tokens (USD) */
|
|
30
|
+
outputCost: number;
|
|
31
|
+
/** Total cost (inputCost + outputCost) in USD */
|
|
32
|
+
totalCost: number;
|
|
33
|
+
/** The model that was used */
|
|
34
|
+
model: string;
|
|
35
|
+
/** Whether the model was found in the pricing table */
|
|
36
|
+
priced: boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Returns the built-in default pricing table for major models.
|
|
40
|
+
*
|
|
41
|
+
* All prices are per 1,000,000 tokens in USD.
|
|
42
|
+
* Sources: Public pricing as of February 2026.
|
|
43
|
+
*/
|
|
44
|
+
export declare function getDefaultPricing(): PricingTable;
|
|
45
|
+
/**
|
|
46
|
+
* Load a pricing table, starting from built-in defaults and applying config overrides.
|
|
47
|
+
*
|
|
48
|
+
* Config prices override defaults for the same model name, allowing users to:
|
|
49
|
+
* - Override default pricing for known models
|
|
50
|
+
* - Add pricing for custom/private models
|
|
51
|
+
*
|
|
52
|
+
* @param configPricing - Optional pricing from YAML config (per-million-token pricing)
|
|
53
|
+
* @returns Complete pricing table with defaults and config overrides applied
|
|
54
|
+
*/
|
|
55
|
+
export declare function loadPricing(configPricing?: Record<string, {
|
|
56
|
+
input: number;
|
|
57
|
+
output: number;
|
|
58
|
+
}>): PricingTable;
|
|
59
|
+
/**
|
|
60
|
+
* Calculate the cost of a request from token usage and a pricing table.
|
|
61
|
+
*
|
|
62
|
+
* For known models: computes cost = (tokens / 1,000,000) * pricePerMillion
|
|
63
|
+
* For unknown models: logs a warning, returns totalCost 0 with priced = false
|
|
64
|
+
*
|
|
65
|
+
* @param usage - Token usage extracted from a provider response
|
|
66
|
+
* @param pricingTable - Pricing table (from loadPricing)
|
|
67
|
+
* @returns Cost result with breakdown and pricing status
|
|
68
|
+
*/
|
|
69
|
+
export declare function calculateCost(usage: TokenUsage, pricingTable: PricingTable): CostResult;
|
package/dist/pricing.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pricing table and cost calculation engine for the Govyn proxy server.
|
|
3
|
+
*
|
|
4
|
+
* Provides built-in default pricing for major models, config overrides,
|
|
5
|
+
* and accurate cost calculation from token usage data.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Returns the built-in default pricing table for major models.
|
|
9
|
+
*
|
|
10
|
+
* All prices are per 1,000,000 tokens in USD.
|
|
11
|
+
* Sources: Public pricing as of February 2026.
|
|
12
|
+
*/
|
|
13
|
+
export function getDefaultPricing() {
|
|
14
|
+
const table = new Map();
|
|
15
|
+
const defaults = [
|
|
16
|
+
// [model, inputPricePerMillion, outputPricePerMillion]
|
|
17
|
+
['gpt-4o', 2.50, 10.00],
|
|
18
|
+
['gpt-4o-mini', 0.15, 0.60],
|
|
19
|
+
['gpt-4.1', 2.00, 8.00],
|
|
20
|
+
['gpt-4.1-mini', 0.40, 1.60],
|
|
21
|
+
['gpt-4.1-nano', 0.10, 0.40],
|
|
22
|
+
['o3', 2.00, 8.00],
|
|
23
|
+
['o3-mini', 1.10, 4.40],
|
|
24
|
+
['o4-mini', 1.10, 4.40],
|
|
25
|
+
['claude-sonnet-4-20250514', 3.00, 15.00],
|
|
26
|
+
['claude-haiku-3-5-20241022', 0.80, 4.00],
|
|
27
|
+
['claude-opus-4-20250514', 15.00, 75.00],
|
|
28
|
+
];
|
|
29
|
+
for (const [model, inputPricePerMillion, outputPricePerMillion] of defaults) {
|
|
30
|
+
table.set(model, { model, inputPricePerMillion, outputPricePerMillion });
|
|
31
|
+
}
|
|
32
|
+
return table;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Load a pricing table, starting from built-in defaults and applying config overrides.
|
|
36
|
+
*
|
|
37
|
+
* Config prices override defaults for the same model name, allowing users to:
|
|
38
|
+
* - Override default pricing for known models
|
|
39
|
+
* - Add pricing for custom/private models
|
|
40
|
+
*
|
|
41
|
+
* @param configPricing - Optional pricing from YAML config (per-million-token pricing)
|
|
42
|
+
* @returns Complete pricing table with defaults and config overrides applied
|
|
43
|
+
*/
|
|
44
|
+
export function loadPricing(configPricing) {
|
|
45
|
+
const table = getDefaultPricing();
|
|
46
|
+
if (configPricing) {
|
|
47
|
+
for (const [model, prices] of Object.entries(configPricing)) {
|
|
48
|
+
if (typeof model !== 'string')
|
|
49
|
+
continue;
|
|
50
|
+
if (typeof prices?.input !== 'number' || typeof prices?.output !== 'number')
|
|
51
|
+
continue;
|
|
52
|
+
table.set(model, {
|
|
53
|
+
model,
|
|
54
|
+
inputPricePerMillion: prices.input,
|
|
55
|
+
outputPricePerMillion: prices.output,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return table;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Calculate the cost of a request from token usage and a pricing table.
|
|
63
|
+
*
|
|
64
|
+
* For known models: computes cost = (tokens / 1,000,000) * pricePerMillion
|
|
65
|
+
* For unknown models: logs a warning, returns totalCost 0 with priced = false
|
|
66
|
+
*
|
|
67
|
+
* @param usage - Token usage extracted from a provider response
|
|
68
|
+
* @param pricingTable - Pricing table (from loadPricing)
|
|
69
|
+
* @returns Cost result with breakdown and pricing status
|
|
70
|
+
*/
|
|
71
|
+
export function calculateCost(usage, pricingTable) {
|
|
72
|
+
const pricing = pricingTable.get(usage.model);
|
|
73
|
+
if (!pricing) {
|
|
74
|
+
console.warn(`[govyn] WARNING: Unknown model "${usage.model}" — cost marked as unpriced`);
|
|
75
|
+
return {
|
|
76
|
+
inputCost: 0,
|
|
77
|
+
outputCost: 0,
|
|
78
|
+
totalCost: 0,
|
|
79
|
+
model: usage.model,
|
|
80
|
+
priced: false,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
const inputCost = (usage.inputTokens / 1_000_000) * pricing.inputPricePerMillion;
|
|
84
|
+
const outputCost = (usage.outputTokens / 1_000_000) * pricing.outputPricePerMillion;
|
|
85
|
+
return {
|
|
86
|
+
inputCost,
|
|
87
|
+
outputCost,
|
|
88
|
+
totalCost: inputCost + outputCost,
|
|
89
|
+
model: usage.model,
|
|
90
|
+
priced: true,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=pricing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pricing.js","sourceRoot":"","sources":["../src/pricing.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAqCH;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,KAAK,GAAG,IAAI,GAAG,EAAwB,CAAC;IAE9C,MAAM,QAAQ,GAAoC;QAChD,uDAAuD;QACvD,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC;QACvB,CAAC,aAAa,EAAE,IAAI,EAAE,IAAI,CAAC;QAC3B,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC;QACvB,CAAC,cAAc,EAAE,IAAI,EAAE,IAAI,CAAC;QAC5B,CAAC,cAAc,EAAE,IAAI,EAAE,IAAI,CAAC;QAC5B,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;QAClB,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC;QACvB,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC;QACvB,CAAC,0BAA0B,EAAE,IAAI,EAAE,KAAK,CAAC;QACzC,CAAC,2BAA2B,EAAE,IAAI,EAAE,IAAI,CAAC;QACzC,CAAC,wBAAwB,EAAE,KAAK,EAAE,KAAK,CAAC;KACzC,CAAC;IAEF,KAAK,MAAM,CAAC,KAAK,EAAE,oBAAoB,EAAE,qBAAqB,CAAC,IAAI,QAAQ,EAAE,CAAC;QAC5E,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,CAAC,CAAC;IAC3E,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,WAAW,CACzB,aAAiE;IAEjE,MAAM,KAAK,GAAG,iBAAiB,EAAE,CAAC;IAElC,IAAI,aAAa,EAAE,CAAC;QAClB,KAAK,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;YAC5D,IAAI,OAAO,KAAK,KAAK,QAAQ;gBAAE,SAAS;YACxC,IAAI,OAAO,MAAM,EAAE,KAAK,KAAK,QAAQ,IAAI,OAAO,MAAM,EAAE,MAAM,KAAK,QAAQ;gBAAE,SAAS;YACtF,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE;gBACf,KAAK;gBACL,oBAAoB,EAAE,MAAM,CAAC,KAAK;gBAClC,qBAAqB,EAAE,MAAM,CAAC,MAAM;aACrC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAAC,KAAiB,EAAE,YAA0B;IACzE,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAE9C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,mCAAmC,KAAK,CAAC,KAAK,6BAA6B,CAAC,CAAC;QAC1F,OAAO;YACL,SAAS,EAAE,CAAC;YACZ,UAAU,EAAE,CAAC;YACb,SAAS,EAAE,CAAC;YACZ,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,MAAM,EAAE,KAAK;SACd,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,CAAC,KAAK,CAAC,WAAW,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,oBAAoB,CAAC;IACjF,MAAM,UAAU,GAAG,CAAC,KAAK,CAAC,YAAY,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAEpF,OAAO;QACL,SAAS;QACT,UAAU;QACV,SAAS,EAAE,SAAS,GAAG,UAAU;QACjC,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,MAAM,EAAE,IAAI;KACb,CAAC;AACJ,CAAC"}
|
package/dist/prompt.d.ts
ADDED
package/dist/prompt.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import * as readline from 'node:readline';
|
|
2
|
+
export function createPrompt() {
|
|
3
|
+
const output = process.stdout;
|
|
4
|
+
const rl = readline.createInterface({
|
|
5
|
+
input: process.stdin,
|
|
6
|
+
output,
|
|
7
|
+
terminal: true,
|
|
8
|
+
});
|
|
9
|
+
const originalWrite = rl._writeToOutput?.bind(rl) ??
|
|
10
|
+
((stringToWrite) => {
|
|
11
|
+
output.write(stringToWrite);
|
|
12
|
+
});
|
|
13
|
+
rl.stdoutMuted = false;
|
|
14
|
+
rl._writeToOutput = (stringToWrite) => {
|
|
15
|
+
if (!rl.stdoutMuted) {
|
|
16
|
+
originalWrite(stringToWrite);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
if (stringToWrite.includes('\n')) {
|
|
20
|
+
output.write('\n');
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
output.write('*');
|
|
24
|
+
};
|
|
25
|
+
function ask(question) {
|
|
26
|
+
return new Promise((resolve) => {
|
|
27
|
+
rl.question(question, (answer) => {
|
|
28
|
+
resolve(answer.trim());
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
function askHidden(question) {
|
|
33
|
+
return new Promise((resolve) => {
|
|
34
|
+
rl.stdoutMuted = true;
|
|
35
|
+
rl.question(question, (answer) => {
|
|
36
|
+
rl.stdoutMuted = false;
|
|
37
|
+
output.write('\n');
|
|
38
|
+
resolve(answer.trim());
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
function close() {
|
|
43
|
+
rl.close();
|
|
44
|
+
}
|
|
45
|
+
return { ask, askHidden, close };
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAa1C,MAAM,UAAU,YAAY;IAC1B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC9B,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;QAClC,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM;QACN,QAAQ,EAAE,IAAI;KACf,CAAoB,CAAC;IAEtB,MAAM,aAAa,GACjB,EAAE,CAAC,cAAc,EAAE,IAAI,CAAC,EAAE,CAAC;QAC3B,CAAC,CAAC,aAAqB,EAAE,EAAE;YACzB,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;IAEL,EAAE,CAAC,WAAW,GAAG,KAAK,CAAC;IACvB,EAAE,CAAC,cAAc,GAAG,CAAC,aAAqB,EAAE,EAAE;QAC5C,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC;YACpB,aAAa,CAAC,aAAa,CAAC,CAAC;YAC7B,OAAO;QACT,CAAC;QAED,IAAI,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACjC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACnB,OAAO;QACT,CAAC;QAED,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC,CAAC;IAEF,SAAS,GAAG,CAAC,QAAgB;QAC3B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC7B,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,MAAc,EAAE,EAAE;gBACvC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;YACzB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,SAAS,SAAS,CAAC,QAAgB;QACjC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC7B,EAAE,CAAC,WAAW,GAAG,IAAI,CAAC;YACtB,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,MAAc,EAAE,EAAE;gBACvC,EAAE,CAAC,WAAW,GAAG,KAAK,CAAC;gBACvB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACnB,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;YACzB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,SAAS,KAAK;QACZ,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;IAED,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anthropic provider configuration and header mapping.
|
|
3
|
+
*/
|
|
4
|
+
import type { ProviderConfig } from '../types.js';
|
|
5
|
+
import type { IncomingHttpHeaders } from 'node:http';
|
|
6
|
+
/**
|
|
7
|
+
* Default Anthropic provider configuration.
|
|
8
|
+
*/
|
|
9
|
+
export declare const anthropicProvider: ProviderConfig;
|
|
10
|
+
/**
|
|
11
|
+
* Map incoming request headers for Anthropic upstream requests.
|
|
12
|
+
*
|
|
13
|
+
* - Sets x-api-key: {ANTHROPIC_API_KEY} from env var
|
|
14
|
+
* - Sets anthropic-version header if not already present
|
|
15
|
+
* - Forwards Content-Type and other relevant headers
|
|
16
|
+
* - Does NOT forward the Host header (uses upstream host)
|
|
17
|
+
*/
|
|
18
|
+
export declare function mapAnthropicHeaders(incomingHeaders: IncomingHttpHeaders, apiKeyEnv: string | null): Record<string, string>;
|