mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-07 02:59:05 +00:00
test(anthropic): send the full 24-tool Claude Code request and pin upstream headers
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
4356a00b5f
commit
90c8f22174
2 changed files with 428 additions and 51 deletions
|
|
@ -51,55 +51,6 @@ def field(description: str, **extra: JsonValue) -> dict[str, JsonValue]:
|
|||
def tools() -> tuple[dict[str, JsonValue], ...]:
|
||||
_MAX: Final = 9007199254740991
|
||||
return (
|
||||
{
|
||||
"name": "Bash",
|
||||
"description": "Executes a given bash command and returns its output.",
|
||||
"input_schema": schema(
|
||||
{
|
||||
"command": field("The command to execute", type="string"),
|
||||
"timeout": field("Optional timeout in milliseconds (max 600000)", type="number"),
|
||||
"description": field(
|
||||
"Clear, concise description of what this command does in active voice.", type="string"
|
||||
),
|
||||
"run_in_background": field("Set to true to run this command in the background.", type="boolean"),
|
||||
"dangerouslyDisableSandbox": field(
|
||||
"Set this to true to dangerously override sandbox mode and run commands without sandboxing.",
|
||||
type="boolean",
|
||||
),
|
||||
},
|
||||
("command",),
|
||||
),
|
||||
},
|
||||
{
|
||||
"name": "Read",
|
||||
"description": "Reads a file from the local filesystem.",
|
||||
"input_schema": schema(
|
||||
{
|
||||
"file_path": field("The absolute path to the file to read", type="string"),
|
||||
"offset": field("The line number to start reading from.", type="integer", minimum=0, maximum=_MAX),
|
||||
"limit": field("The number of lines to read.", type="integer", exclusiveMinimum=0, maximum=_MAX),
|
||||
"pages": field('Page range for PDF files (e.g., "1-5", "3", "10-20").', type="string"),
|
||||
},
|
||||
("file_path",),
|
||||
),
|
||||
},
|
||||
{
|
||||
"name": "Edit",
|
||||
"description": "Performs exact string replacements in files.",
|
||||
"input_schema": schema(
|
||||
{
|
||||
"file_path": field("The absolute path to the file to modify", type="string"),
|
||||
"old_string": field("The text to replace", type="string"),
|
||||
"new_string": field(
|
||||
"The text to replace it with (must be different from old_string)", type="string"
|
||||
),
|
||||
"replace_all": field(
|
||||
"Replace all occurrences of old_string (default false)", default=False, type="boolean"
|
||||
),
|
||||
},
|
||||
("file_path", "old_string", "new_string"),
|
||||
),
|
||||
},
|
||||
{
|
||||
"name": "Agent",
|
||||
"description": "Launch a new agent to handle complex, multi-step tasks.",
|
||||
|
|
@ -122,6 +73,429 @@ def tools() -> tuple[dict[str, JsonValue], ...]:
|
|||
("description", "prompt"),
|
||||
),
|
||||
},
|
||||
{
|
||||
"name": "Bash",
|
||||
"description": "Executes a given bash command and returns its output.",
|
||||
"input_schema": schema(
|
||||
{
|
||||
"command": field("The command to execute", type="string"),
|
||||
"timeout": field("Optional timeout in milliseconds (max 600000)", type="number"),
|
||||
"description": field(
|
||||
"Clear, concise description of what this command does in active voice.",
|
||||
type="string",
|
||||
),
|
||||
"run_in_background": field("Set to true to run this command in the background.", type="boolean"),
|
||||
"dangerouslyDisableSandbox": field(
|
||||
"Set this to true to dangerously override sandbox mode and run commands without sandboxing.",
|
||||
type="boolean",
|
||||
),
|
||||
},
|
||||
("command",),
|
||||
),
|
||||
},
|
||||
{
|
||||
"name": "CronCreate",
|
||||
"description": "Schedule a prompt to be enqueued at a future time.",
|
||||
"input_schema": schema(
|
||||
{
|
||||
"cron": field(
|
||||
'Standard 5-field cron expression in local time: "M H DoM Mon DoW" (e.g.',
|
||||
type="string",
|
||||
),
|
||||
"prompt": field("The prompt to enqueue at each fire time.", type="string"),
|
||||
"recurring": field(
|
||||
"true (default) = fire on every cron match until deleted or auto-expired after 7 days.",
|
||||
type="boolean",
|
||||
),
|
||||
"durable": field(
|
||||
"true = persist to .claude/scheduled_tasks.json and survive restarts.",
|
||||
type="boolean",
|
||||
),
|
||||
},
|
||||
("cron", "prompt"),
|
||||
),
|
||||
},
|
||||
{
|
||||
"name": "CronDelete",
|
||||
"description": "Cancel a cron job previously scheduled with CronCreate.",
|
||||
"input_schema": schema(
|
||||
{
|
||||
"id": field("Job ID returned by CronCreate.", type="string"),
|
||||
},
|
||||
("id",),
|
||||
),
|
||||
},
|
||||
{
|
||||
"name": "CronList",
|
||||
"description": "List all cron jobs scheduled via CronCreate, both durable (.claude/scheduled_tasks.json) and session-only.",
|
||||
"input_schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": False,
|
||||
},
|
||||
},
|
||||
{
|
||||
"name": "Edit",
|
||||
"description": "Performs exact string replacements in files.",
|
||||
"input_schema": schema(
|
||||
{
|
||||
"file_path": field("The absolute path to the file to modify", type="string"),
|
||||
"old_string": field("The text to replace", type="string"),
|
||||
"new_string": field("The text to replace it with (must be different from old_string)", type="string"),
|
||||
"replace_all": field(
|
||||
"Replace all occurrences of old_string (default false)",
|
||||
default=False,
|
||||
type="boolean",
|
||||
),
|
||||
},
|
||||
("file_path", "old_string", "new_string"),
|
||||
),
|
||||
},
|
||||
{
|
||||
"name": "EnterWorktree",
|
||||
"description": "Use this tool ONLY when explicitly instructed to work in a worktree — either by the user directly, or by project instruc",
|
||||
"input_schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": field("Optional name for a new worktree.", type="string"),
|
||||
"path": field(
|
||||
"Path to an existing worktree to switch into instead of creating a new one.",
|
||||
type="string",
|
||||
),
|
||||
},
|
||||
"additionalProperties": False,
|
||||
},
|
||||
},
|
||||
{
|
||||
"name": "ExitWorktree",
|
||||
"description": "Exit a worktree session created by EnterWorktree and return the session to the original working directory.",
|
||||
"input_schema": schema(
|
||||
{
|
||||
"action": field(
|
||||
'"keep" leaves the worktree and branch on disk; "remove" deletes both.',
|
||||
type="string",
|
||||
enum=["keep", "remove"],
|
||||
),
|
||||
"discard_changes": field(
|
||||
'Required true when action is "remove" and the worktree has uncommitted files or unmerged commits.',
|
||||
type="boolean",
|
||||
),
|
||||
},
|
||||
("action",),
|
||||
),
|
||||
},
|
||||
{
|
||||
"name": "ListAgents",
|
||||
"description": "Lists agents you can SendMessage to — in-process subagents you spawned, the teammates on your team, other local Claude s",
|
||||
"input_schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"channel": field("Not available in this build; leave unset.", type="string", maxLength=256),
|
||||
"q": field("Not available in this build; leave unset.", type="string", maxLength=256),
|
||||
},
|
||||
"additionalProperties": False,
|
||||
},
|
||||
},
|
||||
{
|
||||
"name": "NotebookEdit",
|
||||
"description": "Replaces, inserts, or deletes a single cell in a Jupyter notebook (.ipynb file).",
|
||||
"input_schema": schema(
|
||||
{
|
||||
"notebook_path": field(
|
||||
"The absolute path to the Jupyter notebook file to edit (must be absolute, not relative)",
|
||||
type="string",
|
||||
),
|
||||
"cell_id": field("The ID of the cell to edit.", type="string"),
|
||||
"new_source": field("The new source for the cell", type="string"),
|
||||
"cell_type": field(
|
||||
"The type of the cell (code or markdown).",
|
||||
type="string",
|
||||
enum=["code", "markdown"],
|
||||
),
|
||||
"edit_mode": field(
|
||||
"The type of edit to make (replace, insert, delete).",
|
||||
type="string",
|
||||
enum=["replace", "insert", "delete"],
|
||||
),
|
||||
},
|
||||
("notebook_path", "new_source"),
|
||||
),
|
||||
},
|
||||
{
|
||||
"name": "Read",
|
||||
"description": "Reads a file from the local filesystem.",
|
||||
"input_schema": schema(
|
||||
{
|
||||
"file_path": field("The absolute path to the file to read", type="string"),
|
||||
"offset": field("The line number to start reading from.", type="integer", minimum=0, maximum=_MAX),
|
||||
"limit": field(
|
||||
"The number of lines to read.",
|
||||
type="integer",
|
||||
exclusiveMinimum=0,
|
||||
maximum=_MAX,
|
||||
),
|
||||
"pages": field('Page range for PDF files (e.g., "1-5", "3", "10-20").', type="string"),
|
||||
},
|
||||
("file_path",),
|
||||
),
|
||||
},
|
||||
{
|
||||
"name": "ReportFindings",
|
||||
"description": "Report code-review findings as a typed list so the host UI can render them.",
|
||||
"input_schema": schema(
|
||||
{
|
||||
"level": field(
|
||||
"Effort level the review ran at",
|
||||
type="string",
|
||||
enum=["low", "medium", "high", "xhigh", "max"],
|
||||
),
|
||||
"findings": field(
|
||||
"Verified findings, most-severe first; empty if none survived",
|
||||
maxItems=32,
|
||||
type="array",
|
||||
items={
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"file": field("Repo-relative path of the file the finding is in", type="string"),
|
||||
"line": field(
|
||||
"1-indexed line the finding anchors to",
|
||||
type="integer",
|
||||
minimum=-_MAX,
|
||||
maximum=_MAX,
|
||||
),
|
||||
"summary": field("One-sentence statement of the defect", type="string"),
|
||||
"short_summary": field(
|
||||
"Compressed label for compact UI (≤60 chars): the claim alone, no rationale or consequence clause",
|
||||
type="string",
|
||||
maxLength=60,
|
||||
),
|
||||
"failure_scenario": field("Concrete inputs/state → wrong output/crash", type="string"),
|
||||
"category": field(
|
||||
"Short kebab-case slug of the finding type, e.g.",
|
||||
type="string",
|
||||
maxLength=40,
|
||||
),
|
||||
"verdict": field(
|
||||
"Set when a verify pass ran; absent on inline-only reviews",
|
||||
type="string",
|
||||
enum=["CONFIRMED", "PLAUSIBLE"],
|
||||
),
|
||||
"outcome": field(
|
||||
"Set ONLY when re-reporting after applying fixes: what happened to this finding",
|
||||
type="string",
|
||||
enum=["fixed", "skipped", "no_change_needed"],
|
||||
),
|
||||
},
|
||||
"required": ["file", "summary", "failure_scenario"],
|
||||
"additionalProperties": False,
|
||||
},
|
||||
),
|
||||
},
|
||||
("findings",),
|
||||
),
|
||||
},
|
||||
{
|
||||
"name": "ScheduleWakeup",
|
||||
"description": "Schedule when to resume work in /loop dynamic mode — the user invoked /loop without an interval, asking you to self-pace",
|
||||
"input_schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"delaySeconds": field("Seconds from now to wake up.", type="number"),
|
||||
"reason": field("One short sentence explaining the chosen delay.", type="string"),
|
||||
"prompt": field("The /loop input to fire on wake-up.", type="string"),
|
||||
"stop": field(
|
||||
"Set to true to end the dynamic loop immediately instead of scheduling another wakeup.",
|
||||
type="boolean",
|
||||
),
|
||||
"noop": field(
|
||||
"true = nothing changed (you checked and there is nothing to report).",
|
||||
type="boolean",
|
||||
),
|
||||
},
|
||||
"additionalProperties": False,
|
||||
},
|
||||
},
|
||||
{
|
||||
"name": "SendMessage",
|
||||
"description": "# SendMessage\n\nSend a message to another agent.",
|
||||
"input_schema": schema(
|
||||
{
|
||||
"to": field(
|
||||
'Recipient: a name from ListAgents (append its " [ref]" only when a listing or an error shows one), a teammate name, "mai',
|
||||
type="string",
|
||||
allOf=[{"pattern": "^[^\\n\\r]*$"}, {"pattern": "^[\\s\\S]{0,300}$"}],
|
||||
),
|
||||
"summary": field(
|
||||
"A 5-10 word label for your own transcript row (not transmitted — the recipient previews the first line of `message`).",
|
||||
type="string",
|
||||
maxLength=200,
|
||||
),
|
||||
"message": field("Plain text message content.", default="", type="string"),
|
||||
"notify_when_idle": field(
|
||||
"Ask a session ON THIS MACHINE to send you ONE notice when it next goes idle (finishes its turn with nothing queued) or e",
|
||||
type="boolean",
|
||||
),
|
||||
},
|
||||
("to", "message"),
|
||||
),
|
||||
},
|
||||
{
|
||||
"name": "Skill",
|
||||
"description": "Invoke a skill.",
|
||||
"input_schema": schema(
|
||||
{
|
||||
"skill": field("The name of a skill from the available-skills list.", type="string"),
|
||||
"args": field("Optional arguments for the skill", type="string"),
|
||||
},
|
||||
("skill",),
|
||||
),
|
||||
},
|
||||
{
|
||||
"name": "TaskCreate",
|
||||
"description": "Use this tool to create a structured task list for your current coding session.",
|
||||
"input_schema": schema(
|
||||
{
|
||||
"subject": field("A brief title for the task", type="string"),
|
||||
"description": field("What needs to be done", type="string"),
|
||||
"activeForm": field(
|
||||
'Present continuous form shown in spinner when in_progress (e.g., "Running tests")',
|
||||
type="string",
|
||||
),
|
||||
"metadata": field(
|
||||
"Arbitrary metadata to attach to the task",
|
||||
type="object",
|
||||
propertyNames={"type": "string"},
|
||||
additionalProperties={},
|
||||
),
|
||||
},
|
||||
("subject", "description"),
|
||||
),
|
||||
},
|
||||
{
|
||||
"name": "TaskGet",
|
||||
"description": "Use this tool to retrieve a task by its ID from the task list.",
|
||||
"input_schema": schema(
|
||||
{
|
||||
"taskId": field("The ID of the task to retrieve", type="string"),
|
||||
},
|
||||
("taskId",),
|
||||
),
|
||||
},
|
||||
{
|
||||
"name": "TaskList",
|
||||
"description": "Use this tool to list all tasks in the task list.",
|
||||
"input_schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": False,
|
||||
},
|
||||
},
|
||||
{
|
||||
"name": "TaskStop",
|
||||
"description": "- Stops a running background task by its ID\n- Takes a task_id parameter identifying the task to stop\n- To stop an agent-",
|
||||
"input_schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"task_id": field("The ID of the background task to stop.", type="string"),
|
||||
"shell_id": field("Deprecated: use task_id instead", type="string"),
|
||||
},
|
||||
"additionalProperties": False,
|
||||
},
|
||||
},
|
||||
{
|
||||
"name": "TaskUpdate",
|
||||
"description": "Use this tool to update a task in the task list.",
|
||||
"input_schema": schema(
|
||||
{
|
||||
"taskId": field("The ID of the task to update", type="string"),
|
||||
"subject": field("New subject for the task", type="string"),
|
||||
"description": field("New description for the task", type="string"),
|
||||
"activeForm": field(
|
||||
'Present continuous form shown in spinner when in_progress (e.g., "Running tests")',
|
||||
type="string",
|
||||
),
|
||||
"status": field(
|
||||
"New status for the task",
|
||||
anyOf=[
|
||||
{"type": "string", "enum": ["pending", "in_progress", "completed"]},
|
||||
{"type": "string", "const": "deleted"},
|
||||
],
|
||||
),
|
||||
"addBlocks": field("Task IDs that this task blocks", type="array", items={"type": "string"}),
|
||||
"addBlockedBy": field("Task IDs that block this task", type="array", items={"type": "string"}),
|
||||
"owner": field("New owner for the task", type="string"),
|
||||
"metadata": field(
|
||||
"Metadata keys to merge into the task.",
|
||||
type="object",
|
||||
propertyNames={"type": "string"},
|
||||
additionalProperties={},
|
||||
),
|
||||
},
|
||||
("taskId",),
|
||||
),
|
||||
},
|
||||
{
|
||||
"name": "WebFetch",
|
||||
"description": "IMPORTANT: WebFetch WILL FAIL for authenticated or private URLs.",
|
||||
"input_schema": schema(
|
||||
{
|
||||
"url": field("The URL to fetch content from", type="string", format="uri"),
|
||||
"prompt": field("The prompt to run on the fetched content", type="string"),
|
||||
},
|
||||
("url", "prompt"),
|
||||
),
|
||||
},
|
||||
{
|
||||
"name": "WebSearch",
|
||||
"description": "- Allows Claude to search the web and use the results to inform responses\n- Provides up-to-date information for current ",
|
||||
"input_schema": schema(
|
||||
{
|
||||
"query": field("The search query to use", type="string", minLength=2),
|
||||
"allowed_domains": field("Only include search results from these domains", type="array", items={"type": "string"}),
|
||||
"blocked_domains": field("Never include search results from these domains", type="array", items={"type": "string"}),
|
||||
},
|
||||
("query",),
|
||||
),
|
||||
},
|
||||
{
|
||||
"name": "Workflow",
|
||||
"description": "Execute a workflow script that orchestrates multiple subagents deterministically.",
|
||||
"input_schema": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"script": field("Self-contained workflow script.", type="string", maxLength=524288),
|
||||
"name": field("Name of a predefined workflow (built-in or from .claude/workflows/).", type="string"),
|
||||
"description": field("Ignored — set the workflow description in the script's `meta` block.", type="string"),
|
||||
"title": field("Ignored — set the workflow title in the script's `meta` block.", type="string"),
|
||||
"args": field("Optional input value exposed to the script as the global `args`, verbatim."),
|
||||
"scriptPath": field("Path to a workflow script file on disk.", type="string"),
|
||||
"resumeFromRunId": field(
|
||||
"Run ID of a prior Workflow invocation to resume from.",
|
||||
type="string",
|
||||
pattern="^wf_[a-z0-9-]{6,}$",
|
||||
),
|
||||
},
|
||||
"additionalProperties": False,
|
||||
},
|
||||
},
|
||||
{
|
||||
"name": "Write",
|
||||
"description": "Writes a file to the local filesystem.",
|
||||
"input_schema": schema(
|
||||
{
|
||||
"file_path": field("The absolute path to the file to write (must be absolute, not relative)", type="string"),
|
||||
"content": field("The content to write to the file", type="string"),
|
||||
},
|
||||
("file_path", "content"),
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -19,8 +19,11 @@ def test_claude_code_streaming_request_reaches_anthropic_intact_and_streams_back
|
|||
assert request.target == "/v1/messages", request.target
|
||||
assert request.headers["x-api-key"] == cc.ANTHROPIC_API_KEY
|
||||
assert request.headers["anthropic-version"] == "2023-06-01"
|
||||
upstream_beta: Final = frozenset(request.headers.get("anthropic-beta", "").split(","))
|
||||
assert cli_beta <= upstream_beta, request.headers.get("anthropic-beta")
|
||||
assert frozenset(request.headers.get("anthropic-beta", "").split(",")) == cli_beta, request.headers.get(
|
||||
"anthropic-beta"
|
||||
)
|
||||
assert "authorization" not in request.headers, dict(request.headers)
|
||||
assert all(gateway.key not in value for value in request.headers.values()), dict(request.headers)
|
||||
body: Final = cc.JSON_OBJECT.validate_json(request.body)
|
||||
expected: Final = {**request_body, "model": _MODEL}
|
||||
assert body == expected, {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue