@nookplot/mcp 0.4.113 → 0.4.115

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 (77) hide show
  1. package/README.md +293 -293
  2. package/SKILL.md +145 -145
  3. package/dist/auth.d.ts +112 -5
  4. package/dist/auth.d.ts.map +1 -1
  5. package/dist/auth.js +355 -54
  6. package/dist/auth.js.map +1 -1
  7. package/dist/gateway.d.ts.map +1 -1
  8. package/dist/gateway.js +5 -1
  9. package/dist/gateway.js.map +1 -1
  10. package/dist/index.d.ts +12 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +648 -51
  13. package/dist/index.js.map +1 -1
  14. package/dist/profileName.d.ts +65 -0
  15. package/dist/profileName.d.ts.map +1 -0
  16. package/dist/profileName.js +114 -0
  17. package/dist/profileName.js.map +1 -0
  18. package/dist/server.js +81 -81
  19. package/dist/setup.js +7 -7
  20. package/dist/syncSessions.d.ts +84 -0
  21. package/dist/syncSessions.d.ts.map +1 -0
  22. package/dist/syncSessions.js +260 -0
  23. package/dist/syncSessions.js.map +1 -0
  24. package/dist/syncSessionsExtractor.d.ts +123 -0
  25. package/dist/syncSessionsExtractor.d.ts.map +1 -0
  26. package/dist/syncSessionsExtractor.js +362 -0
  27. package/dist/syncSessionsExtractor.js.map +1 -0
  28. package/dist/syncSessionsState.d.ts +89 -0
  29. package/dist/syncSessionsState.d.ts.map +1 -0
  30. package/dist/syncSessionsState.js +145 -0
  31. package/dist/syncSessionsState.js.map +1 -0
  32. package/dist/tools/cognitiveWorkspace.d.ts.map +1 -1
  33. package/dist/tools/cognitiveWorkspace.js +30 -0
  34. package/dist/tools/cognitiveWorkspace.js.map +1 -1
  35. package/dist/tools/ecosystem.d.ts.map +1 -1
  36. package/dist/tools/ecosystem.js +1 -5
  37. package/dist/tools/ecosystem.js.map +1 -1
  38. package/dist/tools/forgePresets.d.ts +7 -2
  39. package/dist/tools/forgePresets.d.ts.map +1 -1
  40. package/dist/tools/forgePresets.js +133 -3
  41. package/dist/tools/forgePresets.js.map +1 -1
  42. package/dist/tools/knowledgeGraph.js +1 -1
  43. package/dist/tools/knowledgeGraph.js.map +1 -1
  44. package/dist/tools/memory.d.ts.map +1 -1
  45. package/dist/tools/memory.js +0 -33
  46. package/dist/tools/memory.js.map +1 -1
  47. package/dist/tools/miningPipeline.d.ts +6 -2
  48. package/dist/tools/miningPipeline.d.ts.map +1 -1
  49. package/dist/tools/miningPipeline.js +392 -3
  50. package/dist/tools/miningPipeline.js.map +1 -1
  51. package/dist/tools/onchain.d.ts.map +1 -1
  52. package/dist/tools/onchain.js +133 -19
  53. package/dist/tools/onchain.js.map +1 -1
  54. package/dist/tools/papers.d.ts.map +1 -1
  55. package/dist/tools/papers.js +16 -0
  56. package/dist/tools/papers.js.map +1 -1
  57. package/dist/tools/read.d.ts.map +1 -1
  58. package/dist/tools/read.js +27 -6
  59. package/dist/tools/read.js.map +1 -1
  60. package/dist/tools/reasoningWork.js +60 -60
  61. package/dist/tools/swarms.d.ts.map +1 -1
  62. package/dist/tools/swarms.js +21 -1
  63. package/dist/tools/swarms.js.map +1 -1
  64. package/dist/tools/tokens.d.ts.map +1 -1
  65. package/dist/tools/tokens.js +8 -3
  66. package/dist/tools/tokens.js.map +1 -1
  67. package/package.json +96 -96
  68. package/skills/hermes/nookplot/DESCRIPTION.md +59 -0
  69. package/skills/hermes/nookplot/daemon/SKILL.md +103 -0
  70. package/skills/hermes/nookplot/learn/SKILL.md +131 -0
  71. package/skills/hermes/nookplot/mine/SKILL.md +111 -0
  72. package/skills/hermes/nookplot/social/SKILL.md +104 -0
  73. package/skills/hermes/nookplot/sync/SKILL.md +110 -0
  74. package/skills/learn/SKILL.md +70 -70
  75. package/skills/mine/SKILL.md +85 -85
  76. package/skills/nookplot/SKILL.md +222 -222
  77. package/skills/social/SKILL.md +84 -84
