Skip to content

feat: add the Claude Agent SDK coding agent - #16

Merged
zimeg merged 7 commits into
mainfrom
clack/coding-agent-claude-agent-sdk
Oct 20, 2026
Merged

zimeg merged 7 commits into
mainfrom
clack/coding-agent-claude-agent-sdk

Conversation

@zimeg

@zimeg zimeg commented Oct 16, 2026 •

Copy link
Copy Markdown
Member

Summary

This pull request adds a Claude Agent SDK implementation of the coding agent in claude-agent-sdk/, ported from openai-agents-sdk/ with the starter agent's Claude Agent SDK app as the framework reference.

  • Matches the OpenAI Agents SDK version's experience: the same 16 tools with the same names, arguments, and descriptions, the same prompts, and the same approvals, stop, and archive behavior. listeners/ and the framework-free agent/ files are copied unchanged. The SDK stays in agent/agent.py, agent/guardrails.py, and agent/tools/, plus agent/runtime.py, which holds the deps that @tool functions can't be passed.
  • Tools are @tool functions served by an in-process MCP server. Claude Code's built-in tools are off, and so are the machine's settings, CLAUDE.md files, and MCP servers. verbatim_prompts keeps an @path inside a Slack message from reading a local file. Uses claude-sonnet-5-5 for coding and claude-haiku-4-5 for routing.
  • Command approvals use the PreToolUse hook's defer decision. The run ends with the command waiting, and a click resumes the Claude Code session. The hook then allows or denies that same call.
  • A dropped approval, from a newer message or the stop button, is answered as not run at the start of the next turn. can_use_tool denies it with interrupt, so closing it costs no model call.
  • A PostToolUse hook ends the run once a channel is created or archived. The stop button denies every tool call, a raising tool reaches the model as an error result, and running out of turns ends with a message, keeping the session.
  • History is the session's run results, and the conversation lives in the CLI's transcript under ~/.claude/projects/, as the README notes.
  • Keeps ANTHROPIC_ variables out of a command's environment in place of OPENAI_, since each implementation hides its own provider's.
  • Adds claude-agent-sdk/ to the lint and test matrices in ci.yml, dependabot, the root README, and AGENTS.md. The root AGENTS.md now words the dropped-pause rule so it fits both kinds of pausing.

tests/test_runs.py drives the real SDK and bundled CLI against tests/fake_model.py, a local server that answers the Messages API from a script. The CLI's config goes to a temp directory, and these tests take about 30s.

Testing

  • Copy claude-agent-sdk/.env.sample to .env, set ANTHROPIC_API_KEY, and start the app with slack run from claude-agent-sdk/.
  • Mention the agent in a thread with a question and confirm it answers in place, then with a task on a throwaway repo and confirm it links a new code channel.
  • In the code channel, approve a test or build command and confirm it runs, then deny one and confirm the agent carries on without running it.
  • Send a new message while an approval is pending and confirm the buttons show it was skipped and the agent answers the new message.
  • Press stop mid-turn and confirm the agent says it stopped and posts nothing more from that turn.
  • Say the work is done and confirm the summary is shared back to your original message and the channel is archived.

🤖 Generated with Claude Code

Adds claude-agent-sdk/, the coding agent built with the Claude Agent SDK. It shares structure, listeners, and the framework-free agent files with openai-agents-sdk/. Command approvals defer run_command from a PreToolUse hook and resume the Claude Code session with the decision.

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
@zimeg zimeg added the enhancement M-T: A feature request for new functionality label Oct 16, 2026
@zimeg zimeg self-assigned this Oct 16, 2026
zimeg and others added 2 commits October 19, 2026 13:27
Moves the claude-agent-sdk lint and test matrix entries into the combined ci.yml workflow.

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
…-agent-sdk

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
@zimeg zimeg added the semver:minor Use on pull requests to describe the release version increment label Oct 19, 2026
zimeg and others added 2 commits October 19, 2026 15:53
…ands

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Adds the claude-agent-sdk row to the framework table alongside pydantic-ai.

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>

@zimeg zimeg left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👾 A comment for me and a comment for thee-


from agent.sessions import AgentDeps, RequestDeps

current_deps: ContextVar[AgentDeps | RequestDeps] = ContextVar("current_deps")

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this go with sessions?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Yep, moved in 8742907: current_deps now sits under RequestDeps in agent/sessions.py, next to the deps it carries, and runtime.py is gone. One tradeoff is that sessions.py is otherwise identical across implementations, so the root AGENTS.md now says to keep current_deps in place when copying changes to that file.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Reverted in 1872a9d after a second look. Moving current_deps here made sessions.py the one shared file that differs between implementations, so it'd need review and care on every copy. Keeping it in runtime.py leaves every Claude difference in the framework files and the shared files byte-identical.

Comment on lines +15 to +17
def tool_result(text: str) -> dict:
"""A tool's reply to the model."""
return {"content": [{"type": "text", "text": text}]}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and can this go with tools/init.py?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Done in the same commit! It's defined above the tool imports in agent/tools/__init__.py, since each tool imports it back from the package and a definition below them would be a circular import. With both moves, claude-agent-sdk/ has the same set of files as the other implementations.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Reverted with the other move in 1872a9d. This only worked defined above the tool imports, which is easy to break with an import sort or E402, so tool_result stays in runtime.py beside current_deps.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧪 note: Plans to follow up on test alignment remain but for now coverage is good!

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 note: Planning also to follow up with updates to mirror between samples once features are complete!

zimeg and others added 2 commits October 19, 2026 20:46
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
This reverts commit 8742907, so files shared across implementations stay identical.

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
@zimeg
zimeg marked this pull request as ready for review October 20, 2026 03:56
@zimeg

zimeg commented Oct 20, 2026

Copy link
Copy Markdown
Member Author

🏁 Testing remains good so I'll merge now with planned follow up after landing similar changes in JS!

@zimeg
zimeg merged commit 9c34553 into main Oct 20, 2026
7 checks passed
@zimeg
zimeg deleted the clack/coding-agent-claude-agent-sdk branch October 20, 2026 04:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement M-T: A feature request for new functionality semver:minor Use on pull requests to describe the release version increment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant