@sage-protocol/openclaw-sage 0.1.8 → 0.1.10

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 CHANGED
@@ -5,19 +5,56 @@ MCP bridge plugin that exposes Sage Protocol tools inside OpenClaw via Code Mode
5
5
  ## What It Does
6
6
 
7
7
  - **Code Mode Gateway** - Spawns `sage mcp start` and routes plugin calls through `sage_search`/`sage_execute`/`sage_status`
8
- - **Auto-Context Injection** - Injects Sage tool context and skill suggestions at agent start
8
+ - **Agent Profile (Identity Context)** - Injects wallet, active libraries, and skill counts into every turn so the agent knows who it's working for
9
+ - **Auto-Context Injection** - Injects Sage tool context and skill suggestions via `before_prompt_build` with stable context cached separately from per-turn dynamic context
9
10
  - **Injection Guard** - Optional prompt-injection scanning on outgoing `sage_execute` mutations
10
11
  - **Crash Recovery** - Automatically restarts the MCP subprocess on unexpected exits
11
12
  - **External Servers** - Sage internal tools are available immediately; only external MCP tools require starting servers first via the Sage app, CLI, or raw MCP `hub_*` tools
12
13
 
14
+ ## Agent Profile (Identity Context)
15
+
16
+ Every OpenClaw session automatically gets Sage Protocol identity context injected via the `before_prompt_build` hook. Stable context (protocol description, identity, tool docs) goes in `prependSystemContext` so providers can cache it across turns. Dynamic content (skill suggestions, security guard) goes in `prependContext` and refreshes each turn.
17
+
18
+ Example of what gets injected:
19
+
20
+ ```
21
+ ## Sage Protocol Context
22
+ Sage Protocol is a decentralized network for collaborative prompt, skill, and knowledge
23
+ curation on Base (L2). Skills and prompts live in libraries governed by DAOs. Creators
24
+ and curators earn when their work is used. SXXX is the governance token: hold it to
25
+ vote, create DAOs, and shape the protocol. Burns from activity create deflationary
26
+ pressure — early participants gain governance influence and economic upside as the
27
+ network grows. The more skills published, the more valuable discovery becomes for every
28
+ user and agent.
29
+
30
+ ### Active Identity
31
+ - Wallet: 0x9794...507ca (privy, Base Sepolia)
32
+ - Active libraries (6): sage-entrypoints, impeccable-ui-review, sage-review-foundations, ...
33
+ - Libraries: 10 installed (48 skills, 12 prompts)
34
+ ```
35
+
36
+ The context is fetched from the sage CLI (`wallet current`, `library active`, `library list`) and cached for 60 seconds. If the CLI is unavailable or any query fails, the identity block is silently omitted.
37
+
13
38
  ## Install
14
39
 
40
+ ```bash
41
+ sage init --openclaw
42
+ ```
43
+
44
+ This is the recommended product path: it installs the bundled OpenClaw plugin, the companion Sage
45
+ skills, and only the scan-only internal hooks.
46
+
47
+ If you only want the raw plugin package flow, you can still run:
48
+
15
49
  ```bash
16
50
  openclaw plugins install @sage-protocol/openclaw-sage
17
51
  ```
18
52
 
19
53
  After install, **restart the Gateway** for the plugin to take effect.
20
54
 
55
+ CI validates the packed tarball against the latest published `openclaw` CLI by running
56
+ `npx openclaw@latest plugins install` in an isolated `OPENCLAW_HOME`.
57
+
21
58
  ### Verify
22
59
 
23
60
  ```bash
@@ -33,6 +70,35 @@ openclaw plugins update openclaw-sage
33
70
  openclaw plugins update --all
34
71
  ```
35
72
 
73
+ ### Auto-Enable
74
+
75
+ The plugin sets `enabledByDefault: true` in its manifest, so it auto-enables when referenced in `openclaw.json` config without needing a manual `plugins.allow` entry.
76
+
77
+ ### Hook Priority
78
+
79
+ The `before_prompt_build` hook runs at priority 90 (higher = earlier). This ensures Sage's stable system context (protocol description, wallet identity, tool docs) is the base layer that other plugins build on. Dynamic per-turn content (skill suggestions, security guards) goes in `prependContext`.
80
+
81
+ ### Secrets Management
82
+
83
+ Sage credentials support OpenClaw's SecretRef system instead of raw environment variables:
84
+
85
+ ```json5
86
+ {
87
+ "secrets": {
88
+ "providers": {
89
+ "default": { "source": "env", "allowlist": ["SAGE_*", "KEYSTORE_*"] }
90
+ }
91
+ }
92
+ }
93
+ ```
94
+
95
+ The plugin declares three SecretRef-compatible credentials:
96
+ - `SAGE_IPFS_UPLOAD_TOKEN` — Bearer token for Worker API auth
97
+ - `KEYSTORE_PASSWORD` — Wallet keystore password (non-interactive)
98
+ - `SAGE_DELEGATE_KEYSTORE_PASSWORD` — Delegate keystore password (daemon/operator)
99
+
100
+ These are resolved through OpenClaw's secret provider chain (env, file, or exec) rather than passed as raw env vars.
101
+
36
102
  ### Login With Code (Privy Device-Code)
