Repository-Based Agents
Repository-based agents are standalone projects that can be published and shared with other Compozy users. You can create agents using either TypeScript (running on Deno runtime) or Python, which can be compiled into platform-specific binaries for efficient distribution.
Repository Structure
my-agent/
├── deno.json # Deno configuration and tasks
├── manifest.yaml # Agent metadata and schema definitions
├── README.md # Documentation
├── src/ # Source code directory
│ ├── index.ts # Main entry point
│ └── lib/ # Additional modules
├── tests/ # Test files
│ └── index.test.ts
├── dist/ # Compiled binaries
└── my-agent
my-agent/
├── pyproject.toml # Python project configuration
├── manifest.yaml # Agent metadata and schema definitions
├── src/ # Source code directory
│ ├── main.py # Main entry point
│ └── lib/ # Additional modules
├── tests/ # Test files
│ └── test_main.py
├── README.md # Documentation
└── dist/ # Compiled binaries
└── my-agent
Project Configuration
The deno.json file configures your development environment and build process: {
"tasks" : {
"dev" : "deno run --allow-read --allow-net src/index.ts" ,
"test" : "deno test --allow-read --allow-net tests/" ,
"compile" : "deno compile --allow-read --allow-net --output dist/market-analyst src/index.ts" ,
},
}
The compile task is required in your deno.json file. Compozy uses this task to compile your agent into a platform-specific binary during the publishing process.
The pyproject.toml file configures your Python project: [project]
name = "market-analyst"
version = "1.0.0"
description = "AI agent for market analysis and insights"
requires-python = ">=3.8"
dependencies = [
"openai" ,
"pydantic" ,
"controlflow"
]
[project.optional-dependencies]
test = [ "pytest" , "pytest-asyncio" ]
[tool.pytest.ini_options]
asyncio_mode = "auto"
Manifest File
The manifest.yaml defines your agent’s metadata, configuration, and action schemas. Here’s a comprehensive example:
The type field is required and must be set to agent. For Python projects, set main: src/main.py instead of src/index.ts.
type : agent
name : market-analyst
version : 1.0.0
license : MIT
description : AI agent for analyzing market trends and providing financial insights
repository : https://github.com/your-org/market-analyst
main : src/index.ts # Use src/main.py for Python projects
tags :
- finance
- analysis
- market
author :
name : Your Name
email : [email protected]
organization : Your Organization
# Default agent configuration
config :
provider : openrouter
model : anthropic/claude-3-sonnet
temperature : 0.7
max_tokens : 2000
top_p : 0.95
frequency_penalty : 0
presence_penalty : 0
schema :
# Agent-specific parameters
input :
type : object
properties :
language :
type : string
description : "Response language"
default : "en"
threshold :
type : number
description : "Confidence threshold for recommendations"
minimum : 0
maximum : 1
default : 0.7
required : []
actions :
analyze_market :
id : analyze_market
instructions : "Analyze market trends and provide detailed insights"
messages :
- role : system
content : "You are an expert market analyst. Focus on technical analysis and market sentiment."
- role : user
content : |
Analyze these stocks: {{ input.symbols }} for timeframe: {{ input.timeframe }}
input :
type : object
properties :
symbols :
type : array
items :
type : string
description : "List of stock symbols to analyze"
timeframe :
type : string
enum : [ "1d" , "1w" , "1m" , "3m" , "1y" ]
default : "1d"
required : [ symbols ]
output :
type : object
properties :
sentiment :
type : string
enum : [ positive , negative , neutral ]
confidence :
type : number
minimum : 0
maximum : 1
analysis :
type : string
recommendations :
type : array
items :
type : string
required : [ sentiment , confidence , analysis ]
See all 85 lines
Implementation
import { Agent } from "@mastra/core/agent" ;
import { AgentConfig , ActionFromSchema } from "@compozy/types" ;
import { createMessages } from "@compozy/utils" ;
import { z } from "zod" ;
import { Mastra } from "@mastra/core" ;
// Define types based on manifest schema
interface AgentParams {
language ?: string ;
threshold ?: number ;
}
interface MarketAnalysis {
symbols : string [];
timeframe ?: '1d' | '1w' | '1m' | '3m' | '1y' ;
}
const actionSchema = z . object ({
name: z . literal ( "analyze_market" ),
instructions: z . string (),
messages: z . array ( z . object ({
role: z . string (),
content: z . string ()
})),
input: z . object ({
symbols: z . array ( z . string ()),
timeframe: z . enum ([ '1d' , '1w' , '1m' , '3m' , '1y' ]),
}),
output: z . object ({
sentiment: z . enum ([ 'positive' , 'negative' , 'neutral' ]),
confidence: z . number (),
analysis: z . string (),
recommendations: z . array ( z . string ()). optional (),
}),
temperature: z . number (). optional (),
max_tokens: z . number (). optional (),
});
type AgentAction = ActionFromSchema < typeof actionSchema >;
function getModel ( config : AgentConfig < AgentParams >) {
if ( config . provider === "openai" ) {
return openai ( config . model );
}
if ( config . provider === "anthropic" ) {
return anthropic ( config . model );
}
throw new Error ( `Unsupported provider: {{ config.provider }}` );
}
export async function run (
input : MarketAnalysis ,
action : AgentAction ,
config : AgentConfig < AgentParams >
) {
const agent = new Agent ({
name: "Market Analyst" ,
model: getModel ( config ),
});
if ( action . name === "analyze_market" ) {
const messages = createMessages ({ action , input , config });
const response = await agent . generate (
messages ,
{
output: action . output ,
temperature: action . temperature ?? config . temperature ,
maxTokens: action . max_tokens ?? config . max_tokens ,
}
);
return response . object ;
}
throw new Error ( `Unsupported action: {{ action.name }}` );
}
from typing import TypedDict, List, Optional, Literal, Dict, Any
from compozy.types import AgentConfig
from compozy.utils import create_messages
import controlflow as cf
class AgentParams ( TypedDict ):
language: Optional[ str ]
threshold: Optional[ float ]
class Input ( TypedDict ):
symbols: List[ str ]
timeframe: Optional[Literal[ '1d' , '1w' , '1m' , '3m' , '1y' ]]
class Message ( TypedDict ):
role: str
content: str
class Action ( TypedDict ):
name: str
instructions: str
messages: List[Message]
input : Dict[ str , Any]
output: Dict[ str , Any]
temperature: Optional[ float ]
max_tokens: Optional[ int ]
class Output ( TypedDict ):
sentiment: Literal[ 'positive' , 'negative' , 'neutral' ]
confidence: float
analysis: str
recommendations: Optional[List[ str ]]
async def run ( input : Input, action : Action, config : AgentConfig[AgentParams]) -> Output:
agent = cf.Agent(
name = "Market Analyst" ,
provider =config.provider,
model =config.model,
temperature =action.get( 'temperature' , config.temperature),
max_tokens =action.get( 'max_tokens' , config.max_tokens),
top_p =config.top_p,
frequency_penalty =config.frequency_penalty,
presence_penalty =config.presence_penalty,
)
if action[ 'name' ] != 'analyze_market' :
raise ValueError ( f "Unsupported action: { action[ 'name' ] } " )
messages = create_messages({ action=action, input = input , config=config })
result = await agent.run(
messages =messages,
output_schema =action[ 'output' ]
)
if result[ 'confidence' ] < config.params.get( 'threshold' , 0.7 ):
result[ 'recommendations' ] = [ 'Confidence too low for specific recommendations' ]
return result
Publishing Process
Prepare Your Repository
Initialize a GitHub repository
Set up CI/CD workflows for testing and releases
Include comprehensive documentation in README.md
Validate
Ensure your agent configuration is valid:
Version and Release
Use semantic versioning (MAJOR.MINOR.PATCH)
Create GitHub releases with detailed changelogs
Tag releases (e.g., v1.0.0)
Build and Distribution
# Compile for all platforms
deno task compile
# Build Python package
python -m build
Submit to Registry
Once your agent is ready for distribution: # Login to Compozy CLI
compozy login
# Submit your agent
compozy publish
After submission, our team will review your agent to ensure it meets our quality and security standards. You’ll receive notifications about the review process and when your agent is approved and listed in the registry.
Make sure your agent follows these best practices:
Use semantic versioning for your agent versions
Include comprehensive documentation in README.md
Implement proper error handling and validation
Use environment variables for sensitive configuration
Define clear action schemas and instructions