diff --git a/.changeset/khaki-coats-do.md b/.changeset/khaki-coats-do.md new file mode 100644 index 0000000..3add5cb --- /dev/null +++ b/.changeset/khaki-coats-do.md @@ -0,0 +1,5 @@ +--- +'@callstack/byorg-core': patch +--- + +core: add plugin for logging context diff --git a/examples/slack/src/index.ts b/examples/slack/src/index.ts index 8a447dc..cb8a45b 100644 --- a/examples/slack/src/index.ts +++ b/examples/slack/src/index.ts @@ -1,4 +1,4 @@ -import { VercelChatModelAdapter, createApp } from '@callstack/byorg-core'; +import { VercelChatModelAdapter, contextLoggerBuilder, createApp } from '@callstack/byorg-core'; import { createOpenAI } from '@ai-sdk/openai'; import { logger, requireEnv } from '@callstack/byorg-utils'; import { createSlackApp, slackThreadNormalizerPlugin } from '@callstack/byorg-slack'; @@ -28,7 +28,12 @@ const app = createApp({ chatModel, systemPrompt: SYSTEM_PROMPT, // Normalize messages coming from Slack AI apps - plugins: [slackThreadNormalizerPlugin], + plugins: [ + contextLoggerBuilder([]), + contextLoggerBuilder(['messages']), + slackThreadNormalizerPlugin, + contextLoggerBuilder(), + ], }); const slack = createSlackApp({ diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 15b1ebf..b8401cd 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -28,7 +28,7 @@ export { VercelChatModelAdapter } from './ai/vercel.js'; export type { Command, CommandsPluginConfig } from './plugins/commands.js'; export { createCommandsPlugin } from './plugins/commands.js'; -export { loggingPlugin } from './plugins/logging.js'; +export { loggingPlugin, contextLoggerBuilder } from './plugins/logging.js'; export type { ApplicationTool } from './tools.js'; diff --git a/packages/core/src/plugins/logging.ts b/packages/core/src/plugins/logging.ts index 38ddbde..dc47844 100644 --- a/packages/core/src/plugins/logging.ts +++ b/packages/core/src/plugins/logging.ts @@ -1,4 +1,6 @@ -import { ApplicationPlugin, MessageResponse } from '../index.js'; +import { inspect } from 'util'; +import { logger } from '@callstack/byorg-utils'; +import { ApplicationPlugin, MessageResponse, RequestContext } from '../index.js'; const getFormattedNow = () => new Date().toISOString(); @@ -23,3 +25,32 @@ export const loggingPlugin: ApplicationPlugin = { } }, }; + +export const contextLoggerBuilder = (fieldsToLog?: (keyof RequestContext)[]): ApplicationPlugin => { + return { + name: 'context-logger', + middleware: (context, next): Promise => { + const toLog: Record = {}; + + if (!fieldsToLog || fieldsToLog.length === 0) { + logger.info(inspect(context, false, null, true)); + return next(); + } + + for (const field of fieldsToLog) { + if (field in context) { + toLog[field] = context[field]; + } else { + logger.debug(`No ${field} in context.`); + } + } + + if (Object.keys(toLog).length > 0) { + logger.info(inspect(toLog, false, null, true)); + } + + // Continue middleware chain + return next(); + }, + }; +};