Skip to content

feat: add agents.conversations.* methods - #1647

Open
zimeg wants to merge 27 commits into
mainfrom
clack/agents-conversations-methods
Open

zimeg wants to merge 27 commits into
mainfrom
clack/agents-conversations-methods

Conversation

@zimeg

@zimeg zimeg commented Sep 23, 2026 •

Copy link
Copy Markdown
Member

Summary

Adds the 9 Slack Code / code channel Web API methods to the Java Web API client, next to the existing agents.sessions.*. All 9 require the bot scope code_channels:manage.

Method Rate limit Notes
agents.conversations.archive t2 Archive a code channel
agents.conversations.create t2 Create a dedicated code channel for an agent session
agents.conversations.getCanvas t3 Fetch a canvas attached to a code channel
agents.conversations.listViews t3 List the views attached to a code channel
agents.conversations.removeView t3 Remove a view from a code channel
agents.conversations.setCanvasContent t3 Replace the full markdown content of a plan canvas
agents.conversations.setCommands t1 Register the agent's slash commands for a code channel
agents.conversations.setProperties t3 Set properties on a code channel
agents.conversations.setView t3 Create or update a view in a code channel

Notes

  • Experimental / draft. Slack Code (code channels) is in a developer-GA state and its docs are still landing (slackapi/docs#816). Shapes may change before GA.
  • Typed request models follow the method references in Unable to connect to RTM Api using java-slack-sdk #816:
    • setProperties: CodeChannel (contextBarItems, summaryMessage), ContextBarItem, SummaryMessage, AgentResource
    • setView: Csp, plus blocks as a typed List<LayoutBlock> or blocksAsString
    • setCommands: Command, including shouldEscape
  • Arg-name caveat. getCanvas and setCanvasContent take channel. The other 7 take channel_id (channelId).
  • Response models are built from real responses: create returns channelId, setView returns the view and file ids, listViews returns views, and getCanvas returns the content plus comment threads (Comment / Reply).
  • No legacy codeChannels.* names. Only agents.conversations.* ships.

Files

18 new request/response classes under com.slack.api.methods.{request,response}.agents.conversations. Wiring in MethodsClient / MethodsClientImpl, AsyncMethodsClient / AsyncMethodsClientImpl, RequestFormBuilder, Methods, MethodsRateLimits and rate_limit_tiers.json. Plus a remote API test and the json-logs/samples/api/agents.conversations.* samples it records.

Testing

  • test_with_remote_apis.methods.agents_conversations_Test runs against a live workspace. It covers create → setProperties → setView (HTML and canvas) → listViews → getCanvas → setCanvasContent → setCommands → removeView → archive, and cleans up the canvas it creates.
  • When SLACK_SDK_TEST_AGENTS_CANVAS_ID names an existing canvas with comments, the test also reads its comment threads through getCanvas. The test runner provides this variable.
  • MethodsClientImplTest, RequestFormBuilderTest, and MethodsResponseDumpTest pass, and the samples are generated by the test run.

🤖 Generated with Claude Code

Add the 9 Slack Code / code channel Web API methods to the Java Web API
client, extending the existing agents.* namespace (agents.sessions.*
already ships):

- agents.conversations.create
- agents.conversations.archive
- agents.conversations.setProperties
- agents.conversations.setView
- agents.conversations.setCommands
- agents.conversations.listViews
- agents.conversations.removeView
- agents.conversations.getCanvas
- agents.conversations.setCanvasContent

All require the bot scope code_channels:manage. Arg schemas follow docs
PR #816. getCanvas + setCanvasContent use the `channel` arg (not
`channel_id`); the rest use `channel_id`. Only agents.conversations.*
names are added — no legacy codeChannels.* aliases (decision 2026-09-23).

Undocumented complex/object args (code_channel, agent_resource, csp,
commands) are exposed as JSON-encoded String params (the *AsString
pattern, mirroring blocks.validate) rather than guessing nested shapes;
setView also accepts a typed List<LayoutBlock>. Response classes carry
only the common top-level fields since the API reference does not yet
document response bodies (Slack Code is developer-GA).

Wires each method into MethodsClient/Impl, AsyncMethodsClient/Impl,
RequestFormBuilder, the Methods constants, and MethodsRateLimits.

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 8.25688% with 100 lines in your changes missing coverage. Please review.
✅ Project coverage is 72.26%. Comparing base (49b62a6) to head (7ac65f1).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...java/com/slack/api/methods/RequestFormBuilder.java 0.00% 64 Missing ⚠️
...slack/api/methods/impl/AsyncMethodsClientImpl.java 0.00% 18 Missing ⚠️
.../com/slack/api/methods/impl/MethodsClientImpl.java 0.00% 18 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main    #1647      +/-   ##
============================================
- Coverage     72.79%   72.26%   -0.53%     
+ Complexity     4550     4547       -3     
============================================
  Files           483      483              
  Lines         14456    14565     +109     
  Branches       1513     1520       +7     
