@alfe.ai/claude-code-host 0.1.15 → 0.1.17
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/dist/cli.js +1 -1
- package/dist/host-config.cjs +595 -123
- package/dist/host-config.js +529 -117
- package/dist/index.cjs +12 -2
- package/dist/index.d.cts +254 -57
- package/dist/index.d.ts +254 -57
- package/dist/index.js +2 -2
- package/package.json +5 -5
package/dist/index.d.ts
CHANGED
|
@@ -90,12 +90,19 @@ interface ConnectProviderAccounts {
|
|
|
90
90
|
}
|
|
91
91
|
/**
|
|
92
92
|
* One AWS CLI profile an agent may use (`GET /agent/connect/aws/accounts`).
|
|
93
|
-
* `roleArn` is null for a connection's Direct identity
|
|
94
|
-
*
|
|
93
|
+
* `roleArn` is null for a connection's Direct identity and for IAM Identity
|
|
94
|
+
* Center (SSO) profiles, which name their `permissionSet` instead. Carries no
|
|
95
|
+
* secret material; sessions are minted per call via `getAwsSession`.
|
|
95
96
|
*/
|
|
96
97
|
interface AwsProfile {
|
|
97
98
|
profile: string;
|
|
98
99
|
roleArn: string | null;
|
|
100
|
+
/**
|
|
101
|
+
* IAM Identity Center permission set (role name) for an SSO profile; `null`
|
|
102
|
+
* for role, access-key and shared-session profiles. Older servers omit the
|
|
103
|
+
* field, which normalizes to `null`.
|
|
104
|
+
*/
|
|
105
|
+
permissionSet: string | null;
|
|
99
106
|
accountId: string;
|
|
100
107
|
region: string;
|
|
101
108
|
label: string | null;
|
|
@@ -862,11 +869,21 @@ interface AgentClaudeCredential {
|
|
|
862
869
|
revision: string;
|
|
863
870
|
updatedAt: string;
|
|
864
871
|
}
|
|
865
|
-
/**
|
|
872
|
+
/**
|
|
873
|
+
* Claude auth health a claude-code host reports for its agent. `missing` is
|
|
874
|
+
* legacy: hosts since the AI-proxy fallback (2026-10-15) never send it.
|
|
875
|
+
*/
|
|
866
876
|
type ClaudeCredentialHealth = "ok" | "missing" | "invalid";
|
|
877
|
+
/**
|
|
878
|
+
* Which auth the host's turns run on: the stored credential, the machine's
|
|
879
|
+
* own `claude` login (self-hosted only), or the Alfe AI proxy (Alfe credits).
|
|
880
|
+
*/
|
|
881
|
+
type ClaudeCredentialSource = "credential" | "local_login" | "ai_proxy";
|
|
867
882
|
/** Body of PUT /agent/claude-credential/status. */
|
|
868
883
|
interface ClaudeCredentialStatusReport {
|
|
869
884
|
status: ClaudeCredentialHealth;
|
|
885
|
+
/** The auth source the status describes. Omitted only by older hosts. */
|
|
886
|
+
source?: ClaudeCredentialSource;
|
|
870
887
|
/** Short (≤200 chars), fixed host-side explanation. Never `claude` output or a secret. */
|
|
871
888
|
detail?: string;
|
|
872
889
|
/**
|
|
@@ -894,8 +911,8 @@ declare class WorkspaceApi extends ApiBase {
|
|
|
894
911
|
}>;
|
|
895
912
|
/**
|
|
896
913
|
* GET /agent/claude-credential — the authenticated claude-code agent's own
|
|
897
|
-
* Claude credential, or `null` when none is stored (
|
|
898
|
-
*
|
|
914
|
+
* Claude credential, or `null` when none is stored (the host then falls back
|
|
915
|
+
* to the local `claude` login when self-hosted, else the Alfe AI proxy). Fetch on every runtime start: the
|
|
899
916
|
* daemon restarts the host whenever the credential changes.
|
|
900
917
|
*/
|
|
901
918
|
getClaudeCredential(): Promise<AgentClaudeCredential | null>;
|
|
@@ -2271,22 +2288,35 @@ declare class ChatServiceClient {
|
|
|
2271
2288
|
/**
|
|
2272
2289
|
* Child-process environment construction for spawned `claude` CLI processes.
|
|
2273
2290
|
*
|
|
2274
|
-
*
|
|
2291
|
+
* Every turn runs on exactly ONE auth source (`ChildAuth`), resolved by the
|
|
2292
|
+
* host (see DEVELOPING.md "Auth source resolution"):
|
|
2293
|
+
*
|
|
2294
|
+
* - `credential` — the agent's stored Claude credential, set as exactly one
|
|
2295
|
+
* variable: `CLAUDE_CODE_OAUTH_TOKEN` (subscription token from
|
|
2296
|
+
* `claude setup-token`) or `ANTHROPIC_API_KEY` (Anthropic API key).
|
|
2297
|
+
* - `local_login` — self-hosted only: no auth variable, so `claude` uses the
|
|
2298
|
+
* machine's own login (and whatever provider the operator configured).
|
|
2299
|
+
* - `ai_proxy` — the Alfe AI proxy via the daemon's loopback proxy:
|
|
2300
|
+
* `ANTHROPIC_BASE_URL` = the local proxy, `ANTHROPIC_AUTH_TOKEN` = a
|
|
2301
|
+
* placeholder the local proxy replaces with the daemon's agent key, and
|
|
2302
|
+
* every model alias pinned to an Alfe registry id (the proxy routes exact
|
|
2303
|
+
* registry ids only; the CLI's built-in aliases resolve to dated ids that
|
|
2304
|
+
* are a 409 there).
|
|
2305
|
+
*
|
|
2306
|
+
* Invariants:
|
|
2275
2307
|
*
|
|
2276
2308
|
* 1. **Scrub inherited Claude auth.** `ANTHROPIC_API_KEY` / `ANTHROPIC_BASE_URL`
|
|
2277
2309
|
* / `ANTHROPIC_AUTH_TOKEN` / `CLAUDE_CODE_OAUTH_TOKEN` are removed from BOTH
|
|
2278
2310
|
* the parent env and any caller `extra`. A self-hosted Mac very often has
|
|
2279
2311
|
* these set for other tooling; if one reaches `claude` it silently switches
|
|
2280
|
-
* accounts or billing plane
|
|
2281
|
-
*
|
|
2312
|
+
* accounts or billing plane. Credential and proxy modes also drop provider
|
|
2313
|
+
* overrides (Bedrock/Vertex/Foundry); proxy mode additionally drops model
|
|
2314
|
+
* and header overrides so nothing reaches the proxy that it cannot price.
|
|
2282
2315
|
*
|
|
2283
|
-
* 2. **Inject the
|
|
2284
|
-
*
|
|
2285
|
-
*
|
|
2286
|
-
*
|
|
2287
|
-
* else can override it. With no credential, no auth variable is set and
|
|
2288
|
-
* `claude` uses the machine's own login (self-hosted fallback). The value
|
|
2289
|
-
* lives only in the host's memory and this env — never on disk, never logged.
|
|
2316
|
+
* 2. **Inject the source last.** Nothing in `base` or `extra` can override the
|
|
2317
|
+
* injected credential or proxy settings. A credential lives only in the
|
|
2318
|
+
* host's memory and this env, never on disk, never logged. Proxy settings
|
|
2319
|
+
* never appear in a credential or local-login env.
|
|
2290
2320
|
*
|
|
2291
2321
|
* 3. **Set `ALFE_CLAUDE_BRIDGE=1`.** The Phase-1 CLI hooks
|
|
2292
2322
|
* (`alfe claude hook ...` in `packages/cli/src/commands/claude.ts`) check
|
|
@@ -2299,14 +2329,55 @@ declare class ChatServiceClient {
|
|
|
2299
2329
|
declare const SCRUBBED_ANTHROPIC_ENV_VARS: readonly ["ANTHROPIC_API_KEY", "ANTHROPIC_BASE_URL", "ANTHROPIC_AUTH_TOKEN", "CLAUDE_CODE_OAUTH_TOKEN"];
|
|
2300
2330
|
/**
|
|
2301
2331
|
* Provider-selection and endpoint overrides that would route `claude` away from
|
|
2302
|
-
* the Anthropic API. Dropped whenever
|
|
2303
|
-
* inherited `CLAUDE_CODE_USE_BEDROCK=1` (say) can't send the turn to
|
|
2304
|
-
* and ignore the
|
|
2305
|
-
* the machine's own `claude` setup is the
|
|
2332
|
+
* the Anthropic API. Dropped whenever a credential or the AI proxy is in use,
|
|
2333
|
+
* so an inherited `CLAUDE_CODE_USE_BEDROCK=1` (say) can't send the turn to
|
|
2334
|
+
* Bedrock and ignore the chosen source. On a local login they are left alone:
|
|
2335
|
+
* the machine's own `claude` setup is the source, whatever provider it uses.
|
|
2306
2336
|
*/
|
|
2307
2337
|
|
|
2308
2338
|
/** Cross-phase contract marker (see header + packages/cli/src/commands/claude.ts). */
|
|
2309
2339
|
declare const BRIDGE_ENV_VAR = "ALFE_CLAUDE_BRIDGE";
|
|
2340
|
+
/**
|
|
2341
|
+
* Placeholder `ANTHROPIC_AUTH_TOKEN` (sent as `Authorization: Bearer`) for
|
|
2342
|
+
* proxy mode. `@alfe.ai/ai-proxy-local` keeps an incoming `alfe_…` key and
|
|
2343
|
+
* replaces anything else with the daemon's agent key (as `x-api-key`, dropping
|
|
2344
|
+
* `authorization`), so the agent key itself never enters the `claude` env (a
|
|
2345
|
+
* managed agent has Bash). Never `alfe_…`.
|
|
2346
|
+
*/
|
|
2347
|
+
declare const PROXY_API_KEY_PLACEHOLDER = "alfe-local-proxy";
|
|
2348
|
+
/**
|
|
2349
|
+
* Default local AI proxy (`DEFAULT_AI_PROXY_PORT` in `@alfe.ai/ai-proxy-local`).
|
|
2350
|
+
* The daemon passes the URL it actually bound as `ALFE_LOCAL_AI_PROXY_URL`;
|
|
2351
|
+
* this is the fallback. Bare host, no `/v1`: `claude` appends `/v1/messages`.
|
|
2352
|
+
*/
|
|
2353
|
+
declare const DEFAULT_LOCAL_AI_PROXY_URL = "http://127.0.0.1:18193";
|
|
2354
|
+
/**
|
|
2355
|
+
* The model `claude -p --model` runs in proxy mode when the agent has no
|
|
2356
|
+
* `defaultModel` (or the daemon's lookup timed out). `claude`'s own default is
|
|
2357
|
+
* a dated id the proxy cannot route. Haiku 4.5 is the one Claude model seeded
|
|
2358
|
+
* on every stage (the memory integration depends on it), so it is the only
|
|
2359
|
+
* id guaranteed to route; the dashboard always sets a model, so this is rare.
|
|
2360
|
+
*/
|
|
2361
|
+
declare const PROXY_DEFAULT_MODEL = "claude-haiku-4-5";
|
|
2362
|
+
/**
|
|
2363
|
+
* Fixed model env in proxy mode, Alfe registry ids (`AnthropicModel` in
|
|
2364
|
+
* `@alfe/types`; the child-env test asserts it). `ANTHROPIC_SMALL_FAST_MODEL`
|
|
2365
|
+
* drives background calls (titles, summaries); `ANTHROPIC_DEFAULT_HAIKU_MODEL`
|
|
2366
|
+
* resolves the `haiku` alias. Haiku 4.5 because it is seeded on every stage.
|
|
2367
|
+
* claude 2.1.284/2.1.287 read these and {@link PROXY_AGENT_MODEL_ENV_VARS}.
|
|
2368
|
+
*/
|
|
2369
|
+
declare const PROXY_MODEL_ENV: {
|
|
2370
|
+
readonly ANTHROPIC_SMALL_FAST_MODEL: "claude-haiku-4-5";
|
|
2371
|
+
readonly ANTHROPIC_DEFAULT_HAIKU_MODEL: "claude-haiku-4-5";
|
|
2372
|
+
};
|
|
2373
|
+
/**
|
|
2374
|
+
* The `sonnet` / `opus` aliases (subagents) resolve to the agent's OWN model
|
|
2375
|
+
* in proxy mode: the agents service validated it against the registry, while a
|
|
2376
|
+
* fixed 5.x id may not be enabled on the workspace.
|
|
2377
|
+
*/
|
|
2378
|
+
declare const PROXY_AGENT_MODEL_ENV_VARS: readonly ["ANTHROPIC_DEFAULT_SONNET_MODEL", "ANTHROPIC_DEFAULT_OPUS_MODEL"];
|
|
2379
|
+
/** Set only in proxy mode (besides the auth pair). */
|
|
2380
|
+
|
|
2310
2381
|
/** The agent's Claude credential, as fetched from `GET /agent/claude-credential`. */
|
|
2311
2382
|
interface ChildCredential {
|
|
2312
2383
|
kind: 'oauth_token' | 'api_key';
|
|
@@ -2314,16 +2385,29 @@ interface ChildCredential {
|
|
|
2314
2385
|
}
|
|
2315
2386
|
/** The single env var each credential kind is exported as. */
|
|
2316
2387
|
declare const CREDENTIAL_ENV_VAR: Record<ChildCredential['kind'], string>;
|
|
2388
|
+
/** The auth source of one `claude` child. */
|
|
2389
|
+
type ChildAuth = {
|
|
2390
|
+
mode: 'credential';
|
|
2391
|
+
credential: ChildCredential;
|
|
2392
|
+
} | {
|
|
2393
|
+
mode: 'local_login';
|
|
2394
|
+
}
|
|
2395
|
+
/** `model` = the turn's registry model id (`--model`); also the sonnet/opus aliases. */ | {
|
|
2396
|
+
mode: 'ai_proxy';
|
|
2397
|
+
baseUrl: string;
|
|
2398
|
+
model: string;
|
|
2399
|
+
};
|
|
2317
2400
|
/**
|
|
2318
2401
|
* Build the env handed to a spawned `claude` child. Pure — takes the base env
|
|
2319
2402
|
* explicitly so it unit-tests without touching `process.env`.
|
|
2320
2403
|
*
|
|
2321
2404
|
* Order: merge `base` + `extra` → drop every scrubbed var (plus provider
|
|
2322
|
-
* overrides
|
|
2323
|
-
*
|
|
2324
|
-
* smuggle an auth variable in or override the
|
|
2405
|
+
* overrides for a credential or the proxy, plus model overrides for the
|
|
2406
|
+
* proxy) → set the bridge marker → set the source's variables. Neither `base`
|
|
2407
|
+
* nor `extra` can smuggle an auth variable in or override the source.
|
|
2408
|
+
* `auth` omitted = local login.
|
|
2325
2409
|
*/
|
|
2326
|
-
declare function buildChildEnv(base: NodeJS.ProcessEnv, extra?: Record<string, string>,
|
|
2410
|
+
declare function buildChildEnv(base: NodeJS.ProcessEnv, extra?: Record<string, string>, auth?: ChildAuth): NodeJS.ProcessEnv;
|
|
2327
2411
|
//#endregion
|
|
2328
2412
|
//#region src/stream-mapper.d.ts
|
|
2329
2413
|
/**
|
|
@@ -2421,6 +2505,11 @@ interface EndEmission {
|
|
|
2421
2505
|
* message). Present only on error turns.
|
|
2422
2506
|
*/
|
|
2423
2507
|
authFailed?: true;
|
|
2508
|
+
/**
|
|
2509
|
+
* The refusal was a 403 (forbidden: an org or provider policy), not a dead
|
|
2510
|
+
* login or key. Present only with `authFailed`.
|
|
2511
|
+
*/
|
|
2512
|
+
authForbidden?: true;
|
|
2424
2513
|
}
|
|
2425
2514
|
type MapperEmission = ActivityEmission | TextEmission | EndEmission;
|
|
2426
2515
|
interface PendingTool {
|
|
@@ -2535,6 +2624,8 @@ interface DriverTurnResult {
|
|
|
2535
2624
|
aborted: boolean;
|
|
2536
2625
|
/** Present (true) when the turn failed because Claude refused the credential. */
|
|
2537
2626
|
authFailed?: true;
|
|
2627
|
+
/** With `authFailed`: the refusal was a 403 (policy), not a dead login/key. */
|
|
2628
|
+
authForbidden?: true;
|
|
2538
2629
|
}
|
|
2539
2630
|
interface RunTurnParams {
|
|
2540
2631
|
/** The user prompt for this turn. */
|
|
@@ -2547,9 +2638,16 @@ interface RunTurnParams {
|
|
|
2547
2638
|
mcpConfigPath?: string;
|
|
2548
2639
|
/** Persona + reply-style text appended to the system prompt. Omitted → none. */
|
|
2549
2640
|
appendSystemPrompt?: string;
|
|
2550
|
-
/**
|
|
2641
|
+
/**
|
|
2642
|
+
* Bare Claude model id for `--model`. Omitted → CLI default (never in proxy
|
|
2643
|
+
* mode: the host always passes a registry id there).
|
|
2644
|
+
*/
|
|
2551
2645
|
model?: string;
|
|
2552
|
-
/**
|
|
2646
|
+
/**
|
|
2647
|
+
* Built-in tool allow-list (defaults to DEFAULT_ALLOWED_TOOLS, or
|
|
2648
|
+
* MANAGED_ALLOWED_TOOLS on a managed VM). The `--mcp-config` servers' rules
|
|
2649
|
+
* are always appended.
|
|
2650
|
+
*/
|
|
2553
2651
|
allowedTools?: readonly string[];
|
|
2554
2652
|
/** Permission mode (defaults to DEFAULT_PERMISSION_MODE — never bypass). */
|
|
2555
2653
|
permissionMode?: ClaudePermissionMode;
|
|
@@ -2580,7 +2678,7 @@ declare class SessionDriver {
|
|
|
2580
2678
|
private abortCurrent;
|
|
2581
2679
|
private readonly bin;
|
|
2582
2680
|
private readonly baseEnv;
|
|
2583
|
-
private readonly
|
|
2681
|
+
private readonly auth;
|
|
2584
2682
|
private readonly managed;
|
|
2585
2683
|
private readonly log;
|
|
2586
2684
|
/** Injected spawn — tests replace this with a fake child. */
|
|
@@ -2589,10 +2687,10 @@ declare class SessionDriver {
|
|
|
2589
2687
|
claudeBin?: string;
|
|
2590
2688
|
baseEnv?: NodeJS.ProcessEnv;
|
|
2591
2689
|
/**
|
|
2592
|
-
* The
|
|
2593
|
-
*
|
|
2690
|
+
* The turn's auth source, applied to the child env after the scrub
|
|
2691
|
+
* (`buildChildEnv`). Absent → the machine's own `claude` login.
|
|
2594
2692
|
*/
|
|
2595
|
-
|
|
2693
|
+
auth?: ChildAuth;
|
|
2596
2694
|
/** Managed VM: Bash allowed + deny rules (see MANAGED_ALLOWED_TOOLS). */
|
|
2597
2695
|
managed?: boolean;
|
|
2598
2696
|
logger?: Logger;
|
|
@@ -2638,22 +2736,46 @@ declare function loadCredentialWithRetry(fetchCredential: () => Promise<HostCred
|
|
|
2638
2736
|
credential: HostCredential | null;
|
|
2639
2737
|
} | null>;
|
|
2640
2738
|
declare function isAuthFailureText(text: string): boolean;
|
|
2739
|
+
/** Why the Alfe AI proxy refused a request it otherwise authenticated. */
|
|
2740
|
+
type ProxyDenial = 'credits' | 'usage_limit' | 'model_unavailable';
|
|
2741
|
+
/**
|
|
2742
|
+
* Classify an Alfe AI proxy refusal from the text `claude` reports. The proxy
|
|
2743
|
+
* answers credit and usage-limit denials on `/v1/messages` with a 429
|
|
2744
|
+
* `rate_limit_error` (never 402, see services/ai DEVELOPING.md "Credit denials
|
|
2745
|
+
* on LLM routes are 429"); claude 2.1.287 surfaces it as
|
|
2746
|
+
* `API Error: Request rejected (429) · <message>` (fixture
|
|
2747
|
+
* `turn-proxy-credits.stream.jsonl`). Credit texts also say "usage limit
|
|
2748
|
+
* reached", so they are checked first. An Anthropic subscription limit
|
|
2749
|
+
* ("Claude AI usage limit reached") is not an Alfe denial.
|
|
2750
|
+
*/
|
|
2751
|
+
declare function classifyProxyDenial(text: string): ProxyDenial | null;
|
|
2641
2752
|
/** HTTP statuses on a `result` event that mean "credential refused". */
|
|
2642
2753
|
|
|
2643
2754
|
type ProbeOutcome = {
|
|
2644
2755
|
result: 'ok';
|
|
2645
|
-
}
|
|
2756
|
+
}
|
|
2757
|
+
/** `forbidden`: a 403 (an org or provider policy), not a dead login or key. */ | {
|
|
2646
2758
|
result: 'invalid';
|
|
2759
|
+
forbidden?: true;
|
|
2760
|
+
}
|
|
2761
|
+
/** The Alfe AI proxy authenticated the agent but refused the request. */ | {
|
|
2762
|
+
result: 'denied';
|
|
2763
|
+
denial: ProxyDenial;
|
|
2647
2764
|
} | {
|
|
2648
2765
|
result: 'unknown';
|
|
2649
2766
|
reason: string;
|
|
2650
2767
|
};
|
|
2651
2768
|
declare const AUTH_PROBE_TIMEOUT_MS = 60000;
|
|
2652
|
-
/**
|
|
2653
|
-
|
|
2769
|
+
/**
|
|
2770
|
+
* argv for the probe. No tools, no session file, no MCP, no settings files.
|
|
2771
|
+
* `model` is `haiku` (the alias) on a credential or local login, and the
|
|
2772
|
+
* registry Haiku id through the AI proxy.
|
|
2773
|
+
*/
|
|
2774
|
+
declare function buildProbeArgs(model?: string): string[];
|
|
2654
2775
|
declare function parseProbeOutput(stdout: string, stderr: string, exitCode: number | null): ProbeOutcome;
|
|
2655
2776
|
interface AuthProbeOptions {
|
|
2656
|
-
credential
|
|
2777
|
+
/** The auth source to check (a credential, the local login, or the AI proxy). */
|
|
2778
|
+
auth: ChildAuth;
|
|
2657
2779
|
baseEnv: NodeJS.ProcessEnv;
|
|
2658
2780
|
/** Any existing directory; the probe reads and writes nothing there. */
|
|
2659
2781
|
cwd: string;
|
|
@@ -2664,12 +2786,17 @@ interface AuthProbeOptions {
|
|
|
2664
2786
|
signal?: AbortSignal;
|
|
2665
2787
|
}
|
|
2666
2788
|
/**
|
|
2667
|
-
* One minimal real turn
|
|
2668
|
-
*
|
|
2789
|
+
* One minimal real turn on the given auth source: Anthropic with the agent's
|
|
2790
|
+
* credential or the machine's own login, or the Alfe AI proxy (a Haiku ping
|
|
2791
|
+
* billed from Alfe credits). Never throws.
|
|
2669
2792
|
*/
|
|
2670
2793
|
declare function runAuthProbe(opts: AuthProbeOptions): Promise<ProbeOutcome>;
|
|
2794
|
+
/** Which auth the host's turns run on (projected as `claudeCredentialSource`). */
|
|
2795
|
+
type CredentialSource = 'credential' | 'local_login' | 'ai_proxy';
|
|
2671
2796
|
interface CredentialStatusReport {
|
|
2797
|
+
/** `missing` is legacy; this host never sends it (it falls back to the AI proxy). */
|
|
2672
2798
|
status: 'ok' | 'missing' | 'invalid';
|
|
2799
|
+
source?: CredentialSource;
|
|
2673
2800
|
/** Fixed, host-authored text only. Never `claude` output. */
|
|
2674
2801
|
detail?: string;
|
|
2675
2802
|
revision?: string;
|
|
@@ -2715,21 +2842,31 @@ interface ClaudeCodeHostConfig {
|
|
|
2715
2842
|
/**
|
|
2716
2843
|
* Bare Claude model id for `claude -p --model` (e.g. `claude-opus-4-8` or the
|
|
2717
2844
|
* `opus`/`sonnet`/`haiku` aliases). Sourced from the agent's `defaultModel`
|
|
2718
|
-
* via `ALFE_DEFAULT_MODEL`. Omitted → the operator's `claude` CLI default
|
|
2845
|
+
* via `ALFE_DEFAULT_MODEL`. Omitted → the operator's `claude` CLI default on
|
|
2846
|
+
* a credential or local login, `PROXY_DEFAULT_MODEL` on the AI proxy.
|
|
2719
2847
|
* NEVER provider-qualified (`anthropic/…`) — that's an OpenClaw-only shape.
|
|
2720
2848
|
*/
|
|
2721
2849
|
model?: string;
|
|
2722
2850
|
/**
|
|
2723
|
-
* Managed VM (`ALFE_MANAGED=1|true`, set by the daemon). Enables Bash
|
|
2724
|
-
*
|
|
2725
|
-
* fall back to). Self-hosted when false/absent.
|
|
2851
|
+
* Managed VM (`ALFE_MANAGED=1|true`, set by the daemon). Enables Bash. With
|
|
2852
|
+
* no stored credential a managed agent always runs on the Alfe AI proxy (no
|
|
2853
|
+
* local login to fall back to). Self-hosted when false/absent.
|
|
2726
2854
|
*/
|
|
2727
2855
|
managed?: boolean;
|
|
2856
|
+
/**
|
|
2857
|
+
* The daemon's loopback AI proxy (`ALFE_LOCAL_AI_PROXY_URL`). Defaults to
|
|
2858
|
+
* `DEFAULT_LOCAL_AI_PROXY_URL`.
|
|
2859
|
+
*/
|
|
2860
|
+
localAiProxyUrl?: string;
|
|
2728
2861
|
logger?: Logger;
|
|
2729
2862
|
}
|
|
2730
2863
|
declare const CREDENTIAL_INVALID_MESSAGE = "This agent's Claude credential is invalid or expired. Update it in agent settings.";
|
|
2731
|
-
declare const
|
|
2732
|
-
declare const
|
|
2864
|
+
declare const OUT_OF_CREDITS_MESSAGE = "This agent is out of Alfe credits. Add credits in Alfe Billing, or add a Claude credential in agent settings, then resend your message.";
|
|
2865
|
+
declare const USAGE_LIMIT_MESSAGE = "This agent hit an Alfe usage limit. Raise the limit in Alfe or wait for it to reset, then resend your message.";
|
|
2866
|
+
declare const LOCAL_LOGIN_SWITCHED_MESSAGE = "Your machine's Claude login stopped working, so this agent switched to Alfe credits. Please resend your message.";
|
|
2867
|
+
declare const LOCAL_LOGIN_REFUSED_MESSAGE = "Claude refused this machine's claude login (403). Check the account or its organisation policy, or add a Claude credential in agent settings.";
|
|
2868
|
+
declare const MODEL_UNAVAILABLE_MESSAGE = "This agent's model isn't available on this workspace. Choose another Claude model in agent settings, then resend your message.";
|
|
2869
|
+
declare const PROXY_AUTH_FAILED_MESSAGE = "Alfe AI rejected this agent's key. Reconnect the agent (run `alfe setup` on its machine), or add a Claude credential in agent settings.";
|
|
2733
2870
|
declare const CREDENTIAL_UNAVAILABLE_MESSAGE = "This agent's Claude credential couldn't be loaded yet. Try again in a moment.";
|
|
2734
2871
|
/** How long a turn waits for the start-up credential fetch before failing. */
|
|
2735
2872
|
|
|
@@ -2768,8 +2905,16 @@ declare class ClaudeCodeHost {
|
|
|
2768
2905
|
/** Turns waiting for the credential, before queue admission (chat.abort). */
|
|
2769
2906
|
private readonly waitingTurns;
|
|
2770
2907
|
private readonly loaderRestartMs;
|
|
2908
|
+
/** How often a fallen-back self-hosted agent re-checks its local login. */
|
|
2909
|
+
private readonly localLoginRecheckMs;
|
|
2910
|
+
private localLoginRecheck;
|
|
2771
2911
|
/** In memory only. Never logged, never persisted. */
|
|
2772
2912
|
private credential;
|
|
2913
|
+
/**
|
|
2914
|
+
* The auth every new turn runs on, resolved once the credential fetch
|
|
2915
|
+
* answers (see `resolveAuthSource`). Null before that.
|
|
2916
|
+
*/
|
|
2917
|
+
private authSource;
|
|
2773
2918
|
private readonly credentialAbort;
|
|
2774
2919
|
private readonly reporter;
|
|
2775
2920
|
private readonly probe;
|
|
@@ -2777,17 +2922,22 @@ declare class ClaudeCodeHost {
|
|
|
2777
2922
|
private readonly credentialRetry;
|
|
2778
2923
|
constructor(cfg: ClaudeCodeHostConfig, deps?: {
|
|
2779
2924
|
/**
|
|
2780
|
-
* Per-turn driver factory (test seam). Called once per turn
|
|
2781
|
-
*
|
|
2925
|
+
* Per-turn driver factory (test seam). Called once per turn (and once
|
|
2926
|
+
* more for a local-login turn re-run on the AI proxy) with its auth.
|
|
2782
2927
|
*/
|
|
2783
|
-
makeDriver?: (
|
|
2928
|
+
makeDriver?: (auth: ChildAuth) => SessionDriver;
|
|
2784
2929
|
chat?: ChatServiceClient;
|
|
2785
2930
|
api?: AgentApiClient;
|
|
2786
2931
|
/** Start-up auth check (test seam; default: a minimal `claude -p`). */
|
|
2787
|
-
probe?: (
|
|
2932
|
+
probe?: (auth: ChildAuth, signal: AbortSignal) => Promise<ProbeOutcome>;
|
|
2788
2933
|
credentialWaitMs?: number;
|
|
2789
2934
|
/** Delay before restarting a credential loader that threw (default 5 s). */
|
|
2790
2935
|
loaderRestartMs?: number;
|
|
2936
|
+
/**
|
|
2937
|
+
* After falling back from a refused local login, re-probe it this often
|
|
2938
|
+
* and switch back when it works (default: the status-report interval).
|
|
2939
|
+
*/
|
|
2940
|
+
localLoginRecheckMs?: number;
|
|
2791
2941
|
credentialRetry?: {
|
|
2792
2942
|
baseDelayMs?: number;
|
|
2793
2943
|
maxDelayMs?: number;
|
|
@@ -2801,11 +2951,33 @@ declare class ClaudeCodeHost {
|
|
|
2801
2951
|
*/
|
|
2802
2952
|
private runCredentialLoader;
|
|
2803
2953
|
private loadCredential;
|
|
2804
|
-
|
|
2805
|
-
|
|
2954
|
+
/**
|
|
2955
|
+
* A method, not a property read: `stopping` flips across awaits, which
|
|
2956
|
+
* control-flow narrowing cannot see.
|
|
2957
|
+
*/
|
|
2958
|
+
private isStopping;
|
|
2959
|
+
/** Same reason as `isStopping`: `authSource` can change across an await. */
|
|
2960
|
+
private currentAuthSource;
|
|
2961
|
+
/** The auth a new turn runs on. Local login until the fetch has answered. */
|
|
2962
|
+
private childAuth;
|
|
2963
|
+
/**
|
|
2964
|
+
* A self-hosted agent with no credential whose local login was refused (401
|
|
2965
|
+
* or an explicit auth message, never a 403): run new turns through the Alfe
|
|
2966
|
+
* AI proxy, and re-check the login periodically so a re-login moves the agent
|
|
2967
|
+
* back off Alfe credits. Never for a stored credential (the user chose it; a
|
|
2968
|
+
* refusal there needs their fix) and never on managed.
|
|
2969
|
+
*/
|
|
2970
|
+
private fallBackToProxy;
|
|
2971
|
+
private scheduleLocalLoginRecheck;
|
|
2972
|
+
/** While fallen back: one local-login probe; back to the login when it works. */
|
|
2973
|
+
private recheckLocalLogin;
|
|
2974
|
+
/**
|
|
2975
|
+
* Start-up check: one minimal real call on the resolved source, reported to
|
|
2976
|
+
* the cloud. A refused local login falls back to the proxy and checks that.
|
|
2977
|
+
*/
|
|
2806
2978
|
private checkCredential;
|
|
2807
|
-
/** Report the
|
|
2808
|
-
private
|
|
2979
|
+
/** Report the current auth source as working or refused. */
|
|
2980
|
+
private reportStatus;
|
|
2809
2981
|
/**
|
|
2810
2982
|
* Wait for the first credential answer BEFORE queue admission, so a waiting
|
|
2811
2983
|
* turn holds no slot. Bounded by the start-up deadline: once it has passed,
|
|
@@ -2829,6 +3001,13 @@ declare class ClaudeCodeHost {
|
|
|
2829
3001
|
private handleAgent;
|
|
2830
3002
|
private deliverAgentOutcome;
|
|
2831
3003
|
private runAgentTurn;
|
|
3004
|
+
/**
|
|
3005
|
+
* Settle a failed turn (C3) after storing its message as the assistant's
|
|
3006
|
+
* reply, so the history shows what the user saw. Stored first: a client that
|
|
3007
|
+
* reloads on the failure must find it. Best-effort: a store failure never
|
|
3008
|
+
* changes the outcome.
|
|
3009
|
+
*/
|
|
3010
|
+
private failTurn;
|
|
2832
3011
|
/**
|
|
2833
3012
|
* Send every message the memory service has not accepted yet. Indices are
|
|
2834
3013
|
* the messages' positions in the session file, so they advance across turns
|
|
@@ -2854,6 +3033,12 @@ declare class ClaudeCodeHost {
|
|
|
2854
3033
|
* Run a turn; on a `--resume` failure (stale/missing claude session id) start
|
|
2855
3034
|
* fresh and prepend the last-N stored messages so the model keeps context.
|
|
2856
3035
|
*/
|
|
3036
|
+
/**
|
|
3037
|
+
* Run one turn on `auth` with its own driver, registered as the session's
|
|
3038
|
+
* running turn so `chat.abort` reaches it. Proxy turns always carry a
|
|
3039
|
+
* registry model.
|
|
3040
|
+
*/
|
|
3041
|
+
private runTurnOn;
|
|
2857
3042
|
private runWithResumeFallback;
|
|
2858
3043
|
private forwardEmission;
|
|
2859
3044
|
private handleChatAbort;
|
|
@@ -2901,6 +3086,12 @@ interface ChatMessage {
|
|
|
2901
3086
|
role: 'user' | 'assistant';
|
|
2902
3087
|
content: string;
|
|
2903
3088
|
timestamp: number;
|
|
3089
|
+
/**
|
|
3090
|
+
* `'error'`: the failure message a turn settled with, stored so the history
|
|
3091
|
+
* shows what the user saw. History only: memory ingest and the resume
|
|
3092
|
+
* preamble skip it (it is not something the agent said).
|
|
3093
|
+
*/
|
|
3094
|
+
kind?: 'error';
|
|
2904
3095
|
senderId?: string;
|
|
2905
3096
|
senderName?: string;
|
|
2906
3097
|
components?: StoredMessageComponent[];
|
|
@@ -2936,7 +3127,10 @@ type ChatActivityRecord = {
|
|
|
2936
3127
|
interface SessionData {
|
|
2937
3128
|
sessionId: string;
|
|
2938
3129
|
agentId: string;
|
|
3130
|
+
/** Always `CHAT_SESSION_CHANNEL` for sessions this host writes. */
|
|
2939
3131
|
channel: string;
|
|
3132
|
+
/** The chat surface that opened the conversation (`mobile`, `dashboard`, ...). */
|
|
3133
|
+
clientType?: string;
|
|
2940
3134
|
tenantId?: string;
|
|
2941
3135
|
userId?: string;
|
|
2942
3136
|
createdAt: string;
|
|
@@ -2979,21 +3173,24 @@ interface SessionSummary {
|
|
|
2979
3173
|
preview?: string;
|
|
2980
3174
|
messageCount: number;
|
|
2981
3175
|
}
|
|
3176
|
+
/**
|
|
3177
|
+
* The channel every chat session is stored on. Every chat client lists with
|
|
3178
|
+
* `sessions.list { channel: 'alfe' }` and openclaw-chat stores `'alfe'`, so any
|
|
3179
|
+
* other value hides the conversation from the rail.
|
|
3180
|
+
*/
|
|
3181
|
+
|
|
2982
3182
|
declare function getSession(sessionId: string): Promise<SessionData | null>;
|
|
2983
3183
|
declare function saveSession(session: SessionData): Promise<void>;
|
|
2984
|
-
declare function createSession(sessionId: string, agentId: string, channel: string, tenantId?: string, userId?: string): Promise<SessionData>;
|
|
3184
|
+
declare function createSession(sessionId: string, agentId: string, channel: string, tenantId?: string, userId?: string, clientType?: string): Promise<SessionData>;
|
|
2985
3185
|
/**
|
|
2986
3186
|
* Append a message. Returns its index (position in `messages`), the stable
|
|
2987
3187
|
* memory-ingest index, or -1 when the session does not exist.
|
|
2988
3188
|
*/
|
|
2989
3189
|
declare function addMessage(sessionId: string, role: 'user' | 'assistant', content: string, senderId?: string, senderName?: string, components?: StoredMessageComponent[], attachments?: StoredAttachment[]): Promise<number>;
|
|
2990
3190
|
/**
|
|
2991
|
-
*
|
|
2992
|
-
*
|
|
2993
|
-
*
|
|
2994
|
-
* trimmed head is lost for good because the consumer's watermark jumps past
|
|
2995
|
-
* it. Staying well under that limit means the server never trims. Bytes, not
|
|
2996
|
-
* characters: one CJK character is three UTF-8 bytes.
|
|
3191
|
+
* Store the failure message a turn settled with as the assistant's reply, so
|
|
3192
|
+
* the history shows what the user saw. Returns its index, or -1 when the
|
|
3193
|
+
* session does not exist.
|
|
2997
3194
|
*/
|
|
2998
3195
|
|
|
2999
3196
|
/**
|
|
@@ -3015,4 +3212,4 @@ declare function listSessions(filters?: {
|
|
|
3015
3212
|
*/
|
|
3016
3213
|
declare function resolveHostConfig(): ClaudeCodeHostConfig;
|
|
3017
3214
|
//#endregion
|
|
3018
|
-
export { AUTH_PROBE_TIMEOUT_MS, type ActivityEmission, BRIDGE_ENV_VAR, CLAUDE_PERMISSION_MODES, CREDENTIAL_ENV_VAR, CREDENTIAL_INVALID_MESSAGE,
|
|
3215
|
+
export { AUTH_PROBE_TIMEOUT_MS, type ActivityEmission, BRIDGE_ENV_VAR, CLAUDE_PERMISSION_MODES, CREDENTIAL_ENV_VAR, CREDENTIAL_INVALID_MESSAGE, CREDENTIAL_UNAVAILABLE_MESSAGE, type ChatActivityRecord, type ChatMessage, type ChildAuth, type ChildCredential, ClaudeCodeHost, type ClaudeCodeHostConfig, type ClaudePermissionMode, type CredentialSource, type CredentialStatusReport, CredentialStatusReporter, DEFAULT_ALLOWED_TOOLS, DEFAULT_LOCAL_AI_PROXY_URL, DEFAULT_PERMISSION_MODE, type DriverTurnResult, type EndEmission, type HostCredential, LOCAL_LOGIN_REFUSED_MESSAGE, LOCAL_LOGIN_SWITCHED_MESSAGE, MANAGED_ALLOWED_TOOLS, MANAGED_DISALLOWED_TOOLS, MODEL_UNAVAILABLE_MESSAGE, type MapperEmission, type MapperState, OUT_OF_CREDITS_MESSAGE, PROXY_AGENT_MODEL_ENV_VARS, PROXY_API_KEY_PLACEHOLDER, PROXY_AUTH_FAILED_MESSAGE, PROXY_DEFAULT_MODEL, PROXY_MODEL_ENV, type ProbeOutcome, type ProxyDenial, type RunTurnParams, SCRUBBED_ANTHROPIC_ENV_VARS, STATUS_REPORT_INTERVAL_MS, type SessionData, SessionDriver, type SessionSummary, TERMINATION_GRACE_MS, TURN_TIMEOUT_MS, type TextEmission, type ThinkingActivity, type ToolActivity, USAGE_LIMIT_MESSAGE, WARM_STREAMING_SUPPORTED, addMessage, appendActivity, buildChildEnv, buildProbeArgs, classifyProxyDenial, collectTurnActivityRecords, createMapperState, createSession, getSession, isAuthFailureText, listSessions, loadCredentialWithRetry, mapStreamEvent, mapStreamEvents, parseProbeOutput, resolveHostConfig, runAuthProbe, saveSession, stripAgentPrefix };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as
|
|
2
|
-
export { AUTH_PROBE_TIMEOUT_MS, BRIDGE_ENV_VAR, CLAUDE_PERMISSION_MODES, CREDENTIAL_ENV_VAR, CREDENTIAL_INVALID_MESSAGE,
|
|
1
|
+
import { A as mapStreamEvents, B as BRIDGE_ENV_VAR, C as SessionDriver, D as collectTurnActivityRecords, E as WARM_STREAMING_SUPPORTED, F as classifyProxyDenial, G as PROXY_DEFAULT_MODEL, H as DEFAULT_LOCAL_AI_PROXY_URL, I as isAuthFailureText, J as buildChildEnv, K as PROXY_MODEL_ENV, L as loadCredentialWithRetry, M as CredentialStatusReporter, N as STATUS_REPORT_INTERVAL_MS, O as createMapperState, P as buildProbeArgs, R as parseProbeOutput, S as MANAGED_DISALLOWED_TOOLS, T as TURN_TIMEOUT_MS, U as PROXY_AGENT_MODEL_ENV_VARS, V as CREDENTIAL_ENV_VAR, W as PROXY_API_KEY_PLACEHOLDER, _ as saveSession, a as LOCAL_LOGIN_REFUSED_MESSAGE, b as DEFAULT_PERMISSION_MODE, c as OUT_OF_CREDITS_MESSAGE, d as stripAgentPrefix, f as addMessage, g as listSessions, h as getSession, i as ClaudeCodeHost, j as AUTH_PROBE_TIMEOUT_MS, k as mapStreamEvent, l as PROXY_AUTH_FAILED_MESSAGE, m as createSession, n as CREDENTIAL_INVALID_MESSAGE, o as LOCAL_LOGIN_SWITCHED_MESSAGE, p as appendActivity, q as SCRUBBED_ANTHROPIC_ENV_VARS, r as CREDENTIAL_UNAVAILABLE_MESSAGE, s as MODEL_UNAVAILABLE_MESSAGE, t as resolveHostConfig, u as USAGE_LIMIT_MESSAGE, v as CLAUDE_PERMISSION_MODES, w as TERMINATION_GRACE_MS, x as MANAGED_ALLOWED_TOOLS, y as DEFAULT_ALLOWED_TOOLS, z as runAuthProbe } from "./host-config.js";
|
|
2
|
+
export { AUTH_PROBE_TIMEOUT_MS, BRIDGE_ENV_VAR, CLAUDE_PERMISSION_MODES, CREDENTIAL_ENV_VAR, CREDENTIAL_INVALID_MESSAGE, CREDENTIAL_UNAVAILABLE_MESSAGE, ClaudeCodeHost, CredentialStatusReporter, DEFAULT_ALLOWED_TOOLS, DEFAULT_LOCAL_AI_PROXY_URL, DEFAULT_PERMISSION_MODE, LOCAL_LOGIN_REFUSED_MESSAGE, LOCAL_LOGIN_SWITCHED_MESSAGE, MANAGED_ALLOWED_TOOLS, MANAGED_DISALLOWED_TOOLS, MODEL_UNAVAILABLE_MESSAGE, OUT_OF_CREDITS_MESSAGE, PROXY_AGENT_MODEL_ENV_VARS, PROXY_API_KEY_PLACEHOLDER, PROXY_AUTH_FAILED_MESSAGE, PROXY_DEFAULT_MODEL, PROXY_MODEL_ENV, SCRUBBED_ANTHROPIC_ENV_VARS, STATUS_REPORT_INTERVAL_MS, SessionDriver, TERMINATION_GRACE_MS, TURN_TIMEOUT_MS, USAGE_LIMIT_MESSAGE, WARM_STREAMING_SUPPORTED, addMessage, appendActivity, buildChildEnv, buildProbeArgs, classifyProxyDenial, collectTurnActivityRecords, createMapperState, createSession, getSession, isAuthFailureText, listSessions, loadCredentialWithRetry, mapStreamEvent, mapStreamEvents, parseProbeOutput, resolveHostConfig, runAuthProbe, saveSession, stripAgentPrefix };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alfe.ai/claude-code-host",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Chat bridge that makes a
|
|
3
|
+
"version": "0.1.17",
|
|
4
|
+
"description": "Chat bridge that makes a Claude Code agent reachable from Alfe chat, on its Claude credential, the local claude login, or Alfe AI credits",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -19,9 +19,9 @@
|
|
|
19
19
|
"dist"
|
|
20
20
|
],
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@alfe.ai/agent-api-client": "^0.21.
|
|
23
|
-
"@alfe.ai/
|
|
24
|
-
"@alfe.ai/
|
|
22
|
+
"@alfe.ai/agent-api-client": "^0.21.2",
|
|
23
|
+
"@alfe.ai/config": "^0.4.2",
|
|
24
|
+
"@alfe.ai/chat": "^0.0.19"
|
|
25
25
|
},
|
|
26
26
|
"license": "UNLICENSED",
|
|
27
27
|
"homepage": "https://alfe.ai",
|