-
-
Notifications
You must be signed in to change notification settings - Fork 4.7k
docs(laravel): Add AI agent monitoring onboarding #118363
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| import type {OnboardingConfig} from 'sentry/components/onboarding/gettingStartedDoc/types'; | ||
| import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/types'; | ||
| import {t, tct} from 'sentry/locale'; | ||
| import {SdkUpdateAlert} from 'sentry/views/insights/pages/agents/components/sdkUpdateAlert'; | ||
|
|
||
| const MIN_REQUIRED_VERSION = '4.27.0'; | ||
|
|
||
| export const agentMonitoring: OnboardingConfig = { | ||
| introduction: params => ( | ||
| <SdkUpdateAlert | ||
| projectId={params.project.id} | ||
| minVersion={MIN_REQUIRED_VERSION} | ||
| packageName="sentry/sentry-laravel" | ||
| /> | ||
| ), | ||
| install: () => [ | ||
| { | ||
| type: StepType.INSTALL, | ||
| content: [ | ||
| { | ||
| type: 'text', | ||
| text: tct( | ||
| 'Agent monitoring for Laravel uses the [code:laravel/ai] package and [code:sentry/sentry-laravel] version [minVersion] or newer.', | ||
| { | ||
| code: <code />, | ||
| minVersion: <code>{MIN_REQUIRED_VERSION}</code>, | ||
| } | ||
| ), | ||
| }, | ||
| { | ||
| type: 'code', | ||
| language: 'bash', | ||
| code: `composer require sentry/sentry-laravel:^${MIN_REQUIRED_VERSION} laravel/ai | ||
| php artisan vendor:publish --provider="Laravel\\Ai\\AiServiceProvider" | ||
| php artisan migrate`, | ||
| }, | ||
| ], | ||
| }, | ||
| ], | ||
| configure: params => [ | ||
| { | ||
| type: StepType.CONFIGURE, | ||
| content: [ | ||
| { | ||
| type: 'text', | ||
| text: t('Configure Sentry and enable performance monitoring:'), | ||
| }, | ||
| { | ||
| type: 'code', | ||
| language: 'shell', | ||
| code: `php artisan sentry:publish --dsn=${params.dsn.public}`, | ||
| }, | ||
| { | ||
| type: 'code', | ||
| language: 'shell', | ||
| code: `SENTRY_LARAVEL_DSN=${params.dsn.public} | ||
| SENTRY_TRACES_SAMPLE_RATE=1.0 | ||
| SENTRY_TRACE_GEN_AI_ENABLED=true | ||
| # Required to capture prompt and response messages | ||
| SENTRY_SEND_DEFAULT_PII=true`, | ||
| }, | ||
| { | ||
| type: 'text', | ||
| text: tct( | ||
| 'Sentry automatically instruments Laravel AI agents, LLM calls, tool calls, and embeddings. Prompt and response messages are captured when [code:SENTRY_SEND_DEFAULT_PII] is enabled.', | ||
| {code: <code />} | ||
| ), | ||
| }, | ||
| ], | ||
| }, | ||
| ], | ||
| verify: () => [ | ||
| { | ||
| type: StepType.VERIFY, | ||
| content: [ | ||
| { | ||
| type: 'text', | ||
| text: t('Verify agent monitoring by calling any Laravel AI agent:'), | ||
| }, | ||
| { | ||
| type: 'code', | ||
| language: 'php', | ||
| code: `<?php | ||
|
|
||
| use App\\Ai\\Agents\\Agent; | ||
|
|
||
| $response = (new Agent)->prompt('What time is it?');`, | ||
| }, | ||
| ], | ||
| }, | ||
| ], | ||
| nextSteps: () => [], | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,7 +30,10 @@ import type { | |
| DocsParams, | ||
| OnboardingStep, | ||
| } from 'sentry/components/onboarding/gettingStartedDoc/types'; | ||
| import {DocsPageLocation} from 'sentry/components/onboarding/gettingStartedDoc/types'; | ||
| import { | ||
| DocsPageLocation, | ||
| StepType, | ||
| } from 'sentry/components/onboarding/gettingStartedDoc/types'; | ||
| import {useSourcePackageRegistries} from 'sentry/components/onboarding/gettingStartedDoc/useSourcePackageRegistries'; | ||
| import {useLoadGettingStarted} from 'sentry/components/onboarding/gettingStartedDoc/utils/useLoadGettingStarted'; | ||
| import {PlatformOptionDropdown} from 'sentry/components/onboarding/platformOptionDropdown'; | ||
|
|
@@ -57,6 +60,7 @@ import { | |
| AGENT_INTEGRATION_LABELS, | ||
| AgentIntegration, | ||
| NODE_AGENT_INTEGRATIONS, | ||
| PHP_AGENT_INTEGRATIONS, | ||
| PYTHON_AGENT_INTEGRATIONS, | ||
| } from 'sentry/views/insights/pages/agents/utils/agentIntegrations'; | ||
| import {AI_INSTRUMENTATION_DOCS_LINKS} from 'sentry/views/insights/pages/agents/utils/docsLinks'; | ||
|
|
@@ -225,35 +229,84 @@ function ConversationOnboardingPanel({ | |
| ); | ||
| } | ||
|
|
||
| function getConversationIdStep(integration: string, isPython: boolean): OnboardingStep { | ||
| function getConversationIdStep( | ||
| integration: string, | ||
| platform: 'javascript' | 'php' | 'python' | ||
| ): OnboardingStep { | ||
| const isOpenAI = | ||
| integration === AgentIntegration.OPENAI || | ||
| integration === AgentIntegration.OPENAI_AGENTS; | ||
|
|
||
| const content: ContentBlock[] = [ | ||
| if (platform === 'php') { | ||
| return { | ||
| title: t('Enable Conversations'), | ||
| content: [ | ||
| { | ||
| type: 'text', | ||
| text: tct( | ||
| 'Make your Laravel AI agent conversational with the [code:Conversational] contract and [code:RemembersConversations] trait:', | ||
| {code: <code />} | ||
| ), | ||
| }, | ||
| { | ||
| type: 'code', | ||
| language: 'php', | ||
| code: `<?php | ||
|
|
||
| namespace App\\Ai\\Agents; | ||
|
|
||
| use Laravel\\Ai\\Concerns\\RemembersConversations; | ||
| use Laravel\\Ai\\Contracts\\Agent as AgentContract; | ||
| use Laravel\\Ai\\Contracts\\Conversational; | ||
| use Laravel\\Ai\\Promptable; | ||
| use Stringable; | ||
|
|
||
| class Agent implements AgentContract, Conversational | ||
| { | ||
| use Promptable, RemembersConversations; | ||
|
|
||
| public function instructions(): Stringable|string | ||
| { | ||
| type: 'text', | ||
| text: t( | ||
| 'Group related LLM calls into a single conversation thread by setting an ID at the start:' | ||
| ), | ||
| }, | ||
| isPython | ||
| return 'You are a helpful sales coach.'; | ||
| } | ||
|
|
||
| public function messages(): iterable | ||
| { | ||
| return []; | ||
| } | ||
| }`, | ||
| }, | ||
| ], | ||
| }; | ||
| } | ||
|
|
||
| const conversationIdCodeBlock: ContentBlock = | ||
| platform === 'python' | ||
| ? { | ||
| type: 'code' as const, | ||
| type: 'code', | ||
| language: 'python', | ||
| code: `import sentry_sdk | ||
|
|
||
| # Call this at the start of each conversation | ||
| sentry_sdk.ai.set_conversation_id("my-conversation-123")`, | ||
| } | ||
| : { | ||
| type: 'code' as const, | ||
| type: 'code', | ||
| language: 'javascript', | ||
| code: `import * as Sentry from "@sentry/node"; | ||
|
|
||
| // Call this at the start of each conversation | ||
| Sentry.setConversationId("my-conversation-123");`, | ||
| }, | ||
| }; | ||
|
|
||
| const content: ContentBlock[] = [ | ||
| { | ||
| type: 'text', | ||
| text: t( | ||
| 'Group related LLM calls into a single conversation thread by setting an ID at the start:' | ||
| ), | ||
| }, | ||
| conversationIdCodeBlock, | ||
| ...(isOpenAI | ||
| ? [ | ||
| { | ||
|
|
@@ -273,6 +326,32 @@ Sentry.setConversationId("my-conversation-123");`, | |
| }; | ||
| } | ||
|
|
||
| function getPhpConversationVerifyStep(): OnboardingStep { | ||
| return { | ||
| type: StepType.VERIFY, | ||
| content: [ | ||
| { | ||
| type: 'text', | ||
| text: tct( | ||
| 'Verify Conversations by continuing an existing Laravel AI conversation with [code:->continue()]:', | ||
| {code: <code />} | ||
| ), | ||
| }, | ||
| { | ||
| type: 'code', | ||
| language: 'php', | ||
| code: `<?php | ||
|
|
||
| use App\\Ai\\Agents\\Agent; | ||
|
|
||
| $response = (new Agent) | ||
| ->continue('my-conversation-123', as: auth()->user()) | ||
| ->prompt('Make it shorter.');`, | ||
| }, | ||
| ], | ||
| }; | ||
| } | ||
|
|
||
| export function ConversationOnboarding({onDismiss}: {onDismiss: () => void}) { | ||
| const api = useApi(); | ||
| const {isSelfHosted, urlPrefix} = useLegacyStore(ConfigStore); | ||
|
|
@@ -293,19 +372,31 @@ export function ConversationOnboarding({onDismiss}: {onDismiss: () => void}) { | |
| }); | ||
|
|
||
| const isPythonPlatform = (project?.platform ?? '').startsWith('python'); | ||
| const isPhpPlatform = (project?.platform ?? '').startsWith('php'); | ||
|
|
||
| const integrations = isPythonPlatform | ||
| ? PYTHON_AGENT_INTEGRATIONS | ||
| : NODE_AGENT_INTEGRATIONS; | ||
| : isPhpPlatform | ||
| ? PHP_AGENT_INTEGRATIONS | ||
| : NODE_AGENT_INTEGRATIONS; | ||
|
|
||
| const integrationOptions = { | ||
| integration: { | ||
| label: t('Integration'), | ||
| items: integrations.map(integration => ({ | ||
| label: AGENT_INTEGRATION_LABELS[integration], | ||
| label: isPhpPlatform | ||
| ? (currentPlatform?.name ?? t('Laravel')) | ||
| : AGENT_INTEGRATION_LABELS[integration], | ||
| value: integration, | ||
| leadingItems: ( | ||
| <PlatformIcon platform={AGENT_INTEGRATION_ICONS[integration]} size={16} /> | ||
| <PlatformIcon | ||
| platform={ | ||
| isPhpPlatform | ||
| ? (project?.platform ?? 'php-laravel') | ||
| : AGENT_INTEGRATION_ICONS[integration] | ||
| } | ||
| size={16} | ||
| /> | ||
| ), | ||
| })), | ||
| }, | ||
|
|
@@ -368,8 +459,13 @@ export function ConversationOnboarding({onDismiss}: {onDismiss: () => void}) { | |
| const steps: OnboardingStep[] = [ | ||
| ...(agentMonitoringDocs.install?.(docParams) || []), | ||
| ...(agentMonitoringDocs.configure?.(docParams) || []), | ||
| getConversationIdStep(selectedIntegration, isPythonPlatform), | ||
| ...(agentMonitoringDocs.verify?.(docParams) || []), | ||
| getConversationIdStep( | ||
| selectedIntegration, | ||
| isPythonPlatform ? 'python' : isPhpPlatform ? 'php' : 'javascript' | ||
| ), | ||
| ...(isPhpPlatform | ||
| ? [getPhpConversationVerifyStep()] | ||
| : agentMonitoringDocs.verify?.(docParams) || []), | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PHP conversations skips verifyMedium Severity For Reviewed by Cursor Bugbot for commit d09a42c. Configure here. |
||
| ].filter(s => !s.collapsible); | ||
|
|
||
| const introduction = agentMonitoringDocs.introduction?.(docParams); | ||
|
|
||


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.
Laravel SDK alert never shows
Low Severity
The Laravel agent monitoring intro uses
SdkUpdateAlertwithpackageNamesentry/sentry-laravel, butSdkUpdateAlertonly maps Python and JavaScript SDK names to package names. Laravel project SDK rows never match, so the minimum-version warning never appears forphp-laravelprojects.Reviewed by Cursor Bugbot for commit 77e4af9. Configure here.