Skip to content
Open
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
2 changes: 1 addition & 1 deletion ee/hogai/context/insight/prompts.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
Insight URL: {{{insight_url}}}
{{/insight_url}}
{{^insight_url}}
This insight is not saved in the project, so it cannot be accessed via a URL. Any `Artifact ID` above is scoped to this conversation, not an insight short ID, so an `/insights/...` link built from it would 404. If the user wants a saved insight, tell them to open the chart as a new insight from the icon below it and save it from there.
This insight is not saved in the project, so it cannot be accessed via a URL. Any `Artifact ID` above is scoped to this conversation, not an insight short ID, so an `/insights/...` link built from it would 404. If the user wants a saved insight, tell them to open the chart as a new insight from the icon below it and save it from there. You cannot export a chart directly from the conversation, because the chart has no download button and no export menu. To export the data, tell the user to open the chart as a new insight from the icon below it, then export it from the insight page.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Saved insight charts skip the export correction

should_fix

Why we think it's a valid issue
  • Checked: the branch condition in ee/hogai/context/insight/prompts.py:13, the insight_url property, every call site that builds an InsightContext, the has_transient_artifacts flag in ee/hogai/tools/task.py, and the controls that VisualizationWidget renders.
  • Found: InsightContext.insight_url returns a URL whenever insight_short_id is set (ee/hogai/context/insight/context.py:62-67). Three call sites set it for saved insights: ee/hogai/tools/read_data/tool.py:449 (read one insight), ee/hogai/context/dashboard/context.py:176 (each insight on a read dashboard), and ee/hogai/context/context.py:537 (an insight the user attaches). All three take the {{#insight_url}} branch, so the new export sentence at prompts.py:13 never reaches the model for a saved insight.
  • Found: ee/hogai/tools/task.py:190-213 sets has_transient_artifacts = True only for artifacts whose source is not ArtifactSource.INSIGHT. A task that returns saved insights alone keeps the flag false, so the whole block at task.py:100-103 — including the export sentence — is omitted.
  • Found: the widget renders the same two controls for both sources. products/posthog_ai/frontend/components/tool/widgets/VisualizationWidget.tsx:126-146 shows only the open-target button and the show/hide button, and getArtifactOpenTarget (same file, lines 56-64) gives a saved insight an "Open insight" link, not an export control. So a saved insight in chat has no download button either.
  • Impact: the PR removes the wrong export answer for charts Max generates, but leaves it reachable on the saved-insight paths, which cover read-insight, read-dashboard, and user-attached-insight renders. A user who asks how to export one of those charts can still get directions to a control that does not exist.
  • Impact: the miss is partly softened, not closed. The saved branches print a real Insight URL, and task.py:102 tells the model that URL is a real link. That gives the model a correct route to offer, so the wrong answer is less likely there than on the transient path. Nothing in either branch states that the chat chart itself has no export control, so the invented download icon stays available to the model.
Issue description

The new export instruction only appears inside {{^insight_url}}. ReadDataTool._read_insight() sets insight_short_id for saved insights, so the formatter omits this instruction. The UI still renders saved insights in VisualizationWidget, which has no download control. Export questions about these charts can still produce the false directions that this PR intends to remove.

Suggested fix

Add guidance for the {{#insight_url}} branch. Tell Max to open the existing insight and export from that page. Move the warning outside has_transient_artifacts in TASK_ARTIFACTS_PROMPT, then give separate routes for Artifact ID and Insight ID entries.

Prompt to fix with AI (copy-paste)
## Context
@ee/hogai/context/insight/prompts.py#L13

<issue_description>
The new export instruction only appears inside `{{^insight_url}}`. `ReadDataTool._read_insight()` sets `insight_short_id` for saved insights, so the formatter omits this instruction. The UI still renders saved insights in `VisualizationWidget`, which has no download control. Export questions about these charts can still produce the false directions that this PR intends to remove.
</issue_description>

<issue_validation>
- **Checked:** the branch condition in `ee/hogai/context/insight/prompts.py:13`, the `insight_url` property, every call site that builds an `InsightContext`, the `has_transient_artifacts` flag in `ee/hogai/tools/task.py`, and the controls that `VisualizationWidget` renders.
- **Found:** `InsightContext.insight_url` returns a URL whenever `insight_short_id` is set (`ee/hogai/context/insight/context.py:62-67`). Three call sites set it for saved insights: `ee/hogai/tools/read_data/tool.py:449` (read one insight), `ee/hogai/context/dashboard/context.py:176` (each insight on a read dashboard), and `ee/hogai/context/context.py:537` (an insight the user attaches). All three take the `{{#insight_url}}` branch, so the new export sentence at `prompts.py:13` never reaches the model for a saved insight.
- **Found:** `ee/hogai/tools/task.py:190-213` sets `has_transient_artifacts = True` only for artifacts whose source is not `ArtifactSource.INSIGHT`. A task that returns saved insights alone keeps the flag false, so the whole block at `task.py:100-103` — including the export sentence — is omitted.
- **Found:** the widget renders the same two controls for both sources. `products/posthog_ai/frontend/components/tool/widgets/VisualizationWidget.tsx:126-146` shows only the open-target button and the show/hide button, and `getArtifactOpenTarget` (same file, lines 56-64) gives a saved insight an "Open insight" link, not an export control. So a saved insight in chat has no download button either.
- **Impact:** the PR removes the wrong export answer for charts Max generates, but leaves it reachable on the saved-insight paths, which cover read-insight, read-dashboard, and user-attached-insight renders. A user who asks how to export one of those charts can still get directions to a control that does not exist.
- **Impact:** the miss is partly softened, not closed. The saved branches print a real `Insight URL`, and `task.py:102` tells the model that URL is a real link. That gives the model a correct route to offer, so the wrong answer is less likely there than on the transient path. Nothing in either branch states that the chat chart itself has no export control, so the invented download icon stays available to the model.
</issue_validation>

## Task
Investigate the issue and solve it

<potential_solution>
Add guidance for the `{{#insight_url}}` branch. Tell Max to open the existing insight and export from that page. Move the warning outside `has_transient_artifacts` in `TASK_ARTIFACTS_PROMPT`, then give separate routes for `Artifact ID` and `Insight ID` entries.
</potential_solution>

{{/insight_url}}
{{#query_schema}}

Expand Down
2 changes: 1 addition & 1 deletion ee/hogai/tools/create_insight.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from ee.hogai.utils.types.base import AssistantNodeName, AssistantState, NodePath

INSIGHT_TOOL_PROMPT = """
Use this tool to generate an insight from a structured plan. It will return a visualization that the user can analyze and a textual representation for your analysis. These visualizations are transient and only exist within the current conversation—they are not saved to the project. To save an insight permanently, users should click the open insight icon below the chart in the conversation.
Use this tool to generate an insight from a structured plan. It will return a visualization that the user can analyze and a textual representation for your analysis. These visualizations are transient and only exist within the current conversation—they are not saved to the project. To save an insight permanently, users should click the open insight icon below the chart in the conversation. You cannot export a chart directly from the conversation, because the chart has no download button and no export menu. To export the data, tell the user to open the chart as a new insight from the icon below it, then export it from the insight page.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The transient export route omits the save step

should_fix

Why we think it's a valid issue
  • Checked: the CTA target the chat widget builds for a transient chart, the short_id state of a new insight, the gate on the insight page's Export menu, and every in-page export control that does not need a saved insight.
  • Found: the CTA for a transient chart is urls.insightNew({ query }) (products/posthog_ai/frontend/components/tool/widgets/VisualizationWidget.tsx:47-54), and createEmptyInsight('new') leaves short_id: undefined (frontend/src/scenes/insights/insightLogic.tsx:93-102). So the page the user reaches holds an unsaved insight.
  • Found: the insight page hides its whole Export menu until the insight is saved. frontend/src/scenes/insights/SidePanel/InsightSceneMenuBar.tsx:124 computes canExport = exportContext != null && insight.short_id != null, and line 269 renders the Export submenu — PNG, CSV, and XLSX — only when canExport is true. PNG additionally passes insight: insight.id, which an unsaved insight does not have.
  • Found: one in-page export survives without saving, but only for some charts. frontend/src/queries/nodes/InsightViz/InsightVizDisplay.tsx:436-458 shows a CSV/XLSX button above the detailed results table, and hasDetailedResultsTable is true only for trends and stickiness, minus the display types in DISPLAY_TYPES_WITHOUT_DETAILED_RESULTS (frontend/src/scenes/insights/insightVizDataLogic.ts:2341-2345). SQL and table insights keep their own DataTableExport menu.
  • Impact: for a funnel, retention, paths, or lifecycle chart, and for any PNG request, the user follows the new instruction and lands on a page with no export control at all. That repeats the same unfollowable-direction failure this PR removes, on the path the PR itself creates.
  • Impact: the miss is partial, not total. Each of the three prompt sites mentions saving in a nearby sentence, the unsaved page shows a Save button, and trends charts keep the detailed-results CSV button. So the user can recover, and the model may chain save before export on its own. The export sentence still names a route that does not work as written.
Issue description

getQueryOpenTarget() opens an unsaved /insights/new query. The main insight export menu requires insight.short_id, so it does not appear until the user saves the insight. Unsaved editors expose only limited table exports and no PNG export. A PNG request or funnel-data request therefore reaches another page with no usable export action.

Suggested fix

Tell the model to open the chart, save the new insight, and then use the saved insight's export menu. Update the identical text in all three prompt sites.

Prompt to fix with AI (copy-paste)
## Context
@ee/hogai/tools/create_insight.py#L19

<issue_description>
`getQueryOpenTarget()` opens an unsaved `/insights/new` query. The main insight export menu requires `insight.short_id`, so it does not appear until the user saves the insight. Unsaved editors expose only limited table exports and no PNG export. A PNG request or funnel-data request therefore reaches another page with no usable export action.
</issue_description>

<issue_validation>
- **Checked:** the CTA target the chat widget builds for a transient chart, the short_id state of a new insight, the gate on the insight page's Export menu, and every in-page export control that does not need a saved insight.
- **Found:** the CTA for a transient chart is `urls.insightNew({ query })` (`products/posthog_ai/frontend/components/tool/widgets/VisualizationWidget.tsx:47-54`), and `createEmptyInsight('new')` leaves `short_id: undefined` (`frontend/src/scenes/insights/insightLogic.tsx:93-102`). So the page the user reaches holds an unsaved insight.
- **Found:** the insight page hides its whole Export menu until the insight is saved. `frontend/src/scenes/insights/SidePanel/InsightSceneMenuBar.tsx:124` computes `canExport = exportContext != null && insight.short_id != null`, and line 269 renders the Export submenu — PNG, CSV, and XLSX — only when `canExport` is true. PNG additionally passes `insight: insight.id`, which an unsaved insight does not have.
- **Found:** one in-page export survives without saving, but only for some charts. `frontend/src/queries/nodes/InsightViz/InsightVizDisplay.tsx:436-458` shows a CSV/XLSX button above the detailed results table, and `hasDetailedResultsTable` is true only for trends and stickiness, minus the display types in `DISPLAY_TYPES_WITHOUT_DETAILED_RESULTS` (`frontend/src/scenes/insights/insightVizDataLogic.ts:2341-2345`). SQL and table insights keep their own `DataTableExport` menu.
- **Impact:** for a funnel, retention, paths, or lifecycle chart, and for any PNG request, the user follows the new instruction and lands on a page with no export control at all. That repeats the same unfollowable-direction failure this PR removes, on the path the PR itself creates.
- **Impact:** the miss is partial, not total. Each of the three prompt sites mentions saving in a nearby sentence, the unsaved page shows a Save button, and trends charts keep the detailed-results CSV button. So the user can recover, and the model may chain save before export on its own. The export sentence still names a route that does not work as written.
</issue_validation>

## Task
Investigate the issue and solve it

<potential_solution>
Tell the model to open the chart, save the new insight, and then use the saved insight's export menu. Update the identical text in all three prompt sites.
</potential_solution>


This tool can also be used to edit the visualization the user is currently viewing on the insight page. In that case, you need to generate a new plan based on the schema of the existing insight.

Expand Down
2 changes: 1 addition & 1 deletion ee/hogai/tools/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
{{{artifacts_list}}}
{{#has_transient_artifacts}}

Any `Artifact ID` above is scoped to this conversation, not an insight short ID, so an `/insights/...` link built from it would 404. If the user wants a saved insight, tell them to open the chart as a new insight from the icon below it and save it from there. Any `Insight ID` above is a saved insight, and its insight URL is a real link you can give the user.
Any `Artifact ID` above is scoped to this conversation, not an insight short ID, so an `/insights/...` link built from it would 404. If the user wants a saved insight, tell them to open the chart as a new insight from the icon below it and save it from there. You cannot export a chart directly from the conversation, because the chart has no download button and no export menu. To export the data, tell the user to open the chart as a new insight from the icon below it, then export it from the insight page. Any `Insight ID` above is a saved insight, and its insight URL is a real link you can give the user.
{{/has_transient_artifacts}}
"""

Expand Down
Loading