Skip to content

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

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

zimeg wants to merge 14 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, extending the existing agents.* namespace (agents.sessions.* already ships). All 9 require the bot scope code_channels:manage.

Method Rate limit Notes
agents.conversations.create t2 Create a dedicated code channel for an agent session
agents.conversations.archive t2 Archive 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
agents.conversations.setCommands t1 Register the agent's slash commands for 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.getCanvas t3 Fetch a canvas attached to a code channel
agents.conversations.setCanvasContent t3 Replace the full markdown content of a plan canvas

Notes

  • Experimental / draft. Slack Code (code channels) is in a developer-GA state; the API and its docs are still landing (docs PR Unable to connect to RTM Api using java-slack-sdk #816). This PR is a draft pending API + docs stabilization. Request/response shapes may change before GA.
  • Arg-name caveat preserved. getCanvas and setCanvasContent take the channel argument (modeled as the channel field); the other 7 take channel_id (modeled as channelId).
  • No legacy codeChannels.* names are added (per the 2026-09-23 decision to ship agents.conversations.* only).
  • Honest, minimal shapes. 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 models; setView additionally accepts a typed List<LayoutBlock> for blocks. Response classes carry only the common top-level fields (ok/error/warning/needed/provided) because the API reference does not yet document response bodies.

Files

18 new request/response classes under com.slack.api.methods.{request,response}.agents.conversations, plus wiring in MethodsClient / MethodsClientImpl, AsyncMethodsClient / AsyncMethodsClientImpl, RequestFormBuilder, the Methods constants, and MethodsRateLimits.

Testing

  • mvn -pl slack-api-client -am compile — BUILD SUCCESS
  • mvn -pl slack-api-client -am test-compile — BUILD SUCCESS
  • MethodsTest (endpoint coverage) + MethodsRateLimitsTest — green (3 tests, 0 failures)
  • Remote API integration tests were not run (require live Slack credentials).

🤖 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 7.03125% with 119 lines in your changes missing coverage. Please review.
✅ Project coverage is 72.16%. Comparing base (49b62a6) to head (43efb59).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...java/com/slack/api/methods/RequestFormBuilder.java 0.00% 83 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.16%   -0.63%     
+ Complexity     4550     4546       -4     
============================================
  Files           483      483              
  Lines         14456    14584     +128     
  Branches       1513     1528      +15     
============================================
+ Hits          10523    10525       +2     
- Misses         3038     3161     +123     
- Partials        895      898       +3     
Flag Coverage Δ
jdk-14 72.16% <7.03%> (-0.63%) ⬇️

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 on lines 1338 to +1356
@Override
public CompletableFuture<AgentsSessionsSetStatusResponse> agentsSessionsSetStatus(AgentsSessionsSetStatusRequest req) {
return executor.execute(AGENTS_SESSIONS_SET_STATUS, toMap(req), () -> methods.agentsSessionsSetStatus(req));
}

@Override
public CompletableFuture<AgentsSessionsSetStatusResponse> agentsSessionsSetStatus(RequestConfigurator<AgentsSessionsSetStatusRequest.AgentsSessionsSetStatusRequestBuilder> req) {
return agentsSessionsSetStatus(req.configure(AgentsSessionsSetStatusRequest.builder()).build());
}

@Override
public CompletableFuture<AgentsConversationsCreateResponse> agentsConversationsCreate(AgentsConversationsCreateRequest req) {
return executor.execute(AGENTS_CONVERSATIONS_CREATE, toMap(req), () -> methods.agentsConversationsCreate(req));
}

@Override
public CompletableFuture<AgentsConversationsCreateResponse> agentsConversationsCreate(RequestConfigurator<AgentsConversationsCreateRequest.AgentsConversationsCreateRequestBuilder> req) {
return agentsConversationsCreate(req.configure(AgentsConversationsCreateRequest.builder()).build());
}

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: Please put new methods in alphabetical order!

import com.slack.api.methods.request.admin.users.*;
import com.slack.api.methods.request.admin.users.unsupported_versions.AdminUsersUnsupportedVersionsExportRequest;
import com.slack.api.methods.request.admin.workflows.*;
import com.slack.api.methods.request.agents.conversations.*;

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: Let's use explicit imports

Comment on lines +12 to +13
* NOTE: This method is part of the Slack Code / code channels feature, which is in a developer-GA state.
* The request/response shapes may change before general availability.

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 can be removed - API responses gate such functionalities for now.

public static final String AGENTS_SESSIONS_SET_STATUS = "agents.sessions.setStatus";

// ------------------------------
// agents.conversations (Slack Code / code channels — developer-GA)

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.

Suggested change
// agents.conversations (Slack Code / code channels — developer-GA)
// agents.conversations

👁️‍🗨️ note: Please insert before agents.sessions and also we don't need to note particular features this is released with!

@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


/**
* Encoded team id to create the channel in. Required for org tokens when origin_channel_id is not provided.
* When omitted, the workspace is derived from the token.

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.

Suggested change
* When omitted, the workspace is derived from the token.
* When omitted, the workspace is derived from the origin channel.


/**
* A friendly display name for the code channel. Optional when origin_channel_id and origin_message_ts are
* provided — in that case the channel name may be derived.

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.

Suggested change
* provided — in that case the channel name may be derived.
* provided — in that case the channel name is named from the origin message and re-titled automatically. Required when no origin link is given.


/**
* The channel ID where the agent session was initiated from. Must be provided together with origin_message_ts.
* The channel must be accessible.

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.

Suggested change
* The channel must be accessible.
* The channel must be accessible to the calling user and must not be externally shared (Slack Connect). When team_id is omitted with an org token, the channel is created in the same workspace as this origin channel.


/**
* The message timestamp in the origin channel that started the agent session. Must be provided together with
* origin_channel_id.

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.

Suggested change
* origin_channel_id.
* origin_channel_id. The author of this message is automatically invited to the newly created code channel.


/**
* Timestamp of a message in the code channel to share back as a thread reply on the origin message. Requires the
* channel to have an origin link.

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.

Suggested change
* channel to have an origin link.
* channel to have an origin_link set.

zimeg and others added 2 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>

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