Added markdown links to ai insgihts and obs agent#250030
Added markdown links to ai insgihts and obs agent#250030yuliia-fryshko merged 20 commits intoelastic:mainfrom
Conversation
| | Service | \`[<serviceName>](/app/apm/services/<serviceName>)\` | "The [payments](/app/apm/services/payments) service is experiencing high latency." | | ||
| | Transaction | \`[<transactionName>](/app/apm/services/<serviceName>/transactions)\` | "The transaction [POST /checkout](/app/apm/services/payments/transactions) took 500ms." | | ||
| | Trace | \`[<traceId>](/app/apm/link-to/trace/<traceId>)\` | "See trace [8bc26008603e16819bd6fcfb80fceff5](/app/apm/link-to/trace/8bc26008603e16819bd6fcfb80fceff5)" | | ||
| | Error | \`[<errorKey>](/app/apm/services/<serviceName>/errors/<errorKey>)\` | "Error [upstream-5xx](/app/apm/services/catalog-api/errors/upstream-5xx) suggests a dependency failure." | | ||
| | Service Errors | \`[errors](/app/apm/services/<serviceName>/errors)\` | "Review all [errors](/app/apm/services/frontend/errors) for the [frontend](/app/apm/services/frontend) service." | | ||
| | Service Logs | \`[logs](/app/apm/services/<serviceName>/logs)\` | "Check [logs](/app/apm/services/frontend/logs) for the [frontend](/app/apm/services/frontend) service." | | ||
| | Host | \`[<hostName>](/app/metrics/detail/host/<hostName>)\` | "Host [web-01](/app/metrics/detail/host/web-01) is experiencing high CPU usage." | | ||
| | Service Map | \`[Service Map](/app/apm/services/<serviceName>/service-map)\` | "Check the [Service Map](/app/apm/services/payments/service-map) to see dependencies." | | ||
| | Dependencies | \`[Dependencies](/app/apm/services/<serviceName>/dependencies)\` | "View [Dependencies](/app/apm/services/catalog-api/dependencies) to identify upstream issues." | | ||
| | Alert | \`[<alertId>](/app/observability/alerts/<alertId>)\` | "Alert [alert-uuid-123](/app/observability/alerts/alert-uuid-123) was triggered." | | ||
| | Logs Explorer | \`[Logs](/app/logs)\` | "View [Logs](/app/logs) to investigate the issue further." | |
There was a problem hiding this comment.
I think you will have to consider the kibana base path and spaces for the links (and maybe the time range?).
When I have a base path: The URLs result in Not Found
Screen.Recording.2026-01-22.at.7.59.40.PM.mov
When I am in a space: Same result as above
Screen.Recording.2026-01-22.at.8.01.24.PM.mov
There was a problem hiding this comment.
Good point @viduni94 .
@yuliia-fryshko You should be able to get the the base url like coreStart.http.basePath.publicBaseUrl
There was a problem hiding this comment.
Thank you, @viduni94 ! I updated the PR , now links are space aware for AI Insights and the Observability Agent
Screen.Recording.2026-01-27.at.18.29.21.mov
…lder/server/agent/register_observability_agent.ts Co-authored-by: Viduni Wickramarachchi <viduni.ushanka@gmail.com>
| - <TraceServices>: Service aggregates for the trace (serviceName, count, errorCount) | ||
| - <TraceLogCategories>: Categorized log patterns tied to the trace (errorCategory, docCount, sampleMessage) | ||
| `); | ||
| ${getEntityLinkingInstructions(spaceId)} |
There was a problem hiding this comment.
Nice to see you are importing the instruction here. This got me thinking: what about the other instructions:
${getInvestigationInstructions()}
${getReasoningInstructions()}
${getFieldDiscoveryInstructions()}
${getKqlInstructions()}
Should they be included as well?
How are you handling this for alerts and log AI insights? @viduni94 @neptunian?
There was a problem hiding this comment.
Actually, nevermind. The other instructions are only relevant when doing tool calling, which the AI insight is not doing atm. So probably only the instructions related to formatting (like markdown links) are needed.
| ${getReasoningInstructions()} | ||
| ${getFieldDiscoveryInstructions()} | ||
| ${getKqlInstructions()} | ||
| ${getEntityLinkingInstructions()} |
There was a problem hiding this comment.
Let's hear AB team if we can render this dynamically so we can access context
There was a problem hiding this comment.
I made a change, so now it allows BuiltInAgentDefinition.configuration to be either: a static configuration object or a function that receives context and returns configuration dynamically.
How It will work:
- At the setup (registration) time agent stores a configuration function
- Then createAgentHandler checks if configuration is a function
- If function, calls it with { spaceId, request } to get the actual config
- Instructions include correct space
cc: @pgayvallet
…lder/server/agent/register_observability_agent.ts Co-authored-by: Søren Louv-Jansen <sorenlouv@gmail.com>
|
|
||
| | Entity | Link Format | Example | | ||
| |--------|-------------|---------| | ||
| | Service | [<serviceName>](${prefix}/app/apm/services/<serviceName>) | "The [payments](${prefix}/app/apm/services/payments) service is experiencing high latency." | |
There was a problem hiding this comment.
Thanks for adding the space path changes.
How about the base path?
The URLs will result in 404 if there is a base path configured.
There was a problem hiding this comment.
If possible, you could try to use this shared util by agent builder which handles the space and base path:
| configuration: ({ spaceId }) => { | ||
| const basePath = core.http.basePath.serverBasePath; |
There was a problem hiding this comment.
Untested, but can you try this?
| configuration: ({ spaceId }) => { | |
| const basePath = core.http.basePath.serverBasePath; | |
| configuration: ({ request }) => { | |
| const prefix = coreStart.http.basePath.get(request); |
The advantage is that you don't to manually stitch basePath and spaceId together.
There was a problem hiding this comment.
You are right, @sorenlouv ! I changed it and tested, it works (here I run kibana with basePath: /kibana and in the space: Agent )
Screen.Recording.2026-01-28.at.22.15.04.mov
💛 Build succeeded, but was flaky
Failed CI StepsTest Failures
Metrics [docs]
History
|
#Closes [431](elastic/obs-ai-team#431) The agent now automatically formats known Observability entities as Markdown links in its responses. This enables users to click directly on entity references to navigate to the relevant APM views, improving workflow efficiency. To make these links space-aware for the agent as well, we introduced a change that allows `BuiltInAgentDefinition.configuration` to be defined as either: a static configuration object, or a function that receives runtime context and returns the configuration dynamically. **How it works** 1. At setup (registration) time, the agent stores the configuration function. 2. When handling a request, createAgentHandler checks whether the configuration is a function. 3. If it is, the function is called with { spaceId, request } to resolve the actual configuration. 4. The resolved instructions then include the correct space-aware links. ### Changes - Added entity-linking instructions to the Observability Agent’s system prompt. - Added entity-linking support to Errors, Logs and Alerts AI Insights. - All links are space-aware. **Testing with Cursor:** Test Prompt: [test_prompt.md](https://github.com/user-attachments/files/24771581/test_prompt.md) Results: [hereisresults.md](https://github.com/user-attachments/files/24771728/hereisresults.md) **Test scenario:** - Start es, kibana and otel-demo - Enable productCatalogFailure feature flag - Start a conversation with the Observability Agent - Ask about a specific service (e.g., "What's the status of checkout service?") - The agent's response should format service names as clickable Markdown links Traces for [Error AI insight](https://oblt-apps.elastic.dev/phoenix-ai/projects/UHJvamVjdDoxMTIy/traces/5fd67e44e280ab0514f17d53e23cd828?selected) and [Alert AI Insight](https://oblt-apps.elastic.dev/phoenix-ai/projects/UHJvamVjdDoxMTIy/traces/9dff61da9be3240830e83e6d99d17265?selected) --------- Co-authored-by: Viduni Wickramarachchi <viduni.ushanka@gmail.com> Co-authored-by: Søren Louv-Jansen <sorenlouv@gmail.com> Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
#Closes 431
The agent now automatically formats known Observability entities as Markdown links in its responses. This enables users to click directly on entity references to navigate to the relevant APM views, improving workflow efficiency.
To make these links space-aware for the agent as well, we introduced a change that allows
BuiltInAgentDefinition.configurationto be defined as either: a static configuration object, or a function that receives runtime context and returns the configuration dynamically.How it works
Changes
Testing with Cursor:
Test Prompt:
test_prompt.md
Results:
hereisresults.md
Test scenario:
Traces for Error AI insight and Alert AI Insight