Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/bubble-core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@bubblelab/bubble-core",
"version": "0.1.245",
"version": "0.1.246",
"type": "module",
"license": "Apache-2.0",
"main": "./dist/index.js",
Expand Down
12 changes: 8 additions & 4 deletions packages/bubble-core/src/bubbles/service-bubble/ai-agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1674,7 +1674,7 @@ export class AIAgentBubble extends ServiceBubble<
'Delegate a task to a specialized capability. The capability has its own tools and context to handle the task.',
schema: z.object({
capabilityId: z
.enum(capIds as [string, ...string[]])
.string()
.describe('Which capability to delegate to'),
task: z
.string()
Expand All @@ -1697,10 +1697,14 @@ export class AIAgentBubble extends ServiceBubble<
const credentialOverrides = input.credentials as
| Record<string, string | number>
| undefined;
const capConfig = caps.find((c) => c.id === capabilityId);
const capConfig = caps.find((c) => c.id === capabilityId) ?? {
id: capabilityId,
};
const capDef = getCapability(capabilityId);
if (!capConfig || !capDef)
return { error: `Capability "${capabilityId}" not found` };
if (!capDef)
return {
error: `Capability "${capabilityId}" not found. Available: ${capIds.join(', ')}`,
};
Comment on lines 1674 to +1707
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use-capability tool now accepts any string capabilityId and has additional behavior (fallback capConfig, name-based credential selection, revised error message). There doesn’t appear to be automated test coverage exercising these new paths (dynamic capability IDs, unknown IDs, credential selection by name/ID). Adding a focused test would help prevent regressions, especially around delegation correctness and error messages.

Copilot uses AI. Check for mistakes.

// Resolve credential overrides from the credential pool
const subAgentCredentials = this.params.credentials
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export async function applyCapabilityPreprocessing(
)
).filter((summary): summary is string => Boolean(summary));

params.systemPrompt += `\n\n---\nSYSTEM CAPABILITY EXTENSIONS:\nMultiple specialized capabilities are available. You MUST delegate to them using the 'use-capability' tool.\n\nAvailable Capabilities:\n${summaries.join('\n\n')}\n\nDELEGATION RULES:\n- Use 'use-capability' tool to delegate tasks to the appropriate capability\n- Do NOT attempt to handle capability tasks yourself\n- Include full context when delegating, including all known user details and preferences from context (especially timezone)\n- Can chain multiple capabilities if needed\n- Only respond directly for: greetings, clarifications, or tasks outside all capabilities\n- IMPORTANT: The user CANNOT see tool results from delegate agents. You MUST re-present all information, data, tables, and results returned by delegates in your own response. Never say "as shown above" or assume the user saw the delegate's output.\n- PRESERVE ALL LINKS: When a delegate returns URLs or clickable links (e.g., HubSpot record links, Jira ticket links, document URLs), you MUST include them in your response. Never drop links when reformatting tables — links are critical for the user to navigate to the source. If a table has too many rows to include all links, include links for at least the top/highlighted records.\n- When a delegate returns image or photo URLs, include them directly in your response on their own line as a bare URL (no markdown formatting). The chat client will automatically render the image inline from the URL. NEVER call read_image on URLs returned by delegates.\n- Before asking the user for information you don't have, check if any connected capability could help you find or look up that information first. Prefer proactive discovery over asking.\n- CAPABILITY QUESTIONS: When a user asks whether a capability supports a specific feature, what tools are available, or what parameters a tool accepts, you MUST call get_capabilities with the capability id before answering. Tool names alone do not describe what tools can do — you need the full signatures. NEVER answer capability questions from memory alone. NEVER claim a capability cannot do something without checking first.\n---\n\nYour role is to understand the user's request and delegate to the appropriate capability or respond directly when appropriate.`;
params.systemPrompt += `\n\n---\nSYSTEM CAPABILITY EXTENSIONS:\nMultiple specialized capabilities are available. You MUST delegate to them using the 'use-capability' tool.\n\nAvailable Capabilities:\n${summaries.join('\n\n')}\n\nDELEGATION RULES:\n- Use 'use-capability' tool to delegate tasks to the appropriate capability\n- Do NOT attempt to handle capability tasks yourself\n- Include full context when delegating, including all known user details and preferences from context (especially timezone)\n- Can chain multiple capabilities if needed\n- Only respond directly for: greetings, clarifications, or general knowledge questions\n- If a user requests a task that none of your active capabilities handle, you MUST call get_capabilities (with no id) to check for unattached capabilities before responding. NEVER tell the user you can't do something without checking first.\n- IMPORTANT: The user CANNOT see tool results from delegate agents. You MUST re-present all information, data, tables, and results returned by delegates in your own response. Never say "as shown above" or assume the user saw the delegate's output.\n- PRESERVE ALL LINKS: When a delegate returns URLs or clickable links (e.g., HubSpot record links, Jira ticket links, document URLs), you MUST include them in your response. Never drop links when reformatting tables — links are critical for the user to navigate to the source. If a table has too many rows to include all links, include links for at least the top/highlighted records.\n- When a delegate returns image or photo URLs, include them directly in your response on their own line as a bare URL (no markdown formatting). The chat client will automatically render the image inline from the URL. NEVER call read_image on URLs returned by delegates.\n- Before asking the user for information you don't have, check if any connected capability could help you find or look up that information first. Prefer proactive discovery over asking.\n- CAPABILITY QUESTIONS: When a user asks whether a capability supports a specific feature, what tools are available, or what parameters a tool accepts, you MUST call get_capabilities with the capability id before answering. Tool names alone do not describe what tools can do — you need the full signatures. NEVER answer capability questions from memory alone. NEVER claim a capability cannot do something without checking first.\n---\n\nYour role is to understand the user's request and delegate to the appropriate capability or respond directly when appropriate.`;
} else {
// Single or zero capabilities: eager load as before
for (const capConfig of caps) {
Expand Down
2 changes: 1 addition & 1 deletion packages/bubble-runtime/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@bubblelab/bubble-runtime",
"version": "0.1.245",
"version": "0.1.246",
"type": "module",
"license": "Apache-2.0",
"main": "./dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/bubble-scope-manager/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@bubblelab/ts-scope-manager",
"version": "0.1.245",
"version": "0.1.246",
"private": false,
"license": "MIT",
"type": "commonjs",
Expand Down
2 changes: 1 addition & 1 deletion packages/bubble-shared-schemas/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@bubblelab/shared-schemas",
"version": "0.1.245",
"version": "0.1.246",
"type": "module",
"license": "Apache-2.0",
"main": "./dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/create-bubblelab-app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "create-bubblelab-app",
"version": "0.1.245",
"version": "0.1.246",
"type": "module",
"license": "Apache-2.0",
"description": "Create BubbleLab AI agent applications with one command",
Expand Down
6 changes: 3 additions & 3 deletions packages/create-bubblelab-app/templates/basic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@bubblelab/bubble-core": "^0.1.245",
"@bubblelab/bubble-runtime": "^0.1.245",
"@bubblelab/shared-schemas": "^0.1.245",
"@bubblelab/bubble-core": "^0.1.246",
"@bubblelab/bubble-runtime": "^0.1.246",
"@bubblelab/shared-schemas": "^0.1.246",
"dotenv": "^16.4.5"
},
"devDependencies": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@bubblelab/bubble-core": "^0.1.245",
"@bubblelab/bubble-runtime": "^0.1.245",
"@bubblelab/bubble-core": "^0.1.246",
"@bubblelab/bubble-runtime": "^0.1.246",
"dotenv": "^16.4.5"
},
"devDependencies": {
Expand Down
Loading