37
103
 
38
104
  If browser OAuth is unreliable, use:
@@ -96,7 +162,7 @@ sage bounties create --mode direct --assignee 0x... --title "Task" --description
96
162
 
97
163
  ### Auto-Inject / Auto-Suggest
98
164
 
99
- This plugin uses OpenClaw's plugin hook API to inject context at the start of each agent run (`before_agent_start`).
165
+ This plugin uses OpenClaw's plugin hook API to inject context at the start of each prompt build via `before_prompt_build`.
100
166
 
101
167
  Available config fields:
102
168
 
@@ -151,7 +217,9 @@ Notes:
151
217
 
152
218
  If you also enabled Sage's OpenClaw _internal hook_ (installed by `sage init`), both the hook and this plugin can inject Sage context.
153
219
 
154
- - Recommended: keep the plugin injection on, and disable the internal hook injection via `SAGE_OPENCLAW_INJECT_CONTEXT=0` in your OpenClaw environment.
220
+ - `sage init --openclaw` now defaults to plugin-first setup and only installs scan-only hooks, so duplicate injection should not happen by default.
221
+ - Only `sage init --openclaw --mode hooks` installs the legacy `agent:bootstrap` injection hook.
222
+ - If you deliberately re-enable bootstrap injection alongside the plugin, disable it with `SAGE_OPENCLAW_INJECT_CONTEXT=0`.
155
223
 
156
224
  The internal hook now also scans `command:new` and `command:stop` through `sage security scan-hook` and prepends warnings when suspicious content is detected.
157
225
 
@@ -0,0 +1,79 @@
1
+ import { type TSchema } from "@sinclair/typebox";
2
+ /**
3
+ * Minimal type stubs for OpenClaw plugin API.
4
+ *
5
+ * OpenClaw's jiti runtime resolves "openclaw/plugin-sdk" at load time.
6
+ * These stubs keep the code compilable standalone.
7
+ */
8
+ type PluginLogger = {
9
+ info: (msg: string) => void;
10
+ warn: (msg: string) => void;
11
+ error: (msg: string) => void;
12
+ };
13
+ type PluginServiceContext = {
14
+ config: unknown;
15
+ workspaceDir?: string;
16
+ stateDir: string;
17
+ logger: PluginLogger;
18
+ };
19
+ type PluginApi = {
20
+ id: string;
21
+ name: string;
22
+ logger: PluginLogger;
23
+ pluginConfig?: Record<string, unknown>;
24
+ registerTool: (tool: unknown, opts?: {
25
+ name?: string;
26
+ optional?: boolean;
27
+ }) => void;
28
+ registerService: (service: {
29
+ id: string;
30
+ start: (ctx: PluginServiceContext) => void | Promise<void>;
31
+ stop?: (ctx: PluginServiceContext) => void | Promise<void>;
32
+ }) => void;
33
+ on: (hook: string, handler: (...args: unknown[]) => unknown | Promise<unknown>, opts?: {
34
+ priority?: number;
35
+ }) => void;
36
+ };
37
+ declare function normalizePrompt(prompt: string, opts?: {
38
+ maxBytes?: number;
39
+ }): string;
40
+ declare function extractJsonFromMcpResult(result: unknown): unknown;
41
+ type SkillSearchResult = {
42
+ key?: string;
43
+ name?: string;
44
+ description?: string;
45
+ source?: string;
46
+ library?: string;
47
+ mcpServers?: string[];
48
+ };
49
+ declare function formatSkillSuggestions(results: SkillSearchResult[], limit: number): string;
50
+ /**
51
+ * Convert a single MCP JSON Schema property into a TypeBox type.
52
+ * Handles nested objects, typed arrays, and enums.
53
+ */
54
+ declare function jsonSchemaToTypebox(prop: Record<string, unknown>): TSchema;
55
+ /**
56
+ * Convert an MCP JSON Schema inputSchema into a TypeBox object schema
57
+ * that OpenClaw's tool system accepts.
58
+ */
59
+ declare function mcpSchemaToTypebox(inputSchema?: Record<string, unknown>): import("@sinclair/typebox").TObject<{}>;
60
+ declare const plugin: {
61
+ id: string;
62
+ name: string;
63
+ version: string;
64
+ description: string;
65
+ register(api: PluginApi): void;
66
+ };
67
+ /** Map common error patterns to actionable hints */
68
+ declare function enrichErrorMessage(err: Error, toolName: string): string;
69
+ export default plugin;
70
+ export declare const __test: {
71
+ PKG_VERSION: string;
72
+ SAGE_CONTEXT: string;
73
+ normalizePrompt: typeof normalizePrompt;
74
+ extractJsonFromMcpResult: typeof extractJsonFromMcpResult;
75
+ formatSkillSuggestions: typeof formatSkillSuggestions;
76
+ mcpSchemaToTypebox: typeof mcpSchemaToTypebox;
77
+ jsonSchemaToTypebox: typeof jsonSchemaToTypebox;
78
+ enrichErrorMessage: typeof enrichErrorMessage;
79
+ };