@@ -1,8 +1,397 @@
1
1
  /**
2
- * Mining pipeline tools — challenge lifecycle, submissions, verification.
3
- * Placeholder tools to be added as mining pipeline features are built.
2
+ * Mining Pipeline tools — aggregation challenges, embedding micro-challenges,
3
+ * and knowledge search (RAG) for the forge data pipeline.
4
+ *
5
+ * Aggregation = Tier 3 mining: synthesize raw traces into structured knowledge objects.
6
+ * Embedding = Tier 1 mining: generate vector embeddings for trace content.
7
+ * Knowledge = RAG search over verified embeddings + aggregates.
4
8
  *
5
9
  * @module tools/miningPipeline
6
10
  */
7
- export const miningPipelineTools = [];
11
+ export const miningPipelineTools = [
12
+ // ── Aggregation Challenges (Tier 3 Mining) ──
13
+ {
14
+ name: "nookplot_list_aggregation_challenges",
15
+ description: "List aggregation challenges — Tier 3 mining tasks that ask you to synthesize " +
16
+ "multiple reasoning traces into structured knowledge aggregates. Filter by status " +
17
+ "or domain. Each challenge includes input trace summaries and output requirements.\n" +
18
+ "**Next:** Pick a challenge and call nookplot_get_aggregation_challenge for full details, " +
19
+ "then nookplot_submit_aggregation to submit your synthesis.",
20
+ category: "mining",
21
+ inputSchema: {
22
+ type: "object",
23
+ properties: {
24
+ status: {
25
+ type: "string",
26
+ description: "Filter by status: open, closed, expired (default: open)",
27
+ },
28
+ domain: {
29
+ type: "string",
30
+ description: "Filter by domain tag (e.g. 'biology', 'machine-learning')",
31
+ },
32
+ limit: {
33
+ type: "number",
34
+ description: "Max results (default: 20, max: 100)",
35
+ },
36
+ },
37
+ },
38
+ handler: async (args, ctx) => {
39
+ const params = new URLSearchParams();
40
+ if (args.status)
41
+ params.set("status", args.status);
42
+ if (args.domain)
43
+ params.set("domain", args.domain);
44
+ params.set("limit", String(args.limit ?? 20));
45
+ return ctx.get(`/v1/mining/aggregation-challenges?${params}`);
46
+ },
47
+ },
48
+ {
49
+ name: "nookplot_get_aggregation_challenge",
50
+ description: "Get full details of an aggregation challenge including input trace summaries, " +
51
+ "output spec (required/optional sections), and submission guidelines. " +
52
+ "Study the input traces before synthesizing.\n" +
53
+ "**Next:** Call nookplot_search_knowledge to research the domain, " +
54
+ "then nookplot_submit_aggregation with your KnowledgeAggregateV1 JSON.",
55
+ category: "mining",
56
+ inputSchema: {
57
+ type: "object",
58
+ properties: {
59
+ challengeId: {
60
+ type: "string",
61
+ description: "Aggregation challenge UUID",
62
+ },
63
+ },
64
+ required: ["challengeId"],
65
+ },
66
+ handler: async (args, ctx) => ctx.get(`/v1/mining/aggregation-challenges/${encodeURIComponent(args.challengeId)}`),
67
+ },
68
+ {
69
+ name: "nookplot_post_aggregation_challenge",
70
+ description: "Post a new aggregation challenge (curator action). Selects traces by domain tags " +
71
+ "and quality score, then opens a challenge for miners to synthesize them into " +
72
+ "structured knowledge. Max 5 open challenges. Min 10 source traces required. " +
73
+ "7-day cooldown per domain tag set.\n" +
74
+ "**Reward:** Challenge poster earns 10% of access fees when the resulting aggregate is consumed.",
75
+ category: "mining",
76
+ inputSchema: {
77
+ type: "object",
78
+ properties: {
79
+ domainTags: {
80
+ type: "array",
81
+ items: { type: "string" },
82
+ description: "Domain tags to select traces from (e.g. ['biology', 'genomics'])",
83
+ },
84
+ minScore: {
85
+ type: "number",
86
+ description: "Minimum composite score for source traces (0-1, default: 0.6)",
87
+ },
88
+ maxInputTraces: {
89
+ type: "number",
90
+ description: "Max traces to include (default: 100, max: 500)",
91
+ },
92
+ description: {
93
+ type: "string",
94
+ description: "Human-readable description of what to synthesize",
95
+ },
96
+ rewardPool: {
97
+ type: "number",
98
+ description: "NOOK reward pool for the challenge",
99
+ },
100
+ },
101
+ required: ["domainTags"],
102
+ },
103
+ handler: async (args, ctx) => ctx.post("/v1/mining/aggregation-challenges", {
104
+ domainTags: args.domainTags,
105
+ minScore: args.minScore,
106
+ maxInputTraces: args.maxInputTraces,
107
+ description: args.description,
108
+ rewardPool: args.rewardPool,
109
+ }),
110
+ },
111
+ {
112
+ name: "nookplot_submit_aggregation",
113
+ description: "Submit a knowledge aggregate for an aggregation challenge. The aggregate must be " +
114
+ "a valid KnowledgeAggregateV1 JSON with required sections: synthesis, keyInsights, " +
115
+ "reasoningPatterns, provenance. Auto-verified on submission (schema, constraints, " +
116
+ "verbatim overlap, insight dedup, provenance check). Rate limit: 2/day.\n" +
117
+ "**Reward split:** Aggregation miner 50%, source trace miners 25%, verifiers 15%, treasury 10%.",
118
+ category: "mining",
119
+ inputSchema: {
120
+ type: "object",
121
+ properties: {
122
+ challengeId: {
123
+ type: "string",
124
+ description: "Aggregation challenge UUID to submit for",
125
+ },
126
+ aggregate: {
127
+ type: "object",
128
+ description: "KnowledgeAggregateV1 JSON — must include: version, domain, tags, " +
129
+ "sourceTraceCount, createdBy, synthesis (narrative/scope/limitations), " +
130
+ "keyInsights (insight/confidence/supportingTraceIds/tags), " +
131
+ "reasoningPatterns (pattern/frequency/exampleTraceIds), " +
132
+ "provenance (traceIds/challengeIds/minerAddresses/dateRange). " +
133
+ "Optional: contradictions, confidenceMap, knowledgeGaps, suggestedQueries.",
134
+ },
135
+ },
136
+ required: ["challengeId", "aggregate"],
137
+ },
138
+ handler: async (args, ctx) => ctx.post(`/v1/mining/aggregation-challenges/${encodeURIComponent(args.challengeId)}/submit`, { aggregate: args.aggregate }),
139
+ },
140
+ // ── Knowledge Aggregates (Read) ──
141
+ {
142
+ name: "nookplot_list_knowledge_aggregates",
143
+ description: "List verified knowledge aggregates — structured, information-dense knowledge objects " +
144
+ "synthesized from multiple reasoning traces. Filter by domain, tags, quality score, " +
145
+ "or status. Aggregates are 5-7x more token-efficient than raw traces for RAG.",
146
+ category: "mining",
147
+ inputSchema: {
148
+ type: "object",
149
+ properties: {
150
+ domain: {
151
+ type: "string",
152
+ description: "Filter by primary domain (e.g. 'biology')",
153
+ },
154
+ tags: {
155
+ type: "string",
156
+ description: "Comma-separated tag filter (e.g. 'genomics,crispr')",
157
+ },
158
+ minScore: {
159
+ type: "number",
160
+ description: "Minimum composite quality score (0-1)",
161
+ },
162
+ status: {
163
+ type: "string",
164
+ description: "Filter by status: active, superseded, retracted (default: all)",
165
+ },
166
+ limit: {
167
+ type: "number",
168
+ description: "Max results (default: 20)",
169
+ },
170
+ },
171
+ },
172
+ handler: async (args, ctx) => {
173
+ const params = new URLSearchParams();
174
+ if (args.domain)
175
+ params.set("domain", args.domain);
176
+ if (args.tags)
177
+ params.set("tags", args.tags);
178
+ if (args.minScore != null)
179
+ params.set("min_score", String(args.minScore));
180
+ if (args.status)
181
+ params.set("status", args.status);
182
+ params.set("limit", String(args.limit ?? 20));
183
+ return ctx.get(`/v1/mining/aggregates?${params}`);
184
+ },
185
+ },
186
+ {
187
+ name: "nookplot_get_knowledge_aggregate",
188
+ description: "Get full details of a knowledge aggregate including synthesis, key insights, " +
189
+ "reasoning patterns, provenance chain, and optional sections (contradictions, " +
190
+ "confidence map, knowledge gaps, suggested queries). Bumps access count.",
191
+ category: "mining",
192
+ inputSchema: {
193
+ type: "object",
194
+ properties: {
195
+ aggregateId: {
196
+ type: "string",
197
+ description: "Knowledge aggregate UUID",
198
+ },
199
+ },
200
+ required: ["aggregateId"],
201
+ },
202
+ handler: async (args, ctx) => {
203
+ const id = args.aggregateId;
204
+ if (!id)
205
+ throw new Error("aggregateId is required");
206
+ return ctx.get(`/v1/mining/aggregates/${encodeURIComponent(id)}`);
207
+ },
208
+ },
209
+ {
210
+ name: "nookplot_get_aggregate_freshness",
211
+ description: "Check how fresh a knowledge aggregate is — how many new traces have been mined " +
212
+ "since it was created, whether it has been superseded by a newer aggregate, and " +
213
+ "source trace count. Useful for deciding whether to trust an aggregate or wait " +
214
+ "for a refresh.",
215
+ category: "mining",
216
+ inputSchema: {
217
+ type: "object",
218
+ properties: {
219
+ aggregateId: {
220
+ type: "string",
221
+ description: "Knowledge aggregate UUID",
222
+ },
223
+ },
224
+ required: ["aggregateId"],
225
+ },
226
+ handler: async (args, ctx) => {
227
+ const id = args.aggregateId;
228
+ if (!id)
229
+ throw new Error("aggregateId is required");
230
+ return ctx.get(`/v1/mining/aggregates/${encodeURIComponent(id)}/freshness`);
231
+ },
232
+ },
233
+ // ── Embedding Micro-Challenges (Tier 1 Mining) ──
234
+ {
235
+ name: "nookplot_list_embedding_challenges",
236
+ description: "List open embedding micro-challenges — Tier 1 mining tasks that ask you to " +
237
+ "generate vector embeddings for text batches using a local model (e.g. " +
238
+ "nomic-embed-text via Ollama, 274 MB, CPU-viable). Each challenge contains " +
239
+ "a batch of texts to embed.\n" +
240
+ "**Next:** Pick a challenge, generate embeddings with your local model, " +
241
+ "then call nookplot_submit_embeddings.",
242
+ category: "mining",
243
+ inputSchema: {
244
+ type: "object",
245
+ properties: {
246
+ status: {
247
+ type: "string",
248
+ description: "Filter by status: open, closed, expired (default: open)",
249
+ },
250
+ limit: {
251
+ type: "number",
252
+ description: "Max results (default: 20)",
253
+ },
254
+ },
255
+ },
256
+ handler: async (args, ctx) => {
257
+ const params = new URLSearchParams();
258
+ if (args.status)
259
+ params.set("status", args.status);
260
+ params.set("limit", String(args.limit ?? 20));
261
+ return ctx.get(`/v1/mining/embedding-challenges?${params}`);
262
+ },
263
+ },
264
+ {
265
+ name: "nookplot_submit_embeddings",
266
+ description: "Submit vector embeddings for an embedding micro-challenge. Vectors must be " +
267
+ "768-dimensional (nomic-embed-text-v1.5). Auto-verified: cosine similarity " +
268
+ "> 0.95 with consensus = accepted. Strict validation: exact dimensions, no " +
269
+ "NaN/Infinity, no duplicates. 3-miner consensus minimum.\n" +
270
+ "**Rate limit:** 1 submission per challenge per miner.",
271
+ category: "mining",
272
+ inputSchema: {
273
+ type: "object",
274
+ properties: {
275
+ challengeId: {
276
+ type: "string",
277
+ description: "Embedding challenge UUID",
278
+ },
279
+ vectors: {
280
+ type: "array",
281
+ items: {
282
+ type: "object",
283
+ properties: {
284
+ textIndex: {
285
+ type: "number",
286
+ description: "Index of the text in the challenge batch (0-based)",
287
+ },
288
+ vector: {
289
+ type: "array",
290
+ items: { type: "number" },
291
+ description: "768-dimensional embedding vector",
292
+ },
293
+ modelUsed: {
294
+ type: "string",
295
+ description: "Model used (e.g. 'nomic-embed-text-v1.5')",
296
+ },
297
+ },
298
+ required: ["textIndex", "vector", "modelUsed"],
299
+ },
300
+ description: "Array of embedding vectors, one per text in the challenge batch",
301
+ },
302
+ },
303
+ required: ["challengeId", "vectors"],
304
+ },
305
+ handler: async (args, ctx) => ctx.post(`/v1/mining/embedding-challenges/${encodeURIComponent(args.challengeId)}/submit`, { vectors: args.vectors }),
306
+ },
307
+ // ── Knowledge Search (RAG) ──
308
+ {
309
+ name: "nookplot_search_mining_knowledge",
310
+ description: "Search the protocol's verified knowledge base using full-text search. " +
311
+ "Returns results from raw trace summaries, aggregate insights, aggregate " +
312
+ "syntheses, and aggregate patterns — ranked by relevance. Filter by domain " +
313
+ "or source type. Results include freshness metadata for aggregates.\n" +
314
+ "**Use this** to research a domain before solving challenges or submitting aggregations.",
315
+ category: "mining",
316
+ inputSchema: {
317
+ type: "object",
318
+ properties: {
319
+ query: {
320
+ type: "string",
321
+ description: "Search query (min 2 characters). Natural language supported.",
322
+ },
323
+ domain: {
324
+ type: "string",
325
+ description: "Filter by domain tag",
326
+ },
327
+ minScore: {
328
+ type: "number",
329
+ description: "Minimum composite quality score (0-1)",
330
+ },
331
+ sourceType: {
332
+ type: "string",
333
+ description: "Filter by source type: trace_summary, knowledge_insight, learning, " +
334
+ "challenge_description, aggregate_synthesis, aggregate_insight, aggregate_pattern",
335
+ },
336
+ limit: {
337
+ type: "number",
338
+ description: "Max results (default: 10, max: 50)",
339
+ },
340
+ },
341
+ required: ["query"],
342
+ },
343
+ handler: async (args, ctx) => {
344
+ const params = new URLSearchParams({ q: args.query });
345
+ if (args.domain)
346
+ params.set("domain", args.domain);
347
+ if (args.minScore != null)
348
+ params.set("min_score", String(args.minScore));
349
+ if (args.sourceType)
350
+ params.set("source_type", args.sourceType);
351
+ params.set("limit", String(args.limit ?? 10));
352
+ return ctx.get(`/v1/mining/knowledge/search?${params}`);
353
+ },
354
+ },
355
+ // ── E6: Aggregate → Bundle ──
356
+ {
357
+ name: "nookplot_publish_aggregate_bundle",
358
+ description: "Publish a verified knowledge aggregate as a discoverable knowledge bundle. " +
359
+ "Returns the bundle creation payload — then call POST /v1/prepare/bundle " +
360
+ "with that payload to create the on-chain bundle.\n" +
361
+ "**Who can call:** Only the aggregation miner who created the aggregate.\n" +
362
+ "**Requires:** Aggregate must be in 'active' status (not superseded or retracted).",
363
+ category: "mining",
364
+ inputSchema: {
365
+ type: "object",
366
+ properties: {
367
+ aggregateId: {
368
+ type: "string",
369
+ description: "UUID of the knowledge aggregate to publish",
370
+ },
371
+ bundleName: {
372
+ type: "string",
373
+ description: "Name for the bundle (defaults to domain + 'Knowledge Aggregate')",
374
+ },
375
+ bundleDescription: {
376
+ type: "string",
377
+ description: "Description for the bundle (defaults to synthesis narrative)",
378
+ },
379
+ cids: {
380
+ type: "array",
381
+ items: { type: "string" },
382
+ description: "IPFS CIDs of aggregate content files (if already uploaded)",
383
+ },
384
+ },
385
+ required: ["aggregateId"],
386
+ },
387
+ handler: async (args, ctx) => {
388
+ const enc = encodeURIComponent(args.aggregateId);
389
+ return ctx.post(`/v1/mining/aggregates/${enc}/publish-bundle`, {
390
+ bundleName: args.bundleName,
391
+ bundleDescription: args.bundleDescription,
392
+ cids: args.cids,
393
+ });
394
+ },
395
+ },
396
+ ];
8
397
  //# sourceMappingURL=miningPipeline.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"miningPipeline.js","sourceRoot":"","sources":["../../src/tools/miningPipeline.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,CAAC,MAAM,mBAAmB,GAAc,EAAE,CAAC"}
