@argosvix/sdk 0.4.1-alpha.1 → 0.4.3-alpha.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.
- package/README.md +81 -0
- package/dist/approvals.d.ts +84 -0
- package/dist/approvals.d.ts.map +1 -0
- package/dist/approvals.js +143 -0
- package/dist/approvals.js.map +1 -0
- package/dist/budgetGate.d.ts +67 -0
- package/dist/budgetGate.d.ts.map +1 -0
- package/dist/budgetGate.js +356 -0
- package/dist/budgetGate.js.map +1 -0
- package/dist/client.js +32 -0
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/policyScan.d.ts +47 -0
- package/dist/policyScan.d.ts.map +1 -0
- package/dist/policyScan.js +192 -0
- package/dist/policyScan.js.map +1 -0
- package/dist/pricing.d.ts +5 -5
- package/dist/pricing.d.ts.map +1 -1
- package/dist/pricing.js +24 -7
- package/dist/pricing.js.map +1 -1
- package/dist/recorder.d.ts +6 -0
- package/dist/recorder.d.ts.map +1 -1
- package/dist/recorder.js +27 -5
- package/dist/recorder.js.map +1 -1
- package/dist/types.d.ts +59 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +14 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +14 -0
- package/dist/version.js.map +1 -0
- package/package.json +16 -6
package/README.md
CHANGED
|
@@ -103,6 +103,87 @@ export default {
|
|
|
103
103
|
|
|
104
104
|
Long-running Node processes (Express, Next.js dev server, classic servers) do not need this — the buffer auto-flushes well before process exit.
|
|
105
105
|
|
|
106
|
+
## Runtime control plane (ランタイム制御プレーン)
|
|
107
|
+
|
|
108
|
+
Observability tells you what an agent *did*. The runtime control plane lets a human
|
|
109
|
+
bound what an agent *can do* — enforced inside your process, configured from the
|
|
110
|
+
dashboard / chat / MCP without touching agent code.
|
|
111
|
+
|
|
112
|
+
There are three gates. The first two are enforced inside `wrap(...)` by evaluating
|
|
113
|
+
cached backend config locally (no proxy, no per-call round trip). The third is an
|
|
114
|
+
explicit request/await pair around a sensitive operation.
|
|
115
|
+
|
|
116
|
+
A full runnable example lives in [`examples/headless-control-plane`](../../examples/headless-control-plane).
|
|
117
|
+
|
|
118
|
+
### Budget gate
|
|
119
|
+
|
|
120
|
+
Opt in with `budgetGate: true`. Before each wrapped LLM call, the SDK evaluates the
|
|
121
|
+
account's monthly limit + spend (cached, TTL from the backend, default 60s). Over the
|
|
122
|
+
limit throws `ArgosvixBudgetExceededError` *before* the provider request — so a runaway
|
|
123
|
+
loop can't burn the budget.
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
import { wrap, ArgosvixBudgetExceededError } from "@argosvix/sdk";
|
|
127
|
+
|
|
128
|
+
const openai = wrap(new OpenAI(), {
|
|
129
|
+
apiKey: process.env.ARGOSVIX_API_KEY,
|
|
130
|
+
budgetGate: true,
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
try {
|
|
134
|
+
await openai.chat.completions.create({ model: "gpt-4o-mini", messages });
|
|
135
|
+
} catch (err) {
|
|
136
|
+
if (err instanceof ArgosvixBudgetExceededError) {
|
|
137
|
+
// err.spentUsd / err.limitUsd — blocked before reaching the provider
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
The gate is configured from the dashboard / chat ("月 $5 の予算ゲートを作成して"). On an
|
|
143
|
+
account with no gate it's a complete no-op. `enforceMode: "fail_open"` (default) lets
|
|
144
|
+
calls through when the backend is unreachable; `"fail_closed"` blocks while the cached
|
|
145
|
+
state is stale (`ArgosvixBudgetGateUnavailableError`). Set `budgetGateFailClosed: true`
|
|
146
|
+
to also block before the first successful fetch.
|
|
147
|
+
|
|
148
|
+
### Policy gate
|
|
149
|
+
|
|
150
|
+
Opt in with `policyGate: true` (shares the same config fetch). Before each call the SDK
|
|
151
|
+
checks the request payload against the account's policy — model allowlist, PII block,
|
|
152
|
+
secret block — and throws `ArgosvixPolicyViolationError` on a hit. The scan runs in your
|
|
153
|
+
process; only the field path + a masked snippet are surfaced, never the plaintext.
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
import { wrap, ArgosvixPolicyViolationError } from "@argosvix/sdk";
|
|
157
|
+
|
|
158
|
+
const openai = wrap(new OpenAI(), {
|
|
159
|
+
apiKey: process.env.ARGOSVIX_API_KEY,
|
|
160
|
+
policyGate: true,
|
|
161
|
+
});
|
|
162
|
+
// err.reason is "model_not_allowed" | "pii_detected" | "secret_detected"
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Approval gate
|
|
166
|
+
|
|
167
|
+
For destructive or irreversible operations (delete / refund / send), request a human
|
|
168
|
+
approval and wait. The owner/admins get an email; a human approves in the dashboard
|
|
169
|
+
`/approvals` or via the email link. **API keys cannot approve** — the agent can't
|
|
170
|
+
self-approve. Anything other than `"approved"` (denied / expired / timeout) is
|
|
171
|
+
default-deny.
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
import { requestApproval, waitForApproval } from "@argosvix/sdk";
|
|
175
|
+
|
|
176
|
+
const approval = await requestApproval({
|
|
177
|
+
apiKey: process.env.ARGOSVIX_API_KEY!,
|
|
178
|
+
action: "delete_user",
|
|
179
|
+
summary: "Delete inactive user usr_123 (90 days no login)",
|
|
180
|
+
timeoutSeconds: 3600,
|
|
181
|
+
});
|
|
182
|
+
const status = await waitForApproval({ apiKey, id: approval.id });
|
|
183
|
+
if (status !== "approved") return; // default-deny
|
|
184
|
+
// ...perform the operation...
|
|
185
|
+
```
|
|
186
|
+
|
|
106
187
|
## Composite client / explicit provider
|
|
107
188
|
|
|
108
189
|
When auto-detection is ambiguous (e.g. for composite or adapter clients), set `config.provider` explicitly:
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 人間承認ゲートの SDK API (= ランタイム制御プレーン Phase 3)。
|
|
3
|
+
*
|
|
4
|
+
* agent の危険操作 (= 削除 / 送金 / 退会等) の前に呼ぶと、 Argosvix backend に
|
|
5
|
+
* 承認依頼が作られ、 account owner へ email 通知が飛ぶ。 人間が dashboard
|
|
6
|
+
* (/approvals) か email link で承認 / 否認するまで `waitForApproval()` が待つ。
|
|
7
|
+
*
|
|
8
|
+
* 設計:
|
|
9
|
+
* - wrap() とは独立した明示 API (= LLM 呼び出し単位ではなく操作単位)
|
|
10
|
+
* - timeout 切れ / waitForApproval の待ち時間超過は "expired" / "denied"
|
|
11
|
+
* 扱いで返す = default-deny。 呼び出し側は approved 以外で操作を中止する
|
|
12
|
+
* - polling は default 5 秒間隔 + jitter。 backend の read rate limit は
|
|
13
|
+
* account 単位 60/分 のため、 同時に待てる approval は実質 ~5 件
|
|
14
|
+
* (= 超過分は 429 → 次 poll で再試行されるので安全側だが遅くなる)
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* import { requestApproval, waitForApproval } from "@argosvix/sdk";
|
|
18
|
+
*
|
|
19
|
+
* const approval = await requestApproval({
|
|
20
|
+
* apiKey: "argk_...",
|
|
21
|
+
* action: "delete_user",
|
|
22
|
+
* summary: "user usr_123 を削除します (LTV $0、90 日 inactive)",
|
|
23
|
+
* });
|
|
24
|
+
* const status = await waitForApproval({ apiKey: "argk_...", id: approval.id });
|
|
25
|
+
* if (status !== "approved") throw new Error(`not approved: ${status}`);
|
|
26
|
+
*/
|
|
27
|
+
export type ApprovalStatus = "pending" | "approved" | "denied" | "expired";
|
|
28
|
+
export interface ApprovalRequestShape {
|
|
29
|
+
id: string;
|
|
30
|
+
action: string;
|
|
31
|
+
summary: string;
|
|
32
|
+
metadata: unknown;
|
|
33
|
+
status: ApprovalStatus;
|
|
34
|
+
expiresAt: string;
|
|
35
|
+
decidedAt: string | null;
|
|
36
|
+
decidedBy: string | null;
|
|
37
|
+
createdAt: string;
|
|
38
|
+
}
|
|
39
|
+
export declare class ArgosvixApprovalError extends Error {
|
|
40
|
+
readonly status: number | null;
|
|
41
|
+
constructor(message: string, status?: number | null);
|
|
42
|
+
}
|
|
43
|
+
export interface ApprovalClientOptions {
|
|
44
|
+
/** Argosvix API key (= 必須)。 */
|
|
45
|
+
apiKey: string;
|
|
46
|
+
/**
|
|
47
|
+
* API base の override (= self-host / test 用)。 未指定は
|
|
48
|
+
* https://ingest.argosvix.com。 ArgosvixConfig.endpoint (= .../v1/ingest)
|
|
49
|
+
* を渡した場合は prefix を導出する。
|
|
50
|
+
*/
|
|
51
|
+
endpoint?: string;
|
|
52
|
+
}
|
|
53
|
+
export interface RequestApprovalParams extends ApprovalClientOptions {
|
|
54
|
+
/** 操作の識別子 (= 1-128 文字、 [A-Za-z0-9._: -])。 例: "delete_user" */
|
|
55
|
+
action: string;
|
|
56
|
+
/** 人間が読む 1 行説明 (= 1-500 文字)。 承認 email にそのまま載る。 */
|
|
57
|
+
summary: string;
|
|
58
|
+
/** 補足 JSON object (= 4KB まで、 任意)。 */
|
|
59
|
+
metadata?: Record<string, unknown>;
|
|
60
|
+
/** 承認期限秒 (= 60-86400、 default 3600)。 期限切れ = expired = deny 扱い。 */
|
|
61
|
+
timeoutSeconds?: number;
|
|
62
|
+
}
|
|
63
|
+
/** 承認依頼を作成する。 account owner へ email 通知が飛ぶ。 */
|
|
64
|
+
export declare function requestApproval(params: RequestApprovalParams): Promise<ApprovalRequestShape>;
|
|
65
|
+
/** 承認依頼の現在状態を 1 回取得する。 */
|
|
66
|
+
export declare function getApproval(params: ApprovalClientOptions & {
|
|
67
|
+
id: string;
|
|
68
|
+
}): Promise<ApprovalRequestShape>;
|
|
69
|
+
export interface WaitForApprovalParams extends ApprovalClientOptions {
|
|
70
|
+
id: string;
|
|
71
|
+
/** polling 間隔 ms (= default 5000、 最小 1000)。 */
|
|
72
|
+
pollIntervalMs?: number;
|
|
73
|
+
/**
|
|
74
|
+
* 待機の上限 ms (= default 1 時間)。 超過時は "expired" を返す = default-deny。
|
|
75
|
+
* backend 側の依頼 timeout とは独立 (= 短い方が先に効く)。
|
|
76
|
+
*/
|
|
77
|
+
timeoutMs?: number;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* 承認 / 否認 / 期限切れまで polling して最終 status を返す。
|
|
81
|
+
* "approved" 以外が返ったら呼び出し側は操作を実行しないこと (= default-deny)。
|
|
82
|
+
*/
|
|
83
|
+
export declare function waitForApproval(params: WaitForApprovalParams): Promise<Exclude<ApprovalStatus, "pending">>;
|
|
84
|
+
//# sourceMappingURL=approvals.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approvals.d.ts","sourceRoot":"","sources":["../src/approvals.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AASH,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE3E,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,cAAc,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;gBACnB,OAAO,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,GAAG,IAAW;CAK1D;AAED,MAAM,WAAW,qBAAqB;IACpC,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAkDD,MAAM,WAAW,qBAAsB,SAAQ,qBAAqB;IAClE,8DAA8D;IAC9D,MAAM,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,kEAAkE;IAClE,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,8CAA8C;AAC9C,wBAAsB,eAAe,CACnC,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,oBAAoB,CAAC,CAe/B;AAED,0BAA0B;AAC1B,wBAAsB,WAAW,CAC/B,MAAM,EAAE,qBAAqB,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,GAC7C,OAAO,CAAC,oBAAoB,CAAC,CAS/B;AAED,MAAM,WAAW,qBAAsB,SAAQ,qBAAqB;IAClE,EAAE,EAAE,MAAM,CAAC;IACX,+CAA+C;IAC/C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,OAAO,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC,CA4B7C"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 人間承認ゲートの SDK API (= ランタイム制御プレーン Phase 3)。
|
|
3
|
+
*
|
|
4
|
+
* agent の危険操作 (= 削除 / 送金 / 退会等) の前に呼ぶと、 Argosvix backend に
|
|
5
|
+
* 承認依頼が作られ、 account owner へ email 通知が飛ぶ。 人間が dashboard
|
|
6
|
+
* (/approvals) か email link で承認 / 否認するまで `waitForApproval()` が待つ。
|
|
7
|
+
*
|
|
8
|
+
* 設計:
|
|
9
|
+
* - wrap() とは独立した明示 API (= LLM 呼び出し単位ではなく操作単位)
|
|
10
|
+
* - timeout 切れ / waitForApproval の待ち時間超過は "expired" / "denied"
|
|
11
|
+
* 扱いで返す = default-deny。 呼び出し側は approved 以外で操作を中止する
|
|
12
|
+
* - polling は default 5 秒間隔 + jitter。 backend の read rate limit は
|
|
13
|
+
* account 単位 60/分 のため、 同時に待てる approval は実質 ~5 件
|
|
14
|
+
* (= 超過分は 429 → 次 poll で再試行されるので安全側だが遅くなる)
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* import { requestApproval, waitForApproval } from "@argosvix/sdk";
|
|
18
|
+
*
|
|
19
|
+
* const approval = await requestApproval({
|
|
20
|
+
* apiKey: "argk_...",
|
|
21
|
+
* action: "delete_user",
|
|
22
|
+
* summary: "user usr_123 を削除します (LTV $0、90 日 inactive)",
|
|
23
|
+
* });
|
|
24
|
+
* const status = await waitForApproval({ apiKey: "argk_...", id: approval.id });
|
|
25
|
+
* if (status !== "approved") throw new Error(`not approved: ${status}`);
|
|
26
|
+
*/
|
|
27
|
+
const DEFAULT_API_BASE = "https://ingest.argosvix.com";
|
|
28
|
+
const INGEST_SUFFIX = "/v1/ingest";
|
|
29
|
+
const DEFAULT_POLL_INTERVAL_MS = 5_000;
|
|
30
|
+
const MIN_POLL_INTERVAL_MS = 1_000;
|
|
31
|
+
const DEFAULT_WAIT_TIMEOUT_MS = 3_600_000;
|
|
32
|
+
const REQUEST_TIMEOUT_MS = 10_000;
|
|
33
|
+
export class ArgosvixApprovalError extends Error {
|
|
34
|
+
status;
|
|
35
|
+
constructor(message, status = null) {
|
|
36
|
+
super(`[argosvix] approval: ${message}`);
|
|
37
|
+
this.name = "ArgosvixApprovalError";
|
|
38
|
+
this.status = status;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function apiBase(opts) {
|
|
42
|
+
const ep = opts.endpoint;
|
|
43
|
+
if (!ep)
|
|
44
|
+
return DEFAULT_API_BASE;
|
|
45
|
+
if (ep.endsWith(INGEST_SUFFIX))
|
|
46
|
+
return ep.slice(0, -INGEST_SUFFIX.length);
|
|
47
|
+
return ep.replace(/\/$/, "");
|
|
48
|
+
}
|
|
49
|
+
async function callApi(opts, path, init = {}) {
|
|
50
|
+
const controller = new AbortController();
|
|
51
|
+
const timer = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
52
|
+
let res;
|
|
53
|
+
try {
|
|
54
|
+
res = await fetch(`${apiBase(opts)}${path}`, {
|
|
55
|
+
method: init.method ?? "GET",
|
|
56
|
+
headers: {
|
|
57
|
+
Authorization: `Bearer ${opts.apiKey}`,
|
|
58
|
+
...(init.body !== undefined ? { "Content-Type": "application/json" } : {}),
|
|
59
|
+
},
|
|
60
|
+
...(init.body !== undefined ? { body: JSON.stringify(init.body) } : {}),
|
|
61
|
+
signal: controller.signal,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
throw new ArgosvixApprovalError(`network error: ${err instanceof Error ? err.message : String(err)}`);
|
|
66
|
+
}
|
|
67
|
+
finally {
|
|
68
|
+
clearTimeout(timer);
|
|
69
|
+
}
|
|
70
|
+
let body = null;
|
|
71
|
+
try {
|
|
72
|
+
body = await res.json();
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
body = null;
|
|
76
|
+
}
|
|
77
|
+
if (!res.ok) {
|
|
78
|
+
const message = body && typeof body === "object" && typeof body.error === "string"
|
|
79
|
+
? (body.error)
|
|
80
|
+
: `HTTP ${res.status}`;
|
|
81
|
+
throw new ArgosvixApprovalError(message, res.status);
|
|
82
|
+
}
|
|
83
|
+
return body;
|
|
84
|
+
}
|
|
85
|
+
/** 承認依頼を作成する。 account owner へ email 通知が飛ぶ。 */
|
|
86
|
+
export async function requestApproval(params) {
|
|
87
|
+
const body = {
|
|
88
|
+
action: params.action,
|
|
89
|
+
summary: params.summary,
|
|
90
|
+
};
|
|
91
|
+
if (params.metadata !== undefined)
|
|
92
|
+
body["metadata"] = params.metadata;
|
|
93
|
+
if (params.timeoutSeconds !== undefined)
|
|
94
|
+
body["timeoutSeconds"] = params.timeoutSeconds;
|
|
95
|
+
const res = (await callApi(params, "/v1/gate/approvals", {
|
|
96
|
+
method: "POST",
|
|
97
|
+
body,
|
|
98
|
+
}));
|
|
99
|
+
if (!res || !res.approval) {
|
|
100
|
+
throw new ArgosvixApprovalError("unexpected response shape");
|
|
101
|
+
}
|
|
102
|
+
return res.approval;
|
|
103
|
+
}
|
|
104
|
+
/** 承認依頼の現在状態を 1 回取得する。 */
|
|
105
|
+
export async function getApproval(params) {
|
|
106
|
+
const res = (await callApi(params, `/v1/gate/approvals/${encodeURIComponent(params.id)}`));
|
|
107
|
+
if (!res || !res.approval) {
|
|
108
|
+
throw new ArgosvixApprovalError("unexpected response shape");
|
|
109
|
+
}
|
|
110
|
+
return res.approval;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* 承認 / 否認 / 期限切れまで polling して最終 status を返す。
|
|
114
|
+
* "approved" 以外が返ったら呼び出し側は操作を実行しないこと (= default-deny)。
|
|
115
|
+
*/
|
|
116
|
+
export async function waitForApproval(params) {
|
|
117
|
+
const baseInterval = Math.max(MIN_POLL_INTERVAL_MS, params.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS);
|
|
118
|
+
const deadline = Date.now() + (params.timeoutMs ?? DEFAULT_WAIT_TIMEOUT_MS);
|
|
119
|
+
for (;;) {
|
|
120
|
+
let status = null;
|
|
121
|
+
try {
|
|
122
|
+
const approval = await getApproval(params);
|
|
123
|
+
status = approval.status;
|
|
124
|
+
}
|
|
125
|
+
catch (err) {
|
|
126
|
+
// 一時的な network / 429 は次の poll で再試行 (= 4xx の恒久 error は throw)
|
|
127
|
+
if (err instanceof ArgosvixApprovalError &&
|
|
128
|
+
err.status !== null &&
|
|
129
|
+
err.status !== 429 &&
|
|
130
|
+
err.status < 500) {
|
|
131
|
+
throw err;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (status && status !== "pending")
|
|
135
|
+
return status;
|
|
136
|
+
if (Date.now() >= deadline)
|
|
137
|
+
return "expired";
|
|
138
|
+
// jitter (= 0-20%) で複数 agent の poll が同期して rate limit に張り付くのを防ぐ
|
|
139
|
+
const jitter = baseInterval * 0.2 * Math.random();
|
|
140
|
+
await new Promise((resolve) => setTimeout(resolve, baseInterval + jitter));
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=approvals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approvals.js","sourceRoot":"","sources":["../src/approvals.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { ArgosvixConfig } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* model 名の canonical form (= R72b MEDIUM 3)。 Gemini 系 SDK が保持する
|
|
4
|
+
* "models/gemini-pro" の provider prefix を除去し、 allowlist 比較を
|
|
5
|
+
* TS / Python 両 SDK で同一にする。 export = test + Python 側と並走 verify 用。
|
|
6
|
+
*/
|
|
7
|
+
export declare function canonicalizeModelName(model: string): string;
|
|
8
|
+
export declare class ArgosvixBudgetExceededError extends Error {
|
|
9
|
+
readonly spentUsd: number;
|
|
10
|
+
readonly limitUsd: number;
|
|
11
|
+
constructor(spentUsd: number, limitUsd: number);
|
|
12
|
+
}
|
|
13
|
+
export declare class ArgosvixBudgetGateUnavailableError extends Error {
|
|
14
|
+
constructor();
|
|
15
|
+
}
|
|
16
|
+
export type PolicyViolationReason = "model_not_allowed" | "pii_detected" | "secret_detected";
|
|
17
|
+
export declare class ArgosvixPolicyViolationError extends Error {
|
|
18
|
+
readonly reason: PolicyViolationReason;
|
|
19
|
+
readonly detail: string;
|
|
20
|
+
constructor(reason: PolicyViolationReason, detail: string);
|
|
21
|
+
}
|
|
22
|
+
/** wrapper が check() に渡す呼び出し文脈。 */
|
|
23
|
+
export interface GateCheckContext {
|
|
24
|
+
/** request の model 名 (= 取れない経路では payload から補完)。 */
|
|
25
|
+
model?: string | undefined;
|
|
26
|
+
/** provider に渡す request payload (= policy の PII / secret 検査対象)。 */
|
|
27
|
+
payload?: unknown;
|
|
28
|
+
}
|
|
29
|
+
export declare class RuntimeGate {
|
|
30
|
+
private readonly config;
|
|
31
|
+
private snapshot;
|
|
32
|
+
private inflight;
|
|
33
|
+
private lastAttemptMs;
|
|
34
|
+
private lastAttemptFailed;
|
|
35
|
+
private warnedEndpoint;
|
|
36
|
+
private warnedNoPolicy;
|
|
37
|
+
/** 直近の成功 fetch 以降にこのプロセスが record した消費の補正値。 */
|
|
38
|
+
private localSpendUsd;
|
|
39
|
+
constructor(config: ArgosvixConfig);
|
|
40
|
+
/** monotonic clock。wall clock の逆行 (NTP step / VM resume) に影響されない。 */
|
|
41
|
+
private now;
|
|
42
|
+
/** opt-in + 送信可能な構成のときだけ動く。それ以外は完全 no-op。 */
|
|
43
|
+
private get active();
|
|
44
|
+
/** recorder.record() から呼ばれる。TTL 窓内のローカル消費補正。 */
|
|
45
|
+
noteSpend(costUsd: number): void;
|
|
46
|
+
/**
|
|
47
|
+
* LLM 呼び出し直前の enforce。超過なら throw、それ以外は素通し。
|
|
48
|
+
* backend 障害は enforce mode に従って fail-open / fail-closed。
|
|
49
|
+
*/
|
|
50
|
+
check(ctx?: GateCheckContext): Promise<void>;
|
|
51
|
+
private evaluate;
|
|
52
|
+
/** ポリシーゲートのローカル評価 (= モデル allowlist / PII / secret)。 */
|
|
53
|
+
private evaluatePolicy;
|
|
54
|
+
private isStale;
|
|
55
|
+
/** 直近 fetch が失敗していた場合、FAILURE_RETRY_MS 経過まで再試行しない。 */
|
|
56
|
+
private attemptAllowed;
|
|
57
|
+
private refresh;
|
|
58
|
+
/**
|
|
59
|
+
* gate endpoint の決定。 ingest endpoint を override している場合は同 prefix
|
|
60
|
+
* から導出し、 導出できない形 (= /v1/ingest で終わらない custom URL) なら
|
|
61
|
+
* gate を無効化する (= 他環境向け Bearer key を production に送らない、R65b M-2)。
|
|
62
|
+
*/
|
|
63
|
+
private gateEndpoint;
|
|
64
|
+
private fetchOnce;
|
|
65
|
+
}
|
|
66
|
+
export { RuntimeGate as BudgetGate };
|
|
67
|
+
//# sourceMappingURL=budgetGate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"budgetGate.d.ts","sourceRoot":"","sources":["../src/budgetGate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAgDjD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,qBAAa,2BAA4B,SAAQ,KAAK;IACpD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBACd,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;CAQ/C;AAED,qBAAa,kCAAmC,SAAQ,KAAK;;CAO5D;AAED,MAAM,MAAM,qBAAqB,GAC7B,mBAAmB,GACnB,cAAc,GACd,iBAAiB,CAAC;AAEtB,qBAAa,4BAA6B,SAAQ,KAAK;IACrD,QAAQ,CAAC,MAAM,EAAE,qBAAqB,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBACZ,MAAM,EAAE,qBAAqB,EAAE,MAAM,EAAE,MAAM;CAM1D;AAmBD,mCAAmC;AACnC,MAAM,WAAW,gBAAgB;IAC/B,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,mEAAmE;IACnE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAA6B;IAC7C,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,cAAc,CAAS;IAC/B,8CAA8C;IAC9C,OAAO,CAAC,aAAa,CAAK;gBAEd,MAAM,EAAE,cAAc;IAIlC,qEAAqE;IACrE,OAAO,CAAC,GAAG;IAIX,6CAA6C;IAC7C,OAAO,KAAK,MAAM,GAOjB;IAED,gDAAgD;IAChD,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAOhC;;;OAGG;IACG,KAAK,CAAC,GAAG,GAAE,gBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BtD,OAAO,CAAC,QAAQ;IAwChB,uDAAuD;IACvD,OAAO,CAAC,cAAc;IA4CtB,OAAO,CAAC,OAAO;IAKf,sDAAsD;IACtD,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,OAAO;IAUf;;;;OAIG;IACH,OAAO,CAAC,YAAY;YAmBN,SAAS;CAuHxB;AAGD,OAAO,EAAE,WAAW,IAAI,UAAU,EAAE,CAAC"}
|