@sellable/mcp 0.1.318 → 0.1.320

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.
@@ -2426,6 +2426,234 @@ export declare const allTools: ({
2426
2426
  required: string[];
2427
2427
  additionalProperties: boolean;
2428
2428
  };
2429
+ } | {
2430
+ name: string;
2431
+ description: string;
2432
+ inputSchema: {
2433
+ type: string;
2434
+ properties: {
2435
+ threadId: {
2436
+ type: string;
2437
+ };
2438
+ limit?: undefined;
2439
+ cursor?: undefined;
2440
+ filter?: undefined;
2441
+ status?: undefined;
2442
+ senderId?: undefined;
2443
+ classification?: undefined;
2444
+ search?: undefined;
2445
+ includeEnrichment?: undefined;
2446
+ includeReplyEligibility?: undefined;
2447
+ versionId?: undefined;
2448
+ body?: undefined;
2449
+ approvedBody?: undefined;
2450
+ approvedBodyHash?: undefined;
2451
+ approvedThreadSnapshot?: undefined;
2452
+ idempotencyKey?: undefined;
2453
+ approval?: undefined;
2454
+ message?: undefined;
2455
+ approvedMessageHash?: undefined;
2456
+ };
2457
+ required: string[];
2458
+ additionalProperties: boolean;
2459
+ };
2460
+ outputSchema: {
2461
+ type: string;
2462
+ additionalProperties: boolean;
2463
+ };
2464
+ annotations: {
2465
+ readOnlyHint: boolean;
2466
+ destructiveHint: boolean;
2467
+ openWorldHint: boolean;
2468
+ idempotentHint?: undefined;
2469
+ };
2470
+ } | {
2471
+ name: string;
2472
+ description: string;
2473
+ inputSchema: {
2474
+ type: string;
2475
+ properties: {
2476
+ threadId: {
2477
+ type: string;
2478
+ };
2479
+ versionId: {
2480
+ type: string;
2481
+ };
2482
+ body: {
2483
+ type: string;
2484
+ };
2485
+ limit?: undefined;
2486
+ cursor?: undefined;
2487
+ filter?: undefined;
2488
+ status?: undefined;
2489
+ senderId?: undefined;
2490
+ classification?: undefined;
2491
+ search?: undefined;
2492
+ includeEnrichment?: undefined;
2493
+ includeReplyEligibility?: undefined;
2494
+ approvedBody?: undefined;
2495
+ approvedBodyHash?: undefined;
2496
+ approvedThreadSnapshot?: undefined;
2497
+ idempotencyKey?: undefined;
2498
+ approval?: undefined;
2499
+ message?: undefined;
2500
+ approvedMessageHash?: undefined;
2501
+ };
2502
+ required: string[];
2503
+ additionalProperties: boolean;
2504
+ };
2505
+ outputSchema: {
2506
+ type: string;
2507
+ additionalProperties: boolean;
2508
+ };
2509
+ annotations: {
2510
+ readOnlyHint: boolean;
2511
+ destructiveHint: boolean;
2512
+ openWorldHint: boolean;
2513
+ idempotentHint: boolean;
2514
+ };
2515
+ } | {
2516
+ name: string;
2517
+ description: string;
2518
+ inputSchema: {
2519
+ type: string;
2520
+ properties: {
2521
+ threadId: {
2522
+ type: string;
2523
+ };
2524
+ versionId: {
2525
+ type: string;
2526
+ };
2527
+ approvedBody: {
2528
+ type: string;
2529
+ };
2530
+ approvedBodyHash: {
2531
+ type: string;
2532
+ };
2533
+ approvedThreadSnapshot: {
2534
+ type: string;
2535
+ properties: {
2536
+ latestMessageTimestamp: {
2537
+ type: string[];
2538
+ };
2539
+ lastInboundMessageAt: {
2540
+ type: string[];
2541
+ };
2542
+ updatedAt: {
2543
+ type: string[];
2544
+ };
2545
+ reasonCodes: {
2546
+ type: string;
2547
+ items: {
2548
+ type: string;
2549
+ };
2550
+ };
2551
+ };
2552
+ additionalProperties: boolean;
2553
+ };
2554
+ idempotencyKey: {
2555
+ type: string;
2556
+ };
2557
+ approval: {
2558
+ type: string;
2559
+ enum: string[];
2560
+ };
2561
+ limit?: undefined;
2562
+ cursor?: undefined;
2563
+ filter?: undefined;
2564
+ status?: undefined;
2565
+ senderId?: undefined;
2566
+ classification?: undefined;
2567
+ search?: undefined;
2568
+ includeEnrichment?: undefined;
2569
+ includeReplyEligibility?: undefined;
2570
+ body?: undefined;
2571
+ message?: undefined;
2572
+ approvedMessageHash?: undefined;
2573
+ };
2574
+ required: string[];
2575
+ additionalProperties: boolean;
2576
+ };
2577
+ outputSchema: {
2578
+ type: string;
2579
+ additionalProperties: boolean;
2580
+ };
2581
+ annotations: {
2582
+ readOnlyHint: boolean;
2583
+ destructiveHint: boolean;
2584
+ openWorldHint: boolean;
2585
+ idempotentHint: boolean;
2586
+ };
2587
+ } | {
2588
+ name: string;
2589
+ description: string;
2590
+ inputSchema: {
2591
+ type: string;
2592
+ properties: {
2593
+ threadId: {
2594
+ type: string;
2595
+ };
2596
+ message: {
2597
+ type: string;
2598
+ };
2599
+ approvedMessageHash: {
2600
+ type: string;
2601
+ };
2602
+ approvedThreadSnapshot: {
2603
+ type: string;
2604
+ properties: {
2605
+ latestMessageTimestamp: {
2606
+ type: string[];
2607
+ };
2608
+ lastInboundMessageAt: {
2609
+ type: string[];
2610
+ };
2611
+ updatedAt: {
2612
+ type: string[];
2613
+ };
2614
+ reasonCodes: {
2615
+ type: string;
2616
+ items: {
2617
+ type: string;
2618
+ };
2619
+ };
2620
+ };
2621
+ additionalProperties: boolean;
2622
+ };
2623
+ idempotencyKey: {
2624
+ type: string;
2625
+ };
2626
+ approval: {
2627
+ type: string;
2628
+ enum: string[];
2629
+ };
2630
+ limit?: undefined;
2631
+ cursor?: undefined;
2632
+ filter?: undefined;
2633
+ status?: undefined;
2634
+ senderId?: undefined;
2635
+ classification?: undefined;
2636
+ search?: undefined;
2637
+ includeEnrichment?: undefined;
2638
+ includeReplyEligibility?: undefined;
2639
+ versionId?: undefined;
2640
+ body?: undefined;
2641
+ approvedBody?: undefined;
2642
+ approvedBodyHash?: undefined;
2643
+ };
2644
+ required: string[];
2645
+ additionalProperties: boolean;
2646
+ };
2647
+ outputSchema: {
2648
+ type: string;
2649
+ additionalProperties: boolean;
2650
+ };
2651
+ annotations: {
2652
+ readOnlyHint: boolean;
2653
+ destructiveHint: boolean;
2654
+ openWorldHint: boolean;
2655
+ idempotentHint: boolean;
2656
+ };
2429
2657
  } | {
2430
2658
  name: string;
2431
2659
  description: string;
@@ -6313,6 +6541,7 @@ export declare const allTools: ({
6313
6541
  postUrl?: undefined;
6314
6542
  sources?: undefined;
6315
6543
  full?: undefined;
6544
+ fetchMinimal?: undefined;
6316
6545
  companyUrl?: undefined;
6317
6546
  sortBy?: undefined;
6318
6547
  linkedin_url?: undefined;
@@ -6343,6 +6572,7 @@ export declare const allTools: ({
6343
6572
  };
6344
6573
  linkedinUrl?: undefined;
6345
6574
  full?: undefined;
6575
+ fetchMinimal?: undefined;
6346
6576
  companyUrl?: undefined;
6347
6577
  sortBy?: undefined;
6348
6578
  linkedin_url?: undefined;
@@ -6365,6 +6595,11 @@ export declare const allTools: ({
6365
6595
  description: string;
6366
6596
  default: boolean;
6367
6597
  };
6598
+ fetchMinimal: {
6599
+ type: string;
6600
+ description: string;
6601
+ default: boolean;
6602
+ };
6368
6603
  limit?: undefined;
6369
6604
  postUrl?: undefined;
6370
6605
  sources?: undefined;
@@ -6390,6 +6625,7 @@ export declare const allTools: ({
6390
6625
  postUrl?: undefined;
6391
6626
  sources?: undefined;
6392
6627
  full?: undefined;
6628
+ fetchMinimal?: undefined;
6393
6629
  sortBy?: undefined;
6394
6630
  linkedin_url?: undefined;
6395
6631
  max_posts?: undefined;
@@ -6421,6 +6657,7 @@ export declare const allTools: ({
6421
6657
  postUrl?: undefined;
6422
6658
  sources?: undefined;
6423
6659
  full?: undefined;
6660
+ fetchMinimal?: undefined;
6424
6661
  linkedin_url?: undefined;
6425
6662
  max_posts?: undefined;
6426
6663
  };
@@ -6446,6 +6683,7 @@ export declare const allTools: ({
6446
6683
  postUrl?: undefined;
6447
6684
  sources?: undefined;
6448
6685
  full?: undefined;
6686
+ fetchMinimal?: undefined;
6449
6687
  companyUrl?: undefined;
6450
6688
  sortBy?: undefined;
6451
6689
  };
@@ -6466,6 +6704,7 @@ export declare const allTools: ({
6466
6704
  postUrl?: undefined;
6467
6705
  sources?: undefined;
6468
6706
  full?: undefined;
6707
+ fetchMinimal?: undefined;
6469
6708
  companyUrl?: undefined;
6470
6709
  sortBy?: undefined;
6471
6710
  max_posts?: undefined;
@@ -21,6 +21,7 @@ import { engageStateToolDefinitions } from "./engage-state.js";
21
21
  import { enrichmentToolDefinitions } from "./enrichment.js";
22
22
  import { frameworkToolDefinitions } from "./framework.js";
23
23
  import { harvestJobToolDefinitions } from "./harvest-jobs.js";
24
+ import { inboxToolDefinitions } from "./inbox.js";
24
25
  import { leadToolDefinitions } from "./leads.js";
25
26
  import { linkedinToolDefinitions } from "./linkedin.js";
26
27
  import { navigationToolDefinitions } from "./navigation.js";
@@ -53,6 +54,7 @@ export const allTools = [
53
54
  ...navigationToolDefinitions,
54
55
  ...leadToolDefinitions,
55
56
  ...harvestJobToolDefinitions,
57
+ ...inboxToolDefinitions,
56
58
  ...enrichmentToolDefinitions,
57
59
  ...processingToolDefinitions,
58
60
  ...rubricToolDefinitions,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/mcp",
3
- "version": "0.1.318",
3
+ "version": "0.1.320",
4
4
  "type": "module",
5
5
  "description": "Sellable MCP server for Claude Code and Codex campaign workflows",
6
6
  "main": "dist/index.js",
@@ -111,6 +111,10 @@ Blueprint rules:
111
111
  - Use stable, readable column ids such as `linkedin_url`, `enrich_prospect`, and
112
112
  `score_icp_mcp`.
113
113
  - Use registry type keys exactly, not display names.
114
+ - Treat the API column registry as the source of truth for type validation.
115
+ MCP code must not maintain its own hardcoded column-type allowlist; if the API
116
+ returns `phantom_type`, `deprecated_type`, or `not_createable_type`, fix the
117
+ blueprint to match the current registry response.
114
118
  - Treat "Enrich Prospect" as a `http_request` preset, not its own type.
115
119
  - Use `score_icp_mcp` for new AI ICP scoring. Do not use legacy
116
120
  `score_icp` or the old `score_icp_rubric` alias; they are reserved for older
@@ -145,6 +149,28 @@ Blueprint rules:
145
149
  synced sender connections, a positive `check_connection`, or accepted invite
146
150
  proof from the current flow.
147
151
 
152
+ Config rules:
153
+
154
+ - Put native column settings in `config`. The commit path preserves full config
155
+ objects and validates them server-side before mutation.
156
+ - Use blueprint-level `inputMapping` for references to existing producer
157
+ columns. The commit path materializes those references into production
158
+ template mappings such as `{{<actual column id>}}` or
159
+ `{{<actual Enrich Prospect column id>.id}}`.
160
+ - Use `runCondition` for branch gates that should exist in production. Template
161
+ tokens in `config`, AI prompts, formula expressions, and `runCondition` are
162
+ dependency-bearing and must point to real producer columns.
163
+ - For outbound HTTP throttling, set `http_request.config.rateLimit` as either
164
+ `{ "mode": "window", "maxRequests": N, "windowSeconds": S }` or
165
+ `{ "mode": "concurrency", "maxConcurrent": N }`.
166
+ - For public webhook intake throttling, set
167
+ `inbound_webhook.config.rateLimit` as
168
+ `{ "maxRequests": N, "windowSeconds": S }`. Omit it to use the server default.
169
+ - Do not invent per-column `rateLimit` for LinkedIn action columns. Those are
170
+ governed by sender/account limits and scheduling windows; configure action
171
+ behavior with `actionConfig`, `waitForEvent`, `runCondition`, and producer
172
+ mappings.
173
+
148
174
  ## Commit phase
149
175
 
150
176
  Use exactly one tool for the initial commit:
@@ -55,10 +55,11 @@ read/edit/delete safety, but they are not valid `add_column` or
55
55
 
56
56
  - type: `datetime`
57
57
  - displayName: `Date/Time`
58
+ - lifecycle: hidden active, load-only; not a valid create target.
58
59
  - category: Lead Data
59
60
  - inputs: none.
60
61
  - outputs: ISO-like date/time value.
61
- - when to use: Use for system-owned scheduling timestamps.
62
+ - when to use: Existing tables may contain system-owned scheduling timestamps.
62
63
  - when NOT to use: Do not use to wait; use `wait` for sequence timing.
63
64
 
64
65
  ### Next Action
@@ -117,6 +118,8 @@ read/edit/delete safety, but they are not valid `add_column` or
117
118
  - displayName: `Inbound Webhook`
118
119
  - category: Lead Data
119
120
  - inputs: none.
121
+ - config: optional `rateLimit` as `{ "maxRequests": N, "windowSeconds": S }`;
122
+ server defaults to 100 requests per 60 seconds when omitted.
120
123
  - outputs: received JSON payload and webhook metadata.
121
124
  - when to use: Use when rows are populated by external webhook events.
122
125
  - when NOT to use: Do not use for polling APIs; use `http_request`.
@@ -163,6 +166,8 @@ read/edit/delete safety, but they are not valid `add_column` or
163
166
  - displayName: `Check Open Profile`
164
167
  - category: LinkedIn Actions
165
168
  - inputs: required `linkedin_url`.
169
+ - config: may use the same `rateLimit` shape as `http_request` for provider
170
+ lookup throttling.
166
171
  - outputs: boolean open-profile decision and lookup metadata.
167
172
  - when to use: Use before selecting open-profile InMail behavior.
168
173
  - when NOT to use: Do not use to check first-degree connection; use `check_connection`.
@@ -190,6 +195,21 @@ read/edit/delete safety, but they are not valid `add_column` or
190
195
  direct `send_dm` is acceptable because `send_dm` also performs the runtime
191
196
  connection lookup.
192
197
 
198
+ ### Check Paid InMail Credits
199
+
200
+ - type: `check_paid_inmail_credits`
201
+ - displayName: `Check Paid InMail Credits`
202
+ - category: LinkedIn Actions
203
+ - inputs: sender-scoped Sales Navigator credit state and optional paid-credit floor.
204
+ - outputs: `has_paid_inmail_credits`, remaining-credit proof, stale-state flags,
205
+ and fallback reason metadata.
206
+ - when to use: Use after Check Open Profile says a prospect is closed-profile
207
+ and the sequence is explicitly allowed to spend paid InMail credits. Branch
208
+ yes to `send_inmail_closed`; branch no to `check_connection` or invite flow.
209
+ - when NOT to use: Do not use for free open-profile InMail, do not spend credits
210
+ from this check itself, and do not add it unless the campaign policy opts into
211
+ the paid-InMail fallback mode.
212
+
193
213
  ### LinkedIn Action
194
214
 
195
215
  - type: `action`
@@ -296,6 +316,11 @@ read/edit/delete safety, but they are not valid `add_column` or
296
316
 
297
317
  ## Data & Logic
298
318
 
319
+ LinkedIn action columns do not accept a generic per-column `rateLimit`. They
320
+ use sender/account daily limits, sending hours, and action scheduling outside
321
+ the blueprint column config. Use `actionConfig.waitForEvent`, `runCondition`,
322
+ and explicit producer mappings for action behavior.
323
+
299
324
  ### AI Column
300
325
 
301
326
  - type: `ai_column`
@@ -332,6 +357,10 @@ read/edit/delete safety, but they are not valid `add_column` or
332
357
  - displayName: `HTTP Request`
333
358
  - category: Data & Logic
334
359
  - inputs: required `method`, required `endpoint`, optional `headers`, optional `body`.
360
+ - config: optional `rateLimit` supports rolling windows
361
+ `{ "mode": "window", "maxRequests": N, "windowSeconds": S }` and concurrency
362
+ lanes `{ "mode": "concurrency", "maxConcurrent": N }`. Omit it to use the
363
+ server's default I/O concurrency lane.
335
364
  - outputs: HTTP status, response body, and metadata; Enrich Prospect also returns root `id` as the EnrichedProspect id.
336
365
  - when to use: Use for REST API calls, including the canonical "Enrich Prospect" preset at `/api/v4/enrich-prospect`.
337
366
  - when NOT to use: Do not use when a first-party typed column already handles the action.
@@ -31,6 +31,7 @@ const httpEnrichConfig = {
31
31
  endpoint: { value: "/api/v4/enrich-prospect" },
32
32
  body: { value: '{"linkedinUrl":"{{LinkedIn URL}}"}' },
33
33
  },
34
+ runCondition: "{{LinkedIn URL}} !== ''",
34
35
  };
35
36
 
36
37
  export const COMMON_BLUEPRINTS: CommonBlueprintEntry[] = [
@@ -51,7 +52,10 @@ export const COMMON_BLUEPRINTS: CommonBlueprintEntry[] = [
51
52
  id: "c3",
52
53
  type: "score_icp_mcp",
53
54
  name: "ICP Score",
54
- config: { rubric: enrichmentRubric },
55
+ config: {
56
+ rubric: enrichmentRubric,
57
+ runCondition: "{{Enrich Prospect.id}} !== ''",
58
+ },
55
59
  inputMapping: { enrichedProspectId: "c2" },
56
60
  },
57
61
  ],
@@ -78,7 +82,10 @@ export const COMMON_BLUEPRINTS: CommonBlueprintEntry[] = [
78
82
  id: "c3",
79
83
  type: "score_icp_mcp",
80
84
  name: "ICP Score",
81
- config: { rubric: enrichmentRubric },
85
+ config: {
86
+ rubric: enrichmentRubric,
87
+ runCondition: "{{Enrich Prospect.id}} !== ''",
88
+ },
82
89
  inputMapping: { enrichedProspectId: "c2" },
83
90
  },
84
91
  {
@@ -131,7 +138,10 @@ export const COMMON_BLUEPRINTS: CommonBlueprintEntry[] = [
131
138
  id: "c4",
132
139
  type: "score_icp_mcp",
133
140
  name: "ICP Score",
134
- config: { rubric: enrichmentRubric },
141
+ config: {
142
+ rubric: enrichmentRubric,
143
+ runCondition: "{{Enrich Prospect.id}} !== ''",
144
+ },
135
145
  inputMapping: { enrichedProspectId: "c3" },
136
146
  },
137
147
  {
@@ -139,13 +149,15 @@ export const COMMON_BLUEPRINTS: CommonBlueprintEntry[] = [
139
149
  type: "generate_message",
140
150
  name: "Generate Message",
141
151
  config: {
142
- runCondition: "{{ICP Score.score}} >= 70",
152
+ runCondition:
153
+ "{{Enrich Prospect.id}} !== '' && {{ICP Score.score}} >= 70",
143
154
  },
144
155
  inputMapping: {
145
156
  campaignOfferId: "c2",
146
157
  enrichedProspectId: "c3",
147
158
  },
148
- runCondition: "{{ICP Score.score}} >= 70",
159
+ runCondition:
160
+ "{{Enrich Prospect.id}} !== '' && {{ICP Score.score}} >= 70",
149
161
  },
150
162
  ],
151
163
  edges: [
@@ -196,4 +208,41 @@ export const COMMON_BLUEPRINTS: CommonBlueprintEntry[] = [
196
208
  ],
197
209
  },
198
210
  },
211
+ {
212
+ slug: "rate-limited-http-and-webhook",
213
+ description:
214
+ "Receive webhook payloads and call a rate-limited HTTP enrichment API.",
215
+ blueprint: {
216
+ columns: [
217
+ { id: "c1", type: "text", name: "Company Domain", config: {} },
218
+ {
219
+ id: "c2",
220
+ type: "inbound_webhook",
221
+ name: "Inbound Payload",
222
+ config: {
223
+ rateLimit: { maxRequests: 100, windowSeconds: 60 },
224
+ },
225
+ },
226
+ {
227
+ id: "c3",
228
+ type: "http_request",
229
+ name: "Fetch Account Context",
230
+ config: {
231
+ inputMapping: {
232
+ method: { value: "POST" },
233
+ endpoint: { value: "https://example.test/account-context" },
234
+ body: { value: '{"domain":"{{Company Domain}}"}' },
235
+ },
236
+ rateLimit: {
237
+ mode: "window",
238
+ maxRequests: 10,
239
+ windowSeconds: 60,
240
+ },
241
+ },
242
+ inputMapping: { domain: "c1" },
243
+ },
244
+ ],
245
+ edges: [{ from: "c1", to: "c3", via: "domain" }],
246
+ },
247
+ },
199
248
  ];
@@ -42,3 +42,12 @@ Use `ai_column` only when the user needs a bespoke prompt that is not covered by
42
42
  fixed enrichment, scoring, or LinkedIn action columns.
43
43
 
44
44
  See `COMMON_BLUEPRINTS[3].blueprint` in the fixture.
45
+
46
+ ## 5. Rate-Limited HTTP + Webhook (`rate-limited-http-and-webhook`)
47
+
48
+ Use `inbound_webhook.config.rateLimit` for public webhook intake and
49
+ `http_request.config.rateLimit` for outbound HTTP calls. HTTP supports rolling
50
+ window limits with `mode: "window"`, `maxRequests`, and `windowSeconds`, or
51
+ concurrency limits with `mode: "concurrency"` and `maxConcurrent`.
52
+
53
+ See `COMMON_BLUEPRINTS[4].blueprint` in the fixture.
@@ -80,6 +80,14 @@ It bootstraps auth and host capabilities, then loads the internal
80
80
  the internal campaign workflow prompt and `core/flow.v2.json` through MCP. Keep
81
81
  this wrapper thin; the packaged workflow is the operational source of truth.
82
82
 
83
+ ## Inbox Reply Tool Boundary
84
+
85
+ Inbox reply tools are outside campaign creation. If a user asks to search,
86
+ review, edit, or send inbox replies, treat that as a separate inbox workflow
87
+ using the existing product /api/v3/inbox routes. Any draft edit or send requires
88
+ exact approval for the workspace, sender, thread, body, tool, and expected side
89
+ effect before the write tool is called.
90
+
83
91
  CampaignOffer state and the watch link are the customer-facing source of truth.
84
92
  Disk artifacts are optional debug/UAT diagnostics; normal customer runs should
85
93
  not create, link, or surface local draft files unless the user explicitly asks
@@ -40,6 +40,13 @@ active flow. Legacy packet/mint artifacts stay in
40
40
  7. Choose filters, save/approve criteria, then review the message template.
41
41
  8. Sync the approved template, queue bounded filtering, review one generated pass, then Settings and launch.
42
42
 
43
+ ## Inbox Reply Tool Boundary
44
+
45
+ Inbox reply tools are outside campaign creation. Stop the campaign lane for
46
+ reply search/review/edit/send asks and use existing product /api/v3/inbox routes.
47
+ Before any draft edit/send tool call, require exact approval for workspace,
48
+ sender, thread, body, tool, and expected side effect.
49
+
43
50
  ## Identity-First Campaign Setup
44
51
 
45
52
  Do not treat the active workspace as the campaign subject. Resolve the
@@ -0,0 +1,9 @@
1
+ {
2
+ "parallelMode": "wide",
3
+ "agentCount": 6,
4
+ "maxToolCallsPerAgent": 2,
5
+ "senderMaxAgents": 2,
6
+ "senderMaxToolCallsPerAgent": 3,
7
+ "progressMode": true,
8
+ "debugMode": true
9
+ }