-
Notifications
You must be signed in to change notification settings - Fork 680
feat(web-api): add a chat stream method to the web client #2379
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## ai-apps #2379 +/- ##
==========================================
Coverage ? 92.99%
==========================================
Files ? 40
Lines ? 11076
Branches ? 714
==========================================
Hits ? 10300
Misses ? 764
Partials ? 12
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
packages/web-api/src/WebClient.ts
Outdated
| */ | ||
| public async stream(params: ChatStartStreamArguments): Promise<ChatStreamer> { | ||
| const streamer = new ChatStreamer(this); | ||
| await streamer.start(params); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
startStream turns off the loading animation, we should defer it until we have the first bytes to stream.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mcodik Great callout! The changes of 826e46c address this but also make the ChatStreamer class more opinionated to no longer expose a "start" method.
Instead we expose "append" and "stop" with the actual "chat.startStream" method being called when sending the first of the markdown text!
I find this alright to use in development but am open to adjustments however needed 🤖
packages/web-api/src/chat-stream.ts
Outdated
| if (!this.streamTs) { | ||
| throw new Error('failed to append stream: ts not found'); | ||
| } | ||
| const response = await this.client.chat.appendStream({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
plz buffer some characters here, plus some ways for developers to tune the buffer size
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mcodik The WebClient#chatStream method now configures this with changes of 826e46c:
const streamer = client.chatStream({
channel: "C0123456789",
thread_ts: "1700000001.123456",
recipient_team_id: "T0123456789",
recipient_user_id: "U0123456789",
buffer_size: 500, // This defaults to "250" characters at the moment
});Co-authored-by: Michael Brooks <[email protected]> Co-authored-by: Maurice Codik <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks great thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exciting work @zimeg! I've left a few comments and I'll take it for a spin now 🧪
| * @example | ||
| * const client = new WebClient(process.env.SLACK_BOT_TOKEN); | ||
| * const logger = new ConsoleLogger(); | ||
| * const args = { | ||
| * channel: "C0123456789", | ||
| * thread_ts: "1700000001.123456", | ||
| * recipient_team_id: "T0123456789", | ||
| * recipient_user_id: "U0123456789", | ||
| * }; | ||
| * const streamer = new ChatStreamer(client, logger, args, { buffer_size: 500 }); | ||
| * await streamer.append({ | ||
| * markdown_text: "**hello world!**", | ||
| * }); | ||
| * await streamer.stop(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
praise: Love seeing the example for the generated docs!
packages/web-api/src/chat-stream.ts
Outdated
| * @see {@link https://docs.slack.dev/reference/methods/chat.appendStream} | ||
| */ | ||
| async append( | ||
| params: Omit<ChatAppendStreamArguments, 'channel' | 'ts'>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
praise: Nice touch that we're just passing in the appendSteam args.
❓ question: I noticed that the constructor calls it args while the append calls it params. Is there a reason?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mwbrooks Thanks for calling this out! I agree that a more general typing is nice to have here! 👾
I noticed that the constructor calls it args while the append calls it params. Is there a reason?
A partial reason might be quick naming, but I've added fcbce94 and 0f852cd to be more consistent in how method arguments mapping to args and params including options 🙏 ✨
| if (!this.streamTs) { | ||
| const response = await this.client.chat.startStream({ | ||
| ...this.args, | ||
| token: this.token, | ||
| ...params, | ||
| markdown_text: this.buffer, | ||
| }); | ||
| this.buffer = ''; | ||
| this.streamTs = response.ts; | ||
| this.state = 'in_progress'; | ||
| return response; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: Why did you choose to client.chat.startStream(...) in both the .stop(...) and .flushBuffer(...) instead of the constructor? Just curious.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mwbrooks This skips an extra .appendStream method call if streamer.stop() is called on an existing stream I am hoping. We also avoid adding this to the constructor to delay this as an asynchronous process to favor loading states:
startStream turns off the loading animation, we should defer it until we have the first bytes to stream.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ Nice work @zimeg! Throwing an approval on here - you can work through my feedback and decide what to keep or not.
🧪 I've manually tested locally with a sample app and it works very well. I played with buffer sizes between 250-512 and didn't notice any major difference, so I think 250 (256?) is a good default!
Summary
This PR adds a
WebClient#chatStreammethod that creates chat streams 🤖Preview
Testing
WIP-
Notes
diffis significant at the moment I find.Requirements