dashclaw 2.1.0 → 2.1.2

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.
Files changed (3) hide show
  1. package/README.md +71 -49
  2. package/dashclaw.js +138 -14
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # DashClaw SDK (v2)
1
+ # DashClaw SDK (v2.1.2)
2
2
 
3
3
  **Minimal governance runtime for AI agents.**
4
4
 
@@ -6,70 +6,102 @@ The DashClaw SDK provides the infrastructure to intercept, govern, and verify ag
6
6
 
7
7
  ## Installation
8
8
 
9
+ ### Node.js
9
10
  ```bash
10
11
  npm install dashclaw
11
12
  ```
12
13
 
14
+ ### Python
15
+ ```bash
16
+ pip install dashclaw
17
+ ```
18
+
13
19
  ## The Governance Loop
14
20
 
15
21
  DashClaw v2 is designed around a single 4-step loop.
16
22
 
23
+ ### Node.js
17
24
  ```javascript
18
- import { DashClaw, GuardBlockedError } from 'dashclaw';
25
+ import { DashClaw } from 'dashclaw';
19
26
 
20
27
  const claw = new DashClaw({
21
- baseUrl: process.env.DASHCLAW_BASE_URL,
28
+ baseUrl: 'https://dashclaw.io',
22
29
  apiKey: process.env.DASHCLAW_API_KEY,
23
30
  agentId: 'my-agent'
24
31
  });
25
32
 
26
- async function runAgentTask() {
27
- // 1. GUARD: Ask for permission
28
- // Intercepts intent and evaluates vs. organization policies.
29
- const decision = await claw.guard({
30
- action_type: 'deploy',
31
- risk_score: 85
32
- });
33
-
34
- // 2. RECORD: Log the attempt
35
- // Promotes guarded intent into a recorded action record.
36
- const action = await claw.createAction({
37
- action_type: 'deploy',
38
- declared_goal: 'Deploying latest build'
39
- });
40
-
41
- try {
42
- // 3. VERIFY: Record assumptions
43
- // Tracks beliefs to detect reasoning drift later.
44
- await claw.recordAssumption({
45
- action_id: action.action_id,
46
- assumption: 'The staging tests passed.'
47
- });
48
-
49
- // Execute the real-world action here...
50
- // await deploy();
51
-
52
- // 4. OUTCOME: Log the evidence
53
- await claw.updateOutcome(action.action_id, { status: 'completed' });
54
-
55
- } catch (err) {
56
- await claw.updateOutcome(action.action_id, { status: 'failed', error: err.message });
57
- }
58
- }
33
+ // 1. Ask permission
34
+ const res = await claw.guard({ action_type: 'deploy' });
35
+
36
+ // 2. Log intent
37
+ const { action_id } = await claw.createAction({ action_type: 'deploy' });
38
+
39
+ // 3. Log evidence
40
+ await claw.recordAssumption({ action_id, assumption: 'Tests passed' });
41
+
42
+ // 4. Update result
43
+ await claw.updateOutcome(action_id, { status: 'completed' });
44
+ ```
45
+
46
+ ### Python
47
+ ```python
48
+ from dashclaw import DashClaw
49
+
50
+ claw = DashClaw(
51
+ base_url="https://dashclaw.io",
52
+ api_key="your_api_key",
53
+ agent_id="my-agent"
54
+ )
55
+
56
+ # 1. Ask permission
57
+ res = claw.guard({"action_type": "deploy"})
58
+
59
+ # 2. Log intent
60
+ action = claw.create_action(action_type="deploy")
61
+ action_id = action["action_id"]
62
+
63
+ # 3. Log evidence
64
+ claw.record_assumption({"action_id": action_id, "assumption": "Tests passed"})
65
+
66
+ # 4. Update result
67
+ claw.update_outcome(action_id, status="completed")
59
68
  ```
60
69
 
61
70
  ---
62
71
 
63
- ## SDK Surface Area (v2)
72
+ ## SDK Surface Area (v2.1.2)
64
73
 
65
- The v2 SDK is optimized for stability and zero-overhead governance:
74
+ The v2.1.2 SDK is optimized for stability and zero-overhead governance:
66
75
 
76
+ ### Core Runtime
67
77
  - `guard(context)` — Policy evaluation ("Can I do X?")
68
78
  - `createAction(action)` — Lifecycle tracking ("I am doing X")
69
79
  - `updateOutcome(id, outcome)` — Result recording ("X finished with Y")
70
80
  - `recordAssumption(assumption)` — Integrity tracking ("I believe Z while doing X")
71
81
  - `waitForApproval(id)` — Polling helper for human-in-the-loop approvals
72
82
 
