agentbnb 8.0.1 → 8.2.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/dist/cli/index.js CHANGED
@@ -84,7 +84,6 @@ import {
84
84
  // src/cli/index.ts
85
85
  import { Command } from "commander";
86
86
  import { readFileSync as readFileSync4 } from "fs";
87
- import { createRequire } from "module";
88
87
  import { randomUUID as randomUUID4 } from "crypto";
89
88
  import { join as join4 } from "path";
90
89
  import { networkInterfaces as networkInterfaces2 } from "os";
@@ -868,6 +867,18 @@ function registerMcpWithClaudeCode() {
868
867
  const resolved = execSync("which agentbnb", { encoding: "utf-8" }).trim();
869
868
  if (resolved) agentbnbCommand = resolved;
870
869
  } catch {
870
+ try {
871
+ const scriptPath = process.argv[1];
872
+ if (scriptPath && existsSync3(scriptPath)) {
873
+ agentbnbCommand = scriptPath;
874
+ }
875
+ } catch {
876
+ }
877
+ }
878
+ if (agentbnbCommand === "agentbnb") {
879
+ console.warn(
880
+ "Warning: Could not resolve absolute path to agentbnb binary.\n Claude Code MCP may not work. Install globally first:\n npm install -g agentbnb"
881
+ );
871
882
  }
872
883
  let settings = {};
873
884
  if (existsSync3(settingsPath)) {
@@ -995,8 +1006,7 @@ Skills: ${skills.skillCount} skill(s) in ${skills.path}`);
995
1006
  }
996
1007
 
997
1008
  // src/cli/index.ts
998
- var require2 = createRequire(import.meta.url);
999
- var pkg = require2("../../package.json");
1009
+ var VERSION = "8.2.0";
1000
1010
  function loadIdentityAuth2(owner) {
1001
1011
  const configDir = getConfigDir();
1002
1012
  let keys;
@@ -1023,7 +1033,7 @@ function getLanIp2() {
1023
1033
  return "localhost";
1024
1034
  }
1025
1035
  var program = new Command();
1026
- program.name("agentbnb").description("P2P Agent Capability Sharing Protocol \u2014 Airbnb for AI agent pipelines").version(pkg.version);
1036
+ program.name("agentbnb").description("P2P Agent Capability Sharing Protocol \u2014 Airbnb for AI agent pipelines").version(VERSION);
1027
1037
  program.command("init").description("Initialize AgentBnB config and create agent identity").option("--owner <name>", "Agent owner name").option("--agent-id <id>", "Agent identity (alias for --owner, for genesis-template compat)").option("--port <port>", "Gateway port", "7700").option("--host <ip>", "Override gateway host IP (default: auto-detected LAN IP)").option("--yes", "Auto-confirm all draft cards (non-interactive)").option("--non-interactive", "Non-interactive mode (alias for --yes)").option("--no-detect", "Skip API key detection").option("--from <file>", "Parse a specific file for capability detection").option("--json", "Output as JSON").action(async (opts) => {
1028
1038
  const result = await performInit(opts);
1029
1039
  if (opts.json) {
@@ -2327,7 +2337,7 @@ Feedback for skill: ${opts.skill} (${feedbacks.length} entries)
2327
2337
  });
2328
2338
  program.command("quickstart").alias("qs").description("One-command setup: init + skills.yaml + MCP registration + serve daemon").option("--owner <name>", "Agent owner name").option("--port <port>", "Gateway port", "7700").option("--no-serve", "Skip starting background daemon").option("--no-mcp", "Skip MCP registration with Claude Code").option("--json", "Output as JSON").action(runQuickstart);
2329
2339
  program.command("mcp-server").description("Start an MCP (Model Context Protocol) server for IDE integration").action(async () => {
2330
- const { startMcpServer } = await import("../server-MHMAYXWZ.js");
2340
+ const { startMcpServer } = await import("../server-LMY2A3GT.js");
2331
2341
  await startMcpServer();
2332
2342
  });
2333
2343
  await program.parseAsync(process.argv);
@@ -0,0 +1,266 @@
1
+ import {
2
+ BudgetController,
3
+ BudgetManager,
4
+ decompose,
5
+ matchSubTasks,
6
+ orchestrate,
7
+ requestCapability,
8
+ validateAndNormalizeSubtasks
9
+ } from "./chunk-P4LOYSLA.js";
10
+ import "./chunk-HLUEOLSZ.js";
11
+ import {
12
+ getCardsByCapabilityType,
13
+ getCardsBySkillCapability
14
+ } from "./chunk-7EF3HYVZ.js";
15
+ import "./chunk-NWIQJ2CL.js";
16
+ import "./chunk-IVOYM3WG.js";
17
+ import "./chunk-WVY2W7AA.js";
18
+
19
+ // src/conductor/team-formation.ts
20
+ import { randomUUID } from "crypto";
21
+ function selectByStrategy(matches, strategy) {
22
+ if (matches.length === 0) return void 0;
23
+ if (strategy === "balanced") {
24
+ return matches[0];
25
+ }
26
+ if (strategy === "quality_optimized") {
27
+ return matches.reduce((best, m) => m.score > best.score ? m : best, matches[0]);
28
+ }
29
+ return matches.reduce((best, m) => {
30
+ if (m.credits < best.credits) return m;
31
+ if (m.credits === best.credits && m.score > best.score) return m;
32
+ return best;
33
+ }, matches[0]);
34
+ }
35
+ async function formTeam(opts) {
36
+ const { subtasks, strategy, db, conductorOwner, registryUrl } = opts;
37
+ const team_id = randomUUID();
38
+ if (subtasks.length === 0) {
39
+ return { team_id, strategy, matched: [], unrouted: [] };
40
+ }
41
+ const matched = [];
42
+ const unrouted = [];
43
+ for (const subtask of subtasks) {
44
+ const skillCards = getCardsBySkillCapability(db, subtask.required_capability).filter((c) => c.owner !== conductorOwner);
45
+ if (skillCards.length > 0) {
46
+ const candidates = skillCards.map((card) => {
47
+ const skills = card.skills ?? [];
48
+ const matchingSkill = skills.find(
49
+ (s) => s.capability_type === subtask.required_capability || (s.capability_types ?? []).includes(subtask.required_capability)
50
+ );
51
+ return {
52
+ subtask_id: subtask.id,
53
+ selected_agent: card.owner,
54
+ selected_skill: matchingSkill?.id ?? "",
55
+ selected_card_id: card.id,
56
+ score: 1,
57
+ credits: matchingSkill?.pricing.credits_per_call ?? 0,
58
+ alternatives: []
59
+ };
60
+ });
61
+ const selected2 = selectByStrategy(candidates, strategy);
62
+ matched.push({
63
+ subtask,
64
+ capability_type: subtask.required_capability,
65
+ agent: selected2.selected_agent,
66
+ skill: selected2.selected_skill,
67
+ card_id: selected2.selected_card_id,
68
+ credits: selected2.credits,
69
+ score: selected2.score
70
+ });
71
+ continue;
72
+ }
73
+ const matchResults = await matchSubTasks({
74
+ db,
75
+ subtasks: [subtask],
76
+ conductorOwner,
77
+ registryUrl
78
+ });
79
+ const m = matchResults[0];
80
+ if (!m || m.selected_agent === "") {
81
+ unrouted.push(subtask);
82
+ continue;
83
+ }
84
+ const allCandidates = [
85
+ m,
86
+ ...m.alternatives.map((alt) => ({
87
+ subtask_id: m.subtask_id,
88
+ selected_agent: alt.agent,
89
+ selected_skill: alt.skill,
90
+ score: alt.score,
91
+ credits: alt.credits,
92
+ alternatives: []
93
+ }))
94
+ ];
95
+ const selected = selectByStrategy(allCandidates, strategy);
96
+ matched.push({
97
+ subtask,
98
+ capability_type: subtask.required_capability,
99
+ agent: selected.selected_agent,
100
+ skill: selected.selected_skill,
101
+ card_id: selected === m ? m.selected_card_id : void 0,
102
+ credits: selected.credits,
103
+ score: selected.score
104
+ });
105
+ }
106
+ return { team_id, strategy, matched, unrouted };
107
+ }
108
+
109
+ // src/conductor/conductor-mode.ts
110
+ var ConductorMode = class {
111
+ db;
112
+ creditDb;
113
+ conductorOwner;
114
+ gatewayToken;
115
+ resolveAgentUrl;
116
+ maxBudget;
117
+ constructor(opts) {
118
+ this.db = opts.db;
119
+ this.creditDb = opts.creditDb;
120
+ this.conductorOwner = opts.conductorOwner;
121
+ this.gatewayToken = opts.gatewayToken;
122
+ this.resolveAgentUrl = opts.resolveAgentUrl;
123
+ this.maxBudget = opts.maxBudget ?? 100;
124
+ }
125
+ /**
126
+ * Execute a conductor skill with the given config and params.
127
+ *
128
+ * @param config - SkillConfig with type 'conductor' and conductor_skill field.
129
+ * @param params - Must include `task` string.
130
+ * @returns Execution result without latency_ms (added by SkillExecutor).
131
+ */
132
+ async execute(config, params, onProgress) {
133
+ const conductorSkill = config.conductor_skill;
134
+ if (conductorSkill !== "orchestrate" && conductorSkill !== "plan") {
135
+ return {
136
+ success: false,
137
+ error: `Unknown conductor skill: "${conductorSkill}"`
138
+ };
139
+ }
140
+ const task = params.task;
141
+ if (typeof task !== "string" || task.length === 0) {
142
+ return {
143
+ success: false,
144
+ error: 'Missing or empty "task" parameter'
145
+ };
146
+ }
147
+ const orchestrationDepth = typeof params.orchestration_depth === "number" ? params.orchestration_depth : 0;
148
+ const decompositionDepth = typeof params.decomposition_depth === "number" ? params.decomposition_depth : 0;
149
+ if (orchestrationDepth >= 2) {
150
+ return {
151
+ success: false,
152
+ error: "orchestration_depth limit exceeded: max 1 nested orchestration"
153
+ };
154
+ }
155
+ let subtasks = [];
156
+ if (decompositionDepth === 0) {
157
+ const allDecomposers = getCardsByCapabilityType(this.db, "task_decomposition");
158
+ const externalDecomposers = allDecomposers.filter((c) => c.owner !== this.conductorOwner);
159
+ if (externalDecomposers.length > 0) {
160
+ const provider = externalDecomposers[0];
161
+ try {
162
+ const providerUrl = this.resolveAgentUrl(provider.owner);
163
+ const response = await requestCapability({
164
+ gatewayUrl: providerUrl.url,
165
+ token: this.gatewayToken,
166
+ cardId: provider.id,
167
+ params: {
168
+ task,
169
+ decomposition_depth: decompositionDepth + 1,
170
+ orchestration_depth: orchestrationDepth + 1
171
+ },
172
+ timeoutMs: 3e4
173
+ });
174
+ if (Array.isArray(response)) {
175
+ const validation = validateAndNormalizeSubtasks(response, {
176
+ max_credits: this.maxBudget
177
+ });
178
+ if (validation.errors.length === 0) {
179
+ subtasks = validation.valid;
180
+ }
181
+ }
182
+ } catch {
183
+ }
184
+ }
185
+ }
186
+ if (subtasks.length === 0) {
187
+ subtasks = decompose(task);
188
+ }
189
+ if (subtasks.length === 0) {
190
+ return {
191
+ success: false,
192
+ error: "No template matches task"
193
+ };
194
+ }
195
+ onProgress?.({ step: 1, total: 5, message: `Decomposed into ${subtasks.length} sub-tasks` });
196
+ const matchResults = await matchSubTasks({
197
+ db: this.db,
198
+ subtasks,
199
+ conductorOwner: this.conductorOwner
200
+ });
201
+ onProgress?.({ step: 2, total: 5, message: `Matched ${matchResults.length} sub-tasks to agents` });
202
+ let team;
203
+ if (conductorSkill === "orchestrate") {
204
+ const strategy = typeof params.formation_strategy === "string" && ["cost_optimized", "quality_optimized", "balanced"].includes(params.formation_strategy) ? params.formation_strategy : "balanced";
205
+ team = await formTeam({
206
+ subtasks,
207
+ strategy,
208
+ db: this.db,
209
+ conductorOwner: this.conductorOwner
210
+ });
211
+ onProgress?.({ step: 2, total: 5, message: `Formed team: ${team.matched.length} members, ${team.unrouted.length} unrouted` });
212
+ }
213
+ const budgetManager = new BudgetManager(this.creditDb, this.conductorOwner);
214
+ const budgetController = new BudgetController(budgetManager, this.maxBudget);
215
+ const executionBudget = budgetController.calculateBudget(matchResults);
216
+ if (!budgetController.canExecute(executionBudget)) {
217
+ return {
218
+ success: false,
219
+ error: `Budget exceeded: estimated ${executionBudget.estimated_total} cr, max ${this.maxBudget} cr`
220
+ };
221
+ }
222
+ onProgress?.({ step: 3, total: 5, message: `Budget approved: ${executionBudget.estimated_total} cr` });
223
+ if (conductorSkill === "plan") {
224
+ return {
225
+ success: true,
226
+ result: {
227
+ subtasks,
228
+ matches: matchResults,
229
+ budget: executionBudget,
230
+ team
231
+ // undefined when no role hints
232
+ }
233
+ };
234
+ }
235
+ const matchMap = new Map(
236
+ matchResults.map((m) => [m.subtask_id, m])
237
+ );
238
+ const orchResult = await orchestrate({
239
+ subtasks,
240
+ matches: matchMap,
241
+ gatewayToken: this.gatewayToken,
242
+ resolveAgentUrl: this.resolveAgentUrl,
243
+ maxBudget: this.maxBudget,
244
+ team
245
+ });
246
+ onProgress?.({ step: 4, total: 5, message: "Pipeline execution complete" });
247
+ const resultObj = {};
248
+ for (const [key, value] of orchResult.results) {
249
+ resultObj[key] = value;
250
+ }
251
+ return {
252
+ success: orchResult.success,
253
+ result: {
254
+ plan: subtasks,
255
+ execution: resultObj,
256
+ total_credits: orchResult.total_credits,
257
+ latency_ms: orchResult.latency_ms,
258
+ errors: orchResult.errors
259
+ },
260
+ error: orchResult.success ? void 0 : orchResult.errors?.join("; ")
261
+ };
262
+ }
263
+ };
264
+ export {
265
+ ConductorMode
266
+ };
@@ -32,7 +32,6 @@ import {
32
32
  } from "./chunk-WVY2W7AA.js";
33
33
 
34
34
  // src/mcp/server.ts
35
- import { createRequire } from "module";
36
35
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
37
36
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
38
37
 
@@ -254,8 +253,7 @@ function registerPublishTool(server, ctx) {
254
253
  }
255
254
 
256
255
  // src/mcp/server.ts
257
- var require2 = createRequire(import.meta.url);
258
- var pkg = require2("../../package.json");
256
+ var VERSION = "8.2.0";
259
257
  async function startMcpServer() {
260
258
  const config = loadConfig();
261
259
  if (!config) {
@@ -266,7 +264,7 @@ async function startMcpServer() {
266
264
  const identity = ensureIdentity(configDir, config.owner);
267
265
  const server = new McpServer({
268
266
  name: "agentbnb",
269
- version: pkg.version
267
+ version: VERSION
270
268
  });
271
269
  const ctx = {
272
270
  configDir,