@agenthifive/openclaw 0.3.3 → 0.3.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/dist/register.js CHANGED
@@ -23,7 +23,7 @@ import { verifyPatches } from "./patch-verify.js";
23
23
  // ---------------------------------------------------------------------------
24
24
  const DEFAULT_BASE_URL = "https://app.agenthifive.com";
25
25
  const PLUGIN_ID = "agenthifive";
26
- const PLUGIN_VERSION = "0.3.3";
26
+ const PLUGIN_VERSION = "0.3.5";
27
27
  // ---------------------------------------------------------------------------
28
28
  // Module-scoped singletons (lifecycle managed by register/stop)
29
29
  // ---------------------------------------------------------------------------
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * Credential provider backed by AgentHiFive Vault.
3
3
  *
4
- * resolve() calls POST /v1/vault/execute with model "A" (token vending)
5
- * to get the real provider API key from the vault. Results are cached
6
- * for cacheTtlMs (default: 5 minutes) to avoid excessive vault calls.
4
+ * resolve() always returns null all LLM credential access goes through
5
+ * vault/llm proxy (Model B brokered). The class is kept for isAvailable(),
6
+ * getConfig(), and buildAuthHeaders() used by tools and hooks.
7
7
  */
8
8
  export type CredentialQuery = {
9
9
  provider: string;
@@ -32,12 +32,10 @@ export type VaultProviderConfig = {
32
32
  export declare class VaultCredentialProvider implements CredentialProvider {
33
33
  readonly id = "agenthifive-vault";
34
34
  private config;
35
- private cache;
36
35
  constructor(config: VaultProviderConfig);
37
- resolve(query: CredentialQuery): Promise<CredentialResult | null>;
36
+ resolve(_query: CredentialQuery): Promise<CredentialResult | null>;
38
37
  isAvailable(): Promise<boolean>;
39
38
  getConfig(): VaultProviderConfig;
40
39
  buildAuthHeaders(): Record<string, string>;
41
- private fetchCredential;
42
40
  }
43
41
  //# sourceMappingURL=vault-provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"vault-provider.d.ts","sourceRoot":"","sources":["../src/vault-provider.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IAClE,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CACjC;AAiBD,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,mFAAmF;IACnF,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;CACzC,CAAC;AAOF,qBAAa,uBAAwB,YAAW,kBAAkB;IAChE,QAAQ,CAAC,EAAE,uBAAuB;IAElC,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,KAAK,CAAuC;gBAExC,MAAM,EAAE,mBAAmB;IAIjC,OAAO,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAajE,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAWrC,SAAS,IAAI,mBAAmB;IAIhC,gBAAgB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;YAI5B,eAAe;CAkD9B"}
1
+ {"version":3,"file":"vault-provider.d.ts","sourceRoot":"","sources":["../src/vault-provider.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IAClE,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CACjC;AAMD,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,mFAAmF;IACnF,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;CACzC,CAAC;AAEF,qBAAa,uBAAwB,YAAW,kBAAkB;IAChE,QAAQ,CAAC,EAAE,uBAAuB;IAElC,OAAO,CAAC,MAAM,CAAsB;gBAExB,MAAM,EAAE,mBAAmB;IAIjC,OAAO,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAOlE,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAWrC,SAAS,IAAI,mBAAmB;IAIhC,gBAAgB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;CAG3C"}
@@ -1,36 +1,21 @@
1
1
  /**
2
2
  * Credential provider backed by AgentHiFive Vault.
3
3
  *
4
- * resolve() calls POST /v1/vault/execute with model "A" (token vending)
5
- * to get the real provider API key from the vault. Results are cached
6
- * for cacheTtlMs (default: 5 minutes) to avoid excessive vault calls.
4
+ * resolve() always returns null all LLM credential access goes through
5
+ * vault/llm proxy (Model B brokered). The class is kept for isAvailable(),
6
+ * getConfig(), and buildAuthHeaders() used by tools and hooks.
7
7
  */
8
- // ---------------------------------------------------------------------------
9
- // Provider → service mapping (matches AH5 API's SERVICE_CATALOG)
10
- // ---------------------------------------------------------------------------
11
- const PROVIDER_TO_SERVICE = {
12
- anthropic: "anthropic-messages",
13
- openai: "openai",
14
- gemini: "gemini",
15
- openrouter: "openrouter",
16
- };
17
8
  export class VaultCredentialProvider {
18
9
  id = "agenthifive-vault";
19
10
  config;
20
- cache = new Map();
21
11
  constructor(config) {
22
12
  this.config = config;
23
13
  }
24
- async resolve(query) {
25
- const serviceId = PROVIDER_TO_SERVICE[query.provider];
26
- if (!serviceId)
27
- return null;
28
- // Check cache (with 30s buffer before expiry)
29
- const cached = this.cache.get(query.provider);
30
- if (cached && cached.expiresAt > Date.now() + 30_000) {
31
- return { token: cached.token, expiresAt: cached.expiresAt };
32
- }
33
- return this.fetchCredential(query.provider, serviceId, true);
14
+ async resolve(_query) {
15
+ // All LLM credential resolution goes through vault/llm proxy (Model B).
16
+ // The patch in resolveApiKeyForProvider returns the vault bearer token
17
+ // directly, and the provider baseUrl is redirected to the vault proxy.
18
+ return null;
34
19
  }
35
20
  async isAvailable() {
36
21
  try {
@@ -49,44 +34,5 @@ export class VaultCredentialProvider {
49
34
  buildAuthHeaders() {
50
35
  return { Authorization: `Bearer ${this.config.auth.token}` };
51
36
  }
52
- async fetchCredential(provider, serviceId, allowRetry) {
53
- try {
54
- const response = await fetch(`${this.config.baseUrl}/v1/vault/execute`, {
55
- method: "POST",
56
- headers: {
57
- "Content-Type": "application/json",
58
- ...this.buildAuthHeaders(),
59
- },
60
- body: JSON.stringify({ model: "A", service: serviceId }),
61
- signal: AbortSignal.timeout(this.config.timeoutMs),
62
- });
63
- // Handle 401 with token refresh retry
64
- if (response.status === 401 && allowRetry && this.config.onTokenRefresh) {
65
- const refreshed = await this.config.onTokenRefresh();
66
- if (refreshed) {
67
- return this.fetchCredential(provider, serviceId, false);
68
- }
69
- console.error(`[AH5 resolve] ${provider}: 401 after refresh retry`);
70
- return null;
71
- }
72
- if (!response.ok) {
73
- const body = await response.text().catch(() => "");
74
- console.error(`[AH5 resolve] ${provider}: HTTP ${response.status} ${body.slice(0, 200)}`);
75
- return null;
76
- }
77
- const data = (await response.json());
78
- if (!data.accessToken) {
79
- console.error(`[AH5 resolve] ${provider}: response has no accessToken`, JSON.stringify(data).slice(0, 200));
80
- return null;
81
- }
82
- const expiresAt = Date.now() + (data.expiresIn ?? 3600) * 1000;
83
- this.cache.set(provider, { token: data.accessToken, expiresAt });
84
- return { token: data.accessToken, expiresAt };
85
- }
86
- catch (err) {
87
- console.error(`[AH5 resolve] ${provider}: fetch error:`, err instanceof Error ? err.message : err);
88
- return null;
89
- }
90
- }
91
37
  }
92
38
  //# sourceMappingURL=vault-provider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"vault-provider.js","sourceRoot":"","sources":["../src/vault-provider.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"vault-provider.js","sourceRoot":"","sources":["../src/vault-provider.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAmCH,MAAM,OAAO,uBAAuB;IACzB,EAAE,GAAG,mBAAmB,CAAC;IAE1B,MAAM,CAAsB;IAEpC,YAAY,MAA2B;QACrC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,MAAuB;QACnC,wEAAwE;QACxE,uEAAuE;QACvE,uEAAuE;QACvE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,WAAW;QACf,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,YAAY,EAAE;gBAC/D,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC;aAClC,CAAC,CAAC;YACH,OAAO,QAAQ,CAAC,EAAE,CAAC;QACrB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,gBAAgB;QACd,OAAO,EAAE,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC;IAC/D,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agenthifive/openclaw",
3
- "version": "0.3.3",
3
+ "version": "0.3.5",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/patches/README.md CHANGED
@@ -1,58 +1,53 @@
1
1
  # AgentHiFive OpenClaw Patches
2
2
 
3
- Optional patches that enable credential proxying features in OpenClaw core.
3
+ Optional patches that enable LLM credential proxying in OpenClaw core.
4
4
 
5
5
  **These patches are NOT required for basic functionality.** The AgentHiFive plugin
6
6
  works fully without patches — tools, prompt injection, approval flow, and the
7
7
  brokered API proxy (Model B) all work out of the box. Patches only enable
8
8
  **LLM credential proxying** (routing LLM API calls through the vault).
9
9
 
10
+ ## How It Works
11
+
12
+ The patch injects a small code block into `resolveApiKeyForProvider()` that checks
13
+ `globalThis.__ah5_runtime` (set by the plugin at startup). When the requested
14
+ provider is in the `proxiedProviders` list, it returns the vault bearer token
15
+ instead of looking up a local API key. Combined with the provider `baseUrl`
16
+ redirect (set in `openclaw.json` by the setup wizard), this routes all LLM
17
+ traffic through the vault's Model B proxy.
18
+
10
19
  ## Available Patches
11
20
 
12
21
  ### `model-auth.patch`
13
22
 
14
- Adds vault credential resolution to OpenClaw's `resolveApiKeyForProvider()` function
15
- in `src/agents/model-auth.ts`. This inserts two new resolution tiers before the
16
- existing local profile lookup:
23
+ Adds vault credential resolution to `src/agents/model-auth.ts`:
17
24
 
18
25
  | Tier | What it does | When it activates |
19
26
  |------|-------------|-------------------|
20
- | **Tier 0** | Returns the vault bearer token directly | Provider is in `proxiedProviders` list |
21
- | **Tier 0.5** | Queries the vault credential provider chain | Always (falls through if no credentials found) |
27
+ | **Tier 0** | Returns the vault bearer token | Provider is in `proxiedProviders` list |
22
28
 
23
- The patch uses `await import("@agenthifive/openclaw/runtime")` wrapped in try/catch,
24
- so it's a **complete no-op** when the plugin is not installed — safe for vanilla OpenClaw.
29
+ The patch uses `globalThis.__ah5_runtime` (no dynamic imports), so it's a
30
+ **complete no-op** when the plugin is not installed.
25
31
 
26
32
  ## How to Apply
27
33
 
28
- ### Using pnpm patch (recommended)
34
+ ### Automatic (recommended)
29
35
 
30
36
  ```bash
31
- # 1. Start the patch session
32
- pnpm patch openclaw
33
-
34
- # 2. Apply the patch to the extracted directory
35
- # (pnpm will print the temporary directory path)
36
- cd <temp-directory>
37
- patch -p1 < /path/to/@agenthifive/openclaw/patches/model-auth.patch
38
-
39
- # 3. Commit the patch
40
- pnpm patch-commit <temp-directory>
37
+ npx @agenthifive/openclaw-setup --base-url https://app.agenthifive.com --bootstrap-secret ah5b_...
41
38
  ```
42
39
 
43
- This adds a `patchedDependencies` entry to your `package.json` that pnpm applies
44
- automatically on `pnpm install`.
40
+ The setup wizard applies the patch automatically as step 7/7.
45
41
 
46
- ### Manual application
42
+ ### Manual with pnpm patch
47
43
 
48
44
  ```bash
49
- cd /path/to/openclaw
50
- patch -p1 < node_modules/@agenthifive/openclaw/patches/model-auth.patch
45
+ pnpm patch openclaw
46
+ cd <temp-directory>
47
+ patch -p1 < /path/to/@agenthifive/openclaw/patches/model-auth.patch
48
+ pnpm patch-commit <temp-directory>
51
49
  ```
52
50
 
53
- Note: Manual patches are lost on `npm install` / `pnpm install`. Use `pnpm patch`
54
- for persistence.
55
-
56
51
  ## Verification
57
52
 
58
53
  After applying, the AgentHiFive plugin will log at startup:
@@ -61,25 +56,14 @@ After applying, the AgentHiFive plugin will log at startup:
61
56
  AgentHiFive: model-auth patch detected — credential proxying enabled
62
57
  ```
63
58
 
64
- Without the patch, you'll see:
59
+ Without the patch:
65
60
 
66
61
  ```
67
62
  AgentHiFive: model-auth patch not detected. LLM credential proxying is unavailable.
68
63
  ```
69
64
 
70
- ## Compatibility
71
-
72
- | OpenClaw Version | Patch Status |
73
- |-----------------|-------------|
74
- | Latest (Mar 2026) | Compatible |
75
-
76
- The patch targets `resolveApiKeyForProvider()` in `src/agents/model-auth.ts`.
77
- If OpenClaw restructures this function significantly, the patch may need
78
- regeneration. Check the [AgentHiFive releases](https://github.com/supersantux/AgentH5/releases)
79
- for updated patches.
80
-
81
65
  ## When Patches Become Unnecessary
82
66
 
83
67
  When OpenClaw merges support for `apiKeyOverride` in the `before_model_resolve`
84
68
  hook result type, the plugin can use the hook API directly and patches will be
85
- deprecated. Track progress in the upstream PR.
69
+ deprecated.
@@ -1,42 +1,22 @@
1
1
  --- a/src/agents/model-auth.ts
2
2
  +++ b/src/agents/model-auth.ts
3
- @@ -289,7 +289,41 @@
3
+ @@ -289,7 +289,22 @@
4
4
  }): Promise<ResolvedProviderAuth> {
5
5
  const { provider, cfg, profileId, preferredProfile } = params;
6
6
  const store = params.store ?? ensureAuthProfileStore(params.agentDir);
7
7
 
8
- + // -- Tier 0: AgentHiFive proxied providers (vault bearer token) --
9
- + // When the provider is in proxiedProviders, the vault acts as an LLM proxy.
10
- + // Return the managed vault bearer token directly -- no local API key needed.
11
- + // @agenthifive/openclaw/runtime -- dynamic import is a no-op when plugin is not installed.
8
+ + // -- AgentHiFive: vault LLM proxy (Model B brokered) --
9
+ + // @agenthifive/openclaw/runtime @ah5-patch-v4
12
10
  + try {
13
- + const runtime = await import("@agenthifive/openclaw/runtime");
14
- + if (runtime.isInitialized()) {
15
- + const proxiedProviders = runtime.getProxiedProviders();
16
- + if (proxiedProviders.includes(provider)) {
17
- + const vaultToken = runtime.getVaultBearerToken();
18
- + if (vaultToken) {
19
- + return { apiKey: vaultToken, source: "vault:agent-token", mode: "api-key" };
20
- + }
21
- + }
22
- +
23
- + // -- Tier 0.5: Credential provider chain --
24
- + // Try the vault credential provider before local profiles.
25
- + const vaultResult = await runtime.resolveCredential({
26
- + kind: "model_provider",
27
- + provider,
28
- + profileId: preferredProfile,
29
- + });
30
- + if (vaultResult?.apiKey) {
31
- + return {
32
- + apiKey: vaultResult.apiKey,
33
- + source: "credential-provider:vault",
34
- + mode: vaultResult.mode ?? "api-key",
35
- + };
36
- + }
11
+ + const ah5rt = (globalThis as Record<string, unknown>).__ah5_runtime as
12
+ + | { proxiedProviders?: string[]; vaultBearerToken?: string }
13
+ + | undefined;
14
+ + if (ah5rt?.proxiedProviders?.includes(provider) && ah5rt?.vaultBearerToken) {
15
+ + return { apiKey: ah5rt.vaultBearerToken, source: "vault:agent-token", mode: "api-key" };
37
16
  + }
38
- + } catch {
39
- + // Plugin not installed -- skip vault credential resolution
17
+ + } catch (ah5Err: unknown) {
18
+ + const msg = ah5Err instanceof Error ? ah5Err.message : String(ah5Err);
19
+ + console.error("[AH5 patch] error:", msg);
40
20
  + }
41
21
  +
42
22
  if (profileId) {