Skip to main content

Alpha 171 Cleanup

This guide covers breaking changes in @baleybots/core@0.0.1-alpha.171 and related packages (@baleybots/tools, @baleybots/agent-tools, @baleybots/mcp). If you are on alpha.170 or earlier, work through each section that applies to your imports.

Related: Custom models · Packages


Read this first (behavior cliffs)

  1. No provider guessing. Bare ids like llama3.2 or glm-5.2:cloud no longer auto-route. You get an actionable error — use ollama|…, { id, provider }, a factory, or an AI SDK LanguageModel. Guessing is gone on purpose.
  2. Default tool-loop cap is 50 steps. When the default fires, done.reason is 'out_of_iterations' with iteration_count set. Raise with stopWhen: stepCountIs(n).

1. Custom providers: registerProvider → AI SDK LanguageModel

Before (removed):

import { Baleybot, registerProvider } from '@baleybots/core';

registerProvider('my-llm', {
/* custom HTTP adapter */
});

const bot = Baleybot.create({
name: 'responder',
goal: 'Answer questions',
model: 'my-llm/some-model',
});

After:

import { Baleybot } from '@baleybots/core';
import { createOpenAICompatible } from '@ai-sdk/openai-compatible';

const myLlm = createOpenAICompatible({
name: 'my-llm',
baseURL: 'https://llm.internal.example.com/v1',
apiKey: process.env.MY_LLM_KEY,
});

const bot = Baleybot.create({
name: 'responder',
goal: 'Answer questions',
model: myLlm('some-model'),
});

Any AI SDK LanguageModel works. See Custom models.


2. Ensemble: @baleybots/core/ensemble@baleybots/orchestration/ensemble

Before:

import { groupSession, personality } from '@baleybots/core/ensemble';

After:

import { groupSession, personality } from '@baleybots/orchestration/ensemble';

Exports are unchanged. Orchestration owns multi-agent session code so browser bundles do not pull Node-only dependencies through core. For ticket-based team dispatch, use the main @baleybots/orchestration barrel (Team, createTeam, etc.).


3. Tool loop: agentMode / maxToolIterationsstopWhen

Tool loops are driven by AI SDK stopWhen. Baleybots re-exports stepCountIs, hasToolCall, hasToolResult, combineConditions, and friends from @baleybots/core.

Before:

const bot = Baleybot.create({
name: 'agent',
goal: 'Use tools to complete tasks',
tools: { bash: bashTool },
agentMode: true,
maxToolIterations: 25,
});

After:

import { stepCountIs } from '@baleybots/core';

const bot = Baleybot.create({
name: 'agent',
goal: 'Use tools to complete tasks',
tools: { bash: bashTool },
stopWhen: stepCountIs(25),
});

If you omit stopWhen, the default is stepCountIs(50) (replacing the old silent 200-step cap). When that default fires, the stream emits done with reason: 'out_of_iterations' and iteration_count set. Increase explicitly when you need longer runs:

stopWhen: stepCountIs(100),

Stop when a specific tool finishes:

import { hasToolResult, combineConditions, stepCountIs } from '@baleybots/core';

stopWhen: combineConditions(stepCountIs(50), hasToolResult('submit_answer')),

4. @baleybots/tools is BAL-only; coding tools moved

Before:

import {
createBalTools,
spawnBaleybotTool,
webSearchTool,
readFileTool,
bashTool,
tool,
} from '@baleybots/tools';

After:

import { createBalTools } from '@baleybots/tools';
import { createScopedFilesystemTools } from '@baleybots/agent-tools';
import { tool, subagentTool } from '@baleybots/core';

// Fixed specialists with typed Output.* → subagentTool
// Dynamic spawn demo → typescript/examples/tools/spawn-baleybot.ts
Removed from @baleybots/toolsNew location
readFileTool, bashTool, filesystem helpers@baleybots/agent-tools
spawnBaleybotTool, webSearchTool, sequentialThinkToolDynamic spawn / demos: typescript/examples/tools/. Prefer subagentTool from @baleybots/core for fixed typed specialists.
tool, defineTool, defineZodTool re-exports@baleybots/core
baleybotsCodeToolV2Renamed to createBALTool

5. Platform adapters archived; handler / visualizer removed

Legacy platform adapter packages (adapter-*) are archived. @baleybots/handler and @baleybots/visualizer were deleted.

Migration paths:

  • Streaming chat UIs → @baleybots/react hooks and StreamSegment reducers in core
  • Multi-agent hosts → @baleybots/orchestration (Team, crew patterns)
  • MCP integrations → @baleybots/mcp

6. Config renames: goal + Output.object

Structured output — before:

const bot = Baleybot.create({
name: 'analyzer',
analysisGoal: 'Determine if the email is spam',
outputSchema: z.object({ isSpam: z.boolean() }),
});

After:

import { Output } from '@baleybots/core';

const bot = Baleybot.create({
name: 'analyzer',
goal: 'Determine if the email is spam',
output: Output.object({
schema: z.object({ isSpam: z.boolean() }),
}),
});

Tool definitions — before:

defineZodTool({
name: 'run',
inputSchema: schema,
function: async (params) => ({ ok: true }),
needsApproval: true,
});

After:

tool('run', 'Run the task', schema, async (params) => ({ ok: true }), {
requiresApproval: true,
});

Quick checklist

  • Replace registerProvider with AI SDK LanguageModel on model:
  • Prefix ambiguous model ids (ollama|…) or pass { id, provider } — no guessing
  • Update @baleybots/core/ensemble@baleybots/orchestration/ensemble
  • Replace maxToolIterations / agentMode with stopWhen (default 50 → out_of_iterations)
  • Move filesystem/bash imports to @baleybots/agent-tools; keep BAL in @baleybots/tools
  • Import tool() from @baleybots/core
  • Rename tool functionexecute, needsApprovalrequiresApproval
  • Migrate React approvals to pendingApprovals / respondToToolApprovals
  • Remove @baleybots/handler, @baleybots/visualizer, and archived adapter-* deps
  • Use goal + output: Output.object({ schema }) instead of outputSchema / analysisGoal
  • Remove @baleybots/handler, @baleybots/visualizer, and archived adapter-* deps