============================================
+ Hits          10523    10526       +3     
- Misses         3038     3141     +103     
- Partials        895      898       +3     
Flag Coverage Δ
jdk-14 72.26% <8.25%> (-0.53%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@zimeg zimeg changed the title feat: add agents.conversations.* code channel methods feat: add agents.conversations.* methods Sep 24, 2026
@zimeg zimeg self-assigned this Sep 25, 2026
@zimeg zimeg added enhancement M-T: A feature request for new functionality project:slack-api-client project:slack-api-client java This is a label that @dependabot automatically creates. We don't use it. semver:minor labels Sep 25, 2026
…sations

MethodsRateLimits already assigns tiers for the 9 agents.conversations.*
methods, but the generated metadata/web-api/rate_limit_tiers.json was
missing those entries — so the build regenerates the file and CI's
clean-working-tree check fails. Commit the regenerated entries
(create/archive Tier2, setCommands Tier1, rest Tier3).

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.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.

🧪 Few issues to address before more testing. I'd also like to have remote API tests for sake of generating API logs.

Comment thread slack-api-client/src/main/java/com/slack/api/methods/Methods.java Outdated
@zimeg zimeg added this to the 1.51.1 milestone Sep 25, 2026
zimeg and others added 9 commits September 25, 2026 14:23
- Alphabetize the 9 methods everywhere they're listed: both client
  impls (each overload pair as a unit), both client interfaces, the
  Methods.java constants, and the MethodsRateLimits tier assignments.
- Replace agents.conversations.* wildcard imports with explicit
  per-class imports (impls, interfaces, RequestFormBuilder) to match
  the sibling agents.sessions style.
- Move the agents.conversations constant block before agents.sessions
  and drop the developer-GA parenthetical from the section comments.
- Remove the developer-GA NOTE javadoc from all 9 request + 9 response
  classes (the JSON-encoding facts remain on the individual fields).
- Add agents_conversations_Test remote-API test mirroring
  agents_sessions_Test (token-gated skip, random-channel lookup) to
  generate API logs.

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rewrite the remote-API test as one create -> canvas -> setView ->
listViews -> getCanvas -> setCanvasContent -> setCommands -> removeView
-> archive flow (seeding a real canvas via canvases.create), so the
generated API logs cover a realistic code-channel session end to end.
Token-gated skip and random-channel lookup unchanged.

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Delete the seeded canvas in a finally block so the lifecycle test never
leaks it, and simplify to non-null assertions (dropping log.info and the
now-unused response imports) to match the sibling canvases_Test /
agents_sessions_Test style.

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…aptures

Running the remote lifecycle test against a code-channels-enabled
workspace surfaced response fields the types didn't model (the strict
response parser rejected them). Add, from the real API responses:
- create/setProperties/setCommands: channel_id (+ command_count)
- setView: channel_id, view_id, file_id, content_version, type, canvas_id
- listViews: views[] (typed View: view_id/type/file_id/view_key/name/
  date_added/content_version)
- getCanvas: canvas_id, title, content, comments[], has_more_comments
- setCanvasContent: canvas_id, sections_changed_count
Thread the created code channel's id (create.getChannelId) through the
downstream calls in the remote test so they hit the code channel, and
record the sanitized API sample fixtures. archive/removeView return only
base fields.

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…iew_id

Capture the setView response and remove the view by the view_id it
returns (the canvas view carries no view_key), and note that views
created via setView aren't currently returned by listViews or locatable
by removeView, so removeView asserts the call round-trips rather than ok.

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Attach an HTML view (keyed by view_key) as the listable/removable view in
the lifecycle test; it appears in listViews and removeView succeeds, so
both assert ok. Model the fields that surfaced: listViews view entries
carry label; removeView returns channel_id + view_id. The canvas view is
attached separately to feed getCanvas/setCanvasContent. All nine methods
return ok end to end.

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The agents.conversations block was appended after agents.sessions in the
client impls, interfaces, MethodsRateLimits, and RequestFormBuilder, but
conversations sorts before sessions. Swap the two blocks in each so
conversations precedes sessions. Pure reorder (block internals and tier
values unchanged); test-compile clean.

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nses

Match the adjacent response classes (agents.sessions, canvases, ...),
which carry no class-level javadoc — remove the 'Response for
agents.conversations.X' comment from all nine response types.

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… the docs URL

The class comment carried a <p> and a description line, which the
adjacent request classes (agents.sessions, ...) don't — their class
javadoc is just the docs.slack.dev URL. Drop the <p>/description from
all nine so they match; field-level javadoc is unchanged.

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.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.

☕ To match docs

zimeg and others added 7 commits September 25, 2026 16:40
…#816

Apply the reviewer's suggested wording to the create/archive request
field javadoc (team_id derivation, name/origin-link behavior, origin
channel Slack Connect + org-token note, origin author auto-invite,
origin_link on summary_message_ts).

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Give the string-passthrough args a typed counterpart (keeping the
*AsString escape hatch, per the chat.postMessage blocks/blocksAsString
convention):
- setCommands: List<Command> (name/description/argumentHint)
- setView: Csp (resourceDomains)
- setProperties: CodeChannel (contextBarItems/summaryMessage) +
  AgentResource (url/resourceType/title/provider), with nested
  ContextBarItem/SummaryMessage
