Skip to main content

Custom agent features

Create agents that can dynamically enable or disable features based on workspace configuration. Agents can access user preferences through workspace_options and respond accordingly.

Reference implementation in this GitHub repository.

Custom agent features - on and off Custom agent features - on and on

Architecture

Configure custom features in your agent's descriptor and access them through the query request payload. Features can have default states, descriptions, and labels.

agents.json configuration with custom features:

return JSONResponse(content={
"vanilla_agent_custom_features": {
"name": "Vanilla Agent Custom Features",
"description": "A simple agent that reports its feature status.",
"endpoints": {"query": "/v1/query"},
"features": {
"streaming": True,
"widget-dashboard-select": False,
"widget-dashboard-search": False,
"deep-research": {
"label": "Deep Research",
"default": False,
"description": "Allows the copilot to do deep research",
},
"web-search": {
"label": "Web Search",
"default": True,
"description": "Allows the copilot to search the web.",
},
},
}
})

Feature configuration

  • Simple features: Boolean values for basic on/off features
  • Complex features: Objects with label, default, and description properties
  • Built-in features: Standard features like streaming, widget-dashboard-select, widget-dashboard-search
  • Custom features: User-defined features with custom behavior

Query flow

  • User enables/disables features in workspace settings
  • Features are passed to agent via workspace_options in request payload
  • Agent checks enabled features and adjusts behavior accordingly
  • Agent can report feature status back to user
  • Response content varies based on active features

OpenBB AI SDK

  • QueryRequest.workspace_options: List of enabled feature names
  • message_chunk(text): Streams response content with feature-aware messaging
  • Feature checking via simple list membership: "feature-name" in workspace_options

Core logic

from typing import AsyncGenerator
from openbb_ai import message_chunk
from openbb_ai.models import MessageChunkSSE, QueryRequest
from fastapi.responses import JSONResponse
from sse_starlette.sse import EventSourceResponse

@app.post("/v1/query")
async def query(request: QueryRequest) -> EventSourceResponse:
# Access workspace options from request payload
workspace_options = getattr(request, "workspace_options", [])

# Check which features are enabled
deep_research_enabled = "deep-research" in workspace_options
web_search_enabled = "web-search" in workspace_options

# Build feature status message
features_msg = (
f"- Deep Research: {'✅ Enabled' if deep_research_enabled else '❌ Disabled'}\n"
f"- Web Search: {'✅ Enabled' if web_search_enabled else '❌ Disabled'}"
)

# Include feature status in system prompt
openai_messages = [
{
"role": "system",
"content": (
"You are a simple greeting agent.\n"
"Greet the user and let them know their current feature settings:\n"
f"{features_msg}\n"
"Keep your response brief and friendly."
),
}
]

# Add conversation history
for message in request.messages:
if message.role == "human":
openai_messages.append({"role": "user", "content": message.content})
elif message.role == "ai" and isinstance(message.content, str):
openai_messages.append({"role": "assistant", "content": message.content})

async def execution_loop() -> AsyncGenerator[MessageChunkSSE, None]:
client = openai.AsyncOpenAI()
async for event in await client.chat.completions.create(
model="gpt-4o",
messages=openai_messages,
stream=True,
):
if chunk := event.choices[0].delta.content:
yield message_chunk(chunk)

return EventSourceResponse(
content=(
event.model_dump(exclude_none=True) async for event in execution_loop()
),
media_type="text/event-stream",
)

Feature types

Boolean features

Simple on/off switches in the agent descriptor:

"features": {
"streaming": True,
"some-feature": False
}

Complex features

Rich feature objects with metadata:

"features": {
"research-mode": {
"label": "Research Mode",
"default": True,
"description": "Enables comprehensive research capabilities"
}
}

Conditional behavior

Adjust agent behavior based on enabled features:

workspace_options = getattr(request, "workspace_options", [])

if "research-mode" in workspace_options:
# Enable research capabilities
pass

if "web-search" in workspace_options:
# Enable web search functionality
pass