Skip to content
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

[FIX]: Include metadata with Assistant say util #2300

Merged
merged 4 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions src/Assistant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type {
AssistantThreadsSetSuggestedPromptsResponse,
AssistantThreadsSetTitleResponse,
ChatPostMessageArguments,
MessageMetadataEventPayloadObject,
} from '@slack/web-api';
import {
type AssistantThreadContext,
Expand Down Expand Up @@ -301,12 +302,20 @@ export async function processAssistantMiddleware(
*/
function createSay(args: AllAssistantMiddlewareArgs): SayFn {
const { client, payload } = args;
const { channelId: channel, threadTs: thread_ts } = extractThreadInfo(payload);
const { channelId: channel, threadTs: thread_ts, context } = extractThreadInfo(payload);

return (message: Parameters<SayFn>[0]) => {
return async (message: Parameters<SayFn>[0]) => {
const threadContext = context.channel_id ? context : await args.getThreadContext(args);
const postMessageArgument: ChatPostMessageArguments =
typeof message === 'string' ? { text: message, channel, thread_ts } : { ...message, channel, thread_ts };

if (threadContext) {
postMessageArgument.metadata = {
event_type: 'assistant_thread_context',
event_payload: threadContext as MessageMetadataEventPayloadObject,
};
}

return client.chat.postMessage(postMessageArgument);
};
}
Expand Down
62 changes: 59 additions & 3 deletions test/unit/Assistant.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,9 @@ describe('Assistant class', () => {
const mockThreadContextStore = createMockThreadContextStore();
const { enrichAssistantArgs } = await importAssistant();
// TODO: enrichAssistantArgs likely needs a different argument type, as AssistantMiddlewareArgs type already has the assistant utility enrichments present.
const assistantArgs = enrichAssistantArgs(mockThreadContextStore, { payload } as AllAssistantMiddlewareArgs);
const assistantArgs = enrichAssistantArgs(mockThreadContextStore, {
payload,
} as AllAssistantMiddlewareArgs);

assert.exists(assistantArgs.say);
assert.exists(assistantArgs.setStatus);
Expand All @@ -221,7 +223,9 @@ describe('Assistant class', () => {
const mockThreadContextStore = createMockThreadContextStore();
const { enrichAssistantArgs } = await importAssistant();
// TODO: enrichAssistantArgs likely needs a different argument type, as AssistantMiddlewareArgs type already has the assistant utility enrichments present.
const assistantArgs = enrichAssistantArgs(mockThreadContextStore, { payload } as AllAssistantMiddlewareArgs);
const assistantArgs = enrichAssistantArgs(mockThreadContextStore, {
payload,
} as AllAssistantMiddlewareArgs);

assert.exists(assistantArgs.say);
assert.exists(assistantArgs.setStatus);
Expand All @@ -234,7 +238,9 @@ describe('Assistant class', () => {
const mockThreadContextStore = createMockThreadContextStore();
const { enrichAssistantArgs } = await importAssistant();
// TODO: enrichAssistantArgs likely needs a different argument type, as AssistantMiddlewareArgs type already has the assistant utility enrichments present.
const assistantArgs = enrichAssistantArgs(mockThreadContextStore, { payload } as AllAssistantMiddlewareArgs);
const assistantArgs = enrichAssistantArgs(mockThreadContextStore, {
payload,
} as AllAssistantMiddlewareArgs);

assert.exists(assistantArgs.say);
assert.exists(assistantArgs.setStatus);
Expand Down Expand Up @@ -306,6 +312,56 @@ describe('Assistant class', () => {
sinon.assert.called(fakeClient.chat.postMessage);
});

it('say should be called with message_metadata that includes thread context', async () => {
const mockThreadStartedArgs = wrapMiddleware(createDummyAssistantThreadStartedEventMiddlewareArgs());

const fakeClient = { chat: { postMessage: sinon.spy() } };
mockThreadStartedArgs.client = fakeClient as unknown as WebClient;
const mockThreadContextStore = createMockThreadContextStore();

const { enrichAssistantArgs } = await importAssistant();
const threadStartedArgs = enrichAssistantArgs(mockThreadContextStore, mockThreadStartedArgs);

await threadStartedArgs.say('Say called!');

const {
payload: {
assistant_thread: { channel_id, thread_ts, context },
},
} = mockThreadStartedArgs;

const expectedParams = {
text: 'Say called!',
channel: channel_id,
thread_ts,
metadata: {
event_type: 'assistant_thread_context',
event_payload: context,
},
};

sinon.assert.calledWith(fakeClient.chat.postMessage, expectedParams);
});

it('say should get context from store if no thread context is included in event', async () => {
const mockThreadStartedArgs = wrapMiddleware(createDummyAssistantThreadStartedEventMiddlewareArgs());
mockThreadStartedArgs.payload.assistant_thread.context = {};

const fakeClient = { chat: { postMessage: sinon.spy() } };
mockThreadStartedArgs.client = fakeClient as unknown as WebClient;
const mockThreadContextStore = { save: sinon.spy(), get: sinon.spy() };

const { enrichAssistantArgs } = await importAssistant();
const threadStartedArgs = enrichAssistantArgs(mockThreadContextStore, mockThreadStartedArgs);

misscoded marked this conversation as resolved.
Show resolved Hide resolved
// Verify that get is not called prior to say being used
sinon.assert.notCalled(mockThreadContextStore.get);

await threadStartedArgs.say('Say called!');

sinon.assert.calledOnce(mockThreadContextStore.get);
});

it('setStatus should call assistant.threads.setStatus', async () => {
const mockThreadStartedArgs = wrapMiddleware(createDummyAssistantThreadStartedEventMiddlewareArgs());

Expand Down