Repository navigation
feat: replace the starter agent with the coding agent sample - #5
Conversation
Replaces the starter agent template contents with a coding agent built on the OpenAI Agents SDK. Mentions either get an answer in place or a code channel where the agent clones a repo, plans in a canvas, makes changes with command approvals, and publishes a diff. Removes the claude-agent-sdk and pydantic-ai starter implementations and the .claude directory, adds AGENTS.md files, and narrows CI and dependabot to openai-agents-sdk.
…break later turns
…k-agnostic Listeners now import only from the agent package. The OpenAI Agents SDK is confined to agent/agent.py and the tools, and agent/turns.py runs turns, approvals, and stops without importing it, so another framework can reuse listeners/ and turns.py as they are. Only read-only commands inside the clone run without asking. Shell syntax, paths that leave the clone, and running the repo's own code all ask first. Clones accept only remote URLs and check out symlinks as plain files. A newer message retires a pending approval so a late click can't resume an older run. Stopping skips every tool call through a tool input guardrail. A failed turn leaves processing, and running out of turns ends with a message. The diff compares against the cloned commit and includes new files.
…rns async Moves the app to Bolt's AsyncApp so a long turn never holds up the stop button, an approval click, or another channel. Messages that arrive while a turn runs wait and go into the next turn together, labeled with who sent them. Direct messages are answered like mentions. Requests from a thread or a direct message bring that conversation to the agent, and a new code channel's first turn gets the conversation it was started from. Messages and slash commands pick up code channels the app forgot after a restart. Adds read_file, write_file, and edit_file tools that stay inside the clone and never write into .git, and lets local git changes like add, commit, and switch -c run without asking. Commands run without the app's secrets, and their output keeps its end, where test failures are. Long sessions drop their oldest conversation instead of outgrowing the context window. Runs end once a channel is created or archived. Prompts and the run outcome move to their own modules, and tests drive real agent runs with a scripted model. Adds suggested prompts, pins CI actions, tests Python 3.10 and 3.14, adds a Dependabot cooldown outside of Slack packages, and stops auto-merging 0.x minor updates.
# Conflicts: # claude-agent-sdk/pyproject.toml # claude-agent-sdk/requirements.txt # openai-agents-sdk/pyproject.toml # openai-agents-sdk/requirements.txt # pydantic-ai/pyproject.toml # pydantic-ai/requirements.txt
Replaces run_shell and run_git with one run that starts a program directly, finding it on PATH so npm resolves to npm.cmd on Windows. run_command splits a command into arguments the same way the approval check does, so what's checked is exactly what runs, and takes a directory instead of cd. Shell syntax no longer needs its own rule since it reaches the program as plain text. The outside-the-clone check also catches drive letters, backslashes, and UNC paths.
Apps running over HTTP need code_channels.slash_command_url for agent slash commands to arrive. Renames agent/store.py to agent/sessions.py after the sessions it holds, and brings comments up to date with where turns, approvals, and the SDK now live. Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Moves AgentDeps and RequestDeps from agent/deps.py into agent/sessions.py, next to the CodeChannelSession a turn runs in, and drops their unused user_id. The model already sees who sent each message in the text. Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Discarding a session now marks it archived and stopped, so a turn still running calls no more tools and doesn't put the session back with a deleted clone when it finishes. Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
zimeg
left a comment
There was a problem hiding this comment.
🗣️ Handfuls of comments with a working sample that'll be nice to revisit so I'll merge to iterate more focused.
| "is_enabled": true, | ||
| "request_url": "https://ngrok-free.app/slack/events" | ||
| }, | ||
| "is_mcp_enabled": true, |
There was a problem hiding this comment.
🪬 note: For now we omit these capabilities for more focused experience within this sample.
There was a problem hiding this comment.
🤡 note: This tool is used even though it is a significant enhancement to examples but I'm hoping for now to focus on code channel creation and follow up with improvements like this!
| try: | ||
| response = deps.client.agents_conversations_setView( | ||
| channel_id=deps.channel_id, | ||
| type="html", |
There was a problem hiding this comment.
| type="html", | |
| type="block_kit", |
🧱 note: At the moment we don't include a Block Kit view tool but we can follow up and extend this as cases arrive.
| icon: ( | ||
| Literal[ | ||
| "branch", | ||
| "folder", | ||
| "hierarchy", | ||
| "life-ring", | ||
| "link", | ||
| "globe", | ||
| "terminal", | ||
| "code", | ||
| "search", | ||
| "lock", | ||
| ] | ||
| | None |
There was a problem hiding this comment.
🔭 note: We find this list from reference but keep all of these "informative" instead of handling actions at this time.
🔗 https://docs.slack.dev/ai/slack-code/code-channel-properties#context-bar-items
There was a problem hiding this comment.
📚 note: Will update after landing adjacent frameworks!
| async def run_command_needs_approval(_ctx, arguments: dict, _call_id: str) -> bool: | ||
| """The `needs_approval` hook for `run_command`, checked with its arguments before it runs. | ||
|
|
||
| Returning True pauses the run with a ToolApprovalItem, which `agent/turns.py` | ||
| posts as Approve / Deny buttons. | ||
| """ | ||
| command = (arguments or {}).get("command", "") | ||
| needs = command_needs_approval(command) | ||
| if needs: | ||
| logger.info("run_command needs approval: %s", command) | ||
| return needs |
There was a problem hiding this comment.
👽 note: I'm uneased about not including this with tooling but it keeps patterns more separate and framework logic of agent contained!
There was a problem hiding this comment.
🧪 note: Will reasses test patterns after landing other frameworks but want to have this now for comparison.
Summary
This pull request replaces the starter agent template contents with a coding agent sample built on the OpenAI Agents SDK.
create_code_channeltool, reading the thread or direct message the request came from.git commitrun right away. Running the repo's code and paths outside the clone post Approve / Deny buttons. Commands run without a shell, so&&and|reach the program as plain text, and without the app's secrets in their environment.AsyncApp, so a long turn never holds up the stop button, an approval click, or another channel. Messages sent while the agent works go into its next turn together. Stopping, or archiving the channel from Slack, keeps a running turn from calling more tools.code_channels.slash_command_urlwhen running over HTTP withapp_oauth.py.agentpackage, and the OpenAI Agents SDK stays inagent/agent.py,agent/guardrails.py, andagent/tools/, so other frameworks can follow the same structure. The rootAGENTS.mdlists what implementations keep the same, including what the framework side keeps true foragent/turns.py.claude-agent-sdk/andpydantic-ai/starter implementations and the.claude/directory, including the Bolt vendoring commands, and the maintainers guide.openai-agents-sdk/, tests Python 3.14, pins workflow actions, and checks dependencies daily with a cooldown outside of Slack packages.Testing
openai-agents-sdk/.env.sampleto.env, setOPENAI_API_KEY, and start the app withslack runfromopenai-agents-sdk/./run-tests, and confirm it starts a turn. Repeat over HTTP withapp_oauth.pyafter setting the ngrok domain inmanifest.json.🤖 Generated with Claude Code