Appearance
Migration Guide ​
v6: gnosari_manage_qr → gnosari_manage_link (current) ​
What changed: AgentLink absorbed QrLink. The tool was renamed and extended: every link now opens an agent as a classic chat OR an immersive full-page conversation, with per-link greeting/topic/theme/expiry overrides. gnosari_manage_qr is deleted outright — no alias. Tool count is unchanged (16 → 16); this is a rename + extension, not a consolidation.
Why: QR links were a single narrow use case (physical media redirects). Conversation Mode generalizes the same entity into a general-purpose shareable link — a QR code is now one derived artifact of every link, not the whole feature.
Breaking changes ​
| Change | Migration |
|---|---|
gnosari_manage_qr removed | Use gnosari_manage_link. Same actions: create, get, list, update, delete, check_slug |
qr_link_id param → link_id | Rename the parameter in every call |
clear_agent: bool → clear_fields: list[str] | clear_agent=True has no direct replacement (a link always needs an agent — re-point it with a new agent_id instead). clear_fields now resets greeting / topic / chat_theme_id / expires_at back to inherit |
scan_count field → visit_count | Read visit_count instead |
Return shape QrLinkRead → LinkDetail | Adds presentation, greeting, topic, expires_at, and a urls object (public, embed, qr_image) in place of a bare slug |
New: presentation, greeting, topic, chat_theme_id, expires_at params | Optional on create/update. Default presentation is chat (identical behavior to the old QR link) |
Migration pattern ​
python
# Old way — gnosari_manage_qr
qr = gnosari_manage_qr(action="create", name="Card QR", slug="card", agent_id=123)
print(f"joina.chat/q/{qr['slug']}")
gnosari_manage_qr(action="update", qr_link_id=qr["id"], clear_agent=True)
# New way — gnosari_manage_link (same default behavior, presentation="chat")
link = gnosari_manage_link(action="create", name="Card QR", slug="card", agent_id=123)
print(link.urls.public) # joina.chat/l/card
gnosari_manage_link(action="update", link_id=link.id, agent_id=456) # re-point instead of clearing
# New capability — immersive conversation presentation, not possible before
gnosari_manage_link(
action="update", link_id=link.id, presentation="conversation", topic="A conversation about your stay"
)Printed QR codes encoding the old joina.chat/q/{slug} keep working — the API retains a legacy /resolve/qr/{slug} alias so existing physical media never needs reprinting.
v5: 17 tools → 16 tools — Tool UX v2 ​
What changed: gnosari_create became a validate-first atomic composite, prose hints became a structured readiness block, and the domain surface was removed.
Why: Agents walked into dead ends — schemas advertised things that could not succeed, defaults contradicted the product, and post-create guidance was prose hints agents ignored.
Breaking changes ​
| Change | Migration |
|---|---|
gnosari_create requires empty_state_title, empty_state_description, data_collection | Add these to every create call. The result is a live-ready intake agent in one call (welcome + data collection). Optional greeting, suggested_prompts, publish, uri |
gnosari_list_domains removed | Drop it. Publishing resolves the default domain (joina.chat) server-side |
domain / domain_id params removed from gnosari_manage_access, gnosari_check_uri, gnosari_search | Drop the params. Default domain is resolved server-side |
gnosari_embed_code param agent_id: str → gnosari_id: int | Pass the integer agent id |
collection_mode default passive → active | Set mode/collection_mode explicitly if you relied on the old passive default |
Prose hints → readiness block | Read readiness.percent / readiness.missing / readiness.next_steps instead of hints. gnosari_check_uri still returns hints (URI suggestions) |
v4: 22 tools → 17 tools — Plan 2 consolidation ​
What changed: Consolidated 10 legacy tools into action-discriminated gnosari_* tools. Renamed 1 tool for consistency.
Why: 5 QR tools and 3 data tools were individually registered — unnecessary API sprawl. Consolidating into gnosari_manage_qr and gnosari_collected_data follows the same manage pattern used by traits, knowledge, and data collection. Also renamed list_domains and gnosari_health_check for namespace consistency.
Tool mapping ​
| Old Tool | New Tool | Notes |
|---|---|---|
create_qr_link | gnosari_manage_qr(action="create") | Same params: name, slug, agent_id |
get_qr_link | gnosari_manage_qr(action="get") | qr_link_id required |
list_qr_links | gnosari_manage_qr(action="list") | Same skip/limit pagination |
update_qr_link | gnosari_manage_qr(action="update") | Added clear_agent bool to detach agent |
delete_qr_link | gnosari_manage_qr(action="delete") | qr_link_id required |
list_collected_data | gnosari_collected_data(action="list") | Same filters: agent_id, template_name, days, status, search |
get_collection_stats | gnosari_collected_data(action="stats") | Same params: agent_id, days, group_by_agent |
list_templates | Removed | Use gnosari_manage_data_collection(action="list") or gnosari_search(entity="templates") |
get_embed_code | gnosari_embed_code | Renamed for gnosari_* namespace consistency |
gnosari_health_check | gnosari_health | Shortened name |
list_domains | gnosari_list_domains | Renamed for gnosari_* namespace consistency |
New feature: clear_agent ​
gnosari_manage_qr(action="update") adds a clear_agent boolean flag that was not possible with the old update_qr_link. This allows detaching an agent from a QR link without deleting the link:
python
# Old: no way to detach agent without setting agent_id=None (which was filtered out)
# New: explicit flag
gnosari_manage_qr(action="update", qr_link_id=1, clear_agent=True)clear_agent and agent_id are mutually exclusive.
Migration pattern ​
python
# Old way — 5 separate QR tools
qr = create_qr_link(name="Card QR", slug="card", agent_id=123)
links = list_qr_links()
link = get_qr_link(qr_link_id=1)
update_qr_link(qr_link_id=1, agent_id=456)
delete_qr_link(qr_link_id=1)
# New way — single tool
qr = gnosari_manage_qr(action="create", name="Card QR", slug="card", agent_id=123)
links = gnosari_manage_qr(action="list")
link = gnosari_manage_qr(action="get", qr_link_id=1)
gnosari_manage_qr(action="update", qr_link_id=1, agent_id=456)
gnosari_manage_qr(action="delete", qr_link_id=1)
# Old way — 2 data tools
records = list_collected_data(agent_id=123, days=7)
stats = get_collection_stats(agent_id=123, days=30)
# New way — single tool
records = gnosari_collected_data(action="list", agent_id=123, days=7)
stats = gnosari_collected_data(action="stats", agent_id=123, days=30)
# Old way — other renames
code = get_embed_code(agent_id="abc")
health = gnosari_health_check()
domains = list_domains()
# New way
code = gnosari_embed_code(agent_id="abc")
health = gnosari_health()
domains = gnosari_list_domains()v3: 19 tools → gnosari_* tools ​
What changed: Monolithic create_agent(26 params) replaced by atomic decomposition — one tool per configuration concern.
Why: Single-call creation was all-or-nothing. Atomic tools let you build agents incrementally, retry individual steps, and follow hints to the next configuration step.
Tool mapping ​
| Old Tool | New Tool | Notes |
|---|---|---|
create_agent | gnosari_create + config tools | Decomposed: create bare agent, then configure |
get_agent | gnosari_get | Returns GnosariOverview with hints |
update_agent (identity/model) | gnosari_update | Name, description, model, temperature |
update_agent (instructions) | gnosari_manage_instructions | Replace, append, or prepend |
update_agent (access) | gnosari_manage_access | Access level, URI, domain |
update_agent (appearance) | gnosari_manage_appearance | Greeting, prompts, theme, image |
update_agent (knowledge) | gnosari_manage_knowledge | Assign/remove knowledge sources. type is now optional — omit it to auto-resolve sitemap/discovery (see the Manage Resources reference) |
update_agent (traits) | gnosari_manage_traits | Assign/remove traits |
update_agent (data collection) | gnosari_manage_data_collection | Assign/remove templates |
delete_agent | gnosari_delete | Two-phase with confirmed flag |
list_agents | gnosari_search(entity="agents") | Text search + filters |
list_traits | gnosari_manage_traits(action="list") | Or gnosari_search(entity="traits") |
list_knowledge_sources | gnosari_manage_knowledge(action="list") | Or gnosari_search(entity="knowledge") |
Parameter name change ​
All gnosari_* tools use gnosari_id — not agent_id:
python
# Old
get_agent(agent_id=123)
delete_agent(agent_id=123)
# New
gnosari_get(gnosari_id=123)
gnosari_delete(gnosari_id=123)Migration pattern ​
python
# Old way — one call, all-or-nothing
result = create_agent(
name="Support Bot",
instructions="...",
access_level="PUBLIC",
uri="support",
knowledge_sources=[{"name": "Docs", "url": "https://docs.example.com", "type": "sitemap"}],
trait_ids=[1, 3],
chat_theme={"preset": "standard", "greeting": "Hi!"},
data_collection={"template_name": "Ticket", "fields": [...], "collection_mode": "active"}
)
# New way — atomic decomposition
result = gnosari_create(name="Support Bot", instructions="...")
gnosari_id = result.agent.gnosari_id
gnosari_manage_knowledge(action="create", name="Docs", url="https://docs.example.com", type="sitemap", gnosari_id=gnosari_id)
gnosari_manage_traits(action="assign", trait_ids=[1, 3], gnosari_id=gnosari_id)
gnosari_manage_appearance(gnosari_id=gnosari_id, greeting="Hi!", style_preset="clean-dots")
gnosari_manage_data_collection(action="create", name="Ticket", fields=[...], gnosari_id=gnosari_id, collection_mode="active")
gnosari_manage_access(gnosari_id=gnosari_id, access_level="PUBLIC", uri="support")v2: 127 tools → 19 tools (legacy reference) ​
What changed: 127 type-specific agent tools replaced by 5 unified tools + 7 resources.
Impact: 85% reduction in tool count (127 → 19), single-call agent creation.
Architecture ​
| Before (127 tools) | After (19 tools + 7 resources) |
|---|---|
create_marketing_agent | create_agent (no type needed) |
create_development_agent | create_agent |
create_content_agent | create_agent |
get_marketing_agent(id) | get_agent(agent_id=id) |
update_marketing_agent(id, ...) | update_agent(agent_id=id, ...) |
delete_*_agent(id) | delete_agent(agent_id=id) |
create_knowledge_source(...) then create_agent(source_id=...) | create_agent(knowledge_sources=[{...}]) inline |
list_domains() (tool) | read_resource("gnosari://domains") |
get_traits() | read_resource("gnosari://traits") |
create_team(...) | Use agent instructions instead |
Old workflow vs new ​
python
# Before: 8+ sequential calls
domain = get_default_domain()
source = create_knowledge_source(name="Docs", url="...", type="sitemap")
theme = create_chat_theme(preset="standard")
template = create_data_template(name="Lead", fields=[...])
trait = get_trait_by_name("Friendly")
agent = create_marketing_agent(
name="Bot", instructions="...", domain_id=domain.id,
knowledge_source_ids=[source.id], chat_theme_id=theme.id,
data_template_id=template.id, trait_ids=[trait.id], access_level="PUBLIC"
)
# After: 1 call
agent = create_agent(
name="Bot", instructions="...", access_level="PUBLIC",
knowledge_sources=[{"name": "Docs", "url": "...", "type": "sitemap"}],
chat_theme={"preset": "standard"},
data_collection={"template_name": "Lead", "fields": [...], "collection_mode": "active"},
trait_ids=[friendly["id"]]
)Breaking changes ​
| Change | Old | New |
|---|---|---|
| No agent type parameter | create_marketing_agent(...) | create_agent(...) |
| Inline resource creation | source_id = create_knowledge_source(...) then pass ID | Pass config inline in create_agent |
| Resources replace list tools | domains = list_domains() | domains = read_resource("gnosari://domains") |
| Team tools removed | create_team(...) | Define team behavior in instructions |
| Unified get/update/delete | get_marketing_agent(id) | get_agent(agent_id=id) |
Getting Help ​
- Agent Creation Guide - Current patterns with gnosari_* tools
- Tools Reference - Complete parameter docs
- API Overview - Tool relationships and atomic decomposition pattern