Migrating from v6 to v7
v7 removes a set of legacy protocol surfaces that have provider-agnostic or simpler replacements. This is a v6 release: everything below still works today, but any use is flagged with a non-blocking deprecation warning during protocol validation. Migrate now, while on v6, so upgrading to v7 is a no-op.
To find every deprecated usage in your agents, validate your protocol - either in the dashboard editor (the Problems panel lists warnings) or with the CLI:
octavus validate ./path/to/agentDeprecation warnings never block saving or deploying on v6. In v7 the same usages become validation errors.
What is being removed in v7
display: nameanddisplay: descriptionon tools, skills, MCP servers, workers, and blocks. Usedisplay: titleordisplay: stream.- The default
displaybecomestitle(it isdescriptiontoday). A tool/skill/MCP with nodisplayset will render as a clean label instead of showing its description. - Provider-specific tools and skills (
agent.anthropic.tools,agent.anthropic.skills). Use the provider-agnosticwebSearch: trueand Octavus Skills. - Resources (
resources:, theset-resourceblock, and theresource-update/onResourceUpdateevent). Persist state with a tool instead.
1. Display modes: name / description -> title or stream
v7 keeps three display modes:
| Mode | What the client sees |
|---|---|
hidden | Nothing. The execution is invisible in the UI. |
title | A clean label (the entity's title, falling back to its name) plus the tool name. No arguments, no result. |
stream | Full visibility: arguments stream live, and the result is shown and preserved across refresh. |
The description mode used the entity's description - text written for the model - as the UI label, and name showed the raw slug. Both are replaced by the title/name label rule: the UI shows title when set, otherwise a friendly form of the name, and never the description.
Choosing a replacement:
- Want the client to see the full call (arguments, result, nested activity)? Use
display: stream. This is the natural choice for client-executed tools and anything where transparency matters. - Want a clean, labeled step without exposing arguments or result? Use
display: titleand add atitle. This is the recommended default for server-side tools. - Want it invisible? Use
display: hidden.
Before:
tools:
get-user-account:
display: description # deprecated
description: Looking up your account information
parameters:
userId: { type: string }
save-draft:
display: name # deprecated
description: Persist the current draft
parameters:
body: { type: string }After:
tools:
get-user-account:
display: title
title: Looking up your account # the UI label
description: Retrieves the user's account by id. # written for the model
parameters:
userId: { type: string }
save-draft:
display: stream # show the arguments/result to the client
description: Persist the current draft
parameters:
body: { type: string }The default flip
Today, an entity with no display set defaults to description. In v7 the default becomes title. If you rely on the default and want to keep full visibility, set display: stream explicitly:
tools:
# Relied on the old `description` default and wants the client to see details:
run-report:
display: stream # make the previous full-detail behavior explicit
description: Generates the requested reportAn entity that only needs a label needs no change - it just renders its title (or friendly name) instead of its description once the default flips. Validation points these out ahead of time: an entity that will resolve to title without a title set gets an info recommendation (MISSING_DISPLAY_TITLE) to add one. It is guidance, not a deprecation warning - it never blocks and does not count toward the "zero warnings" check below.
Skill titles
Skills carry their own user-facing label in their SKILL.md frontmatter, separate from the description (which is written for the model). Add a title to each skill so it shows a friendly label in title mode:
# SKILL.md frontmatter
---
name: gmail
title: Working with Gmail # user-facing UI label
description: Read, search, and send email through the Gmail API. # for the model
---A skill's label resolves in order: a protocol override skills.<slug>.title -> onDemandSkills.title -> the skill's built-in title -> the skill slug. The skill description is never used as the UI label.
2. Provider tools/skills -> webSearch and Octavus skills
The provider-specific agent.anthropic.tools and agent.anthropic.skills only worked on Anthropic models. Octavus ships provider-agnostic equivalents that work on any model, so the provider-specific surface is removed in v7.
Before:
agent:
model: anthropic/claude-sonnet-4-5
system: system
anthropic: # deprecated - Anthropic-only
tools:
web-search:
description: Searching the web
code-execution:
description: Running code
skills:
pdf:
type: anthropic
description: Processing PDF documentAfter:
agent:
model: anthropic/claude-sonnet-4-5 # works on any provider now
system: system
webSearch: true # provider-agnostic web search (the octavus_web_search tool)
skills:
- pdf-tools # an Octavus skill for PDF work
# Octavus skills are defined in the protocol's `skills:` section and run in an
# isolated sandbox. See /docs/protocol/skills.
skills:
pdf-tools:
display: title
title: Processing your PDF- Web search: replace
anthropic.tools.web-searchwithwebSearch: trueon the agent. See Web Search. - Code execution and knowledge packages: replace
anthropic.tools.code-executionandanthropic.skills.*with Octavus Skills, which run code and load knowledge packages in an isolated sandbox on any provider.
3. Resources -> tools
Resources (resources:, the set-resource block, and the resource-update event delivered via onResourceUpdate) are removed in v7. Persist state with a tool instead: define a tool whose parameters carry the resource-shaped payload, and write the value in your own application inside the tool handler. This keeps state ownership in your app with no separate resource concept.
Before:
resources:
CONVERSATION_SUMMARY:
type: string
default: ''
variables:
SUMMARY:
type: string
handlers:
wrap-up:
Generate summary:
block: next-message
output: SUMMARY
Save summary:
block: set-resource # deprecated
resource: CONVERSATION_SUMMARY
value: SUMMARY// Client received resource updates via a callback:
useOctavusChat({
onResourceUpdate: (name, value) => {
if (name === 'CONVERSATION_SUMMARY') persist(value); // deprecated
},
});After - a tool the LLM (or a deterministic block) calls to persist the value:
tools:
save-conversation-summary:
display: title
title: Saving the conversation summary
description: Persist the running summary of this conversation.
parameters:
summary:
type: string
description: The summary text to store
variables:
SUMMARY:
type: string
handlers:
wrap-up:
Generate summary:
block: next-message
output: SUMMARY
Save summary:
block: tool-call
tool: save-conversation-summary
input:
summary: SUMMARY// Implement the tool in your backend; you own where the state goes:
const session = client.agentSessions.attach(sessionId, {
tools: {
'save-conversation-summary': async (args) => {
await db.conversations.update(id, { summary: args.summary as string });
return { saved: true };
},
},
});You can also expose the persistence tool through an inline MCP server (createInlineMcpServer from @octavus/server-sdk) if you prefer to group it with other consumer-owned tools - see Inline MCP. Either way, the tool's input schema is the "resource shape," and your handler decides where the value is stored.
Migration checklist
- Validate every agent (
octavus validateor the dashboard editor) and resolve each deprecation warning. - Replace
display: name/display: descriptionwithdisplay: title(add atitle) ordisplay: stream. - Set
display: streamexplicitly on any entity that relied on the olddescriptiondefault and needs full visibility. - Add a
titleto each skill'sSKILL.mdfrontmatter. - Replace
agent.anthropic.tools/agent.anthropic.skillswithwebSearch: trueand Octavus Skills. - Replace
resources:,set-resource, andonResourceUpdatewith a tool that persists state in your application.
When validation reports zero deprecation warnings, your agent is ready for v7.