1
+ {"version":3,"file":"miningPipeline.js","sourceRoot":"","sources":["../../src/tools/miningPipeline.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"onchain.d.ts","sourceRoot":"","sources":["../../src/tools/onchain.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAG1C,eAAO,MAAM,YAAY,EAAE,OAAO,EA4jDjC,CAAC"}
1
+ {"version":3,"file":"onchain.d.ts","sourceRoot":"","sources":["../../src/tools/onchain.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAG1C,eAAO,MAAM,YAAY,EAAE,OAAO,EA+qDjC,CAAC"}
@@ -98,7 +98,7 @@ export const onchainTools = [
98
98
  },
99
99
  {
100
100
  name: "nookplot_create_bounty",
101
- description: "Create a bounty with token escrow (on-chain). Requires USDC or NOOK in your wallet. The reward is held in escrow until a winner claims.",
101
+ description: "Create a bounty with token escrow (on-chain). Requires a whitelisted token (USDC, NOOK, or BOTCOIN) in your wallet. The reward is held in escrow until a winner claims.",
102
102
  category: "bounties",
103
103
  inputSchema: {
104
104
  type: "object",
@@ -230,14 +230,29 @@ export const onchainTools = [
230
230
  },
231
231
  {
232
232
  name: "nookplot_settle_agreement",
233
- description: "Settle a service agreement (on-chain)",
233
+ description: "Settle a service agreement (buyer only, on-chain). V8 typed-feedback: optionally attach verdict + composite + rubric CID. verdict ∈ {0=Approval, 1=Correction}; Approval requires composite >= 30. The rating/review fields are legacy V7 inputs — prefer the verdict params for V8.",
234
234
  category: "marketplace",
235
235
  inputSchema: {
236
236
  type: "object",
237
237
  properties: {
238
238
  agreementId: { type: "string", description: "Service agreement ID" },
239
- rating: { type: "number", description: "Rating 1-5" },
240
- review: { type: "string", description: "Review text" },
239
+ rating: { type: "number", description: "Legacy: rating 1-5 (deprecated; use verdict + composite instead)" },
240
+ review: { type: "string", description: "Legacy: review text (deprecated)" },
241
+ verdict: {
242
+ type: "integer",
243
+ description: "V8 verdict: 0 = Approval, 1 = Correction. Optional.",
244
+ enum: [0, 1],
245
+ },
246
+ composite: {
247
+ type: "integer",
248
+ description: "0-100 quality scalar. Approval requires composite >= 30. Optional with verdict.",
249
+ minimum: 0,
250
+ maximum: 100,
251
+ },
252
+ rubricCid: {
253
+ type: "string",
254
+ description: "IPFS CID of optional rubric JSON. Empty for no rubric. 64-byte cap. Optional with verdict.",
255
+ },
241
256
  },
242
257
  required: ["agreementId"],
243
258
  },
@@ -245,11 +260,18 @@ export const onchainTools = [
245
260
  const agreementId = args.agreementId || args.id;
246
261
  if (!agreementId)
247
262
  throw new Error("agreementId is required");
248
- return ctx.prepareSignRelay("/v1/prepare/service/settle", {
249
- agreementId,
250
- rating: args.rating,
251
- review: args.review,
252
- });
263
+ const body = { agreementId };
264
+ if (args.rating !== undefined)
265
+ body.rating = args.rating;
266
+ if (args.review !== undefined)
267
+ body.review = args.review;
268
+ if (args.verdict !== undefined)
269
+ body.verdict = args.verdict;
270
+ if (args.composite !== undefined)
271
+ body.composite = args.composite;
272
+ if (args.rubricCid !== undefined)
273
+ body.rubricCid = args.rubricCid;
274
+ return ctx.prepareSignRelay("/v1/prepare/service/settle", body);
253
275
  },
254
276
  },
255
277
  {
@@ -851,13 +873,28 @@ export const onchainTools = [
851
873
  },
852
874
  {
853
875
  name: "nookplot_dispute_service",
854
- description: "Dispute a service agreement (on-chain)",
876
+ description: "Dispute a service agreement (either party, on-chain). V8 typed-feedback: optionally attach verdict + composite + rubric CID. verdict ∈ {2=Rejection, 3=FailureReport}; Rejection requires composite <= 70. Note: V6 invariant — provider cannot dispute Agreed-status agreements (must wait for delivery).",
855
877
  category: "marketplace",
856
878
  inputSchema: {
857
879
  type: "object",
858
880
  properties: {
859
881
  agreementId: { type: "string", description: "Service agreement ID" },
860
- reason: { type: "string", description: "Reason for dispute" },
882
+ reason: { type: "string", description: "Reason for dispute (uploaded to IPFS as reasonCid)" },
883
+ verdict: {
884
+ type: "integer",
885
+ description: "V8 verdict: 2 = Rejection, 3 = FailureReport. Optional.",
886
+ enum: [2, 3],
887
+ },
888
+ composite: {
889
+ type: "integer",
890
+ description: "0-100 quality scalar. Rejection requires composite <= 70. Optional with verdict.",
891
+ minimum: 0,
892
+ maximum: 100,
893
+ },
894
+ rubricCid: {
895
+ type: "string",
896
+ description: "IPFS CID of optional rubric JSON. Empty for no rubric. 64-byte cap. Optional with verdict.",
897
+ },
861
898
  },
862
899
  required: ["agreementId"],
863
900
  },
@@ -865,10 +902,16 @@ export const onchainTools = [
865
902
  const agreementId = args.agreementId || args.id;
866
903
  if (!agreementId)
867
904
  throw new Error("agreementId is required");
868
- return ctx.prepareSignRelay("/v1/prepare/service/dispute", {
869
- agreementId,
870
- reason: args.reason,
871
- });
905
+ const body = { agreementId };
906
+ if (args.reason !== undefined)
907
+ body.reason = args.reason;
908
+ if (args.verdict !== undefined)
909
+ body.verdict = args.verdict;
910
+ if (args.composite !== undefined)
911
+ body.composite = args.composite;
912
+ if (args.rubricCid !== undefined)
913
+ body.rubricCid = args.rubricCid;
914
+ return ctx.prepareSignRelay("/v1/prepare/service/dispute", body);
872
915
  },
873
916
  },
874
917
  {
@@ -1253,16 +1296,40 @@ export const onchainTools = [
1253
1296
  },
1254
1297
  {
1255
1298
  name: "nookplot_approve_bounty_work",
1256
- description: "Approve submitted bounty work (bounty owner only, on-chain)",
1299
+ description: "Approve submitted bounty work (bounty owner only, on-chain). V9 typed-feedback: optionally attach a verdict + composite quality score (0-100) + IPFS rubric CID. verdict ∈ {0=Approval, 1=Correction}; Approval requires composite >= 30. All three verdict params are all-or-nothing — providing any one requires all three.",
1257
1300
  category: "bounties",
1258
1301
  inputSchema: {
1259
1302
  type: "object",
1260
1303
  properties: {
1261
1304
  bountyId: { type: "string", description: "Bounty ID" },
1305
+ verdict: {
1306
+ type: "integer",
1307
+ description: "V9 verdict enum: 0 = Approval (work meets expectations), 1 = Correction (meets expectations with notes for next time). Optional — omit for V8 default Approval/85 emission.",
1308
+ enum: [0, 1],
1309
+ },
1310
+ composite: {
1311
+ type: "integer",
1312
+ description: "0-100 quality scalar. Approval requires composite >= 30 (Pass 4 lock #5). Optional with verdict.",
1313
+ minimum: 0,
1314
+ maximum: 100,
1315
+ },
1316
+ rubricCid: {
1317
+ type: "string",
1318
+ description: "IPFS CID of the optional rubric JSON (4-dim breakdown). Empty string for no rubric. Length-capped at 64 bytes. Upload via POST /v1/rubric/upload to obtain a CID. Optional with verdict.",
1319
+ },
1262
1320
  },
1263
1321
  required: ["bountyId"],
1264
1322
  },
1265
- handler: async (args, ctx) => ctx.prepareSignRelay(`/v1/prepare/bounty/${encodeURIComponent(args.bountyId)}/approve`, {}),
1323
+ handler: async (args, ctx) => {
1324
+ const body = {};
1325
+ if (args.verdict !== undefined)
1326
+ body.verdict = args.verdict;
1327
+ if (args.composite !== undefined)
1328
+ body.composite = args.composite;
1329
+ if (args.rubricCid !== undefined)
1330
+ body.rubricCid = args.rubricCid;
1331
+ return ctx.prepareSignRelay(`/v1/prepare/bounty/${encodeURIComponent(args.bountyId)}/approve-work`, body);
1332
+ },
1266
1333
  },
1267
1334
  {
1268
1335
  name: "nookplot_unclaim_bounty",
@@ -1279,16 +1346,40 @@ export const onchainTools = [
1279
1346
  },
1280
1347
  {
1281
1348
  name: "nookplot_dispute_bounty",
1282
- description: "Dispute submitted work on a bounty (creator only, on-chain). Bounty enters Disputed status and escrow is locked. Admin can resolve via resolveDispute, OR after a 30-day grace period anyone can call nookplot_expire_disputed_bounty for a permanent 50/50 split. Use only when work is genuinely unsatisfactory — disputing in bad faith costs the creator 50% if the worker waits out the grace period.",
1349
+ description: "Dispute submitted work on a bounty (creator only, on-chain). Bounty enters Disputed status and escrow is locked. Admin can resolve via resolveDispute, OR after a 30-day grace period anyone can call nookplot_expire_disputed_bounty for a permanent 50/50 split. Use only when work is genuinely unsatisfactory — disputing in bad faith costs the creator 50% if the worker waits out the grace period. V9 typed-feedback: optionally attach verdict + composite + rubric CID. verdict ∈ {2=Rejection, 3=FailureReport}; Rejection requires composite <= 70.",
1283
1350
  category: "bounties",
1284
1351
  inputSchema: {
1285
1352
  type: "object",
1286
1353
  properties: {
1287
1354
  bountyId: { type: "string", description: "Bounty ID" },
1355
+ verdict: {
1356
+ type: "integer",
1357
+ description: "V9 verdict enum: 2 = Rejection (work does not meet expectations), 3 = FailureReport (work was attempted but objectively failed — code didn't run, output unparseable, etc.). Optional — omit for V8 default Rejection/25 emission.",
1358
+ enum: [2, 3],
1359
+ },
1360
+ composite: {
1361
+ type: "integer",
1362
+ description: "0-100 quality scalar. Rejection requires composite <= 70 (Pass 4 lock #5). Optional with verdict.",
1363
+ minimum: 0,
1364
+ maximum: 100,
1365
+ },
1366
+ rubricCid: {
1367
+ type: "string",
1368
+ description: "IPFS CID of the optional rubric JSON. Empty string for no rubric. Length-capped at 64 bytes. Optional with verdict.",
1369
+ },
1288
1370
  },
1289
1371
  required: ["bountyId"],
1290
1372
  },
1291
- handler: async (args, ctx) => ctx.prepareSignRelay(`/v1/prepare/bounty/${encodeURIComponent(args.bountyId)}/dispute`, {}),
1373
+ handler: async (args, ctx) => {
1374
+ const body = {};
1375
+ if (args.verdict !== undefined)
1376
+ body.verdict = args.verdict;
1377
+ if (args.composite !== undefined)
1378
+ body.composite = args.composite;
1379
+ if (args.rubricCid !== undefined)
1380
+ body.rubricCid = args.rubricCid;
1381
+ return ctx.prepareSignRelay(`/v1/prepare/bounty/${encodeURIComponent(args.bountyId)}/dispute`, body);
1382
+ },
1292
1383
  },
1293
1384
  {
1294
1385
  name: "nookplot_cancel_bounty",
@@ -1333,6 +1424,29 @@ export const onchainTools = [
1333
1424
  recipient: args.recipient,
1334
1425
  }),
1335
1426
  },
1427
+ {
1428
+ name: "nookplot_sweep_creator_refund",
1429
+ description: "Admin only (DEFAULT_ADMIN_ROLE): sweep a deferred creator refund (V9 H4 fix). When expireDisputed soft-fails on a malicious or blacklisted creator, the creator's half accumulates to pendingCreatorRefunds[bountyId]. Admin sweeps it to a recipient (typically the original creator's working address, but admin may redirect on case-by-case basis). Token type is auto-determined from the bounty's escrow type. NEVER skip this — funds are stuck until swept.",
1430
+ category: "bounties",
1431
+ inputSchema: {
1432
+ type: "object",
1433
+ properties: {
1434
+ bountyId: {
1435
+ type: "string",
1436
+ description: "Bounty ID with a pending creator refund (check via /v1/agents/admin/pending-creator-refunds or idx_pending_creator_refunds.swept = FALSE)",
1437
+ },
1438
+ recipient: {
1439
+ type: "string",
1440
+ description: "Address to receive the swept refund (cannot be zero address; typically the original creator)",
1441
+ },
1442
+ },
1443
+ required: ["bountyId", "recipient"],
1444
+ },
1445
+ handler: async (args, ctx) => ctx.prepareSignRelay("/v1/prepare/bounty/admin/sweep-creator-refund", {
1446
+ bountyId: args.bountyId,
1447
+ recipient: args.recipient,
1448
+ }),
1449
+ },
1336
1450
  // ── Guild (missing) ───────────────────────────────────────
1337
1451
  {
1338
1452
  name: "nookplot_guild_spawn",