@oh-my-pi/pi-ai 18.1.21 → 18.1.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [18.1.22] - 2026-09-14
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- 400-request debug dumps now redact provider-specific auth headers (`x-goog-api-key`, `x-amz-security-token`, and any header whose name carries a key/token/secret), not just a fixed allow-list, so a shared dump can no longer leak a live API key ([#12007](https://github.com/can1357/oh-my-pi/issues/12007)).
|
|
10
|
+
|
|
5
11
|
## [18.1.20] - 2026-09-13
|
|
6
12
|
|
|
7
13
|
### Fixed
|
|
@@ -60,6 +60,8 @@ export interface ProviderDefinition {
|
|
|
60
60
|
readonly envKeys?: KeyResolver;
|
|
61
61
|
/** Provider transport can authenticate without a resolved API-key string. */
|
|
62
62
|
readonly allowsMissingApiKey?: boolean;
|
|
63
|
+
/** APIs whose provider transport resolves credentials without a stored account. */
|
|
64
|
+
readonly nativeAuthApis?: readonly string[];
|
|
63
65
|
/** Provider-owned model normalization that must run before API-specific option mapping. */
|
|
64
66
|
readonly prepareModel?: ProviderModelPreparer;
|
|
65
67
|
/** Provider-owned request shaping applied before generic API dispatch. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-my-pi/pi-ai",
|
|
3
|
-
"version": "18.1.
|
|
3
|
+
"version": "18.1.22",
|
|
4
4
|
"description": "Unified LLM API with automatic model discovery and provider configuration",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -124,11 +124,11 @@
|
|
|
124
124
|
"fmt": "oxfmt --no-error-on-unmatched-pattern 'src/**/*.{ts,tsx}' '{test,bench,examples,scripts}/**/*.ts' '*.ts'"
|
|
125
125
|
},
|
|
126
126
|
"dependencies": {
|
|
127
|
-
"@oh-my-pi/omptype": "18.1.
|
|
128
|
-
"@oh-my-pi/pi-catalog": "18.1.
|
|
129
|
-
"@oh-my-pi/pi-natives": "18.1.
|
|
130
|
-
"@oh-my-pi/pi-utils": "18.1.
|
|
131
|
-
"@oh-my-pi/pi-wire": "18.1.
|
|
127
|
+
"@oh-my-pi/omptype": "18.1.22",
|
|
128
|
+
"@oh-my-pi/pi-catalog": "18.1.22",
|
|
129
|
+
"@oh-my-pi/pi-natives": "18.1.22",
|
|
130
|
+
"@oh-my-pi/pi-utils": "18.1.22",
|
|
131
|
+
"@oh-my-pi/pi-wire": "18.1.22"
|
|
132
132
|
},
|
|
133
133
|
"devDependencies": {
|
|
134
134
|
"@types/bun": "^1.3.14"
|
package/src/registry/build.ts
CHANGED
|
@@ -62,6 +62,7 @@ export function buildProviderDefinition(
|
|
|
62
62
|
...transport,
|
|
63
63
|
...(envKeys !== undefined ? { envKeys } : {}),
|
|
64
64
|
...(policy.allowsMissingApiKey !== undefined ? { allowsMissingApiKey: policy.allowsMissingApiKey } : {}),
|
|
65
|
+
...(policy.nativeAuthApis !== undefined ? { nativeAuthApis: policy.nativeAuthApis } : {}),
|
|
65
66
|
...(policy.available !== undefined ? { available: policy.available } : {}),
|
|
66
67
|
...(policy.showInLoginList !== undefined ? { showInLoginList: policy.showInLoginList } : {}),
|
|
67
68
|
...(policy.storeAs !== undefined ? { storeCredentialsAs: policy.storeAs } : {}),
|
package/src/registry/types.ts
CHANGED
|
@@ -69,6 +69,8 @@ export interface ProviderDefinition {
|
|
|
69
69
|
readonly envKeys?: KeyResolver;
|
|
70
70
|
/** Provider transport can authenticate without a resolved API-key string. */
|
|
71
71
|
readonly allowsMissingApiKey?: boolean;
|
|
72
|
+
/** APIs whose provider transport resolves credentials without a stored account. */
|
|
73
|
+
readonly nativeAuthApis?: readonly string[];
|
|
72
74
|
/** Provider-owned model normalization that must run before API-specific option mapping. */
|
|
73
75
|
readonly prepareModel?: ProviderModelPreparer;
|
|
74
76
|
/** Provider-owned request shaping applied before generic API dispatch. */
|
|
@@ -20,7 +20,16 @@ export type CapturedHttpErrorResponse = {
|
|
|
20
20
|
bodyJson?: unknown;
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Matches any header name whose value carries a credential, so a persisted dump
|
|
25
|
+
* never leaks one. A substring match — not a hand-maintained allow-list — so
|
|
26
|
+
* provider-specific auth headers (`x-goog-api-key`, `x-amz-security-token`, …)
|
|
27
|
+
* are redacted without enumerating every provider's spelling; the fixed list it
|
|
28
|
+
* replaced silently leaked any auth header it did not name. Redacting a benign
|
|
29
|
+
* header that happens to match is harmless: dumps exist to diagnose the request
|
|
30
|
+
* body, not its transport headers.
|
|
31
|
+
*/
|
|
32
|
+
const SENSITIVE_HEADER_PATTERN = /key|token|secret|auth|credential|cookie/i;
|
|
24
33
|
|
|
25
34
|
/**
|
|
26
35
|
* Build the JSON persisted for a rejected request. Request fields stay at the
|
|
@@ -167,7 +176,7 @@ function redactHeaders(headers: Record<string, string> | undefined): Record<stri
|
|
|
167
176
|
|
|
168
177
|
const redacted: Record<string, string> = {};
|
|
169
178
|
for (const [key, value] of Object.entries(headers)) {
|
|
170
|
-
if (
|
|
179
|
+
if (SENSITIVE_HEADER_PATTERN.test(key)) {
|
|
171
180
|
redacted[key] = "[redacted]";
|
|
172
181
|
continue;
|
|
173
182
|
}
|