offrouter-core 0.2.1 → 0.2.2

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 (139) hide show
  1. package/dist/audit.d.ts +137 -0
  2. package/dist/audit.d.ts.map +1 -0
  3. package/dist/audit.js +320 -0
  4. package/dist/audit.js.map +1 -0
  5. package/dist/auth/credential-chain.d.ts +84 -0
  6. package/dist/auth/credential-chain.d.ts.map +1 -0
  7. package/dist/auth/credential-chain.js +150 -0
  8. package/dist/auth/credential-chain.js.map +1 -0
  9. package/dist/auth/index.d.ts +10 -0
  10. package/dist/auth/index.d.ts.map +1 -0
  11. package/dist/auth/index.js +7 -0
  12. package/dist/auth/index.js.map +1 -0
  13. package/dist/auth/keychain.d.ts +60 -0
  14. package/dist/auth/keychain.d.ts.map +1 -0
  15. package/dist/auth/keychain.js +104 -0
  16. package/dist/auth/keychain.js.map +1 -0
  17. package/dist/auth/oauth-pkce.d.ts +138 -0
  18. package/dist/auth/oauth-pkce.d.ts.map +1 -0
  19. package/dist/auth/oauth-pkce.js +375 -0
  20. package/dist/auth/oauth-pkce.js.map +1 -0
  21. package/dist/auth/oauth-server.d.ts +36 -0
  22. package/dist/auth/oauth-server.d.ts.map +1 -0
  23. package/dist/auth/oauth-server.js +210 -0
  24. package/dist/auth/oauth-server.js.map +1 -0
  25. package/dist/config.d.ts +76 -0
  26. package/dist/config.d.ts.map +1 -0
  27. package/dist/config.js +355 -0
  28. package/dist/config.js.map +1 -0
  29. package/dist/delegation.d.ts +123 -0
  30. package/dist/delegation.d.ts.map +1 -0
  31. package/dist/delegation.js +455 -0
  32. package/dist/delegation.js.map +1 -0
  33. package/dist/index.d.ts +41 -0
  34. package/dist/index.d.ts.map +1 -0
  35. package/dist/index.js +26 -0
  36. package/dist/index.js.map +1 -0
  37. package/dist/policy.d.ts +45 -0
  38. package/dist/policy.d.ts.map +1 -0
  39. package/dist/policy.js +318 -0
  40. package/dist/policy.js.map +1 -0
  41. package/{src/protocol.ts → dist/protocol.d.ts} +2 -2
  42. package/dist/protocol.d.ts.map +1 -0
  43. package/dist/protocol.js +6 -0
  44. package/dist/protocol.js.map +1 -0
  45. package/dist/providers/adapter.d.ts +137 -0
  46. package/dist/providers/adapter.d.ts.map +1 -0
  47. package/dist/providers/adapter.js +163 -0
  48. package/dist/providers/adapter.js.map +1 -0
  49. package/dist/providers/catalog-data.d.ts +128 -0
  50. package/dist/providers/catalog-data.d.ts.map +1 -0
  51. package/dist/providers/catalog-data.js +397 -0
  52. package/dist/providers/catalog-data.js.map +1 -0
  53. package/dist/providers/catalog.d.ts +63 -0
  54. package/dist/providers/catalog.d.ts.map +1 -0
  55. package/dist/providers/catalog.js +394 -0
  56. package/dist/providers/catalog.js.map +1 -0
  57. package/dist/providers/fake.d.ts +46 -0
  58. package/dist/providers/fake.d.ts.map +1 -0
  59. package/dist/providers/fake.js +234 -0
  60. package/dist/providers/fake.js.map +1 -0
  61. package/dist/providers/openai-compatible.d.ts +65 -0
  62. package/dist/providers/openai-compatible.d.ts.map +1 -0
  63. package/dist/providers/openai-compatible.js +434 -0
  64. package/dist/providers/openai-compatible.js.map +1 -0
  65. package/dist/proxy/responses-mapper.d.ts +366 -0
  66. package/dist/proxy/responses-mapper.d.ts.map +1 -0
  67. package/dist/proxy/responses-mapper.js +517 -0
  68. package/dist/proxy/responses-mapper.js.map +1 -0
  69. package/dist/proxy/responses-server.d.ts +29 -0
  70. package/dist/proxy/responses-server.d.ts.map +1 -0
  71. package/dist/proxy/responses-server.js +360 -0
  72. package/dist/proxy/responses-server.js.map +1 -0
  73. package/dist/router.d.ts +18 -0
  74. package/dist/router.d.ts.map +1 -0
  75. package/dist/router.js +296 -0
  76. package/dist/router.js.map +1 -0
  77. package/dist/schemas.d.ts +560 -0
  78. package/dist/schemas.d.ts.map +1 -0
  79. package/{src/schemas.ts → dist/schemas.js} +83 -103
  80. package/dist/schemas.js.map +1 -0
  81. package/dist/secrets.d.ts +112 -0
  82. package/dist/secrets.d.ts.map +1 -0
  83. package/dist/secrets.js +326 -0
  84. package/dist/secrets.js.map +1 -0
  85. package/dist/types.d.ts +117 -0
  86. package/dist/types.d.ts.map +1 -0
  87. package/dist/types.js +6 -0
  88. package/dist/types.js.map +1 -0
  89. package/dist/usage-file.d.ts +59 -0
  90. package/dist/usage-file.d.ts.map +1 -0
  91. package/dist/usage-file.js +316 -0
  92. package/dist/usage-file.js.map +1 -0
  93. package/dist/usage.d.ts +235 -0
  94. package/dist/usage.d.ts.map +1 -0
  95. package/dist/usage.js +517 -0
  96. package/dist/usage.js.map +1 -0
  97. package/package.json +7 -2
  98. package/src/audit.test.ts +0 -302
  99. package/src/audit.ts +0 -553
  100. package/src/auth/credential-chain.test.ts +0 -326
  101. package/src/auth/credential-chain.ts +0 -235
  102. package/src/auth/index.ts +0 -45
  103. package/src/auth/keychain.test.ts +0 -265
  104. package/src/auth/keychain.ts +0 -168
  105. package/src/auth/oauth-pkce.test.ts +0 -329
  106. package/src/auth/oauth-pkce.ts +0 -571
  107. package/src/auth/oauth-server.test.ts +0 -83
  108. package/src/auth/oauth-server.ts +0 -296
  109. package/src/config.test.ts +0 -479
  110. package/src/config.ts +0 -505
  111. package/src/delegation.test.ts +0 -368
  112. package/src/delegation.ts +0 -605
  113. package/src/index.ts +0 -280
  114. package/src/policy.test.ts +0 -634
  115. package/src/policy.ts +0 -420
  116. package/src/providers/adapter.test.ts +0 -293
  117. package/src/providers/adapter.ts +0 -328
  118. package/src/providers/catalog-data.test.ts +0 -258
  119. package/src/providers/catalog-data.ts +0 -498
  120. package/src/providers/catalog.test.ts +0 -84
  121. package/src/providers/catalog.ts +0 -483
  122. package/src/providers/fake.ts +0 -312
  123. package/src/providers/openai-compatible.test.ts +0 -366
  124. package/src/providers/openai-compatible.ts +0 -554
  125. package/src/proxy/responses-mapper.test.ts +0 -290
  126. package/src/proxy/responses-mapper.ts +0 -736
  127. package/src/proxy/responses-server.test.ts +0 -322
  128. package/src/proxy/responses-server.ts +0 -469
  129. package/src/router.test.ts +0 -699
  130. package/src/router.ts +0 -352
  131. package/src/schemas.test.ts +0 -291
  132. package/src/secrets.test.ts +0 -271
  133. package/src/secrets.ts +0 -461
  134. package/src/types.ts +0 -173
  135. package/src/usage-file.test.ts +0 -243
  136. package/src/usage-file.ts +0 -435
  137. package/src/usage.test.ts +0 -335
  138. package/src/usage.ts +0 -859
  139. package/tsconfig.json +0 -9