83
+ ### Decision Integrity
84
+ - `registerOpenLoop(actionId, type, desc)` — Register unresolved dependencies.
85
+ - `resolveOpenLoop(loopId, status, res)` — Resolve pending loops.
86
+ - `getSignals()` — Get current risk signals across all agents.
87
+
88
+ ### Swarm & Connectivity
89
+ - `heartbeat(status, metadata)` — Report agent presence and health.
90
+ - `reportConnections(connections)` — Report active provider connections.
91
+
92
+ ### Learning & Optimization
93
+ - `getLearningVelocity()` — Track agent improvement rate.
94
+ - `getLearningCurves()` — Measure efficiency gains per action type.
95
+ - `renderPrompt(context)` — Fetch rendered prompt templates from DashClaw.
96
+
97
+ ### Compliance & Audit
98
+ - `createScorer(name, type, config)` — Define automated evaluations.
99
+ - `createScoringProfile(profile)` — Weighted quality scoring.
100
+ - `mapCompliance(framework)` — Map behavior to regulatory controls.
101
+ - `getProofReport(format)` — Generate audit-ready evidence exports.
102
+ - `getActivityLogs(filters)` — Query the immutable audit trail.
103
+ - `createWebhook(url, events)` — Real-time event exfiltration.
104
+
73
105
  ---
74
106
 
75
107
  ## Error Handling
@@ -83,17 +115,7 @@ DashClaw uses standard HTTP status codes and custom error classes:
83
115
 
84
116
  ## Legacy SDK (v1)
85
117
 
86
- If you require legacy features (Calendar, Messages, Workflows, etc.), the v1 SDK is available via the `legacy` sub-path:
87
-
88
- ```javascript
89
- // ESM
90
- import { DashClaw } from 'dashclaw/legacy';
91
-
92
- // CommonJS
93
- const { DashClaw } = require('dashclaw/legacy');
94
- ```
95
-
96
- *Note: Legacy features are now considered "Extensions" and require these routes to be enabled on your DashClaw server.*
118
+ If you require legacy features (Calendar, Messages, Workflows, etc.), the v1 SDK is available via the `legacy` sub-path in Node.js or via the full client in Python.
97
119
 
98
120
  ---
99
121
 
