Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
2 changes: 1 addition & 1 deletion .size-limit.js
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ module.exports = [
path: createCDNPath('bundle.tracing.replay.logs.metrics.min.js'),
gzip: false,
brotli: false,
limit: '250 KB',
limit: '251 KB',
},
{
name: 'CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import * as Sentry from '@sentry/node';
import { loggingTransport } from '@sentry-internal/node-integration-tests';

Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
release: '1.0',
tracesSampleRate: 1.0,
sendDefaultPii: true,
transport: loggingTransport,
integrations: [
Sentry.langGraphIntegration({
enableTruncation: false,
Comment thread
nicohrubec marked this conversation as resolved.
}),
],
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { END, MessagesAnnotation, START, StateGraph } from '@langchain/langgraph';
import * as Sentry from '@sentry/node';

async function run() {
await Sentry.startSpan({ op: 'function', name: 'langgraph-test' }, async () => {
const mockLlm = () => {
return {
messages: [
{
role: 'assistant',
content: 'Mock LLM response',
response_metadata: {
model_name: 'mock-model',
finish_reason: 'stop',
tokenUsage: {
promptTokens: 20,
completionTokens: 10,
totalTokens: 30,
},
},
},
],
};
};

const graph = new StateGraph(MessagesAnnotation)
.addNode('agent', mockLlm)
.addEdge(START, 'agent')
.addEdge('agent', END)
.compile({ name: 'weather_assistant' });

// Long content that would normally be truncated
const longContent = 'A'.repeat(50_000);
await graph.invoke({
messages: [{ role: 'user', content: longContent }],
Comment thread
nicohrubec marked this conversation as resolved.
Outdated
});
});

await Sentry.flush(2000);
}

run();
Original file line number Diff line number Diff line change
Expand Up @@ -364,4 +364,32 @@ describe('LangGraph integration', () => {
await createRunner().ignore('event').expect({ transaction: EXPECTED_TRANSACTION_RESUME }).start().completed();
});
});

const longContent = 'A'.repeat(50_000);

const EXPECTED_TRANSACTION_NO_TRUNCATION = {
transaction: 'langgraph-test',
spans: expect.arrayContaining([
expect.objectContaining({
data: expect.objectContaining({
[GEN_AI_INPUT_MESSAGES_ATTRIBUTE]: expect.stringContaining(longContent),
}),
Comment thread
nicohrubec marked this conversation as resolved.
}),
]),
};

createEsmAndCjsTests(
__dirname,
'scenario-no-truncation.mjs',
'instrument-no-truncation.mjs',
(createRunner, test) => {
test('does not truncate input messages when enableTruncation is false', async () => {
await createRunner()
.ignore('event')
.expect({ transaction: EXPECTED_TRANSACTION_NO_TRUNCATION })
.start()
.completed();
});
},
);
});
14 changes: 10 additions & 4 deletions packages/core/src/tracing/langgraph/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@ import {
GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE,
GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE,
} from '../ai/gen-ai-attributes';
import { truncateGenAiMessages } from '../ai/messageTruncation';
import { extractSystemInstructions, resolveAIRecordingOptions } from '../ai/utils';
import {
extractSystemInstructions,
getJsonString,
getTruncatedJsonString,
resolveAIRecordingOptions,
} from '../ai/utils';
import type { LangChainMessage } from '../langchain/types';
import { normalizeLangChainMessages } from '../langchain/utils';
import { startSpan } from '../trace';
Expand Down Expand Up @@ -146,10 +150,12 @@ function instrumentCompiledGraphInvoke(
span.setAttribute(GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE, systemInstructions);
}

const truncatedMessages = truncateGenAiMessages(filteredMessages as unknown[]);
const enableTruncation = options.enableTruncation ?? true;
const filteredLength = Array.isArray(filteredMessages) ? filteredMessages.length : 0;
span.setAttributes({
[GEN_AI_INPUT_MESSAGES_ATTRIBUTE]: JSON.stringify(truncatedMessages),
[GEN_AI_INPUT_MESSAGES_ATTRIBUTE]: enableTruncation
? getTruncatedJsonString(filteredMessages)
: getJsonString(filteredMessages),
[GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE]: filteredLength,
});
}
Expand Down
5 changes: 5 additions & 0 deletions packages/core/src/tracing/langgraph/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ export interface LangGraphOptions {
* Enable or disable output recording.
*/
recordOutputs?: boolean;
/**
* Enable or disable truncation of recorded input messages.
* Defaults to `true`.
*/
enableTruncation?: boolean;
}

/**
Expand Down
Loading