@@ -0,0 +1,76 @@
1
+ import type { PolicyConfig } from "./policy.js";
2
+ /** Defaults applied when user config omits policy knobs. */
3
+ export interface PolicyDefaults {
4
+ subscriptionFirst: boolean;
5
+ allowApiKeyFallback: boolean;
6
+ }
7
+ /** Declared provider entry from config (no secrets here). */
8
+ export interface ConfiguredProvider {
9
+ id: string;
10
+ enabled: boolean;
11
+ accounts: ConfiguredAccount[];
12
+ }
13
+ /** Named profile overlay loaded from profiles/*.toml. */
14
+ export interface ConfiguredProfile {
15
+ id: string;
16
+ deniedProviders?: string[];
17
+ allowApiKeyFallback?: boolean;
18
+ subscriptionFirst?: boolean;
19
+ }
20
+ /** Single configured account within a provider. */
21
+ export interface ConfiguredAccount {
22
+ id: string;
23
+ label?: string;
24
+ }
25
+ export interface ConfigWarning {
26
+ filePath: string;
27
+ path: string;
28
+ message: string;
29
+ }
30
+ export interface OffRouterConfig {
31
+ homeDir: string;
32
+ sources: string[];
33
+ policy: PolicyConfig;
34
+ policyDefaults: PolicyDefaults;
35
+ providers: Record<string, ConfiguredProvider>;
36
+ profiles: Record<string, ConfiguredProfile>;
37
+ warnings: ConfigWarning[];
38
+ }
39
+ export interface LoadConfigOptions {
40
+ /** Override process.env (for tests). */
41
+ env?: NodeJS.ProcessEnv;
42
+ /** Override os.homedir (for tests). */
43
+ homedir?: () => string;
44
+ /** Workspace directory that may contain .offrouter/config.toml. */
45
+ workspaceDir?: string;
46
+ /**
47
+ * Whether the workspace is trusted. Project config is ignored when false
48
+ * or when workspaceDir is unset.
49
+ */
50
+ workspaceTrusted?: boolean;
51
+ }
52
+ export interface ResolveHomeOptions {
53
+ env?: NodeJS.ProcessEnv;
54
+ homedir?: () => string;
55
+ }
56
+ export declare class ConfigError extends Error {
57
+ readonly filePath: string;
58
+ readonly issues: string[];
59
+ constructor(filePath: string, issues: string[], cause?: unknown);
60
+ }
61
+ /**
62
+ * Safe default config: work profiles denied, nothing allowlisted, no providers.
63
+ */
64
+ export declare function defaultConfig(homeDir?: string): OffRouterConfig;
65
+ export declare function resolveOffRouterHome(options?: ResolveHomeOptions): string;
66
+ /**
67
+ * Load OffRouter configuration.
68
+ *
69
+ * Resolution order:
70
+ * 1. defaults (deny *-work, empty allowlist, no providers)
71
+ * 2. `$OFFROUTER_HOME/config.toml` or `~/.offrouter/config.toml`
72
+ * 3. `$OFFROUTER_HOME/profiles/*.toml`
73
+ * 4. `<workspace>/.offrouter/config.toml` only when workspaceTrusted
74
+ */
75
+ export declare function loadConfig(options?: LoadConfigOptions): Promise<OffRouterConfig>;
76
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,4DAA4D;AAC5D,MAAM,WAAW,cAAc;IAC7B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,mBAAmB,EAAE,OAAO,CAAC;CAC9B;AAED,6DAA6D;AAC7D,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED,yDAAyD;AACzD,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,mDAAmD;AACnD,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,YAAY,CAAC;IACrB,cAAc,EAAE,cAAc,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAC9C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC5C,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,wCAAwC;IACxC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,uCAAuC;IACvC,OAAO,CAAC,EAAE,MAAM,MAAM,CAAC;IACvB,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,MAAM,CAAC;CACxB;AAED,qBAAa,WAAY,SAAQ,KAAK;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;gBAEd,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,KAAK,CAAC,EAAE,OAAO;CAUhE;AA+DD;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,SAAK,GAAG,eAAe,CAkB3D;AAED,wBAAgB,oBAAoB,CAClC,OAAO,GAAE,kBAAuB,GAC/B,MAAM,CAQR;AAsSD;;;;;;;;GAQG;AACH,wBAAsB,UAAU,CAC9B,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,eAAe,CAAC,CAe1B"}
package/dist/config.js ADDED
@@ -0,0 +1,355 @@
1
+ /**
2
+ * OffRouter V1 user/project config loader.
3
+ * Loads TOML from OFFROUTER_HOME (or ~/.offrouter) with Zod validation.
4
+ * Project .offrouter/config.toml is ignored unless the workspace is trusted.
5
+ */
6
+ import { readdir, readFile } from "node:fs/promises";
7
+ import { homedir as osHomedir } from "node:os";
8
+ import { join, resolve } from "node:path";
9
+ import { parse as parseToml } from "smol-toml";
10
+ import { z } from "zod";
11
+ export class ConfigError extends Error {
12
+ filePath;
13
+ issues;
14
+ constructor(filePath, issues, cause) {
15
+ const detail = issues.length > 0 ? issues.join("; ") : "unknown validation error";
16
+ super(`Invalid OffRouter config in ${filePath}: ${detail}`, {
17
+ cause,
18
+ });
19
+ this.name = "ConfigError";
20
+ this.filePath = filePath;
21
+ this.issues = issues;
22
+ }
23
+ }
24
+ function allowedFromZodShape(shape) {
25
+ return Object.fromEntries(Object.keys(shape).map((key) => [key, "leaf"]));
26
+ }
27
+ const ProviderConfigShape = {
28
+ enabled: z.boolean().optional(),
29
+ accounts: z
30
+ .array(z.object({ id: z.string().min(1), label: z.string().optional() }).strict())
31
+ .optional(),
32
+ };
33
+ const PolicySectionShape = {
34
+ subscription_first: z.boolean().optional(),
35
+ allow_api_key_fallback: z.boolean().optional(),
36
+ allow_third_party_subscription_adapters: z.boolean().optional(),
37
+ denied_providers: z.array(z.string().min(1)).optional(),
38
+ near_limit_threshold: z.number().min(0).max(1).optional(),
39
+ };
40
+ const RootConfigShape = {
41
+ allowlisted_profiles: z.array(z.string().min(1)).optional(),
42
+ denied_profile_patterns: z.array(z.string().min(1)).optional(),
43
+ policy: z.object(PolicySectionShape).strict().optional(),
44
+ providers: z
45
+ .record(z.string().min(1), z.object(ProviderConfigShape).strict())
46
+ .optional(),
47
+ };
48
+ const ProfileFileShape = {
49
+ id: z.string().min(1).optional(),
50
+ denied_providers: z.array(z.string().min(1)).optional(),
51
+ allow_api_key_fallback: z.boolean().optional(),
52
+ subscription_first: z.boolean().optional(),
53
+ };
54
+ const RootConfigSchema = z.object(RootConfigShape).strict();
55
+ const ProfileFileSchema = z.object(ProfileFileShape).strict();
56
+ const PROVIDER_ALLOWED = {
57
+ ...allowedFromZodShape(ProviderConfigShape),
58
+ accounts: "leaf",
59
+ };
60
+ const ROOT_ALLOWED = {
61
+ ...allowedFromZodShape(RootConfigShape),
62
+ policy: allowedFromZodShape(PolicySectionShape),
63
+ providers: "record",
64
+ };
65
+ const PROFILE_ALLOWED = allowedFromZodShape(ProfileFileShape);
66
+ const DEFAULT_DENIED_PROFILE_PATTERNS = ["*-work"];
67
+ /**
68
+ * Safe default config: work profiles denied, nothing allowlisted, no providers.
69
+ */
70
+ export function defaultConfig(homeDir = "") {
71
+ return {
72
+ homeDir,
73
+ sources: [],
74
+ policy: {
75
+ allowlistedProfiles: [],
76
+ deniedProfilePatterns: [...DEFAULT_DENIED_PROFILE_PATTERNS],
77
+ allowThirdPartySubscriptionAdapters: false,
78
+ deniedProviders: [],
79
+ },
80
+ policyDefaults: {
81
+ subscriptionFirst: true,
82
+ allowApiKeyFallback: false,
83
+ },
84
+ providers: {},
85
+ profiles: {},
86
+ warnings: [],
87
+ };
88
+ }
89
+ export function resolveOffRouterHome(options = {}) {
90
+ const env = options.env ?? process.env;
91
+ const home = options.homedir ?? osHomedir;
92
+ const override = env.OFFROUTER_HOME?.trim();
93
+ if (override) {
94
+ return resolve(override);
95
+ }
96
+ return resolve(join(home(), ".offrouter"));
97
+ }
98
+ function isPlainObject(value) {
99
+ return typeof value === "object" && value !== null && !Array.isArray(value);
100
+ }
101
+ function formatZodIssues(error) {
102
+ return error.issues.map((issue) => {
103
+ const path = issue.path.length > 0 ? issue.path.join(".") : "(root)";
104
+ return `${path}: ${issue.message}`;
105
+ });
106
+ }
107
+ /**
108
+ * Non-Zod path walker that flags keys absent from a schema tree.
109
+ * Uses Zod internals only as type-shape guidance via a parallel known-keys model.
110
+ */
111
+ function collectUnknownKeyWarnings(value, allowed, filePath, pathPrefix) {
112
+ if (!isPlainObject(value)) {
113
+ return [];
114
+ }
115
+ const warnings = [];
116
+ for (const key of Object.keys(value)) {
117
+ const keyPath = pathPrefix ? `${pathPrefix}.${key}` : key;
118
+ const child = allowed[key];
119
+ if (child === undefined) {
120
+ warnings.push({
121
+ filePath,
122
+ path: keyPath,
123
+ message: `Unknown config key "${keyPath}" in ${filePath}`,
124
+ });
125
+ continue;
126
+ }
127
+ if (child === "leaf") {
128
+ continue;
129
+ }
130
+ if (child === "record") {
131
+ const recordValue = value[key];
132
+ if (isPlainObject(recordValue)) {
133
+ for (const nestedKey of Object.keys(recordValue)) {
134
+ const nestedPath = `${keyPath}.${nestedKey}`;
135
+ warnings.push(...collectUnknownKeyWarnings(recordValue[nestedKey], PROVIDER_ALLOWED, filePath, nestedPath));
136
+ }
137
+ }
138
+ continue;
139
+ }
140
+ warnings.push(...collectUnknownKeyWarnings(value[key], child, filePath, keyPath));
141
+ }
142
+ return warnings;
143
+ }
144
+ function parseTomlFile(content, filePath) {
145
+ try {
146
+ return parseToml(content);
147
+ }
148
+ catch (err) {
149
+ const message = err instanceof Error ? err.message : String(err);
150
+ throw new ConfigError(filePath, [`parse error: ${message}`], err);
151
+ }
152
+ }
153
+ function validateRoot(raw, filePath) {
154
+ const warnings = collectUnknownKeyWarnings(raw, ROOT_ALLOWED, filePath, "");
155
+ // Strip unknown keys before strict Zod parse so warnings ≠ hard failure.
156
+ const stripped = stripUnknown(raw, ROOT_ALLOWED);
157
+ const parsed = RootConfigSchema.safeParse(stripped);
158
+ if (!parsed.success) {
159
+ throw new ConfigError(filePath, formatZodIssues(parsed.error), parsed.error);
160
+ }
161
+ return { data: parsed.data, warnings };
162
+ }
163
+ function validateProfile(raw, filePath, fallbackId) {
164
+ const warnings = collectUnknownKeyWarnings(raw, PROFILE_ALLOWED, filePath, "");
165
+ const stripped = stripUnknown(raw, PROFILE_ALLOWED);
166
+ const parsed = ProfileFileSchema.safeParse(stripped);
167
+ if (!parsed.success) {
168
+ throw new ConfigError(filePath, formatZodIssues(parsed.error), parsed.error);
169
+ }
170
+ const profile = parsed.data;
171
+ const data = {
172
+ id: profile.id ?? fallbackId,
173
+ };
174
+ if (profile.denied_providers !== undefined) {
175
+ data.deniedProviders = profile.denied_providers;
176
+ }
177
+ if (profile.allow_api_key_fallback !== undefined) {
178
+ data.allowApiKeyFallback = profile.allow_api_key_fallback;
179
+ }
180
+ if (profile.subscription_first !== undefined) {
181
+ data.subscriptionFirst = profile.subscription_first;
182
+ }
183
+ return {
184
+ data,
185
+ warnings,
186
+ };
187
+ }
188
+ function stripUnknown(value, allowed) {
189
+ if (!isPlainObject(value)) {
190
+ return value;
191
+ }
192
+ const out = {};
193
+ for (const [key, child] of Object.entries(allowed)) {
194
+ if (!(key in value))
195
+ continue;
196
+ const v = value[key];
197
+ if (child === "leaf") {
198
+ out[key] = v;
199
+ }
200
+ else if (child === "record") {
201
+ if (isPlainObject(v)) {
202
+ const recordOut = {};
203
+ for (const [nestedKey, nestedVal] of Object.entries(v)) {
204
+ recordOut[nestedKey] = stripUnknown(nestedVal, PROVIDER_ALLOWED);
205
+ }
206
+ out[key] = recordOut;
207
+ }
208
+ else {
209
+ out[key] = v;
210
+ }
211
+ }
212
+ else {
213
+ out[key] = stripUnknown(v, child);
214
+ }
215
+ }
216
+ return out;
217
+ }
218
+ function mergeRootInto(target, root, sourcePath) {
219
+ target.sources.push(sourcePath);
220
+ if (root.allowlisted_profiles) {
221
+ target.policy.allowlistedProfiles = uniqueStrings([
222
+ ...target.policy.allowlistedProfiles,
223
+ ...root.allowlisted_profiles,
224
+ ]);
225
+ }
226
+ if (root.denied_profile_patterns) {
227
+ target.policy.deniedProfilePatterns = uniqueStrings([
228
+ ...(target.policy.deniedProfilePatterns ?? [
229
+ ...DEFAULT_DENIED_PROFILE_PATTERNS,
230
+ ]),
231
+ ...root.denied_profile_patterns,
232
+ ]);
233
+ }
234
+ if (root.policy) {
235
+ if (root.policy.subscription_first !== undefined) {
236
+ target.policyDefaults.subscriptionFirst = root.policy.subscription_first;
237
+ }
238
+ if (root.policy.allow_api_key_fallback !== undefined) {
239
+ target.policyDefaults.allowApiKeyFallback =
240
+ root.policy.allow_api_key_fallback;
241
+ }
242
+ if (root.policy.allow_third_party_subscription_adapters !== undefined) {
243
+ target.policy.allowThirdPartySubscriptionAdapters =
244
+ root.policy.allow_third_party_subscription_adapters;
245
+ }
246
+ if (root.policy.near_limit_threshold !== undefined) {
247
+ target.policy.nearLimitThreshold = root.policy.near_limit_threshold;
248
+ }
249
+ if (root.policy.denied_providers) {
250
+ target.policy.deniedProviders = uniqueStrings([
251
+ ...(target.policy.deniedProviders ?? []),
252
+ ...root.policy.denied_providers,
253
+ ]);
254
+ }
255
+ }
256
+ if (root.providers) {
257
+ for (const [id, provider] of Object.entries(root.providers)) {
258
+ const accounts = provider.accounts
259
+ ? provider.accounts.map((a) => ({ id: a.id, label: a.label }))
260
+ : [{ id }];
261
+ target.providers[id] = {
262
+ id,
263
+ enabled: provider.enabled ?? true,
264
+ accounts,
265
+ };
266
+ }
267
+ }
268
+ }
269
+ function uniqueStrings(values) {
270
+ return [...new Set(values)];
271
+ }
272
+ async function readOptionalFile(path) {
273
+ try {
274
+ return await readFile(path, "utf8");
275
+ }
276
+ catch (err) {
277
+ if (err &&
278
+ typeof err === "object" &&
279
+ "code" in err &&
280
+ err.code === "ENOENT") {
281
+ return null;
282
+ }
283
+ throw err;
284
+ }
285
+ }
286
+ async function loadRootFile(filePath, target) {
287
+ const content = await readOptionalFile(filePath);
288
+ if (content === null) {
289
+ return;
290
+ }
291
+ // Empty file is valid and means no overrides.
292
+ if (content.trim() === "") {
293
+ target.sources.push(filePath);
294
+ return;
295
+ }
296
+ const raw = parseTomlFile(content, filePath);
297
+ const { data, warnings } = validateRoot(raw, filePath);
298
+ target.warnings.push(...warnings);
299
+ mergeRootInto(target, data, filePath);
300
+ }
301
+ async function loadProfileDir(dirPath, target) {
302
+ let entries;
303
+ try {
304
+ entries = await readdir(dirPath);
305
+ }
306
+ catch (err) {
307
+ if (err &&
308
+ typeof err === "object" &&
309
+ "code" in err &&
310
+ err.code === "ENOENT") {
311
+ return;
312
+ }
313
+ throw err;
314
+ }
315
+ const tomlFiles = entries
316
+ .filter((name) => name.endsWith(".toml"))
317
+ .sort((a, b) => a.localeCompare(b));
318
+ for (const name of tomlFiles) {
319
+ const filePath = join(dirPath, name);
320
+ const content = await readFile(filePath, "utf8");
321
+ const raw = content.trim() === "" ? {} : parseTomlFile(content, filePath);
322
+ const fallbackId = name.replace(/\.toml$/i, "");
323
+ const { data, warnings } = validateProfile(raw, filePath, fallbackId);
324
+ target.warnings.push(...warnings);
325
+ target.sources.push(filePath);
326
+ if (target.profiles[data.id]) {
327
+ target.warnings.push({
328
+ filePath,
329
+ path: `profiles.${data.id}`,
330
+ message: `Duplicate profile id "${data.id}" in ${filePath}; later profile file overwrote an earlier definition.`,
331
+ });
332
+ }
333
+ target.profiles[data.id] = data;
334
+ }
335
+ }
336
+ /**
337
+ * Load OffRouter configuration.
338
+ *
339
+ * Resolution order:
340
+ * 1. defaults (deny *-work, empty allowlist, no providers)
341
+ * 2. `$OFFROUTER_HOME/config.toml` or `~/.offrouter/config.toml`
342
+ * 3. `$OFFROUTER_HOME/profiles/*.toml`
343
+ * 4. `<workspace>/.offrouter/config.toml` only when workspaceTrusted
344
+ */
345
+ export async function loadConfig(options = {}) {
346
+ const homeDir = resolveOffRouterHome(options);
347
+ const config = defaultConfig(homeDir);
348
+ await loadRootFile(join(homeDir, "config.toml"), config);
349
+ await loadProfileDir(join(homeDir, "profiles"), config);
350
+ if (options.workspaceDir && options.workspaceTrusted) {
351
+ await loadRootFile(join(options.workspaceDir, ".offrouter", "config.toml"), config);
352
+ }
353
+ return config;
354
+ }
355
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,123 @@
1
+ import { type AuditStore } from "./audit.js";
2
+ import type { PolicyConfig } from "./policy.js";
3
+ import type { ProviderAdapter } from "./providers/adapter.js";
4
+ import type { ProviderCandidate, RouteDecision, RouteRequest } from "./types.js";
5
+ export type DelegationMode = "oneshot" | "stream" | "background";
6
+ export type DelegationOutput = "text" | "json" | "patch";
7
+ export type DelegationTaskStatus = "queued" | "running" | "completed" | "cancelled" | "failed";
8
+ /**
9
+ * Delegation carries full prompt text only after the caller is past policy.
10
+ * The runtime still re-checks policy before invoke and rejects when blocked.
11
+ */
12
+ export interface DelegationRequest {
13
+ taskId: string;
14
+ mode: DelegationMode;
15
+ output: DelegationOutput;
16
+ /** Full user prompt; never audited raw. */
17
+ prompt: string;
18
+ route: RouteRequest;
19
+ model?: string;
20
+ providerId?: string;
21
+ maxOutputTokens?: number;
22
+ temperature?: number;
23
+ }
24
+ export type DelegationEvent = {
25
+ type: "start";
26
+ taskId: string;
27
+ callId: string;
28
+ model: string;
29
+ } | {
30
+ type: "text-delta";
31
+ taskId: string;
32
+ callId: string;
33
+ text: string;
34
+ } | {
35
+ type: "usage";
36
+ taskId: string;
37
+ callId: string;
38
+ inputTokens?: number;
39
+ outputTokens?: number;
40
+ totalTokens?: number;
41
+ } | {
42
+ type: "done";
43
+ taskId: string;
44
+ callId: string;
45
+ finishReason?: string;
46
+ text?: string;
47
+ } | {
48
+ type: "error";
49
+ taskId: string;
50
+ callId?: string;
51
+ message: string;
52
+ code?: string;
53
+ } | {
54
+ type: "cancelled";
55
+ taskId: string;
56
+ callId?: string;
57
+ };
58
+ export interface DelegationTask {
59
+ taskId: string;
60
+ callId: string;
61
+ status: DelegationTaskStatus;
62
+ mode: DelegationMode;
63
+ requestId: string;
64
+ providerId?: string;
65
+ model?: string;
66
+ createdAt: string;
67
+ updatedAt: string;
68
+ text?: string;
69
+ error?: string;
70
+ events: DelegationEvent[];
71
+ decision?: RouteDecision;
72
+ }
73
+ export interface DelegationResult {
74
+ taskId: string;
75
+ status: DelegationTaskStatus;
76
+ text?: string;
77
+ error?: string;
78
+ events: DelegationEvent[];
79
+ decision?: RouteDecision;
80
+ }
81
+ export interface DelegationRuntimeOptions {
82
+ adapters: Record<string, ProviderAdapter>;
83
+ candidates: ProviderCandidate[];
84
+ policy: PolicyConfig;
85
+ audit?: AuditStore;
86
+ now?: () => Date;
87
+ /** Default true: store redacted prompt preview on audit append. */
88
+ includePromptPreview?: boolean;
89
+ }
90
+ export declare class DelegationPolicyError extends Error {
91
+ readonly decision: RouteDecision;
92
+ constructor(message: string, decision: RouteDecision);
93
+ }
94
+ export declare class DelegationRuntime {
95
+ #private;
96
+ private readonly adapters;
97
+ private readonly candidates;
98
+ private readonly policy;
99
+ private readonly audit;
100
+ private readonly now;
101
+ private readonly includePromptPreview;
102
+ private readonly tasks;
103
+ private readonly controllers;
104
+ private readonly waiters;
105
+ constructor(options: DelegationRuntimeOptions);
106
+ getTask(taskId: string): DelegationTask | undefined;
107
+ listTasks(): DelegationTask[];
108
+ /**
109
+ * One-shot: run to completion and return aggregated text + events.
110
+ */
111
+ delegate(request: DelegationRequest): Promise<DelegationResult>;
112
+ /**
113
+ * Streaming async iterator of DelegationEvents.
114
+ */
115
+ stream(request: DelegationRequest): AsyncGenerator<DelegationEvent, void, undefined>;
116
+ /**
117
+ * Start background work; returns immediately with a running/queued task.
118
+ */
119
+ startBackground(request: DelegationRequest): Promise<DelegationTask>;
120
+ wait(taskId: string): Promise<DelegationTask>;
121
+ cancel(taskId: string): Promise<DelegationTask | undefined>;
122
+ }
123
+ //# sourceMappingURL=delegation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delegation.d.ts","sourceRoot":"","sources":["../src/delegation.ts"],"names":[],"mappings":"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"}