package/dashclaw.js CHANGED
@@ -57,10 +57,12 @@ class DashClaw {
57
57
  const data = await res.json();
58
58
 
59
59
  if (!res.ok) {
60
- const err = new Error(data.error || `Request failed with status ${res.status}`);
60
+ // Prioritize reason (from governance blocks) over generic error field
61
+ const errorMessage = data.reason || data.error || `Request failed with status ${res.status}`;
62
+ const err = new Error(errorMessage);
61
63
  err.status = res.status;
62
64
  err.details = data.details;
63
- err.decision = data.decision;
65
+ err.decision = data;
64
66
  throw err;
65
67
  }
66
68
 
@@ -70,9 +72,6 @@ class DashClaw {
70
72
  /**
71
73
  * POST /api/guard — "Can I do X?"
72
74
  * @param {Object} context
73
- * @param {string} context.action - Action type (e.g. "deploy")
74
- * @param {string} [context.intent] - What the action aims to do
75
- * @param {number} [context.risk_score] - Risk score 0-100
76
75
  * @returns {Promise<{decision: 'allow'|'block'|'require_approval', action_id: string, reason: string, signals: string[]}>}
77
76
  */
78
77
  async guard(context) {
@@ -84,23 +83,16 @@ class DashClaw {
84
83
 
85
84
  /**
86
85
  * POST /api/actions — "I am attempting X."
87
- * @param {Object} action
88
- * @param {string} action.action_type - e.g. "deploy"
89
- * @param {string} action.declared_goal - e.g. "deploy to production"
90
- * @returns {Promise<{action: Object, action_id: string}>}
91
86
  */
92
87
  async createAction(action) {
93
- const res = await this._request('/api/actions', 'POST', {
88
+ return this._request('/api/actions', 'POST', {
94
89
  ...action,
95
90
  agent_id: this.agentId,
96
91
  });
97
- return res;
98
92
  }
99
93
 
100
94
  /**
101
95
  * PATCH /api/actions/:id — "X finished with result Y."
102
- * @param {string} actionId
103
- * @param {Object} outcome
104
96
  */
105
97
  async updateOutcome(actionId, outcome) {
106
98
  return this._request(`/api/actions/${actionId}`, 'PATCH', {
@@ -111,7 +103,6 @@ class DashClaw {
111
103
 
112
104
  /**
113
105
  * POST /api/assumptions — "I believe Z is true while doing X."
114
- * @param {Object} assumption
115
106
  */
116
107
  async recordAssumption(assumption) {
117
108
  return this._request('/api/assumptions', 'POST', assumption);
@@ -132,6 +123,139 @@ class DashClaw {
132
123
  }
133
124
  throw new Error(`Timed out waiting for approval of action ${actionId}`);
134
125
  }
126
+
127
+ /**
128
+ * POST /api/agents/heartbeat
129
+ */
130
+ async heartbeat(status = 'online', metadata = null) {
131
+ return this._request('/api/agents/heartbeat', 'POST', {
132
+ agent_id: this.agentId,
133
+ status,
134
+ metadata
135
+ });
136
+ }
137
+
138
+ /**
139
+ * POST /api/agents/connections
140
+ */
141
+ async reportConnections(connections) {
142
+ return this._request('/api/agents/connections', 'POST', {
143
+ agent_id: this.agentId,
144
+ connections
145
+ });
146
+ }
147
+
148
+ /**
149
+ * POST /api/actions/loops
150
+ */
151
+ async registerOpenLoop(actionId, loopType, description, metadata = null) {
152
+ return this._request('/api/actions/loops', 'POST', {
153
+ action_id: actionId,
154
+ loop_type: loopType,
155
+ description,
156
+ metadata
157
+ });
158
+ }
159
+
160
+ /**
161
+ * PATCH /api/actions/loops/:id
162
+ */
163
+ async resolveOpenLoop(loopId, status, resolution = null) {
164
+ return this._request(`/api/actions/loops/${loopId}`, 'PATCH', {
165
+ status,
166
+ resolution
167
+ });
168
+ }
169
+
170
+ /**
171
+ * GET /api/actions/signals
172
+ */
173
+ async getSignals() {
174
+ return this._request('/api/actions/signals');
175
+ }
176
+
177
+ /**
178
+ * GET /api/learning/analytics/velocity
179
+ */
180
+ async getLearningVelocity(lookbackDays = 30) {
181
+ return this._request('/api/learning/analytics/velocity', 'GET', null, {
182
+ agent_id: this.agentId,
183
+ lookback_days: lookbackDays
184
+ });
185
+ }
186
+
187
+ /**
188
+ * GET /api/learning/analytics/curves
189
+ */
190
+ async getLearningCurves(lookbackDays = 60) {
191
+ return this._request('/api/learning/analytics/curves', 'GET', null, {
192
+ agent_id: this.agentId,
193
+ lookback_days: lookbackDays
194
+ });
195
+ }
196
+
197
+ /**
198
+ * POST /api/prompts/render
199
+ */
200
+ async renderPrompt({ template_id, version_id, variables, record = false }) {
201
+ return this._request('/api/prompts/render', 'POST', {
202
+ template_id,
203
+ version_id,
204
+ variables,
205
+ agent_id: this.agentId,
206
+ record
207
+ });
208
+ }
209
+
210
+ /**
211
+ * POST /api/evaluations/scorers
212
+ */
213
+ async createScorer(name, scorer_type, config = null, description = null) {
214
+ return this._request('/api/evaluations/scorers', 'POST', {
215
+ name,
216
+ scorer_type,
217
+ config,
218
+ description
219
+ });
220
+ }
221
+
222
+ /**
223
+ * POST /api/scoring/profiles
224
+ */
225
+ async createScoringProfile(profile) {
226
+ return this._request('/api/scoring/profiles', 'POST', profile);
227
+ }
228
+
229
+ /**
230
+ * GET /api/compliance/map
231
+ */
232
+ async mapCompliance(framework) {
233
+ return this._request(`/api/compliance/map`, 'GET', null, { framework });
234
+ }
235
+
236
+ /**
237
+ * GET /api/policies/proof
238
+ */
239
+ async getProofReport(format = 'json') {
240
+ return this._request('/api/policies/proof', 'GET', null, { format });
241
+ }
242
+
243
+ /**
244
+ * GET /api/activity
245
+ */
246
+ async getActivityLogs(filters = {}) {
247
+ return this._request('/api/activity', 'GET', null, filters);
248
+ }
249
+
250
+ /**
251
+ * POST /api/webhooks
252
+ */
253
+ async createWebhook(url, events = null) {
254
+ return this._request('/api/webhooks', 'POST', {
255
+ url,
256
+ events
257
+ });
258
+ }
135
259
  }
136
260
 
137
261
  export { DashClaw, ApprovalDeniedError, GuardBlockedError };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dashclaw",
3
- "version": "2.1.0",
3
+ "version": "2.1.2",
4
4
  "description": "Minimal governance runtime for AI agents. Intercept, govern, and verify agent actions.",
5
5
  "type": "module",
6
6
  "publishConfig": {