dashclaw 2.13.1 → 4.0.0
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 +64 -31
- package/dashclaw.js +174 -53
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -223,6 +223,39 @@ answer to "does this need human review?" is always `action.status` on the
|
|
|
223
223
|
Short version: **trust `action.status`, not `decision.decision`, for HITL
|
|
224
224
|
branching.**
|
|
225
225
|
|
|
226
|
+
### Non-fabrication checks
|
|
227
|
+
|
|
228
|
+
When a `non_fabrication` guard policy is active, attach the outbound text and the
|
|
229
|
+
facts it is allowed to state, and DashClaw verifies the content before the action
|
|
230
|
+
proceeds — every amount, date, percentage, and registered ID must trace to an
|
|
231
|
+
allowed fact, every required fact must be present, and no forbidden pattern may
|
|
232
|
+
appear. A violation blocks (or routes to approval) and is recorded with a signed,
|
|
233
|
+
re-verifiable receipt.
|
|
234
|
+
|
|
235
|
+
```javascript
|
|
236
|
+
const decision = await claw.guard({
|
|
237
|
+
action_type: 'message',
|
|
238
|
+
content: 'Hi Jane — your refund of $1,500.00 will arrive by June 1, 2026.',
|
|
239
|
+
sourceOfTruth: {
|
|
240
|
+
allowedFacts: [
|
|
241
|
+
{ label: 'refund', value: '$1,500.00' },
|
|
242
|
+
{ label: 'date', value: 'June 1, 2026' },
|
|
243
|
+
],
|
|
244
|
+
requiredFacts: [{ label: 'name', value: 'Jane' }],
|
|
245
|
+
// forbiddenPatterns, extract (money/dates/percentages/patterns) are optional
|
|
246
|
+
},
|
|
247
|
+
});
|
|
248
|
+
// decision.decision === 'block' if the text states a fact not in sourceOfTruth.
|
|
249
|
+
// decision.non_fabrication[0].receipt is an Ed25519-signed proof you can
|
|
250
|
+
// re-verify at POST /api/integrity/verify (public key: /.well-known/jwks.json),
|
|
251
|
+
// or null if the instance has no usable signing key — the verdict is enforced either way.
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
`createAction()` accepts the same `content` + `sourceOfTruth` fields. Fail-closed:
|
|
255
|
+
a missing or malformed `sourceOfTruth` blocks. A signature proves integrity, the
|
|
256
|
+
verdict, the ruleset version, and the issuer — not time-of-issuance or the
|
|
257
|
+
correctness of prose with no extractable token.
|
|
258
|
+
|
|
226
259
|
---
|
|
227
260
|
|
|
228
261
|
## SDK Tiers
|
|
@@ -266,6 +299,9 @@ The v2 SDK exposes the stable governance runtime plus promoted execution domains
|
|
|
266
299
|
- `approveAction(id, decision, reasoning?)` -- Submit approval decisions from code
|
|
267
300
|
- `getPendingApprovals()` -- List actions awaiting human review
|
|
268
301
|
|
|
302
|
+
### Policies
|
|
303
|
+
- `simulatePolicy({ policy_type, rules, days })` -- Side-effect-free dry-run of a proposed policy against recent historical actions before committing it (pairs with `guard()` for live enforcement). `policy_type` and `rules` are required; `days` is optional. Returns `{ summary: { total, matches, block, warn, require_approval, allow }, matches, sample_size, window_days }`. Persists nothing.
|
|
304
|
+
|
|
269
305
|
### Durable Execution Finality (v2.13.3+)
|
|
270
306
|
Terminal outcome reporting that is one-shot, retry-safe, and immutable once non-pending. Separate from `updateOutcome`, which remains the lifecycle-PATCH path. Full spec: [`docs/architecture/durable-execution-finality.md`](../docs/architecture/durable-execution-finality.md). Detailed examples in the [Action Outcome](#action-outcome-durable-execution-finality) subsection of Execution Studio below.
|
|
271
307
|
|
|
@@ -291,6 +327,22 @@ Terminal outcome reporting that is one-shot, retry-safe, and immutable once non-
|
|
|
291
327
|
- `getLessons({ actionType, limit })` -- Fetch consolidated lessons from scored outcomes.
|
|
292
328
|
- `renderPrompt({ template_id, version_id, variables, record })` -- Fetch a rendered prompt template from DashClaw. `template_id` is required; `version_id` defaults to the active version; `variables` is an object of mustache values; `record: true` persists the render as a governance event.
|
|
293
329
|
|
|
330
|
+
### Prompt Library
|
|
331
|
+
|
|
332
|
+
Manage reusable prompt templates, their versions, and usage analytics. `renderPrompt` (above) fetches a rendered version; these manage the library itself. Mutations (`create*`, `update*`, `delete*`, version creation, and `activate*`) require an admin org role.
|
|
333
|
+
|
|
334
|
+
- `listPromptTemplates({ category })` -- List prompt templates (each with `version_count` + `active_version`). Returns `{ templates }`.
|
|
335
|
+
- `getPromptTemplate(templateId)` -- Fetch a single template.
|
|
336
|
+
- `createPromptTemplate({ name, description, category })` -- Create a template (admin). `name` is required; `description` and `category` are optional. Returns `{ id, name, description, category }`.
|
|
337
|
+
- `updatePromptTemplate(templateId, patch)` -- Update a template (admin). `patch` accepts `name`, `description`, `category`.
|
|
338
|
+
- `deletePromptTemplate(templateId)` -- Delete a template plus its versions and runs (admin). Returns `{ deleted: true }`.
|
|
339
|
+
- `listPromptVersions(templateId)` -- List versions for a template (newest first). Returns `{ versions }`.
|
|
340
|
+
- `createPromptVersion(templateId, { content, model_hint, parameters, changelog })` -- Create a version (admin). `content` is required; `model_hint`, `parameters`, `changelog` are optional.
|
|
341
|
+
- `getPromptVersion(templateId, versionId)` -- Fetch a single version.
|
|
342
|
+
- `activatePromptVersion(templateId, versionId)` -- Activate a version (admin). Activating one version deactivates the others for that template.
|
|
343
|
+
- `getPromptStats({ template_id })` -- Prompt usage analytics, optionally scoped to one template.
|
|
344
|
+
- `listPromptRuns({ template_id, version_id, limit })` -- List recorded prompt runs.
|
|
345
|
+
|
|
294
346
|
### Learning Loop
|
|
295
347
|
|
|
296
348
|
The guard response now includes a `learning` field when DashClaw has historical data for the agent and action type. This creates a closed learning loop: outcomes feed back into guard decisions automatically.
|
|
@@ -315,6 +367,9 @@ lessons.forEach(l => console.log(l.guidance));
|
|
|
315
367
|
// guidance, sample_size
|
|
316
368
|
```
|
|
317
369
|
|
|
370
|
+
- `recordDecision({ decision, context, reasoning, outcome, confidence, agent_id })` -- Record a decision/outcome into the learning ledger. `decision` is required; `agent_id` is auto-injected from the constructor when omitted. Returns `{ decision }`.
|
|
371
|
+
- `getLearningRecommendations({ agent_id, action_type, include_metrics, lookback_days, limit })` -- Read learned recommendations for an agent/action type. `agent_id` defaults to the constructor's agent.
|
|
372
|
+
|
|
318
373
|
### Scoring Profiles
|
|
319
374
|
- `createScorer(name, type, config)` -- Define automated evaluations.
|
|
320
375
|
- `createScoringProfile(profile)` -- Create a weighted multi-dimensional scoring profile.
|
|
@@ -335,6 +390,9 @@ lessons.forEach(l => console.log(l.guidance));
|
|
|
335
390
|
- `deleteRiskTemplate(templateId)` -- Delete a risk template.
|
|
336
391
|
- `autoCalibrate(options)` -- Analyze historical actions and suggest percentile-based scoring scales.
|
|
337
392
|
|
|
393
|
+
### Evaluations
|
|
394
|
+
- `previewScorer({ scorer_type, config, sample })` -- Dry-run a scorer config against a sample action to validate a quality gate before creating a scorer or launching a run. `scorer_type` is required; `config` and `sample` are optional. Writes **no** `eval_scores` row (distinct from the scoring-profiles subsystem above). Returns `{ preview, scorer_type, result: { score, label, reasoning, error } }`.
|
|
395
|
+
|
|
338
396
|
### Messaging
|
|
339
397
|
- `sendMessage({ to, type, subject, body, threadId, urgent })` -- Send a message to another agent or broadcast.
|
|
340
398
|
- `getInbox({ type, unread, limit })` -- Retrieve inbox messages with optional filters.
|
|
@@ -389,36 +447,6 @@ if (result.recommendation === 'block') {
|
|
|
389
447
|
}
|
|
390
448
|
```
|
|
391
449
|
|
|
392
|
-
### Feedback
|
|
393
|
-
- `submitFeedback({ action_id, rating, comment, category, tags, metadata })` -- Submit feedback on an action.
|
|
394
|
-
|
|
395
|
-
```javascript
|
|
396
|
-
// Submit feedback on an action
|
|
397
|
-
await claw.submitFeedback({
|
|
398
|
-
action_id: 'act_123',
|
|
399
|
-
rating: 5,
|
|
400
|
-
comment: 'Deploy was smooth',
|
|
401
|
-
category: 'deployment',
|
|
402
|
-
tags: ['fast', 'clean'],
|
|
403
|
-
metadata: { deploy_duration_ms: 1200 }
|
|
404
|
-
});
|
|
405
|
-
```
|
|
406
|
-
|
|
407
|
-
### Context Threads
|
|
408
|
-
- `createThread(thread)` -- Create a context thread for tracking multi-step work.
|
|
409
|
-
- `addThreadEntry(threadId, content, entryType)` -- Add an entry to a context thread.
|
|
410
|
-
- `closeThread(threadId, summary)` -- Close a context thread with an optional summary.
|
|
411
|
-
|
|
412
|
-
```javascript
|
|
413
|
-
// Create a thread, add entries, and close it
|
|
414
|
-
const thread = await claw.createThread({ name: 'Release Planning' });
|
|
415
|
-
|
|
416
|
-
await claw.addThreadEntry(thread.thread_id, 'Kickoff complete', 'note');
|
|
417
|
-
await claw.addThreadEntry(thread.thread_id, 'Tests green on staging', 'milestone');
|
|
418
|
-
|
|
419
|
-
await claw.closeThread(thread.thread_id, 'Release shipped successfully');
|
|
420
|
-
```
|
|
421
|
-
|
|
422
450
|
### Bulk Sync
|
|
423
451
|
- `syncState(state)` -- Push a full agent state snapshot in a single call.
|
|
424
452
|
|
|
@@ -601,7 +629,7 @@ If your agent supports Model Context Protocol (Claude Code, Claude Desktop, Mana
|
|
|
601
629
|
|
|
602
630
|
**Streamable HTTP transport** (same surface, served by your DashClaw instance at `POST /api/mcp`).
|
|
603
631
|
|
|
604
|
-
**
|
|
632
|
+
**26 tools** in 9 groups:
|
|
605
633
|
|
|
606
634
|
- **Core governance (8):** `dashclaw_guard`, `dashclaw_record`, `dashclaw_invoke`, `dashclaw_capabilities_list`, `dashclaw_policies_list`, `dashclaw_wait_for_approval`, `dashclaw_session_start`, `dashclaw_session_end`.
|
|
607
635
|
- **Optimal files (2):** `dashclaw_optimal_files_preview`, `dashclaw_optimal_files_manifest` — Code Sessions optimizer output (root CLAUDE.md, path-scoped rules, hooks, skill packs).
|
|
@@ -610,6 +638,8 @@ If your agent supports Model Context Protocol (Claude Code, Claude Desktop, Mana
|
|
|
610
638
|
- **Skill safety (1):** `dashclaw_skill_scan` — static safety scan of untrusted skill files; results cached by content hash.
|
|
611
639
|
- **Open loops (3):** `dashclaw_loop_add`, `dashclaw_loop_list`, `dashclaw_loop_close` — action-scoped commitments (the "I will X later" tracker).
|
|
612
640
|
- **Learning + retrospection (3):** `dashclaw_learning_log`, `dashclaw_learning_query`, `dashclaw_decisions_recent` — log + query non-obvious decisions; recent governed-action ledger.
|
|
641
|
+
- **Agent inbox (2):** `dashclaw_inbox_list`, `dashclaw_messages_mark_read`
|
|
642
|
+
- **Behavior learning (1):** `dashclaw_behavior_suggestions`
|
|
613
643
|
|
|
614
644
|
**6 resources:** `dashclaw://policies`, `dashclaw://capabilities`, `dashclaw://agent/{agent_id}/history`, `dashclaw://status`, `dashclaw://code-sessions/projects`, `dashclaw://code-sessions/sessions/{session_id}`.
|
|
615
645
|
|
|
@@ -911,6 +941,9 @@ const { results } = await claw.searchKnowledgeCollection(
|
|
|
911
941
|
{ limit: 5 }
|
|
912
942
|
);
|
|
913
943
|
results.forEach(r => console.log(`${(r.score * 100).toFixed(1)}%: ${r.content.slice(0, 80)}...`));
|
|
944
|
+
|
|
945
|
+
// Delete a collection (cascades its items + chunks)
|
|
946
|
+
const { deleted, collection_id } = await claw.deleteKnowledgeCollection(collection.collection_id);
|
|
914
947
|
```
|
|
915
948
|
|
|
916
949
|
### Capability Runtime
|
package/dashclaw.js
CHANGED
|
@@ -121,6 +121,14 @@ class DashClaw {
|
|
|
121
121
|
/**
|
|
122
122
|
* POST /api/guard — "Can I do X?"
|
|
123
123
|
* @param {Object} context
|
|
124
|
+
* @param {string} [context.content] - Outbound content to fabrication-check
|
|
125
|
+
* (e.g. a drafted email/message). Pairs with `sourceOfTruth` and a
|
|
126
|
+
* `non_fabrication` guard policy: every operational token (amounts, dates,
|
|
127
|
+
* percentages, registered IDs) must trace to an allowed fact, or the action
|
|
128
|
+
* is blocked / routed to approval. The response carries a signed,
|
|
129
|
+
* re-verifiable receipt under `non_fabrication`.
|
|
130
|
+
* @param {Object} [context.sourceOfTruth] - The facts `content` is allowed to
|
|
131
|
+
* state: `{ allowedFacts, requiredFacts, forbiddenPatterns?, extract? }`.
|
|
124
132
|
* @returns {Promise<{
|
|
125
133
|
* decision: 'allow'|'block'|'require_approval'|'warn',
|
|
126
134
|
* action_id: string,
|
|
@@ -150,6 +158,13 @@ class DashClaw {
|
|
|
150
158
|
|
|
151
159
|
/**
|
|
152
160
|
* POST /api/actions — "I am attempting X."
|
|
161
|
+
*
|
|
162
|
+
* Optional non-fabrication fields: pass `content` (the outbound text) and
|
|
163
|
+
* `sourceOfTruth` ({ allowedFacts, requiredFacts, forbiddenPatterns?, extract? })
|
|
164
|
+
* to have a `non_fabrication` guard policy verify the content before the
|
|
165
|
+
* action proceeds. A violation blocks the action or routes it to approval and
|
|
166
|
+
* is recorded with a signed receipt in the decision ledger.
|
|
167
|
+
* @param {Object} action
|
|
153
168
|
*/
|
|
154
169
|
async createAction(action) {
|
|
155
170
|
return this._request('/api/actions', 'POST', {
|
|
@@ -738,59 +753,6 @@ class DashClaw {
|
|
|
738
753
|
});
|
|
739
754
|
}
|
|
740
755
|
|
|
741
|
-
// ---------------------------------------------------------------------------
|
|
742
|
-
// User Feedback
|
|
743
|
-
// ---------------------------------------------------------------------------
|
|
744
|
-
|
|
745
|
-
/**
|
|
746
|
-
* POST /api/feedback — Submit user feedback linked to an action.
|
|
747
|
-
*/
|
|
748
|
-
async submitFeedback({ action_id, rating, comment, category, tags, metadata }) {
|
|
749
|
-
return this._request('/api/feedback', 'POST', {
|
|
750
|
-
action_id,
|
|
751
|
-
agent_id: this.agentId,
|
|
752
|
-
rating,
|
|
753
|
-
comment,
|
|
754
|
-
category,
|
|
755
|
-
tags,
|
|
756
|
-
metadata,
|
|
757
|
-
});
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
// ---------------------------------------------------------------------------
|
|
761
|
-
// Context Threads
|
|
762
|
-
// ---------------------------------------------------------------------------
|
|
763
|
-
|
|
764
|
-
/**
|
|
765
|
-
* POST /api/context/threads — Create a reasoning context thread.
|
|
766
|
-
*/
|
|
767
|
-
async createThread(thread) {
|
|
768
|
-
return this._request('/api/context/threads', 'POST', {
|
|
769
|
-
agent_id: this.agentId,
|
|
770
|
-
...thread,
|
|
771
|
-
});
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
/**
|
|
775
|
-
* POST /api/context/threads/:id/entries — Append a reasoning step.
|
|
776
|
-
*/
|
|
777
|
-
async addThreadEntry(threadId, content, entryType) {
|
|
778
|
-
return this._request(`/api/context/threads/${threadId}/entries`, 'POST', {
|
|
779
|
-
content,
|
|
780
|
-
entry_type: entryType,
|
|
781
|
-
});
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
/**
|
|
785
|
-
* PATCH /api/context/threads/:id — Close a reasoning thread.
|
|
786
|
-
*/
|
|
787
|
-
async closeThread(threadId, summary) {
|
|
788
|
-
return this._request(`/api/context/threads/${threadId}`, 'PATCH', {
|
|
789
|
-
status: 'closed',
|
|
790
|
-
...(summary ? { summary } : {}),
|
|
791
|
-
});
|
|
792
|
-
}
|
|
793
|
-
|
|
794
756
|
// ---------------------------------------------------------------------------
|
|
795
757
|
// Bulk Sync
|
|
796
758
|
// ---------------------------------------------------------------------------
|
|
@@ -1129,6 +1091,13 @@ class DashClaw {
|
|
|
1129
1091
|
});
|
|
1130
1092
|
}
|
|
1131
1093
|
|
|
1094
|
+
/**
|
|
1095
|
+
* DELETE /api/knowledge/collections/:id — Delete a collection (cascades items + chunks).
|
|
1096
|
+
*/
|
|
1097
|
+
async deleteKnowledgeCollection(collectionId) {
|
|
1098
|
+
return this._request(`/api/knowledge/collections/${collectionId}`, 'DELETE');
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1132
1101
|
// ---------------------------------------------------------------------------
|
|
1133
1102
|
// Execution Studio — Capability Registry
|
|
1134
1103
|
// ---------------------------------------------------------------------------
|
|
@@ -1202,6 +1171,158 @@ class DashClaw {
|
|
|
1202
1171
|
async getCapabilityHistory(capabilityId, filters = {}) {
|
|
1203
1172
|
return this._request(`/api/capabilities/${capabilityId}/history`, 'GET', null, filters);
|
|
1204
1173
|
}
|
|
1174
|
+
|
|
1175
|
+
// ---------------------------------------------------------------------------
|
|
1176
|
+
// Prompt Library — reusable prompt templates, versions, render + analytics.
|
|
1177
|
+
// renderPrompt() already lives in the rendering section above; these add the
|
|
1178
|
+
// template/version management surface so the library is first-class in the SDK.
|
|
1179
|
+
// Mutations (create/update/delete/version/activate) require an admin org role.
|
|
1180
|
+
// ---------------------------------------------------------------------------
|
|
1181
|
+
|
|
1182
|
+
/**
|
|
1183
|
+
* GET /api/prompts/templates — List prompt templates (each with version_count + active_version).
|
|
1184
|
+
* @param {Object} [filters={}] - { category }
|
|
1185
|
+
*/
|
|
1186
|
+
async listPromptTemplates(filters = {}) {
|
|
1187
|
+
return this._request('/api/prompts/templates', 'GET', null, filters);
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
/**
|
|
1191
|
+
* GET /api/prompts/templates/:id — Fetch a single template.
|
|
1192
|
+
*/
|
|
1193
|
+
async getPromptTemplate(templateId) {
|
|
1194
|
+
return this._request(`/api/prompts/templates/${templateId}`, 'GET');
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
/**
|
|
1198
|
+
* POST /api/prompts/templates — Create a template (admin). { name, description?, category? }
|
|
1199
|
+
*/
|
|
1200
|
+
async createPromptTemplate(data) {
|
|
1201
|
+
return this._request('/api/prompts/templates', 'POST', data);
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
/**
|
|
1205
|
+
* PATCH /api/prompts/templates/:id — Update a template (admin). { name?, description?, category? }
|
|
1206
|
+
*/
|
|
1207
|
+
async updatePromptTemplate(templateId, patch) {
|
|
1208
|
+
return this._request(`/api/prompts/templates/${templateId}`, 'PATCH', patch);
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
/**
|
|
1212
|
+
* DELETE /api/prompts/templates/:id — Delete a template + its versions/runs (admin).
|
|
1213
|
+
*/
|
|
1214
|
+
async deletePromptTemplate(templateId) {
|
|
1215
|
+
return this._request(`/api/prompts/templates/${templateId}`, 'DELETE');
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
/**
|
|
1219
|
+
* GET /api/prompts/templates/:id/versions — List versions (newest first).
|
|
1220
|
+
*/
|
|
1221
|
+
async listPromptVersions(templateId) {
|
|
1222
|
+
return this._request(`/api/prompts/templates/${templateId}/versions`, 'GET');
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
/**
|
|
1226
|
+
* POST /api/prompts/templates/:id/versions — Create a version (admin).
|
|
1227
|
+
* @param {string} templateId
|
|
1228
|
+
* @param {Object} data - { content, model_hint?, parameters?, changelog? }
|
|
1229
|
+
*/
|
|
1230
|
+
async createPromptVersion(templateId, data) {
|
|
1231
|
+
return this._request(`/api/prompts/templates/${templateId}/versions`, 'POST', data);
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
/**
|
|
1235
|
+
* GET /api/prompts/templates/:id/versions/:versionId — Fetch a single version.
|
|
1236
|
+
*/
|
|
1237
|
+
async getPromptVersion(templateId, versionId) {
|
|
1238
|
+
return this._request(`/api/prompts/templates/${templateId}/versions/${versionId}`, 'GET');
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1241
|
+
/**
|
|
1242
|
+
* POST /api/prompts/templates/:id/versions/:versionId — Activate a version (admin).
|
|
1243
|
+
* Activating one version deactivates the others for that template.
|
|
1244
|
+
*/
|
|
1245
|
+
async activatePromptVersion(templateId, versionId) {
|
|
1246
|
+
return this._request(`/api/prompts/templates/${templateId}/versions/${versionId}`, 'POST');
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
/**
|
|
1250
|
+
* GET /api/prompts/stats — Prompt usage analytics.
|
|
1251
|
+
* @param {Object} [filters={}] - { template_id }
|
|
1252
|
+
*/
|
|
1253
|
+
async getPromptStats(filters = {}) {
|
|
1254
|
+
return this._request('/api/prompts/stats', 'GET', null, filters);
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1257
|
+
/**
|
|
1258
|
+
* GET /api/prompts/runs — List recorded prompt runs.
|
|
1259
|
+
* @param {Object} [filters={}] - { template_id, version_id, limit }
|
|
1260
|
+
*/
|
|
1261
|
+
async listPromptRuns(filters = {}) {
|
|
1262
|
+
return this._request('/api/prompts/runs', 'GET', null, filters);
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
// ---------------------------------------------------------------------------
|
|
1266
|
+
// Learning — record decisions/outcomes and read back recommendations so the
|
|
1267
|
+
// governance loop improves over time.
|
|
1268
|
+
// ---------------------------------------------------------------------------
|
|
1269
|
+
|
|
1270
|
+
/**
|
|
1271
|
+
* POST /api/learning — Record a decision/outcome into the learning ledger.
|
|
1272
|
+
* @param {Object} entry - { decision (required), context?, reasoning?, outcome?, confidence?, agent_id? }
|
|
1273
|
+
* @returns {Promise<{ decision: Object }>}
|
|
1274
|
+
*/
|
|
1275
|
+
async recordDecision(entry) {
|
|
1276
|
+
return this._request('/api/learning', 'POST', {
|
|
1277
|
+
...entry,
|
|
1278
|
+
agent_id: entry.agent_id || this.agentId,
|
|
1279
|
+
});
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
/**
|
|
1283
|
+
* GET /api/learning/recommendations — Read learned recommendations for an agent/action_type.
|
|
1284
|
+
* @param {Object} [filters={}] - { agent_id, action_type, include_metrics, lookback_days, limit }
|
|
1285
|
+
*/
|
|
1286
|
+
async getLearningRecommendations(filters = {}) {
|
|
1287
|
+
return this._request('/api/learning/recommendations', 'GET', null, {
|
|
1288
|
+
...filters,
|
|
1289
|
+
agent_id: filters.agent_id || this.agentId,
|
|
1290
|
+
});
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
// ---------------------------------------------------------------------------
|
|
1294
|
+
// Policies — dry-run a proposed policy against historical actions before
|
|
1295
|
+
// committing it (no persistence; pairs with guard() for live enforcement).
|
|
1296
|
+
// ---------------------------------------------------------------------------
|
|
1297
|
+
|
|
1298
|
+
/**
|
|
1299
|
+
* POST /api/policies/simulate — Simulate a single proposed policy against
|
|
1300
|
+
* recent historical actions. Side-effect-free.
|
|
1301
|
+
* @param {Object} args - { policy_type (required), rules (Object, required), days? }
|
|
1302
|
+
* @returns {Promise<{ summary: { total, matches, block, warn, require_approval, allow }, matches: Array, sample_size, window_days }>}
|
|
1303
|
+
*/
|
|
1304
|
+
async simulatePolicy({ policy_type, rules, days } = {}) {
|
|
1305
|
+
return this._request('/api/policies/simulate', 'POST', {
|
|
1306
|
+
policy_type,
|
|
1307
|
+
rules,
|
|
1308
|
+
...(days !== undefined ? { days } : {}),
|
|
1309
|
+
});
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1312
|
+
// ---------------------------------------------------------------------------
|
|
1313
|
+
// Evaluations — preview a scorer (dry-run, no eval_scores written).
|
|
1314
|
+
// ---------------------------------------------------------------------------
|
|
1315
|
+
|
|
1316
|
+
/**
|
|
1317
|
+
* POST /api/evaluations/scorers/preview — Dry-run a scorer config against a
|
|
1318
|
+
* sample action without persisting a score. Use to validate a quality gate
|
|
1319
|
+
* (e.g. branch-finish scoring) before creating a scorer or launching a run.
|
|
1320
|
+
* @param {Object} args - { scorer_type (required), config?, sample? }
|
|
1321
|
+
* @returns {Promise<{ preview: true, scorer_type, result: { score, label, reasoning, error } }>}
|
|
1322
|
+
*/
|
|
1323
|
+
async previewScorer({ scorer_type, config, sample } = {}) {
|
|
1324
|
+
return this._request('/api/evaluations/scorers/preview', 'POST', { scorer_type, config, sample });
|
|
1325
|
+
}
|
|
1205
1326
|
}
|
|
1206
1327
|
|
|
1207
1328
|
export { DashClaw, ApprovalDeniedError, GuardBlockedError };
|