Appearance
Agent Data Model ​
Complete reference for the Agent object structure and all enum types used in agent configuration.
Agent Object ​
The core agent object returned by create_agent, update_agent, and get_agent.
Top-Level Fields ​
| Field | Type | Description |
|---|---|---|
id | integer | Unique agent identifier |
name | string | Agent display name |
instructions | string | System prompt defining agent behavior |
uri | string | URL-friendly identifier (e.g., "support-bot") |
public_url | string | null | Full public URL if access_level is PUBLIC |
model | string | LLM model identifier |
temperature | float | Response creativity (0.0-2.0) |
reasoning_effort | string | Reasoning effort level (for reasoning models) |
access_level | string | Visibility level (enum: see below) |
domain_id | integer | Domain ID for public URL |
image_url | string | null | Agent avatar/logo URL |
empty_state_title | string | null | Welcome screen title |
empty_state_description | string | null | Welcome screen description |
suggested_prompts | list[dict] | null | Starter prompts for users |
created_at | string | ISO 8601 timestamp |
updated_at | string | ISO 8601 timestamp |
Nested Objects ​
| Field | Type | Description |
|---|---|---|
knowledge_ids | list[int] | IDs of attached knowledge sources |
knowledge_sources | list[object] | Full knowledge source objects with loading status |
trait_ids | list[int] | IDs of applied personality traits |
traits | list[object] | Full trait objects |
chat_theme_id | integer | null | ID of chat theme |
chat_theme | object | null | Full chat theme object |
data_template_id | integer | null | ID of data collection template |
data_template | object | null | Full data collection template object |
Example Full Agent Object ​
json
{
"id": 123,
"name": "Support Bot",
"instructions": "You are a helpful customer support agent that answers questions about our products...",
"uri": "support-bot",
"public_url": "https://joina.chat/support-bot",
"model": "gpt-5-mini",
"temperature": 0.7,
"reasoning_effort": "medium",
"access_level": "PUBLIC",
"domain_id": 1,
"image_url": "https://example.com/avatar.png",
"empty_state_title": "Welcome to Support",
"empty_state_description": "Ask me anything about our products!",
"suggested_prompts": [
{
"icon": "i-heroicons-light-bulb",
"title": "Get Started",
"text": "What can you help me with?"
}
],
"knowledge_ids": [10, 20],
"knowledge_sources": [
{
"id": 10,
"name": "Product Docs",
"url": "https://docs.example.com",
"type": "sitemap",
"status": "ready"
},
{
"id": 20,
"name": "FAQ",
"url": "https://example.com/faq",
"type": "website",
"status": "loading"
}
],
"trait_ids": [1, 3],
"traits": [
{"id": 1, "name": "Friendly"},
{"id": 3, "name": "Professional"}
],
"chat_theme_id": 5,
"chat_theme": {
"id": 5,
"preset": "standard",
"greeting": "How can I help you today?"
},
"data_template_id": 2,
"data_template": {
"id": 2,
"name": "Contact Info",
"fields": [...]
},
"created_at": "2026-01-15T10:30:00Z",
"updated_at": "2026-01-20T14:22:00Z"
}Enums ​
access_level ​
Defines who can interact with the agent.
| Value | Description | Use Case |
|---|---|---|
PRIVATE | Only accessible via API with authentication | Internal tools, authenticated apps |
PUBLIC | Anyone with the joina.chat link can chat | Public-facing agents, website embedding |
PASSWORD_PROTECTED | Public link but requires password | Shared with specific users/teams |
Examples:
python
# Internal assistant
create_agent(name="Internal Bot", access_level="PRIVATE")
# Public support bot
create_agent(name="Support", access_level="PUBLIC", uri="support")
# Partner portal
create_agent(name="Partner Bot", access_level="PASSWORD_PROTECTED", password="secret123")collection_mode ​
Defines how aggressively an agent collects data from conversations.
| Value | Description | When to Use |
|---|---|---|
passive | Silent extraction after conversation ends | Non-intrusive, background collection |
opportunistic | Captures when user mentions data, brief follow-ups | Balanced approach, most common |
active | Proactively asks for information during chat | Lead generation, high-value data |
guided | Follows custom script (requires custom_prompt) | Structured interviews, complex forms |
Behavior comparison:
| Mode | User mentions email | User doesn't mention email |
|---|---|---|
passive | Captures it silently | Doesn't ask |
opportunistic | Captures it + brief "And your phone?" | Doesn't ask |
active | Captures it + asks for all missing fields | Asks for email + all fields |
guided | Follows custom script | Follows custom script |
Examples:
python
# Passive: background analytics
data_collection={
"template_name": "Feedback",
"fields": [...],
"collection_mode": "passive"
}
# Active: sales lead capture
data_collection={
"template_name": "Lead Info",
"fields": [...],
"collection_mode": "active"
}
# Guided: job application
data_collection={
"template_name": "Application",
"fields": [...],
"collection_mode": "guided",
"custom_prompt": "Walk the candidate through each section..."
}field_type ​
Data types for fields in data collection templates.
| Value | Description | Validation | Example |
|---|---|---|---|
text | Free-form text | None | Name, description, feedback |
email | Email address | Valid email format | user@example.com |
phone | Phone number | Valid phone format | +1-555-123-4567 |
number | Numeric value | Must be number | Age: 25, quantity: 10 |
date | Date value | ISO 8601 or natural language | 2026-01-15, "next Monday" |
url | URL | Valid URL format | https://example.com |
Examples:
python
fields=[
{"name": "full_name", "type": "text", "required": True},
{"name": "email", "type": "email", "required": True},
{"name": "phone", "type": "phone", "required": False},
{"name": "age", "type": "number", "required": False},
{"name": "start_date", "type": "date", "required": False},
{"name": "website", "type": "url", "required": False}
]knowledge_source_type ​
Type of knowledge source for RAG-based retrieval.
| Value | Description | When to Use |
|---|---|---|
website | Crawls pages recursively from starting URL | General website content, blogs |
sitemap | Follows sitemap.xml for page discovery | Well-structured docs sites, large sites |
discovery | Crawl-based discovery via NeoReader, no sitemap required | Default fallback when no sitemap exists — omit type to get this automatically |
The table above describes the stored data_type and how each is loaded. As an input to gnosari_manage_knowledge(action="create"), type behaves differently: omitting it or passing "website" triggers server-side auto-resolve — it probes for a sitemap first and falls back to discovery if none is found (so a website input is stored as sitemap or discovery, never website). Pass single_page=true to store a single-page website source without probing. Most callers never need to pick a value explicitly — see the Manage Resources reference for the full probe order.
Behavior comparison:
| Type | Discovery Method | Best For |
|---|---|---|
website | Recursive link following | Small sites, blogs, marketing pages |
sitemap | Reads sitemap.xml | Documentation sites, large structured sites |
discovery | NeoReader crawl at load time | Fallback when no sitemap is found — this is what auto-resolve lands on |
Examples:
python
# Whole-site (type="website" auto-resolves — same as omitting type)
knowledge_sources=[
{"name": "Blog", "url": "https://example.com/blog", "type": "website"}
]
# Sitemap-based explicitly (skips the probe)
knowledge_sources=[
{"name": "Docs", "url": "https://docs.example.com", "type": "sitemap"}
]
# Single page only — opt out of whole-site with single_page
gnosari_manage_knowledge(action="create", name="Pricing", url="https://example.com/pricing", single_page=True)
# Recommended default — omit type, server auto-resolves sitemap -> discovery
gnosari_manage_knowledge(action="create", name="Docs", url="https://docs.example.com")AgentMutationResult Response ​
When creating or updating agents via create_agent or update_agent, the tool returns an AgentMutationResult Pydantic model with three fields:
| Field | Type | Description |
|---|---|---|
agent | AgentRead | The created or updated agent |
created_resources | list[str] | String summaries of resources created as side-effects |
warnings | list[str] | Non-fatal issues encountered during the operation |
The created_resources list contains human-readable summaries, not structured objects. For details about inline-created resources, use the returned agent.id to call the relevant listing tools.
Example ​
python
result = create_agent(
name="Sales Bot",
instructions="...",
knowledge_sources=[{"name": "Docs", "url": "https://docs.example.com", "type": "sitemap"}],
)
# Access typed attributes directly
print(result.agent.id) # 123
print(result.agent.name) # "Sales Bot"
print(result.agent.public_url) # None (PRIVATE by default)
print(result.created_resources) # ["knowledge_source: Docs (id=45, status=loading)"]
print(result.warnings) # ["Knowledge source 'Docs' (ID: 45) is still loading."]Legacy envelope format (removed) ​
Prior to Plan 18, tools returned {"success": True, "data": {...}} envelopes. That format no longer exists. Use attribute access on the returned Pydantic model:
python
# Old (broken): result["data"]["agent"]["id"]
# New (correct): result.agent.idChecking inline-created resources ​
json
{
"agent": {
"id": 123,
"name": "Sales Bot",
"..."
},
"created_resources": [
"knowledge_source: Docs (id=45, status=loading)"
],
"warnings": [
"Knowledge source 'Docs' (ID: 45) is still loading. Use get_knowledge_source to check status."
]
}Warnings ​
Non-fatal issues that don't prevent agent creation:
| Warning | Meaning | Action |
|---|---|---|
| "Knowledge source still loading" | Async indexing in progress | Poll with get_agent until status is "ready" |
| "Data template name matched existing" | Inline template matched by name, existing one used | Verify with get_agent that correct template applied |
Knowledge Source Status ​
Knowledge sources load asynchronously. The status field indicates loading progress.
| Status | Meaning | Agent Behavior | Action |
|---|---|---|---|
loading | Currently indexing pages | Agent works but without this knowledge | Wait for completion |
ready | Successfully indexed | Agent uses this knowledge | No action needed |
failed | Indexing failed | Agent works without this knowledge | Check URL accessibility, retry |
Monitoring example:
python
# Create agent with knowledge
result = create_agent(
name="Support Bot",
instructions="...",
knowledge_sources=[
{"name": "Docs", "url": "https://docs.example.com", "type": "sitemap"}
]
)
# Check loading status
agent = get_agent(agent_id=result.agent.id)
for source in agent.knowledge_sources:
print(f"{source.name}: {source.status}")Next Steps ​
- Tools Reference - Full tool parameter documentation
- API Overview - Tool relationships and call sequences