Field shapes are from docs #816. RequestFormBuilder serializes the typed
field when the *AsString form isn't set (and warns if both are), matching
the blocks pattern. Snake_case mapping is automatic via the snake-case
Gson (no @SerializedName needed).

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…perties

Session title/status are set via agents.sessions.rename / setStatus, not
setProperties. Remove the fields + their form serialization, and update
the remote test to exercise setProperties via code_channel context bar
items instead.

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
List.of(...) is Java 9+; the build (8) CI leg compiles the tests on JDK
8. Switch to Arrays.asList (the repo convention in these remote tests).

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
listViews view entries return view_id, view_key, file_id, label,
content_version, date_added — not type or name (confirmed against live
responses; docs #816 lists type but it isn't returned). Drop the two
unpopulated fields so the model matches the actual response.

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… template

The sample recorder fills empty comments arrays with the FileComment shape,
which is not what agents.conversations.getCanvas returns. Keep the captured
value until a real canvas comment is recorded.

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

Typed fields only for commands, code_channel, agent_resource, and csp,
matching other non-Block Kit args (canvases, slackLists, assistant prompts).
setView blocksAsString stays alongside Block Kit blocks.

The remote test now passes typed csp and commands.

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.

⚡ Comments for changes

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: Aligning with docs soon but right now this seems right

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.

👍 Agreed. This sample matches what the API returns today, and we can follow up if the docs land on a different shape.

"canvas_id": "F00000000",
"title": "",
"content": "",
"comments": [],

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: Am considering adding an existing canvas ID environment variable for remote tests to include more comment details.

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.

👍 Makes sense. The public API has no way to create canvas comments, so an optional canvas ID variable pointing at a hand-commented canvas is the clearest path to a real comments capture. Until then, Comment stays untyped and the recorder keeps comments as captured instead of filling it with a template.

* Full set of commands to register for the calling agent in this channel. This replaces that agent's previously
* registered set. Pass an empty list to clear the agent's commands. Required.
*/
private List<Command> commands;

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: This avoids keeping commandsAsString for more structured implementations to start.

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.

✅ Agreed. We only keep the *AsString variants for Block Kit and message payloads, and the other complex arguments here are typed-only too (codeChannel, agentResource, csp).

import java.util.List;

/**
* https://docs.slack.dev/reference/methods/agents.conversations.setProperties

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: We omit deprecated properties in an initial release to discourage new choice to such

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.

👍 Noted. We follow the same rule on setView, where the deprecated label is now removed.

- Remove the deprecated label argument from setView
- Add thread_ts to the setProperties summary_message
- Match the setCommands commands description to the reference docs
- Order the agents.conversations form builders alphabetically

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.

📚 More arguments to adjust? Please!

- Align setView view_key, content, access_level, agent_content_hash, and csp descriptions
- Add csp connect_domains to setView
- Fix the create name description

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

zimeg commented Sep 29, 2026

Copy link
Copy Markdown
Member Author

📚 I checked every agents.conversations request argument against slackapi/docs#816, and the descriptions now match (a3988df). Two changes beyond the suggestions: create name had a wording typo, and setView csp gained connectDomains.

We intentionally still leave out:

  • The deprecated label on setView and the deprecated status and title on setProperties. The docs point to agents.sessions.setStatus and agents.sessions.rename instead.
  • The flat code_channel metadata fields on setProperties (host, repo, branch, pr_url, ci_state, and similar). The guides show repo, branch, PR and CI status through context_bar_items, and node leaves these out as well. We can add them later if they're meant to be public.

zimeg and others added 2 commits September 29, 2026 16:58
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
…ons.setProperties

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

zimeg commented Sep 30, 2026

Copy link
Copy Markdown
Member Author

📚 Correction to my earlier comment: the flat code_channel fields are documented arguments in slackapi/docs#816 and aren't deprecated, so 958da6e adds them. That's host, repo, branch, baseBranch, commitSha, prNumber, prUrl, prTitle, prStatus, ciUrl, ciState, filePaths, language, upstreamUrl and branchUrl. The remote test now sets repo and branch and expects no error. The only arguments still left out are the deprecated ones: label on setView, and status and title on setProperties.

zimeg and others added 4 commits September 29, 2026 17:21
…ote test

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
…ions remote test"

This reverts commit 32157e2.

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

This reverts commit 958da6e.

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
@zimeg
zimeg marked this pull request as ready for review September 30, 2026 02:24
@zimeg
zimeg requested a review from a team as a code owner September 30, 2026 02:24

This branch has not been deployed

No deployments
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 java This is a label that @dependabot automatically creates. We don't use it. project:slack-api-client project:slack-api-client semver:minor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant