Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Calibrate a new dataset from live RTSP camera streams via the AutoMagicCalib REST API.
SkillScore68/100
Test results 68
3/3 safety checks passed
14%68%of test cases passed +55 pts
Passed 15 of 22 test cases with the skill, and 3 of 22 without it.
12 fixed3 passed either way7 still failing0 broke
One test taskWe ingested RTSP stream clips into project 'plaza_south' and uploaded `alignment_data.json` and `layout.png`. No `settings.json` file was uploaded. We are ready to call `/v1/calibrate/plaza_south`. What parameter must be resolved before initiating calibration?
Adds every file the skill has, pinned so you can update it. No account needed.
pip install "decimalai>=0.15"
decimalai skills add nvidia-amc-run-rtsp-calibration
claude --plugin-dir "$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.agents"The same install from Python, for a notebook or a setup script.
pip install "decimalai>=0.15"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("nvidia-amc-run-rtsp-calibration")
if result.exit_code:
raise SystemExit(result.problems)
print("Added. Start Claude Code with the command below.")claude --plugin-dir "$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.agents"Type these in a Claude Code session. No account or API key. It writes the skill and any files it bundles, and asks first when its safety rating isn't Passed.
/plugin marketplace add decimal-labs/decimalai-claude-plugins
/plugin install decimalai@decimalai/decimalai:install nvidia-amc-run-rtsp-calibrationThe plugin needs python3 and curl on your machine.
No Python or account. Claude Code picks it up in its next session.
curl -fsSL --create-dirs -o .claude/skills/nvidia-amc-run-rtsp-calibration/SKILL.md https://app.decimal.ai/s/nvidia-amc-run-rtsp-calibration/SKILL.md.claude/skills/nvidia-amc-run-rtsp-calibration/SKILL.mdThis gets SKILL.md only. The skill's 1 other file is not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[claude-agent-sdk]"
decimalai skills add nvidia-amc-run-rtsp-calibrationimport asyncio
from claude_agent_sdk import ClaudeAgentOptions
from decimalai.claude_agent_sdk import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
async def main():
question = "Hello!"
async with support.run(question) as run: # one user message, one run
async for message in run.query(options=ClaudeAgentOptions(max_turns=6)):
print(message)
# In a notebook or async code: await main()
asyncio.run(main())Prefer its own loader? ClaudeAgentOptions(plugins=[skills_plugin()], skills="all") reads the same folder. Use one or the other: a skill delivered both ways reaches the prompt twice.
The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[claude-agent-sdk]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("nvidia-amc-run-rtsp-calibration")
if result.exit_code:
raise SystemExit(result.problems)
import asyncio
from claude_agent_sdk import ClaudeAgentOptions
from decimalai.claude_agent_sdk import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
async def main():
question = "Hello!"
async with support.run(question) as run: # one user message, one run
async for message in run.query(options=ClaudeAgentOptions(max_turns=6)):
print(message)
# In a notebook or async code: await main()
asyncio.run(main())Prefer its own loader? ClaudeAgentOptions(plugins=[skills_plugin()], skills="all") reads the same folder. Use one or the other: a skill delivered both ways reaches the prompt twice.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/nvidia-amc-run-rtsp-calibration/SKILL.mdimport asyncio
from pathlib import Path
from claude_agent_sdk import ClaudeAgentOptions, query
skill = Path(".agents/skills/nvidia-amc-run-rtsp-calibration/SKILL.md").read_text()
options = ClaudeAgentOptions(system_prompt=f"You are a helpful agent.\n\n{skill}", max_turns=6)
async def main():
async for message in query(prompt="Hello!", options=options):
print(message)
# In a notebook or async code: await main()
asyncio.run(main())This gets SKILL.md only. The skill's 1 other file is not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[openai-agents]"
decimalai skills add nvidia-amc-run-rtsp-calibrationfrom agents import Agent, Runner
from decimalai.openai_agents import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = Agent(
name=support.name,
instructions=support.instructions, # your prompt, then the skill list
tools=[*support.tools], # your tools, then load_skill
)
# In a notebook or async code: result = await Runner.run(agent, "Hello!")
result = Runner.run_sync(agent, "Hello!")Using SandboxAgent? capabilities=[Shell(), decimalai.openai_agents.sandbox_skills()] points its own loader at the same folder.
The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[openai-agents]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("nvidia-amc-run-rtsp-calibration")
if result.exit_code:
raise SystemExit(result.problems)
from agents import Agent, Runner
from decimalai.openai_agents import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = Agent(
name=support.name,
instructions=support.instructions, # your prompt, then the skill list
tools=[*support.tools], # your tools, then load_skill
)
# In a notebook or async code: result = await Runner.run(agent, "Hello!")
result = Runner.run_sync(agent, "Hello!")Using SandboxAgent? capabilities=[Shell(), decimalai.openai_agents.sandbox_skills()] points its own loader at the same folder.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/nvidia-amc-run-rtsp-calibration/SKILL.mdfrom pathlib import Path
from agents import Agent, Runner
skill = Path(".agents/skills/nvidia-amc-run-rtsp-calibration/SKILL.md").read_text()
agent = Agent(name="support", instructions=f"You are a helpful agent.\n\n{skill}")
# In a notebook or async code: result = await Runner.run(agent, "Hello!")
result = Runner.run_sync(agent, "Hello!")This gets SKILL.md only. The skill's 1 other file is not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[openai]"
decimalai skills add nvidia-amc-run-rtsp-calibrationimport json
from openai import OpenAI
from decimalai.openai import agent_config
client = OpenAI()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
def lookup_order(order_id: str) -> str:
return f"Order {order_id} shipped yesterday."
# Your tools, as Chat Completions takes them, and what answers each.
TOOLS = [{"type": "function", "function": {
"name": "lookup_order",
"description": "Look up the status of an order.",
"parameters": {"type": "object", "properties": {"order_id": {"type": "string"}},
"required": ["order_id"]},
}}]
FUNCTIONS = {"lookup_order": lookup_order}
question = "Where is order A1001?"
with support.run(question) as run: # one user message, one run
# run.system is your prompt, then the skill list.
messages = [{"role": "system", "content": run.system}, run.message]
while True:
reply = client.chat.completions.create(
model="gpt-5.4-mini",
messages=messages,
tools=[*TOOLS, *run.tools], # your tools, then load_skill
).choices[0].message
messages.append(reply)
if not reply.tool_calls:
break
for call in reply.tool_calls:
# load_skill is answered by the run; your own tools by FUNCTIONS.
function = FUNCTIONS.get(call.function.name)
messages.append(run.tool_result(call) or {
"role": "tool", "tool_call_id": call.id,
"content": function(**json.loads(call.function.arguments)) if function
else f"There is no tool named {call.function.name!r}.",
})
print(reply.content)
# The Responses API takes run.response_tools instead of run.tools.The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[openai]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("nvidia-amc-run-rtsp-calibration")
if result.exit_code:
raise SystemExit(result.problems)
import json
from openai import OpenAI
from decimalai.openai import agent_config
client = OpenAI()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
def lookup_order(order_id: str) -> str:
return f"Order {order_id} shipped yesterday."
# Your tools, as Chat Completions takes them, and what answers each.
TOOLS = [{"type": "function", "function": {
"name": "lookup_order",
"description": "Look up the status of an order.",
"parameters": {"type": "object", "properties": {"order_id": {"type": "string"}},
"required": ["order_id"]},
}}]
FUNCTIONS = {"lookup_order": lookup_order}
question = "Where is order A1001?"
with support.run(question) as run: # one user message, one run
# run.system is your prompt, then the skill list.
messages = [{"role": "system", "content": run.system}, run.message]
while True:
reply = client.chat.completions.create(
model="gpt-5.4-mini",
messages=messages,
tools=[*TOOLS, *run.tools], # your tools, then load_skill
).choices[0].message
messages.append(reply)
if not reply.tool_calls:
break
for call in reply.tool_calls:
# load_skill is answered by the run; your own tools by FUNCTIONS.
function = FUNCTIONS.get(call.function.name)
messages.append(run.tool_result(call) or {
"role": "tool", "tool_call_id": call.id,
"content": function(**json.loads(call.function.arguments)) if function
else f"There is no tool named {call.function.name!r}.",
})
print(reply.content)
# The Responses API takes run.response_tools instead of run.tools.No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/nvidia-amc-run-rtsp-calibration/SKILL.mdfrom pathlib import Path
from openai import OpenAI
client = OpenAI()
skill = Path(".agents/skills/nvidia-amc-run-rtsp-calibration/SKILL.md").read_text()
reply = client.chat.completions.create(
model="gpt-5.4-mini",
messages=[
{"role": "system", "content": f"You are a helpful agent.\n\n{skill}"},
{"role": "user", "content": "Hello!"},
],
).choices[0].messageThis gets SKILL.md only. The skill's 1 other file is not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[anthropic]"
decimalai skills add nvidia-amc-run-rtsp-calibrationimport anthropic
from decimalai.anthropic import agent_config
client = anthropic.Anthropic()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
question = "Hello!"
with support.run(question) as run: # one user message, one run
answer = client.beta.messages.tool_runner(
model="claude-haiku-5-5",
max_tokens=4096,
system=run.system, # your prompt, then the skill list
tools=[*run.tools], # your tools, then load_skill
messages=[{"role": "user", "content": question}],
).until_done()The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[anthropic]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("nvidia-amc-run-rtsp-calibration")
if result.exit_code:
raise SystemExit(result.problems)
import anthropic
from decimalai.anthropic import agent_config
client = anthropic.Anthropic()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
question = "Hello!"
with support.run(question) as run: # one user message, one run
answer = client.beta.messages.tool_runner(
model="claude-haiku-5-5",
max_tokens=4096,
system=run.system, # your prompt, then the skill list
tools=[*run.tools], # your tools, then load_skill
messages=[{"role": "user", "content": question}],
).until_done()No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/nvidia-amc-run-rtsp-calibration/SKILL.mdfrom pathlib import Path
import anthropic
client = anthropic.Anthropic()
skill = Path(".agents/skills/nvidia-amc-run-rtsp-calibration/SKILL.md").read_text()
reply = client.messages.create(
model="claude-haiku-5-5",
max_tokens=4096,
system=f"You are a helpful agent.\n\n{skill}",
messages=[{"role": "user", "content": "Hello!"}],
)This gets SKILL.md only. The skill's 1 other file is not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[google-genai]"
decimalai skills add nvidia-amc-run-rtsp-calibrationfrom google import genai
from google.genai import types
from decimalai.google_genai import agent_config
client = genai.Client()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
def lookup_order(order_id: str) -> str:
return f"Order {order_id} shipped yesterday."
# Your functions, as declarations for the model, and what answers each.
TOOLS = [{"function_declarations": [{
"name": "lookup_order",
"description": "Look up the status of an order.",
"parameters_json_schema": {"type": "object", "properties": {"order_id": {"type": "string"}},
"required": ["order_id"]},
}]}]
FUNCTIONS = {"lookup_order": lookup_order}
question = "Where is order A1001?"
with support.run(question) as run: # one user message, one run
config = types.GenerateContentConfig(
system_instruction=run.system, # your prompt, then the skill list
tools=[*TOOLS, *run.tool_params], # your functions, then load_skill
)
contents = [{"role": "user", "parts": [{"text": run.message}]}]
while True:
response = client.models.generate_content(
model="gemini-3.5-flash", contents=contents, config=config,
)
if not response.function_calls:
break
contents.append(response.candidates[0].content)
parts = []
for call in response.function_calls:
# load_skill is answered by the run; your own functions by FUNCTIONS.
# A loop of your own rather than automatic function calling, which
# raises KeyError when the model asks for a function you did not pass.
function = FUNCTIONS.get(call.name)
parts.append(run.tool_result(call) or {"function_response": {
"name": call.name, "id": call.id,
"response": {"result": function(**(call.args or {})) if function
else f"There is no function named {call.name!r}."},
}})
contents.append({"role": "user", "parts": parts})
print(response.text)The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[google-genai]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("nvidia-amc-run-rtsp-calibration")
if result.exit_code:
raise SystemExit(result.problems)
from google import genai
from google.genai import types
from decimalai.google_genai import agent_config
client = genai.Client()
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
def lookup_order(order_id: str) -> str:
return f"Order {order_id} shipped yesterday."
# Your functions, as declarations for the model, and what answers each.
TOOLS = [{"function_declarations": [{
"name": "lookup_order",
"description": "Look up the status of an order.",
"parameters_json_schema": {"type": "object", "properties": {"order_id": {"type": "string"}},
"required": ["order_id"]},
}]}]
FUNCTIONS = {"lookup_order": lookup_order}
question = "Where is order A1001?"
with support.run(question) as run: # one user message, one run
config = types.GenerateContentConfig(
system_instruction=run.system, # your prompt, then the skill list
tools=[*TOOLS, *run.tool_params], # your functions, then load_skill
)
contents = [{"role": "user", "parts": [{"text": run.message}]}]
while True:
response = client.models.generate_content(
model="gemini-3.5-flash", contents=contents, config=config,
)
if not response.function_calls:
break
contents.append(response.candidates[0].content)
parts = []
for call in response.function_calls:
# load_skill is answered by the run; your own functions by FUNCTIONS.
# A loop of your own rather than automatic function calling, which
# raises KeyError when the model asks for a function you did not pass.
function = FUNCTIONS.get(call.name)
parts.append(run.tool_result(call) or {"function_response": {
"name": call.name, "id": call.id,
"response": {"result": function(**(call.args or {})) if function
else f"There is no function named {call.name!r}."},
}})
contents.append({"role": "user", "parts": parts})
print(response.text)No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/nvidia-amc-run-rtsp-calibration/SKILL.mdfrom pathlib import Path
from google import genai
from google.genai import types
client = genai.Client()
skill = Path(".agents/skills/nvidia-amc-run-rtsp-calibration/SKILL.md").read_text()
response = client.models.generate_content(
model="gemini-3.5-flash",
contents="Hello!",
config=types.GenerateContentConfig(system_instruction=f"You are a helpful agent.\n\n{skill}"),
)This gets SKILL.md only. The skill's 1 other file is not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[langchain]" langchain-openai
decimalai skills add nvidia-amc-run-rtsp-calibrationfrom langchain.agents import create_agent
from decimalai.langchain import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = create_agent(
"openai:gpt-5.4-mini",
tools=[], # your tools; the middleware adds load_skill
middleware=[support.middleware], # your prompt, the skill list and load_skill
)
result = agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[langchain]" langchain-openaifrom decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("nvidia-amc-run-rtsp-calibration")
if result.exit_code:
raise SystemExit(result.problems)
from langchain.agents import create_agent
from decimalai.langchain import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = create_agent(
"openai:gpt-5.4-mini",
tools=[], # your tools; the middleware adds load_skill
middleware=[support.middleware], # your prompt, the skill list and load_skill
)
result = agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/nvidia-amc-run-rtsp-calibration/SKILL.mdfrom pathlib import Path
from langchain.agents import create_agent
skill = Path(".agents/skills/nvidia-amc-run-rtsp-calibration/SKILL.md").read_text()
agent = create_agent("openai:gpt-5.4-mini", tools=[], system_prompt=f"You are a helpful agent.\n\n{skill}")
result = agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})This gets SKILL.md only. The skill's 1 other file is not included.
CrewAI's own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" "crewai>=1.15.27"
decimalai skills add nvidia-amc-run-rtsp-calibrationimport decimalai.crewai
from crewai import Agent, Crew, Task
agent = Agent(
role="Support", goal="Help the customer", backstory="A support agent.",
llm=llm, # your own CrewAI LLM
skills=decimalai.crewai.skills(), # the installed folder
tools=decimalai.crewai.skill_tools(), # reads a skill's files, runs its scripts
)
task = Task(description="Hello!", expected_output="an answer", agent=agent)
Crew(agents=[agent], tasks=[task]).kickoff()The same install from Python, for a notebook or a setup script. CrewAI's own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" "crewai>=1.15.27"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("nvidia-amc-run-rtsp-calibration")
if result.exit_code:
raise SystemExit(result.problems)
import decimalai.crewai
from crewai import Agent, Crew, Task
agent = Agent(
role="Support", goal="Help the customer", backstory="A support agent.",
llm=llm, # your own CrewAI LLM
skills=decimalai.crewai.skills(), # the installed folder
tools=decimalai.crewai.skill_tools(), # reads a skill's files, runs its scripts
)
task = Task(description="Hello!", expected_output="an answer", agent=agent)
Crew(agents=[agent], tasks=[task]).kickoff()No DecimalAI package. CrewAI's own loader reads the folder, and nothing pins or updates it.
.agents/skills/nvidia-amc-run-rtsp-calibration/SKILL.mdfrom pathlib import Path
from crewai import Agent, Crew, Task
agent = Agent(
role="Support", goal="Help the customer", backstory="A support agent.",
llm=llm, # your own CrewAI LLM
skills=[Path(".agents/skills")],
)
task = Task(description="Hello!", expected_output="an answer", agent=agent)
Crew(agents=[agent], tasks=[task]).kickoff()This gets SKILL.md only. The skill's 1 other file is not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[adk]"
decimalai skills add nvidia-amc-run-rtsp-calibrationfrom decimalai.adk import DecimalAIPlugin, agent_config
from google.adk.agents import LlmAgent
from google.adk.apps import App
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = LlmAgent(
name="support", # ADK needs a Python identifier
model="gemini-3.5-flash",
instruction=support.instruction, # your prompt, then the skill list
tools=[*support.tools], # your tools, then load_skill
)
# DecimalAIPlugin makes each invocation of runners built from this App one trace.
app = App(name="support", root_agent=agent, plugins=[DecimalAIPlugin()])Prefer ADK's own loader? SkillToolset(skills=decimalai.adk.skills(), ...) reads the same folder. Use one or the other: a skill delivered both ways reaches the prompt twice.
The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[adk]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("nvidia-amc-run-rtsp-calibration")
if result.exit_code:
raise SystemExit(result.problems)
from decimalai.adk import DecimalAIPlugin, agent_config
from google.adk.agents import LlmAgent
from google.adk.apps import App
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = LlmAgent(
name="support", # ADK needs a Python identifier
model="gemini-3.5-flash",
instruction=support.instruction, # your prompt, then the skill list
tools=[*support.tools], # your tools, then load_skill
)
# DecimalAIPlugin makes each invocation of runners built from this App one trace.
app = App(name="support", root_agent=agent, plugins=[DecimalAIPlugin()])Prefer ADK's own loader? SkillToolset(skills=decimalai.adk.skills(), ...) reads the same folder. Use one or the other: a skill delivered both ways reaches the prompt twice.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/nvidia-amc-run-rtsp-calibration/SKILL.mdfrom pathlib import Path
from google.adk.agents import LlmAgent
skill = Path(".agents/skills/nvidia-amc-run-rtsp-calibration/SKILL.md").read_text()
agent = LlmAgent(
name="support",
model="gemini-3.5-flash",
instruction=lambda context: f"You are a helpful agent.\n\n{skill}",
)This gets SKILL.md only. The skill's 1 other file is not included.
agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[pydantic-ai]"
decimalai skills add nvidia-amc-run-rtsp-calibrationfrom pydantic_ai import Agent
from decimalai.pydantic_ai import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = Agent(
"openai:gpt-4o-mini",
name=support.name,
tools=[], # your tools; the capability adds load_skill
capabilities=[support], # your prompt, the skill list and load_skill
)
# In a notebook or async code: result = await agent.run("Hello!")
result = agent.run_sync("Hello!")On the Pydantic AI harness, decimalai.pydantic_ai_harness.skills(project) uses its own loader instead.
The same install from Python, for a notebook or a setup script. agent_config() hands your agent the skill. With no DecimalAI key it reads your project's files and sends nothing. Needs SDK 0.27 or newer.
pip install "decimalai[pydantic-ai]"from decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("nvidia-amc-run-rtsp-calibration")
if result.exit_code:
raise SystemExit(result.problems)
from pydantic_ai import Agent
from decimalai.pydantic_ai import agent_config
# With no DECIMAL_API_KEY this reads the skills your project lists, from disk.
support = agent_config("support", fallback="You are a helpful agent.")
agent = Agent(
"openai:gpt-4o-mini",
name=support.name,
tools=[], # your tools; the capability adds load_skill
capabilities=[support], # your prompt, the skill list and load_skill
)
# In a notebook or async code: result = await agent.run("Hello!")
result = agent.run_sync("Hello!")On the Pydantic AI harness, decimalai.pydantic_ai_harness.skills(project) uses its own loader instead.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/nvidia-amc-run-rtsp-calibration/SKILL.mdfrom pathlib import Path
from pydantic_ai import Agent
skill = Path(".agents/skills/nvidia-amc-run-rtsp-calibration/SKILL.md").read_text()
agent = Agent("openai:gpt-4o-mini", instructions=f"You are a helpful agent.\n\n{skill}")
# In a notebook or async code: result = await agent.run("Hello!")
result = agent.run_sync("Hello!")This gets SKILL.md only. The skill's 1 other file is not included.
Deep Agents' own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" deepagents
decimalai skills add nvidia-amc-run-rtsp-calibrationimport decimalai.deepagents
from deepagents import create_deep_agent
agent = create_deep_agent(model=model, **decimalai.deepagents.skills())
agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})The default backend reads files but has no shell. To run a skill's scripts, pass skills(backend=LocalShellBackend(...)).
The same install from Python, for a notebook or a setup script. Deep Agents' own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" deepagentsfrom decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("nvidia-amc-run-rtsp-calibration")
if result.exit_code:
raise SystemExit(result.problems)
import decimalai.deepagents
from deepagents import create_deep_agent
agent = create_deep_agent(model=model, **decimalai.deepagents.skills())
agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})The default backend reads files but has no shell. To run a skill's scripts, pass skills(backend=LocalShellBackend(...)).
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/nvidia-amc-run-rtsp-calibration/SKILL.mdfrom pathlib import Path
from deepagents import create_deep_agent
skill = Path(".agents/skills/nvidia-amc-run-rtsp-calibration/SKILL.md").read_text()
agent = create_deep_agent(model=model, system_prompt=f"You are a helpful agent.\n\n{skill}")
agent.invoke({"messages": [{"role": "user", "content": "Hello!"}]})This gets SKILL.md only. The skill's 1 other file is not included.
Its own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" agent-framework
decimalai skills add nvidia-amc-run-rtsp-calibrationimport asyncio
from agent_framework import Agent
from decimalai.agent_framework import skills
agent = Agent(client=client, instructions="You are a helpful agent.", context_providers=[skills()])
asyncio.run(agent.run("Hello!"))It caches skills by default, so restart the process after decimalai skills update.
The same install from Python, for a notebook or a setup script. Its own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" agent-frameworkfrom decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("nvidia-amc-run-rtsp-calibration")
if result.exit_code:
raise SystemExit(result.problems)
import asyncio
from agent_framework import Agent
from decimalai.agent_framework import skills
agent = Agent(client=client, instructions="You are a helpful agent.", context_providers=[skills()])
asyncio.run(agent.run("Hello!"))It caches skills by default, so restart the process after decimalai skills update.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/nvidia-amc-run-rtsp-calibration/SKILL.mdimport asyncio
from pathlib import Path
from agent_framework import Agent
skill = Path(".agents/skills/nvidia-amc-run-rtsp-calibration/SKILL.md").read_text()
agent = Agent(client=client, instructions=f"You are a helpful agent.\n\n{skill}")
asyncio.run(agent.run("Hello!"))This gets SKILL.md only. The skill's 1 other file is not included.
Strands' own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" strands-agents
decimalai skills add nvidia-amc-run-rtsp-calibrationfrom decimalai.strands import skills
from strands import Agent
from strands.vended_tools import file_editor, shell
agent = Agent(
model=model, # always pass one: the default is Amazon Bedrock
system_prompt="You are a helpful agent.",
tools=[file_editor, shell],
plugins=[skills()],
)
agent("Hello!")Strands loads an agent's skills once, so build the agent again after decimalai skills update.
The same install from Python, for a notebook or a setup script. Strands' own skill loader reads the installed folder. No DecimalAI account needed.
pip install "decimalai>=0.16" strands-agentsfrom decimalai import skillpkg
# Writes .agents/skills and .decimal/skills.toml. Safe to run twice.
result = skillpkg.add("nvidia-amc-run-rtsp-calibration")
if result.exit_code:
raise SystemExit(result.problems)
from decimalai.strands import skills
from strands import Agent
from strands.vended_tools import file_editor, shell
agent = Agent(
model=model, # always pass one: the default is Amazon Bedrock
system_prompt="You are a helpful agent.",
tools=[file_editor, shell],
plugins=[skills()],
)
agent("Hello!")Strands loads an agent's skills once, so build the agent again after decimalai skills update.
No DecimalAI package. The whole skill goes in every prompt, and nothing pins or updates it.
.agents/skills/nvidia-amc-run-rtsp-calibration/SKILL.mdfrom pathlib import Path
from strands import Agent
skill = Path(".agents/skills/nvidia-amc-run-rtsp-calibration/SKILL.md").read_text()
agent = Agent(model=model, system_prompt=f"You are a helpful agent.\n\n{skill}")
agent("Hello!")This gets SKILL.md only. The skill's 1 other file is not included.
Adds every file the skill has, pinned so you can update it. Cursor, Copilot, Cline and Warp read this folder by themselves.
pip install "decimalai>=0.15"
decimalai skills add nvidia-amc-run-rtsp-calibrationNo Python or account. Cursor, Copilot, Cline and Warp read this folder by themselves.
curl -fsSL --create-dirs -o .agents/skills/nvidia-amc-run-rtsp-calibration/SKILL.md https://app.decimal.ai/s/nvidia-amc-run-rtsp-calibration/SKILL.md.agents/skills/nvidia-amc-run-rtsp-calibration/SKILL.mdThis gets SKILL.md only. The skill's 1 other file is not included.
Give its text to your model as instructions. No account or package needed.
This gets SKILL.md only. The skill's 1 other file is not included.
Raw files: /s/nvidia-amc-run-rtsp-calibration/SKILL.md · /s/nvidia-amc-run-rtsp-calibration.json
Fetch the file and give its text to your model as instructions. No account or package needed.
curl -fsSL https://app.decimal.ai/s/nvidia-amc-run-rtsp-calibration/SKILL.mdcurl -fsSL https://app.decimal.ai/s/nvidia-amc-run-rtsp-calibration.jsonThis gets SKILL.md only. The skill's 1 other file is not included.
You don't need a DecimalAI account.
Saved prompts and skills, pinned versions, and traces of this skill in your runs. DecimalAI does not run your agent.
Claude Code reads files from your project, so DecimalAI config does not apply there.
On Claude Agent SDK: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On OpenAI Agents: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On OpenAI SDK: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On Anthropic: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On Gemini API: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On LangChain: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On CrewAI: set DECIMAL_API_KEY and add decimalai.init(crewai=True) to record runs and skill use. The skill version stays in your repo.
On Google ADK: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On Pydantic AI: save the skill to an agent here, set DECIMAL_API_KEY, and the same code uses it with no command to run. Changes you save reach the next run with no redeploy.
On Deep Agents: set DECIMAL_API_KEY and add decimalai.init(langchain=True) to record runs and skill use. The skill version stays in your repo.
On Microsoft Agent Framework: set DECIMAL_API_KEY and add decimalai.init(otel=True, agent_name="support") to record runs and skill use. The skill version stays in your repo.
On Strands: set DECIMAL_API_KEY and add decimalai.init(otel=True, agent_name="support") to record runs and skill use. The skill version stays in your repo.
Editors read files from your project, so DecimalAI config does not apply there.
Anywhere else: record a use with decimalai.log_skill_activation() inside a trace.
Activate this skill when the user wants to calibrate from live RTSP camera streams. Typical prompts:
rtsp://... URLsVIOS records fixed-duration clips from each stream, the AMC microservice ingests those clips into a project, then the workflow follows the same verification, calibration, polling, and results path as pre-recorded MP4 calibration.
Do not use this skill for local MP4 files already on disk; route those requests to skills/amc-run-video-calibration/SKILL.md. Do not use it for the bundled sample dataset; route that to skills/amc-run-sample-calibration/SKILL.md.
Never reuse files from the bundled sample dataset, extracted sample zip, assets/, or previous projects for RTSP calibration unless the user explicitly provides those paths for this RTSP scene. Similar camera names, stream counts, or cam_00/cam_01 ordering are not evidence that sample alignment, layout, GT, or detector settings apply.
skills/amc-setup-calibration-stack/SKILL.md if needed).VIOS_BASE_URL is configured in the AMC microservice environment before capture starts.requests installed when using the bundled script.RTSP URLs may contain usernames, passwords, hostnames, or network topology. Do not print full RTSP URLs if credentials are embedded. Pass VIOS tokens through environment variables or secure host prompts; do not echo tokens in chat, logs, or final answers.
cam_00, cam_01, ... if the user does not provide names.60; prefer 120-180 or more when the scene has sparse motion.http://<HOST_IP>:8000 or http://<HOST_IP>:8000/v1./data/my_rtsp_calib/;If the user does not provide a local asset source, stop and ask whether they want to provide a path or use UI upload. Give the UI link as http://<HOST_IP>:<AUTO_MAGIC_CALIB_UI_PORT>; the default UI port is 5000.
RTSP clips are recorded by VIOS, so there is no local videos directory to anchor file discovery. Only scan a directory the user explicitly provided for this RTSP scene. If the user provides a settings file path, use that file's directory as the scan directory. If the user provides a calibration asset directory, scan only that directory. Otherwise ask this question before planning uploads or calibration:
Do you have a local calibration asset directory or settings file for these RTSP streams, or should you upload/tune settings and alignment in the AMC UI at
http://<HOST_IP>:<AUTO_MAGIC_CALIB_UI_PORT>?
| File | Candidate filenames | UI fallback |
|---|---|---|
| Calibration settings | Explicit user path, or settings.json, config.json, or calibration_config.json in the user-provided asset directory | UI Step 3: Parameters |
| Alignment JSON | Explicit user path, or alignment_data.json in the user-provided asset directory/settings directory | UI Step 4: Alignment |
| Layout PNG | Explicit user path, or layout.png in the user-provided asset directory/settings directory | UI Step 4: Alignment |
| Ground truth zip | Optional explicit user path, or GT.zip/gt.zip in the user-provided asset directory | Omit metrics |
Posting the settings file replaces UI Step 3 and may pin detector or detector_type. If it pins resnet or transformer, pass that same detector to /calibrate. If no settings file pins a detector, ask the user which detector to use; do not silently default to resnet.
sensor_id per stream if the cameras are already registered in VIOS. Leave unset for auto-registration.GT.zip) for evaluation metrics.vggt_state == "READY".The bundled script in scripts/run_rtsp_calibration.py implements this sequence end to end. Use the prose below for decisions, UI fallback, and troubleshooting.
Confirm the AMC microservice is reachable:
curl -sf http://<HOST_IP>:<MS_PORT>/v1/ready
Confirm VIOS is reachable before starting capture. Probe in this order and stop at the first working URL:
: "${REPO_ROOT:?set REPO_ROOT to the auto-magic-calib checkout. Run amc-setup-calibration-stack Step 0b first.}"
grep -q "AutoMagicCalib" "$REPO_ROOT/README.md" 2>/dev/null && grep -q "auto-magic-calib-ms" "$REPO_ROOT/compose/ms/compose.yml" 2>/dev/null || { echo "ERROR: REPO_ROOT is not an auto-magic-calib checkout: $REPO_ROOT" >&2; exit 1; }
VIOS_BASE_URL=""
# Default local VIOS port.
if curl -sf http://localhost:30888/vst/api/v1/sensor/list >/dev/null 2>&1; then
HOST_IP=$(grep ^HOST_IP "$REPO_ROOT/compose/.env" 2>/dev/null | cut -d= -f2)
VIOS_BASE_URL="http://${HOST_IP:-localhost}:30888"
echo "VIOS detected at $VIOS_BASE_URL"
fi
# Running AMC microservice container environment.
if [ -z "$VIOS_BASE_URL" ]; then
VIOS_BASE_URL=$(docker exec auto-magic-calib-ms-1 printenv VIOS_BASE_URL 2>/dev/null)
fi
# Compose environment file.
if [ -z "$VIOS_BASE_URL" ]; then
VIOS_BASE_URL=$(grep ^VIOS_BASE_URL "$REPO_ROOT/compose/.env" 2>/dev/null | cut -d= -f2-)
fi
if [ -n "$VIOS_BASE_URL" ]; then
curl -sf "${VIOS_BASE_URL}/vst/api/v1/sensor/list" >/dev/null \
&& echo "VIOS up at $VIOS_BASE_URL" \
|| { echo "VIOS_BASE_URL=$VIOS_BASE_URL is set but not responding"; VIOS_BASE_URL=""; }
fi
If VIOS is not reachable, ask the user to deploy VIOS and provide the base URL. Do not start RTSP capture until ${VIOS_BASE_URL}/vst/api/v1/sensor/list returns 200.
If VIOS is reachable but the AMC microservice is missing VIOS_BASE_URL, do not edit checked-in compose files. Export the variable and relaunch the microservice with a temporary compose override:
cd "$REPO_ROOT/compose"
export VIOS_BASE_URL="http://<VIOS_HOST>:30888"
OVERRIDE_FILE="${TMPDIR:-/tmp}/amc-vios.override.yml"
cat > "$OVERRIDE_FILE" <<'YAML'
services:
auto-magic-calib-ms:
environment:
- VIOS_BASE_URL=${VIOS_BASE_URL}
YAML
docker compose -f compose.yml -f "$OVERRIDE_FILE" up -d auto-magic-calib-ms
docker exec auto-magic-calib-ms-1 printenv VIOS_BASE_URL
A host-shell export alone is not enough after the container is already running; the microservice process must be restarted with VIOS_BASE_URL in its environment.
POST /v1/create_project with form field project_name. Save the returned project_id.
POST /v1/rtsp/capture/<project_id>
Content-Type: application/json
{
"streams": [
{"rtsp_url": "rtsp://...", "camera_name": "cam_00", "sensor_id": null},
{"rtsp_url": "rtsp://...", "camera_name": "cam_01", "sensor_id": null}
],
"duration_seconds": 180,
"vios_token": null,
"ssl_verify": false
}
The response can nest session fields under session:
{"code": 0, "message": "...", "session": {"session_id": "...", "status": "STARTING"}}
Save session.session_id.
Poll every 10 seconds:
GET /v1/rtsp/capture/<project_id>/<session_id>
Session lifecycle:
STARTING -> RECORDING -> COMPLETED -> INGESTING -> INGESTED
-> ERROR
RECORDING -> CANCELLED
When capture reaches COMPLETED, ingest the recorded clips into the AMC project:
POST /v1/rtsp/capture/<project_id>/<session_id>/ingest
After ingest succeeds, the project has video files attached and the rest of the workflow matches the MP4 upload path.
Need to stop early: POST /v1/rtsp/capture/<project_id>/<session_id>/stop. A partial clip can still be ingested if VIOS produced one.
Other session endpoints:
GET /v1/rtsp/sessions/<project_id> - list sessions for a project.DELETE /v1/rtsp/session/<project_id>/<session_id> - delete a session record.Resolve local files using the anchor-file pattern above. Upload resolved files:
| File | Endpoint | Notes |
|---|---|---|
| Calibration settings | POST /v1/config/<project_id> | JSON body posted as-is; replaces UI Step 3 |
| Alignment JSON | POST /v1/upload_alignment/<project_id> | Multipart alignment_file |
| Layout PNG | POST /v1/upload_layout/<project_id> | Multipart layout_file |
| Ground truth zip | POST /v1/upload_gt_file/<project_id> | Optional |
| Focal lengths | POST /v1/upload_focal_length/<project_id> | Optional repeated focal_length values |
Use only files from explicit user-provided paths or a user-provided calibration asset directory. Do not extract or scan sample data to find fallback settings, alignment, layout, or GT.
If settings are missing, direct the user to UI Step 3: Parameters at http://<HOST_IP>:<AUTO_MAGIC_CALIB_UI_PORT>, then ask which detector to use (resnet or transformer) before calibration. If alignment or layout is missing, direct the user to UI Step 4: Alignment for this project. For RTSP projects, videos are already ingested; do not re-upload videos in the UI fallback.
Before continuing after UI Step 4, verify:
PROJECT_ID=<project_id>
: "${REPO_ROOT:?set REPO_ROOT to the auto-magic-calib checkout. Run amc-setup-calibration-stack Step 0b first.}"
grep -q "AutoMagicCalib" "$REPO_ROOT/README.md" 2>/dev/null && grep -q "auto-magic-calib-ms" "$REPO_ROOT/compose/ms/compose.yml" 2>/dev/null || { echo "ERROR: REPO_ROOT is not an auto-magic-calib checkout: $REPO_ROOT" >&2; exit 1; }
PROJECT_DIR_REL=$(grep ^PROJECT_DIR "$REPO_ROOT/compose/.env" 2>/dev/null | cut -d= -f2 | tr -d '[:space:]')
HOST_PROJECTS=$(cd "$REPO_ROOT/compose" && realpath "${PROJECT_DIR_REL:-../../projects}")
ls "$HOST_PROJECTS/project_${PROJECT_ID}/manual_adjustment/"
# Expected: alignment_data.json, layout.png
Verify:
POST /v1/verify_project/<project_id>
The project must return project_state == "READY".
Confirm the plan before calibrating. Summarize:
resnet or transformer.Start calibration:
POST /v1/calibrate/<project_id>
Content-Type: application/json
{"detector_type": "<resnet-or-transformer>"}
Poll:
GET /v1/get_project_info/<project_id>
Stop on COMPLETED or ERROR. On error, fetch GET /v1/amc/calibrate/<project_id>/log.
Fetch results:
GET /v1/result/<project_id>/evaluation_statistics
Only expect evaluation statistics when GT was uploaded.
After AMC calibration completes, read project_info.vggt_state from GET /v1/get_project_info/<project_id>.
vggt_state == "READY", ask whether to run VGGT refinement.POST /v1/vggt/calibrate/<project_id>, poll vggt_state, then fetch GET /v1/vggt_results/<project_id>/evaluation_statistics.Use the bundled script from the amc-run-rtsp-calibration skill package, not from the auto-magic-calib repo root. If the user points the agent at this skill folder directly instead of installing it, set AMC_RTSP_SKILL_DIR to the directory containing this SKILL.md, or run the command from that directory.
Common environment variables:
export BASE_URL=http://<HOST_IP>:8000
export PROJECT_NAME=rtsp_calibration_run
export RTSP_URLS='rtsp://user:pass@cam0/stream,rtsp://user:pass@cam1/stream'
export CAMERA_NAMES='cam_00,cam_01'
export DURATION_SECONDS=180
export VIOS_BASE_URL=http://<VIOS_HOST>:30888
export CALIB_ASSET_DIR=/path/to/rtsp-calibration-assets
# Or provide explicit CONFIG_FILE, ALIGNMENT_JSON, LAYOUT_PNG, and optional GT_ZIP.
export DETECTOR_TYPE=transformer # Required when settings do not set detector/detector_type.
export AMC_UI_URL=http://<HOST_IP>:5000
export RUN_VGGT=false
# Optional but recommended: REPO_ROOT points to the auto-magic-calib checkout.
# PROJECTS_DIR can be set explicitly when project outputs live elsewhere.
if [ -z "${DEEPSTREAM_REPO_ROOT:-}" ] && [ -n "${REPO_ROOT:-}" ] && [ -d "$REPO_ROOT/../../skills/amc-run-rtsp-calibration" ]; then
DEEPSTREAM_REPO_ROOT="$(cd "$REPO_ROOT/../.." && pwd)"
fi
SCRIPT_PATH=""
for candidate in \
"${AMC_RTSP_SKILL_DIR:+$AMC_RTSP_SKILL_DIR/scripts/run_rtsp_calibration.py}" \
"$PWD/scripts/run_rtsp_calibration.py" \
"${DEEPSTREAM_REPO_ROOT:+$DEEPSTREAM_REPO_ROOT/skills/amc-run-rtsp-calibration/scripts/run_rtsp_calibration.py}" \
"$PWD/skills/amc-run-rtsp-calibration/scripts/run_rtsp_calibration.py" \
"$HOME/.claude/skills/amc-run-rtsp-calibration/scripts/run_rtsp_calibration.py" \
"$HOME/.codex/skills/amc-run-rtsp-calibration/scripts/run_rtsp_calibration.py" \
"$HOME/.cursor/skills/amc-run-rtsp-calibration/scripts/run_rtsp_calibration.py"; do
if [ -f "$candidate" ]; then
SCRIPT_PATH="$candidate"
break
fi
done
[ -n "$SCRIPT_PATH" ] || {
echo "ERROR: could not find amc-run-rtsp-calibration/scripts/run_rtsp_calibration.py" >&2
echo "Set AMC_RTSP_SKILL_DIR to the amc-run-rtsp-calibration skill directory, or run this block from that directory." >&2
exit 1
}
python3 "$SCRIPT_PATH"
Alternative stream input:
export STREAMS_JSON='[
{"rtsp_url":"rtsp://cam0/stream","camera_name":"cam_00","sensor_id":null},
{"rtsp_url":"rtsp://cam1/stream","camera_name":"cam_01","sensor_id":null}
]'
Optional env vars are CALIB_ASSET_DIR, CONFIG_FILE, ALIGNMENT_JSON, LAYOUT_PNG, GT_ZIP, FOCAL_LENGTHS, DETECTOR_TYPE, AMC_UI_URL, VIOS_TOKEN, SSL_VERIFY, RUN_VGGT, REPO_ROOT, and PROJECTS_DIR.
COMPLETED.verify_project returns READY.project_state == "COMPLETED".Results persist on the AMC server under:
projects/project_<project_id>/
|-- manual_adjustment/
| |-- alignment_data.json
| `-- layout.png
|-- output/
| |-- single_view_results/cam_XX/
| | |-- camInfo_hyper_XX.yaml
| | `-- trajDump_Stream_0_3d.txt
| `-- multi_view_results/BA_output/results_ba/
| |-- initial/camInfo_XX.yaml
| `-- refined/camInfo_XX.yaml
`-- calibration.log
| Issue | Fix |
|---|---|
VIOS /vst/api/v1/sensor/list returns connection refused | VIOS is not running or not reachable from this host. Ask the user to deploy VIOS or provide the reachable base URL. |
| Capture endpoint returns 503 or "VIOS not configured" | Export VIOS_BASE_URL, relaunch the microservice with the temporary compose override from Step 0, then retry capture. |
Session stuck in STARTING | VIOS accepted the request but sensors may not be online. Check ${VIOS_BASE_URL}/vst/api/v1/sensor/list and wait 20-30 seconds after sensor restarts. |
Session stuck in RECORDING past duration_seconds | Call POST /v1/rtsp/capture/<project_id>/<session_id>/stop, then ingest the partial clip if available. |
| Ingest fails with "No clip available" | The recording window may not overlap the VIOS timeline. Wait for sensors to become online, then start a new capture. |
| 400 "empty streams" | Pass at least one stream object with rtsp_url and camera_name. |
| 400 "duration too short" | Use duration_seconds >= 60. |
404 on /v1/rtsp/capture/<project_id> | Create the project first with /v1/create_project. |
verify_project is not READY after ingest | Check project info and confirm expected videos, alignment, and layout are attached. |
Calibration reaches ERROR | Fetch GET /v1/amc/calibrate/<project_id>/log; common causes are insufficient tracklets, static scenes, or incorrect alignment. |
skills/amc-setup-calibration-stack/SKILL.md - start AMC microservice and UI first.skills/amc-run-video-calibration/SKILL.md - calibrate from local pre-recorded MP4 files.skills/amc-run-sample-calibration/SKILL.md - verify the stack with the bundled sample dataset.Automatically, when a task matches. Use when the user provides RTSP URLs or asks to calibrate live cameras; VIOS records clips, AMC ingests them, then runs calibration.
Skills that do similar work, with their headline benchmark lift.
From the same source and nearby in the catalogue.