From fba4d1310002637a3b25eb33ec45a4e775cd2ce5 Mon Sep 17 00:00:00 2001 From: Peter Kirkham Date: Thu, 23 Jul 2026 22:31:45 +0100 Subject: [PATCH 1/5] feat(tasks): replace turn_complete thread writeback with pr_created artifact messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task threads become a human-to-human surface with artifact announcements. The sandbox event relay no longer posts the agent's closing turn message into the thread, legacy turn_complete rows are excluded from the thread listing, and a pr_created agent message (deduped per PR URL) is now emitted when a run's pull request is recorded — from the agent-output paths and the GitHub webhook backstop — joining the existing canvas_created announcement. Generated-By: PostHog Code Task-Id: 4ca58c61-95e3-4b36-a0df-474345b61483 --- products/tasks/backend/facade/api.py | 74 +++++----- .../activities/relay_sandbox_events.py | 41 ------ .../backend/tests/test_thread_updates.py | 128 +++++++++--------- products/tasks/backend/webhooks.py | 3 +- 4 files changed, 104 insertions(+), 142 deletions(-) diff --git a/products/tasks/backend/facade/api.py b/products/tasks/backend/facade/api.py index 3c13fee43ab4..733ecea29033 100644 --- a/products/tasks/backend/facade/api.py +++ b/products/tasks/backend/facade/api.py @@ -25,7 +25,7 @@ from uuid import UUID, uuid4 from django.conf import settings -from django.db import IntegrityError, close_old_connections, transaction +from django.db import IntegrityError, transaction from django.db.models import CharField, Count, Exists, F, Min, OuterRef, Q, QuerySet, Subquery from django.db.models.fields.json import KeyTextTransform from django.utils import timezone as django_timezone @@ -49,7 +49,7 @@ is_custom_images_enabled, read_spec_from_builder_sandbox, ) -from products.tasks.backend.mentions import format_mention_token, resolve_mentioned_user_ids +from products.tasks.backend.mentions import resolve_mentioned_user_ids from products.tasks.backend.models import ( Channel, ChannelFeedMessage, @@ -2112,6 +2112,7 @@ def update_task_run( if new_pr_url and new_pr_url != old_pr_url: _post_slack_update_for_pr(run) _send_wizard_pr_ready_email_for_pr(run) + post_pr_created_thread_update(run, new_pr_url) # Surface the PR in the run's progress timeline the moment the agent reports it, so the install # UI advances past "Started agent" instead of waiting on the 15-min CI follow-up loop to emit # these. Steps coalesce by id with the workflow's own pr/ci emissions (frontend mergeProgressStep), @@ -2162,6 +2163,8 @@ def set_task_run_output( run.publish_stream_state_event() _post_slack_update_for_pr(run) _send_wizard_pr_ready_email_for_pr(run) + if merged.get("pr_url"): + post_pr_created_thread_update(run, merged["pr_url"]) return _task_run_detail_to_dto(run) @@ -5109,6 +5112,9 @@ def list_thread_messages( return None messages = ( TaskThreadMessage.objects.filter(task_id=task_id, team_id=team_id) + # The thread is human-to-human plus artifact announcements; rows written + # back when the agent finished a turn (a since-removed behavior) stay out. + .exclude(event="turn_complete") .select_related("author", "forwarded_by") .order_by("created_at", "id") ) @@ -5248,13 +5254,6 @@ def forward_thread_message( # updates are gated on the same flag — evaluated for the task creator. AGENT_THREAD_UPDATES_FLAG = "project-bluebird" -# One turn-complete post per run within the window, so an SSE relay reconnect -# replaying the tail of the stream can't double-post the same end-of-turn. -_TURN_COMPLETE_COOLDOWN_SECONDS = 30 - -# Cap the relayed final message so one agent essay can't dwarf the thread. -_TURN_MESSAGE_MAX_CHARS = 4000 - def _create_agent_thread_message(task: Task, content: str, *, event: str, payload: dict | None = None) -> None: """Write an agent-authored thread message and index its mentions. @@ -5326,42 +5325,45 @@ def post_canvas_created_thread_update( logger.exception("Failed to post canvas-created thread update", extra={"task_id": str(task_id)}) -def post_turn_complete_thread_update( - run_id: str | UUID, task_id: str | UUID, team_id: int, *, message: str | None = None -) -> None: - """Post the agent's final turn message into the task's thread, @-mentioning the task creator. +_GITHUB_PR_URL_PATTERN = re.compile(r"github\.com/([^/]+)/([^/]+)/pull/(\d+)", re.IGNORECASE) + + +def _pr_display_label(pr_url: str) -> str: + match = _GITHUB_PR_URL_PATTERN.search(pr_url) + if match: + owner, repo, number = match.groups() + return f"{owner}/{repo}#{number}" + return pr_url - Fires from the sandbox event relay on every end-of-turn of a channel task's - background run, so the update lands even with no client open. ``message`` is - the agent's closing prose for the turn; when the relay captured none, a plain - "Turn complete." stands in. Best-effort and never raises — a failed post must - not disturb the relay. + +def post_pr_created_thread_update(run: TaskRun, pr_url: str) -> None: + """Announce a run's freshly opened pull request in its task's thread. + + Posts "[owner/repo#N](url) has been opened" as an agent artifact message + (``event="pr_created"``). Both the agent-output path and the GitHub webhook + backstop can observe the same PR, so the announcement dedupes on the task's + existing ``pr_created`` rows for this URL. Best-effort and never raises — + recording the PR must not fail because its announcement couldn't be written. """ try: - if not settings.TEST: - close_old_connections() - task = Task.objects.select_related("created_by").filter(id=task_id, team_id=team_id).first() + task = Task.objects.select_related("created_by").filter(id=run.task_id, team_id=run.team_id).first() # Threads hang off a task's channel feed; a channel-less task has no audience. if task is None or task.channel_id is None: return - creator = task.created_by - if creator is None or not _agent_thread_updates_enabled(creator): + if task.created_by is None or not _agent_thread_updates_enabled(task.created_by): return - from products.tasks.backend.redis import get_tasks_cache # noqa: PLC0415 — keep redis off the api import path - - if not get_tasks_cache().add(f"thread_update:{run_id}:turn_complete", True, _TURN_COMPLETE_COOLDOWN_SECONDS): + if ( + TaskThreadMessage.objects.for_team(task.team_id) + .filter(task_id=task.id, event="pr_created", payload__pr_url=pr_url) + .exists() + ): return - body = (message or "").strip() or "Turn complete." - if len(body) > _TURN_MESSAGE_MAX_CHARS: - body = body[: _TURN_MESSAGE_MAX_CHARS - 1] + "…" - mention = format_mention_token(creator.get_full_name() or creator.email, creator.email) - # payload.run_id is the dedupe key: a client already rendering this run's - # live agent turns can suppress the durable row (or vice versa). + label = _pr_display_label(pr_url) _create_agent_thread_message( task, - f"{mention} {body}", - event="turn_complete", - payload={"run_id": str(run_id)}, + f"[{label}]({pr_url}) has been opened", + event="pr_created", + payload={"pr_url": pr_url}, ) except Exception: - logger.exception("Failed to post turn-complete thread update", extra={"task_id": str(task_id)}) + logger.exception("Failed to post pr-created thread update", extra={"task_id": str(run.task_id)}) diff --git a/products/tasks/backend/temporal/process_task/activities/relay_sandbox_events.py b/products/tasks/backend/temporal/process_task/activities/relay_sandbox_events.py index 1c508a428ffd..7f83fb51a35d 100644 --- a/products/tasks/backend/temporal/process_task/activities/relay_sandbox_events.py +++ b/products/tasks/backend/temporal/process_task/activities/relay_sandbox_events.py @@ -19,7 +19,6 @@ from posthog.temporal.common.utils import close_db_connections -from products.tasks.backend.facade import api as tasks_facade from products.tasks.backend.logic.services.agent_command import validate_sandbox_url from products.tasks.backend.logic.services.connection_token import create_sandbox_connection_token from products.tasks.backend.logic.services.permission_broker import ( @@ -331,10 +330,6 @@ async def _relay_loop( last_audit_ts_ns: list[int] = [0] # track last agentsh audit timestamp # Brackets turn_started / turn_completed signals to the parent. slack_turn_active: list[bool] = [False] - # The agent's in-progress closing message for the current turn. Chunks - # accumulate; a new tool call or user message resets it, so at end-of-turn - # it holds the prose after the last tool call — what the thread update posts. - final_message_parts: list[str] = [] # ACP emits one tool_call + N tool_call_update per id; only render the start. emitted_tool_call_ids: set[str] = set() # Buffered prose + last flush time (monotonic); see TEXT_DELTA_FLUSH_INTERVAL_SECONDS. @@ -409,22 +404,6 @@ async def _relay_loop( # does sync Redis (cache.add) and a potential network call to # the feature-flag service. asyncio.create_task(asyncio.to_thread(_safe_dispatch_awaiting_input, task_run)) - if task_run is not None and task_run.mode != "interactive": - # Background run finished a turn — post its closing message - # into the task's thread so teammates following it see the - # outcome without a client open. Guards (flag, channel, - # cooldown) live in the facade; same thread hop as above - # for its sync I/O. - asyncio.create_task( - asyncio.to_thread( - tasks_facade.post_turn_complete_thread_update, - str(task_run.id), - str(task_run.task_id), - task_run.team_id, - message="".join(final_message_parts).strip() or None, - ) - ) - final_message_parts.clear() if is_agent_design_enabled and slack_turn_active[0] and workflow_handle is not None: slack_turn_active[0] = False # Awaited in order: the final prose must be recorded before @@ -435,9 +414,6 @@ async def _relay_loop( elif not agent_active[0] and _is_active_agent_update(event_data): agent_active[0] = True - if task_run is not None and task_run.mode != "interactive": - _track_final_message(event_data, final_message_parts) - # Agent-design signal fan-out: first session/update opens the # child relay; tool_call → step, agent_message_chunk → markdown. if is_agent_design_enabled and workflow_handle is not None: @@ -500,7 +476,6 @@ async def _relay_loop( reconnect_count += 1 # May have missed an end_of_turn on the dropped stream — assume idle until re-confirmed. agent_active[0] = False - final_message_parts.clear() # Drop un-flushed partial prose — the agent replays events on reconnect. pending_text_parts.clear() logger.warning( @@ -524,7 +499,6 @@ async def _relay_loop( # 5xx — transient server error, worth retrying reconnect_count += 1 agent_active[0] = False # missed-end_of_turn guard (see ReadTimeout above) - final_message_parts.clear() # Drop un-flushed partial prose — the agent replays events on reconnect. pending_text_parts.clear() logger.warning( @@ -539,7 +513,6 @@ async def _relay_loop( except (httpx.TransportError, httpx_sse.SSEError) as e: reconnect_count += 1 agent_active[0] = False # missed-end_of_turn guard (see ReadTimeout above) - final_message_parts.clear() # Drop un-flushed partial prose — the agent replays events on reconnect. pending_text_parts.clear() logger.warning( @@ -671,20 +644,6 @@ def _tool_args_preview(raw_input: Any) -> str | None: return one_line -def _track_final_message(event_data: dict, parts: list[str]) -> None: - """Accumulate agent_message_chunk text; a new tool call or user message resets, - so `parts` ends the turn holding only the agent's closing prose.""" - text = _extract_agent_message_text(event_data) - if text: - parts.append(text) - return - if not _is_session_update(event_data): - return - update = (event_data.get("notification", {}).get("params") or {}).get("update") or {} - if update.get("sessionUpdate") in ("tool_call", "user_message", "user_message_chunk"): - parts.clear() - - def _extract_agent_message_text(event_data: dict) -> str | None: """Text delta from an ACP agent_message_chunk session/update, else None.""" notification = event_data.get("notification", {}) diff --git a/products/tasks/backend/tests/test_thread_updates.py b/products/tasks/backend/tests/test_thread_updates.py index 2e7f71b270ca..92fa34693116 100644 --- a/products/tasks/backend/tests/test_thread_updates.py +++ b/products/tasks/backend/tests/test_thread_updates.py @@ -1,15 +1,19 @@ from unittest.mock import patch from django.core.cache import cache -from django.test import SimpleTestCase, TestCase +from django.test import TestCase from parameterized import parameterized from posthog.models import Organization, OrganizationMembership, Team, User +from posthog.models.scoping import team_scope -from products.tasks.backend.facade.api import post_canvas_created_thread_update, post_turn_complete_thread_update -from products.tasks.backend.models import Channel, Task, TaskRun, TaskThreadMessage, TaskThreadMessageMention -from products.tasks.backend.temporal.process_task.activities.relay_sandbox_events import _track_final_message +from products.tasks.backend.facade.api import ( + list_thread_messages, + post_canvas_created_thread_update, + post_pr_created_thread_update, +) +from products.tasks.backend.models import Channel, Task, TaskRun, TaskThreadMessage _FLAG_TARGET = "products.tasks.backend.facade.api.posthoganalytics.feature_enabled" @@ -40,51 +44,48 @@ def setUp(self) -> None: def _messages(self, task: Task) -> list[TaskThreadMessage]: return list(TaskThreadMessage.objects.for_team(self.team.id).filter(task=task).order_by("created_at")) - @parameterized.expand( - [ - ( - "relays_final_message", - "Shipped the canvas with three charts.", - "@[Casey Creator](creator@example.com) Shipped the canvas with three charts.", - ), - ("falls_back_without_message", None, "@[Casey Creator](creator@example.com) Turn complete."), - ] - ) @patch(_FLAG_TARGET, return_value=True) - def test_turn_complete_posts_authorless_message_mentioning_creator(self, _name, message, expected, _flag) -> None: - post_turn_complete_thread_update(str(self.task_run.id), str(self.task.id), self.team.id, message=message) + def test_pr_created_posts_authorless_artifact_message(self, _flag) -> None: + post_pr_created_thread_update(self.task_run, "https://github.com/posthog/posthog/pull/123") messages = self._messages(self.task) self.assertEqual(len(messages), 1) self.assertIsNone(messages[0].author_id) self.assertEqual(messages[0].author_kind, TaskThreadMessage.AuthorKind.AGENT) - self.assertEqual(messages[0].event, "turn_complete") - # run_id is the client's key for deduping this durable row against - # live session-derived agent turns. - self.assertEqual(messages[0].payload, {"run_id": str(self.task_run.id)}) - self.assertEqual(messages[0].content, expected) - # The creator's mention is indexed so it lands in their mentions feed. - self.assertTrue( - TaskThreadMessageMention.objects.for_team(self.team.id) - .filter(message=messages[0], mentioned_user=self.user) - .exists() + self.assertEqual(messages[0].event, "pr_created") + self.assertEqual(messages[0].payload, {"pr_url": "https://github.com/posthog/posthog/pull/123"}) + self.assertEqual( + messages[0].content, + "[posthog/posthog#123](https://github.com/posthog/posthog/pull/123) has been opened", ) @patch(_FLAG_TARGET, return_value=True) - def test_turn_complete_truncates_oversized_message(self, _flag) -> None: - post_turn_complete_thread_update(str(self.task_run.id), str(self.task.id), self.team.id, message="x" * 5000) + def test_pr_created_falls_back_to_url_label_for_non_github_urls(self, _flag) -> None: + post_pr_created_thread_update(self.task_run, "https://example.com/pr/9") - content = self._messages(self.task)[0].content - self.assertTrue(content.endswith("…")) - self.assertLess(len(content), 4100) + messages = self._messages(self.task) + self.assertEqual(len(messages), 1) + self.assertEqual( + messages[0].content, + "[https://example.com/pr/9](https://example.com/pr/9) has been opened", + ) @patch(_FLAG_TARGET, return_value=True) - def test_turn_complete_cooldown_collapses_duplicate_end_of_turn_events(self, _flag) -> None: - post_turn_complete_thread_update(str(self.task_run.id), str(self.task.id), self.team.id) - post_turn_complete_thread_update(str(self.task_run.id), str(self.task.id), self.team.id) + def test_pr_created_dedupes_per_pr_url(self, _flag) -> None: + # Both the agent-output path and the GitHub webhook backstop can announce + # the same PR; only one artifact row must land in the thread. + post_pr_created_thread_update(self.task_run, "https://github.com/posthog/posthog/pull/123") + post_pr_created_thread_update(self.task_run, "https://github.com/posthog/posthog/pull/123") self.assertEqual(len(self._messages(self.task)), 1) + @patch(_FLAG_TARGET, return_value=True) + def test_pr_created_posts_separate_messages_for_distinct_prs(self, _flag) -> None: + post_pr_created_thread_update(self.task_run, "https://github.com/posthog/posthog/pull/1") + post_pr_created_thread_update(self.task_run, "https://github.com/posthog/posthog/pull/2") + + self.assertEqual(len(self._messages(self.task)), 2) + @parameterized.expand( [ ("flag_off", False, True, True), @@ -93,7 +94,7 @@ def test_turn_complete_cooldown_collapses_duplicate_end_of_turn_events(self, _fl ] ) @patch(_FLAG_TARGET) - def test_turn_complete_skips(self, _name, flag_on, has_channel, has_creator, flag_mock) -> None: + def test_pr_created_skips(self, _name, flag_on, has_channel, has_creator, flag_mock) -> None: flag_mock.return_value = flag_on task = Task.objects.create( team=self.team, @@ -105,7 +106,7 @@ def test_turn_complete_skips(self, _name, flag_on, has_channel, has_creator, fla ) run = TaskRun.objects.create(task=task, team=self.team) - post_turn_complete_thread_update(str(run.id), str(task.id), self.team.id) + post_pr_created_thread_update(run, "https://github.com/posthog/posthog/pull/123") self.assertEqual(self._messages(task), []) @@ -157,33 +158,32 @@ def test_canvas_created_skips_when_flag_off(self, _flag) -> None: self.assertEqual(self._messages(self.task), []) + def test_list_thread_messages_excludes_legacy_turn_complete_rows(self) -> None: + # The thread is human-to-human plus artifacts: rows written back when the + # agent finished a turn (before that writeback was removed) must not + # resurface in the listing. + TaskThreadMessage.objects.for_team(self.team.id).create( + team=self.team, task=self.task, author=self.user, content="Kicking this off" + ) + TaskThreadMessage.objects.for_team(self.team.id).create( + team=self.team, + task=self.task, + author_kind=TaskThreadMessage.AuthorKind.AGENT, + event="turn_complete", + payload={"run_id": str(self.task_run.id)}, + content="@[Casey Creator](creator@example.com) Turn complete.", + ) + TaskThreadMessage.objects.for_team(self.team.id).create( + team=self.team, + task=self.task, + author_kind=TaskThreadMessage.AuthorKind.AGENT, + event="canvas_created", + payload={"canvas_name": "Signups", "canvas_url": None}, + content="Signups has been created", + ) -def _session_update(update: dict) -> dict: - return {"type": "notification", "notification": {"method": "session/update", "params": {"update": update}}} - - -def _chunk(text: str) -> dict: - return _session_update({"sessionUpdate": "agent_message_chunk", "content": {"type": "text", "text": text}}) - - -class TestTrackFinalMessage(SimpleTestCase): - def test_holds_only_prose_after_last_tool_call(self) -> None: - parts: list[str] = [] - for event in [ - _chunk("Let me look at the data first. "), - _session_update({"sessionUpdate": "tool_call", "toolCallId": "t1"}), - _session_update({"sessionUpdate": "tool_call_update", "toolCallId": "t1"}), - _chunk("Done. The canvas "), - _chunk("shows signups by week."), - ]: - _track_final_message(event, parts) - - self.assertEqual("".join(parts), "Done. The canvas shows signups by week.") - - @parameterized.expand([("user_message",), ("user_message_chunk",), ("tool_call",)]) - def test_resets_on(self, session_update: str) -> None: - parts = ["stale narration"] - - _track_final_message(_session_update({"sessionUpdate": session_update}), parts) + with team_scope(self.team.id): + messages = list_thread_messages(self.task.id, self.team.id, self.user.id) - self.assertEqual(parts, []) + assert messages is not None + self.assertEqual([message.event for message in messages], ["", "canvas_created"]) diff --git a/products/tasks/backend/webhooks.py b/products/tasks/backend/webhooks.py index b4d69b90a496..dbdfd8dc721e 100644 --- a/products/tasks/backend/webhooks.py +++ b/products/tasks/backend/webhooks.py @@ -15,7 +15,7 @@ from posthog.models.team.team import Team from products.signals.backend.models import InvalidStatusTransition, SignalReport -from products.tasks.backend.facade.api import signal_workflow_completion +from products.tasks.backend.facade.api import post_pr_created_thread_update, signal_workflow_completion from products.tasks.backend.facade.cancellation import cancel_task_run from products.tasks.backend.models import TaskRun from products.tasks.backend.prompts import WIZARD_HEAD_BRANCH_PREFIX @@ -218,6 +218,7 @@ def _record_run_pr_url(task_run: TaskRun, pr_url: str) -> None: """ if not _record_run_output_field(task_run, "pr_url", pr_url, "github_pr_webhook_record_pr_url_failed"): return + post_pr_created_thread_update(task_run, pr_url) # Publish-only (no append_log): the S3 run log has a live writer — the agent is streaming # log batches at exactly this moment — and append_log's read-modify-write would race it. # Tolerant: a stream hiccup must not fail the webhook; clients recover on refetch. From eea52de4776053805fc964a246960a47271fc81f Mon Sep 17 00:00:00 2001 From: Peter Kirkham Date: Thu, 23 Jul 2026 22:31:47 +0100 Subject: [PATCH 2/5] fix(tasks): harden pr_created thread announcements against races and unsafe URLs Address review findings: lock the task row so the agent-output path and webhook backstop can't both pass the pr_created dedupe check, reject pr_url values that aren't plain http(s) URLs before embedding them in the markdown message, and exclude legacy turn_complete mention rows from the mentions feed now that their messages are hidden from threads. Generated-By: PostHog Code Task-Id: 4ca58c61-95e3-4b36-a0df-474345b61483 --- products/tasks/backend/facade/api.py | 55 ++++++++++++++----- .../backend/tests/test_thread_updates.py | 52 +++++++++++++++++- 2 files changed, 92 insertions(+), 15 deletions(-) diff --git a/products/tasks/backend/facade/api.py b/products/tasks/backend/facade/api.py index 733ecea29033..3cc1de8e5904 100644 --- a/products/tasks/backend/facade/api.py +++ b/products/tasks/backend/facade/api.py @@ -5172,7 +5172,9 @@ def list_mentions( mentioned_user_id=user_id, # task__in keeps the visibility rules single-sourced in _visible_task_qs. task__in=_visible_task_qs(team_id, user_id), - ) + # Legacy turn_complete rows are hidden from threads (see list_thread_messages), + # so their indexed mentions must not surface notifications pointing at them. + ).exclude(message__event="turn_complete") if since is not None: qs = qs.filter(created_at__gt=since) mentions = qs.select_related("message__author", "task__channel").order_by("-created_at")[:limit] @@ -5327,6 +5329,25 @@ def post_canvas_created_thread_update( _GITHUB_PR_URL_PATTERN = re.compile(r"github\.com/([^/]+)/([^/]+)/pull/(\d+)", re.IGNORECASE) +# Characters that could break out of a markdown [label](url) token or smuggle +# extra markdown into the rendered thread message. +_PR_URL_UNSAFE_CHARS = set(" \t\n\r()[]<>\"'`\\") + +_PR_URL_MAX_LENGTH = 2048 + + +def _is_safe_pr_url(pr_url: str) -> bool: + """Whether ``pr_url`` is a plain http(s) URL safe to embed in a markdown link. + + ``pr_url`` originates from task-run output APIs, so it is caller-controlled. + Real PR URLs never contain whitespace, quotes, brackets, or parentheses; + anything that does is rejected rather than escaped. + """ + if not pr_url or len(pr_url) > _PR_URL_MAX_LENGTH or any(char in _PR_URL_UNSAFE_CHARS for char in pr_url): + return False + parsed = urlparse(pr_url) + return parsed.scheme in ("http", "https") and bool(parsed.netloc) + def _pr_display_label(pr_url: str) -> str: match = _GITHUB_PR_URL_PATTERN.search(pr_url) @@ -5346,24 +5367,30 @@ def post_pr_created_thread_update(run: TaskRun, pr_url: str) -> None: recording the PR must not fail because its announcement couldn't be written. """ try: + if not _is_safe_pr_url(pr_url): + return task = Task.objects.select_related("created_by").filter(id=run.task_id, team_id=run.team_id).first() # Threads hang off a task's channel feed; a channel-less task has no audience. if task is None or task.channel_id is None: return if task.created_by is None or not _agent_thread_updates_enabled(task.created_by): return - if ( - TaskThreadMessage.objects.for_team(task.team_id) - .filter(task_id=task.id, event="pr_created", payload__pr_url=pr_url) - .exists() - ): - return - label = _pr_display_label(pr_url) - _create_agent_thread_message( - task, - f"[{label}]({pr_url}) has been opened", - event="pr_created", - payload={"pr_url": pr_url}, - ) + # The agent-output path and the webhook backstop can race on the same PR; + # locking the task row makes the dedupe check-and-create atomic across them. + with transaction.atomic(): + Task.objects.select_for_update().filter(id=task.id).first() + if ( + TaskThreadMessage.objects.for_team(task.team_id) + .filter(task_id=task.id, event="pr_created", payload__pr_url=pr_url) + .exists() + ): + return + label = _pr_display_label(pr_url) + _create_agent_thread_message( + task, + f"[{label}]({pr_url}) has been opened", + event="pr_created", + payload={"pr_url": pr_url}, + ) except Exception: logger.exception("Failed to post pr-created thread update", extra={"task_id": str(run.task_id)}) diff --git a/products/tasks/backend/tests/test_thread_updates.py b/products/tasks/backend/tests/test_thread_updates.py index 92fa34693116..bf50f2371341 100644 --- a/products/tasks/backend/tests/test_thread_updates.py +++ b/products/tasks/backend/tests/test_thread_updates.py @@ -9,11 +9,12 @@ from posthog.models.scoping import team_scope from products.tasks.backend.facade.api import ( + list_mentions, list_thread_messages, post_canvas_created_thread_update, post_pr_created_thread_update, ) -from products.tasks.backend.models import Channel, Task, TaskRun, TaskThreadMessage +from products.tasks.backend.models import Channel, Task, TaskRun, TaskThreadMessage, TaskThreadMessageMention _FLAG_TARGET = "products.tasks.backend.facade.api.posthoganalytics.feature_enabled" @@ -86,6 +87,23 @@ def test_pr_created_posts_separate_messages_for_distinct_prs(self, _flag) -> Non self.assertEqual(len(self._messages(self.task)), 2) + @parameterized.expand( + [ + ("javascript_scheme", "javascript:alert(1)"), + ("markdown_breakout_paren", "https://example.com/pr)+[click](https://evil.example)"), + ("embedded_newline", "https://example.com/pr\n![tracker](https://evil.example/p.png)"), + ("embedded_bracket", "https://github.com/own]er/repo/pull/1"), + ("no_host", "https:///pull/1"), + ] + ) + @patch(_FLAG_TARGET, return_value=True) + def test_pr_created_skips_unsafe_urls(self, _name, pr_url, _flag) -> None: + # pr_url flows from task-run output into a markdown [label](url) token in a + # shared thread; anything that can't be a plain http(s) URL is dropped. + post_pr_created_thread_update(self.task_run, pr_url) + + self.assertEqual(self._messages(self.task), []) + @parameterized.expand( [ ("flag_off", False, True, True), @@ -187,3 +205,35 @@ def test_list_thread_messages_excludes_legacy_turn_complete_rows(self) -> None: assert messages is not None self.assertEqual([message.event for message in messages], ["", "canvas_created"]) + + def test_list_mentions_excludes_legacy_turn_complete_mentions(self) -> None: + # turn_complete messages @-mentioned the task creator and indexed that + # mention; with the messages hidden from threads, their mention rows must + # not surface notifications pointing at rows the thread no longer shows. + human_message = TaskThreadMessage.objects.for_team(self.team.id).create( + team=self.team, + task=self.task, + author=self.user, + content="@[Casey Creator](creator@example.com) thoughts?", + ) + turn_message = TaskThreadMessage.objects.for_team(self.team.id).create( + team=self.team, + task=self.task, + author_kind=TaskThreadMessage.AuthorKind.AGENT, + event="turn_complete", + payload={"run_id": str(self.task_run.id)}, + content="@[Casey Creator](creator@example.com) Turn complete.", + ) + for message in (human_message, turn_message): + TaskThreadMessageMention.objects.for_team(self.team.id).create( + team=self.team, + message=message, + task=self.task, + mentioned_user=self.user, + created_at=message.created_at, + ) + + with team_scope(self.team.id): + mentions = list_mentions(self.team.id, self.user.id) + + self.assertEqual([mention.message_id for mention in mentions], [human_message.id]) From 023efb1c59c6a1aa6ac43c39802c0acaeecbab9d Mon Sep 17 00:00:00 2001 From: Peter Kirkham Date: Thu, 23 Jul 2026 22:31:49 +0100 Subject: [PATCH 3/5] fix(tasks): post pr_created for channel-less tasks and log skip reasons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every task has a thread panel, so PR artifact announcements no longer require the task to be filed in a channel (canvas_created already behaved this way). Each remaining skip path (unsafe URL, missing creator, flag off) now logs its reason so a missing announcement is diagnosable. Adds end-to-end tests through update_task_run and set_task_run_output — the paths the agent actually uses to attach a PR. Generated-By: PostHog Code Task-Id: 4ca58c61-95e3-4b36-a0df-474345b61483 --- products/tasks/backend/facade/api.py | 10 ++- .../backend/tests/test_thread_updates.py | 61 +++++++++++++++++-- 2 files changed, 64 insertions(+), 7 deletions(-) diff --git a/products/tasks/backend/facade/api.py b/products/tasks/backend/facade/api.py index 3cc1de8e5904..bc0e2fe1eb7d 100644 --- a/products/tasks/backend/facade/api.py +++ b/products/tasks/backend/facade/api.py @@ -5368,12 +5368,18 @@ def post_pr_created_thread_update(run: TaskRun, pr_url: str) -> None: """ try: if not _is_safe_pr_url(pr_url): + logger.info("pr_created thread update skipped", extra={"task_id": str(run.task_id), "reason": "unsafe_url"}) return + # Unlike turn_complete's old channel guard, artifact rows post for + # channel-less tasks too: every task has a thread panel. task = Task.objects.select_related("created_by").filter(id=run.task_id, team_id=run.team_id).first() - # Threads hang off a task's channel feed; a channel-less task has no audience. - if task is None or task.channel_id is None: + if task is None: return if task.created_by is None or not _agent_thread_updates_enabled(task.created_by): + logger.info( + "pr_created thread update skipped", + extra={"task_id": str(task.id), "reason": "no_creator" if task.created_by is None else "flag_off"}, + ) return # The agent-output path and the webhook backstop can race on the same PR; # locking the task row makes the dedupe check-and-create atomic across them. diff --git a/products/tasks/backend/tests/test_thread_updates.py b/products/tasks/backend/tests/test_thread_updates.py index bf50f2371341..3a2104999881 100644 --- a/products/tasks/backend/tests/test_thread_updates.py +++ b/products/tasks/backend/tests/test_thread_updates.py @@ -13,6 +13,8 @@ list_thread_messages, post_canvas_created_thread_update, post_pr_created_thread_update, + set_task_run_output, + update_task_run, ) from products.tasks.backend.models import Channel, Task, TaskRun, TaskThreadMessage, TaskThreadMessageMention @@ -106,13 +108,12 @@ def test_pr_created_skips_unsafe_urls(self, _name, pr_url, _flag) -> None: @parameterized.expand( [ - ("flag_off", False, True, True), - ("no_channel", True, False, True), - ("no_creator", True, True, False), + ("flag_off", False, True), + ("no_creator", True, False), ] ) @patch(_FLAG_TARGET) - def test_pr_created_skips(self, _name, flag_on, has_channel, has_creator, flag_mock) -> None: + def test_pr_created_skips(self, _name, flag_on, has_creator, flag_mock) -> None: flag_mock.return_value = flag_on task = Task.objects.create( team=self.team, @@ -120,7 +121,7 @@ def test_pr_created_skips(self, _name, flag_on, has_channel, has_creator, flag_m description="", origin_product=Task.OriginProduct.USER_CREATED, created_by=self.user if has_creator else None, - channel=self.channel if has_channel else None, + channel=self.channel, ) run = TaskRun.objects.create(task=task, team=self.team) @@ -128,6 +129,56 @@ def test_pr_created_skips(self, _name, flag_on, has_channel, has_creator, flag_m self.assertEqual(self._messages(task), []) + @patch(_FLAG_TARGET, return_value=True) + def test_pr_created_posts_when_run_patch_records_pr_url(self, _flag) -> None: + # The agent attaches a PR by PATCHing the run's output — the path the + # desktop/cloud agent actually uses (attachPullRequestToTask). + with team_scope(self.team.id): + update_task_run( + self.task_run.id, + self.task.id, + self.team.id, + validated_data={"output": {"pr_url": "https://github.com/posthog/posthog/pull/321"}}, + ) + + messages = self._messages(self.task) + self.assertEqual([message.event for message in messages], ["pr_created"]) + self.assertEqual(messages[0].payload, {"pr_url": "https://github.com/posthog/posthog/pull/321"}) + + @patch(_FLAG_TARGET, return_value=True) + def test_pr_created_posts_when_set_output_records_pr_url(self, _flag) -> None: + with team_scope(self.team.id): + set_task_run_output( + self.task_run.id, + self.task.id, + self.team.id, + output={"pr_url": "https://github.com/posthog/posthog/pull/654"}, + ) + + messages = self._messages(self.task) + self.assertEqual([message.event for message in messages], ["pr_created"]) + + @patch(_FLAG_TARGET, return_value=True) + def test_pr_created_posts_for_channel_less_tasks(self, _flag) -> None: + # Threads exist per-task, not only per-channel: a task filed outside a + # channel still has a thread panel, and its PR artifact must land there + # (canvas_created behaves the same way). + task = Task.objects.create( + team=self.team, + title="Channel-less task", + description="", + origin_product=Task.OriginProduct.USER_CREATED, + created_by=self.user, + channel=None, + ) + run = TaskRun.objects.create(task=task, team=self.team) + + post_pr_created_thread_update(run, "https://github.com/posthog/posthog/pull/123") + + messages = self._messages(task) + self.assertEqual(len(messages), 1) + self.assertEqual(messages[0].event, "pr_created") + @parameterized.expand( [ ( From 3049ff4199d319b9e3f9040e07b506b327644358 Mon Sep 17 00:00:00 2001 From: Peter Kirkham Date: Thu, 23 Jul 2026 22:31:51 +0100 Subject: [PATCH 4/5] fix(tasks): address pr artifact review feedback Generated-By: PostHog Code Task-Id: 3afd10d7-2202-4615-b3c8-43d7373766b4 --- products/tasks/backend/facade/api.py | 7 ++-- .../backend/tests/test_thread_updates.py | 12 +++++-- products/tasks/backend/tests/test_webhooks.py | 34 ++++++++++++++++++- products/tasks/backend/webhooks.py | 5 ++- 4 files changed, 51 insertions(+), 7 deletions(-) diff --git a/products/tasks/backend/facade/api.py b/products/tasks/backend/facade/api.py index bc0e2fe1eb7d..807288bbc911 100644 --- a/products/tasks/backend/facade/api.py +++ b/products/tasks/backend/facade/api.py @@ -5327,7 +5327,7 @@ def post_canvas_created_thread_update( logger.exception("Failed to post canvas-created thread update", extra={"task_id": str(task_id)}) -_GITHUB_PR_URL_PATTERN = re.compile(r"github\.com/([^/]+)/([^/]+)/pull/(\d+)", re.IGNORECASE) +_GITHUB_PR_PATH_PATTERN = re.compile(r"/([^/]+)/([^/]+)/pull/(\d+)/?", re.IGNORECASE) # Characters that could break out of a markdown [label](url) token or smuggle # extra markdown into the rendered thread message. @@ -5350,7 +5350,10 @@ def _is_safe_pr_url(pr_url: str) -> bool: def _pr_display_label(pr_url: str) -> str: - match = _GITHUB_PR_URL_PATTERN.search(pr_url) + parsed = urlparse(pr_url) + if parsed.hostname is None or parsed.hostname.lower() != "github.com": + return pr_url + match = _GITHUB_PR_PATH_PATTERN.fullmatch(parsed.path) if match: owner, repo, number = match.groups() return f"{owner}/{repo}#{number}" diff --git a/products/tasks/backend/tests/test_thread_updates.py b/products/tasks/backend/tests/test_thread_updates.py index 3a2104999881..79de4d75874c 100644 --- a/products/tasks/backend/tests/test_thread_updates.py +++ b/products/tasks/backend/tests/test_thread_updates.py @@ -62,15 +62,21 @@ def test_pr_created_posts_authorless_artifact_message(self, _flag) -> None: "[posthog/posthog#123](https://github.com/posthog/posthog/pull/123) has been opened", ) + @parameterized.expand( + [ + ("non_github", "https://example.com/pr/9"), + ("github_in_path", "https://evil.example/github.com/posthog/posthog/pull/123"), + ] + ) @patch(_FLAG_TARGET, return_value=True) - def test_pr_created_falls_back_to_url_label_for_non_github_urls(self, _flag) -> None: - post_pr_created_thread_update(self.task_run, "https://example.com/pr/9") + def test_pr_created_falls_back_to_url_label_for_non_github_urls(self, _name, pr_url, _flag) -> None: + post_pr_created_thread_update(self.task_run, pr_url) messages = self._messages(self.task) self.assertEqual(len(messages), 1) self.assertEqual( messages[0].content, - "[https://example.com/pr/9](https://example.com/pr/9) has been opened", + f"[{pr_url}]({pr_url}) has been opened", ) @patch(_FLAG_TARGET, return_value=True) diff --git a/products/tasks/backend/tests/test_webhooks.py b/products/tasks/backend/tests/test_webhooks.py index 90e5e3a1743b..d33ab3af3567 100644 --- a/products/tasks/backend/tests/test_webhooks.py +++ b/products/tasks/backend/tests/test_webhooks.py @@ -18,7 +18,7 @@ from products.signals.backend.models import SignalReport from products.signals.backend.task_run_artefacts import append_task_run_artefact -from products.tasks.backend.models import Task, TaskRun +from products.tasks.backend.models import Task, TaskRun, TaskThreadMessage from products.tasks.backend.webhooks import _account_type, find_task_run @@ -445,6 +445,38 @@ def test_pr_opened_backfills_pr_url_on_branch_match(self, mock_capture, mock_get assert run.output is not None self.assertEqual(run.output["pr_url"], pr_url) + @patch("products.tasks.backend.facade.api.posthoganalytics.feature_enabled", return_value=True) + @patch("products.tasks.backend.facade.webhooks.get_github_webhook_secret") + @patch("products.tasks.backend.models.posthoganalytics.capture") + def test_pr_opened_repairs_missing_artifact_for_existing_pr_url( + self, mock_capture, mock_get_secret, mock_feature_enabled + ) -> None: + mock_get_secret.return_value = self.webhook_secret + pr_url = "https://github.com/posthog/posthog/pull/780" + TaskRun.objects.create( + task=self.task, + team=self.team, + status=TaskRun.Status.IN_PROGRESS, + branch="feature/missing-artifact", + output={"pr_url": pr_url}, + ) + payload = { + "action": "opened", + "pull_request": { + "html_url": pr_url, + "merged": False, + "head": {"ref": "feature/missing-artifact", "repo": {"full_name": "posthog/posthog"}}, + }, + "repository": {"full_name": "posthog/posthog"}, + } + + response = self._make_webhook_request(payload) + + self.assertEqual(response.status_code, 200) + self.assertTrue( + TaskThreadMessage.objects.for_team(self.team.id).filter(task=self.task, payload__pr_url=pr_url).exists() + ) + @patch("products.tasks.backend.facade.webhooks.get_github_webhook_secret") @patch("products.tasks.backend.models.posthoganalytics.capture") def test_pr_opened_backfills_pr_url_on_wizard_head_branch_match(self, mock_capture, mock_get_secret): diff --git a/products/tasks/backend/webhooks.py b/products/tasks/backend/webhooks.py index dbdfd8dc721e..b6b34dfaf16d 100644 --- a/products/tasks/backend/webhooks.py +++ b/products/tasks/backend/webhooks.py @@ -216,9 +216,12 @@ def _record_run_pr_url(task_run: TaskRun, pr_url: str) -> None: ``output.pr_url`` stays empty, so inbox notifications, the CI follow-up loop, and later webhook lookups never resolve the PR. """ - if not _record_run_output_field(task_run, "pr_url", pr_url, "github_pr_webhook_record_pr_url_failed"): + recorded = _record_run_output_field(task_run, "pr_url", pr_url, "github_pr_webhook_record_pr_url_failed") + if not recorded and not TaskRun.objects.filter(id=task_run.id, output__pr_url=pr_url).exists(): return post_pr_created_thread_update(task_run, pr_url) + if not recorded: + return # Publish-only (no append_log): the S3 run log has a live writer — the agent is streaming # log batches at exactly this moment — and append_log's read-modify-write would race it. # Tolerant: a stream hiccup must not fail the webhook; clients recover on refetch. From ac44ec10af41de92a95989da65c2d9eb661698bf Mon Sep 17 00:00:00 2001 From: "tests-posthog[bot]" <250237707+tests-posthog[bot]@users.noreply.github.com> Date: Thu, 23 Jul 2026 21:36:23 +0000 Subject: [PATCH 5/5] chore: update OpenAPI generated types --- services/mcp/src/tools/generated/actions.ts | 10 +++---- .../mcp/src/tools/generated/agent_platform.ts | 4 +-- .../src/tools/generated/ai_observability.ts | 8 ++--- services/mcp/src/tools/generated/alerts.ts | 6 ++-- .../mcp/src/tools/generated/annotations.ts | 8 ++--- .../mcp/src/tools/generated/batch_exports.ts | 6 ++-- .../src/tools/generated/business_knowledge.ts | 8 ++--- .../tools/generated/cdp_function_templates.ts | 6 ++-- .../mcp/src/tools/generated/cdp_functions.ts | 6 ++-- services/mcp/src/tools/generated/cohorts.ts | 10 +++---- .../mcp/src/tools/generated/conversations.ts | 6 ++-- services/mcp/src/tools/generated/core.ts | 8 ++--- .../src/tools/generated/customer_analytics.ts | 8 ++--- .../mcp/src/tools/generated/dashboards.ts | 20 ++++++------- .../mcp/src/tools/generated/data_catalog.ts | 16 +++++----- .../src/tools/generated/data_management.ts | 6 ++-- .../mcp/src/tools/generated/data_warehouse.ts | 6 ++-- services/mcp/src/tools/generated/docs.ts | 4 +-- .../tools/generated/early_access_features.ts | 6 ++-- .../src/tools/generated/email_templates.ts | 10 +++---- services/mcp/src/tools/generated/endpoints.ts | 6 ++-- .../tools/generated/engineering_analytics.ts | 6 ++-- .../mcp/src/tools/generated/error_tracking.ts | 8 ++--- .../tools/generated/error_tracking_alerts.ts | 6 ++-- .../mcp/src/tools/generated/experiments.ts | 12 ++++---- .../mcp/src/tools/generated/feature_flags.ts | 12 ++++---- .../mcp/src/tools/generated/field_notes.ts | 6 ++-- .../mcp/src/tools/generated/health_issues.ts | 6 ++-- .../mcp/src/tools/generated/integrations.ts | 6 ++-- services/mcp/src/tools/generated/logs.ts | 6 ++-- .../src/tools/generated/managed_migrations.ts | 6 ++-- .../tools/generated/marketing_analytics.ts | 4 +-- .../mcp/src/tools/generated/mcp_analytics.ts | 8 ++--- services/mcp/src/tools/generated/mcp_store.ts | 6 ++-- services/mcp/src/tools/generated/metrics.ts | 6 ++-- services/mcp/src/tools/generated/notebooks.ts | 6 ++-- services/mcp/src/tools/generated/persons.ts | 8 ++--- .../src/tools/generated/platform_features.ts | 30 +++++++++---------- .../src/tools/generated/product_analytics.ts | 8 ++--- .../mcp/src/tools/generated/proxy-records.ts | 6 ++-- .../mcp/src/tools/generated/query-wrappers.ts | 2 +- services/mcp/src/tools/generated/reminders.ts | 6 ++-- services/mcp/src/tools/generated/replay.ts | 10 +++---- .../mcp/src/tools/generated/replay_vision.ts | 6 ++-- services/mcp/src/tools/generated/signals.ts | 22 +++++++------- services/mcp/src/tools/generated/skills.ts | 4 +-- services/mcp/src/tools/generated/stamphog.ts | 6 ++-- .../mcp/src/tools/generated/subscriptions.ts | 8 ++--- services/mcp/src/tools/generated/surveys.ts | 8 ++--- services/mcp/src/tools/generated/tasks.ts | 18 +++++------ services/mcp/src/tools/generated/tracing.ts | 8 ++--- .../src/tools/generated/user_interviews.ts | 8 ++--- .../mcp/src/tools/generated/visual_review.ts | 8 ++--- .../src/tools/generated/warehouse_sources.ts | 8 ++--- .../mcp/src/tools/generated/web_analytics.ts | 6 ++-- services/mcp/src/tools/generated/workflows.ts | 10 +++---- 56 files changed, 176 insertions(+), 286 deletions(-) diff --git a/services/mcp/src/tools/generated/actions.ts b/services/mcp/src/tools/generated/actions.ts index 20794a3e0675..eb6cca916925 100644 --- a/services/mcp/src/tools/generated/actions.ts +++ b/services/mcp/src/tools/generated/actions.ts @@ -1,13 +1,7 @@ // AUTO-GENERATED from products/actions/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' -import { withUiApp } from '@/resources/ui-apps' -import { castStringToInt } from '@/tools/cast-helpers' - import { ActionsCreateBody, ActionsDestroyParams, @@ -16,6 +10,10 @@ import { ActionsPartialUpdateParams, ActionsRetrieveParams, } from '@/generated/actions/api' +import { withUiApp } from '@/resources/ui-apps' +import { castStringToInt } from '@/tools/cast-helpers' +import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const ActionCreateSchema = ActionsCreateBody.omit({ _create_in_folder: true }).extend({ name: ActionsCreateBody.shape['name'].describe('Name of the action (must be unique within the project)'), diff --git a/services/mcp/src/tools/generated/agent_platform.ts b/services/mcp/src/tools/generated/agent_platform.ts index 3f7c1bc592d2..67bc289cf2f4 100644 --- a/services/mcp/src/tools/generated/agent_platform.ts +++ b/services/mcp/src/tools/generated/agent_platform.ts @@ -1,10 +1,7 @@ // AUTO-GENERATED from services/mcp/definitions/agent_platform.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' - import type { Schemas } from '@/api/generated' - import { AgentApplicationsCreateBody, AgentApplicationsDestroyParams, @@ -66,6 +63,7 @@ import { AgentRevisionsEnvKeysGetParams, AgentRevisionsEnvKeysListParams, } from '@/generated/agent_platform/api' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const AgentApplicationsCreateSchema = AgentApplicationsCreateBody diff --git a/services/mcp/src/tools/generated/ai_observability.ts b/services/mcp/src/tools/generated/ai_observability.ts index d21b03e4859b..e6554c360de3 100644 --- a/services/mcp/src/tools/generated/ai_observability.ts +++ b/services/mcp/src/tools/generated/ai_observability.ts @@ -1,12 +1,7 @@ // AUTO-GENERATED from products/ai_observability/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' -import { PromptListInputSchema, ScoreDefinitionConfigSchema } from '@/schema/tool-inputs' - import { EvaluationRunsCreateBody, EvaluationsCreateBody, @@ -77,6 +72,9 @@ import { TaggersListQueryParams, TaggersTestHogCreateBody, } from '@/generated/ai_observability/api' +import { PromptListInputSchema, ScoreDefinitionConfigSchema } from '@/schema/tool-inputs' +import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const LlmaClusteringConfigGetSchema = z.object({}) diff --git a/services/mcp/src/tools/generated/alerts.ts b/services/mcp/src/tools/generated/alerts.ts index fa04c73f75c2..4d42f258738e 100644 --- a/services/mcp/src/tools/generated/alerts.ts +++ b/services/mcp/src/tools/generated/alerts.ts @@ -1,11 +1,7 @@ // AUTO-GENERATED from products/alerts/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' - import { AlertsCreateBody, AlertsDestroyParams, @@ -16,6 +12,8 @@ import { AlertsRetrieveQueryParams, AlertsSimulateCreateBody, } from '@/generated/alerts/api' +import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const AlertCreateSchema = AlertsCreateBody diff --git a/services/mcp/src/tools/generated/annotations.ts b/services/mcp/src/tools/generated/annotations.ts index 8123570f9e82..ce51fff73175 100644 --- a/services/mcp/src/tools/generated/annotations.ts +++ b/services/mcp/src/tools/generated/annotations.ts @@ -1,12 +1,7 @@ // AUTO-GENERATED from products/annotations/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, omitResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' -import { castStringToInt } from '@/tools/cast-helpers' - import { AnnotationsCreateBody, AnnotationsDestroyParams, @@ -15,6 +10,9 @@ import { AnnotationsPartialUpdateParams, AnnotationsRetrieveParams, } from '@/generated/annotations/api' +import { castStringToInt } from '@/tools/cast-helpers' +import { withPostHogUrl, omitResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const AnnotationCreateSchema = AnnotationsCreateBody.omit({ creation_type: true, diff --git a/services/mcp/src/tools/generated/batch_exports.ts b/services/mcp/src/tools/generated/batch_exports.ts index 48641cfcda79..c441fa8a02a7 100644 --- a/services/mcp/src/tools/generated/batch_exports.ts +++ b/services/mcp/src/tools/generated/batch_exports.ts @@ -1,11 +1,7 @@ // AUTO-GENERATED from products/batch_exports/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, pickResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' - import { BatchExportsCreateBody, BatchExportsDestroyParams, @@ -18,6 +14,8 @@ import { FileDownloadBatchExportsCreateBody, FileDownloadBatchExportsRetrieveParams, } from '@/generated/batch_exports/api' +import { withPostHogUrl, pickResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const BatchExportCreateSchema = BatchExportsCreateBody diff --git a/services/mcp/src/tools/generated/business_knowledge.ts b/services/mcp/src/tools/generated/business_knowledge.ts index a79ac458c600..b1736d6b493c 100644 --- a/services/mcp/src/tools/generated/business_knowledge.ts +++ b/services/mcp/src/tools/generated/business_knowledge.ts @@ -1,12 +1,7 @@ // AUTO-GENERATED from products/business_knowledge/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, pickResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' -import { BusinessKnowledgeUrlSourceCreateSchema } from '@/schema/tool-inputs' - import { BusinessKnowledgeDocumentsSearchListQueryParams, BusinessKnowledgeDocumentsWindowListParams, @@ -17,6 +12,9 @@ import { BusinessKnowledgeSourcesPartialUpdateParams, BusinessKnowledgeSourcesRetrieveParams, } from '@/generated/business_knowledge/api' +import { BusinessKnowledgeUrlSourceCreateSchema } from '@/schema/tool-inputs' +import { withPostHogUrl, pickResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const BusinessKnowledgeDocumentWindowRetrieveSchema = BusinessKnowledgeDocumentsWindowListParams.omit({ project_id: true, diff --git a/services/mcp/src/tools/generated/cdp_function_templates.ts b/services/mcp/src/tools/generated/cdp_function_templates.ts index 0a66f8089124..0da3a2798e56 100644 --- a/services/mcp/src/tools/generated/cdp_function_templates.ts +++ b/services/mcp/src/tools/generated/cdp_function_templates.ts @@ -1,15 +1,13 @@ // AUTO-GENERATED from products/cdp/mcp/cdp_function_templates.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, pickResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' - import { HogFunctionTemplatesListQueryParams, HogFunctionTemplatesRetrieveParams, } from '@/generated/cdp_function_templates/api' +import { withPostHogUrl, pickResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const CdpFunctionTemplatesListSchema = HogFunctionTemplatesListQueryParams diff --git a/services/mcp/src/tools/generated/cdp_functions.ts b/services/mcp/src/tools/generated/cdp_functions.ts index 9fced4e9eaf5..56788dd29a21 100644 --- a/services/mcp/src/tools/generated/cdp_functions.ts +++ b/services/mcp/src/tools/generated/cdp_functions.ts @@ -1,11 +1,7 @@ // AUTO-GENERATED from products/cdp/mcp/cdp_functions.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, omitResponseFields, pickResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' - import { HogFunctionsCreateBody, HogFunctionsDestroyParams, @@ -21,6 +17,8 @@ import { HogFunctionsRearrangePartialUpdateBody, HogFunctionsRetrieveParams, } from '@/generated/cdp_functions/api' +import { withPostHogUrl, omitResponseFields, pickResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const CdpFunctionsCreateSchema = HogFunctionsCreateBody.extend({ type: HogFunctionsCreateBody.shape['type'].describe( diff --git a/services/mcp/src/tools/generated/cohorts.ts b/services/mcp/src/tools/generated/cohorts.ts index 367e938fe062..b5142fad8aba 100644 --- a/services/mcp/src/tools/generated/cohorts.ts +++ b/services/mcp/src/tools/generated/cohorts.ts @@ -1,13 +1,7 @@ // AUTO-GENERATED from products/cohorts/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, pickResponseFields, omitResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' -import { withUiApp } from '@/resources/ui-apps' -import { castStringToInt } from '@/tools/cast-helpers' - import { CohortsAddPersonsToStaticCohortPartialUpdateBody, CohortsAddPersonsToStaticCohortPartialUpdateParams, @@ -19,6 +13,10 @@ import { CohortsRemovePersonFromStaticCohortPartialUpdateParams, CohortsRetrieveParams, } from '@/generated/cohorts/api' +import { withUiApp } from '@/resources/ui-apps' +import { castStringToInt } from '@/tools/cast-helpers' +import { withPostHogUrl, pickResponseFields, omitResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const CohortsAddPersonsToStaticCohortPartialUpdateSchema = CohortsAddPersonsToStaticCohortPartialUpdateParams.omit({ project_id: true, diff --git a/services/mcp/src/tools/generated/conversations.ts b/services/mcp/src/tools/generated/conversations.ts index 94e6d4172423..66945a46b415 100644 --- a/services/mcp/src/tools/generated/conversations.ts +++ b/services/mcp/src/tools/generated/conversations.ts @@ -1,11 +1,7 @@ // AUTO-GENERATED from products/conversations/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, pickResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' - import { ConversationsTicketsListQueryParams, ConversationsTicketsMessagesListParams, @@ -17,6 +13,8 @@ import { ConversationsTicketsRetrieveParams, ConversationsViewsListQueryParams, } from '@/generated/conversations/api' +import { withPostHogUrl, pickResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const ConversationsTicketsListSchema = ConversationsTicketsListQueryParams diff --git a/services/mcp/src/tools/generated/core.ts b/services/mcp/src/tools/generated/core.ts index bfbc3da2f48f..4f75c3a51080 100644 --- a/services/mcp/src/tools/generated/core.ts +++ b/services/mcp/src/tools/generated/core.ts @@ -1,12 +1,7 @@ // AUTO-GENERATED from services/mcp/definitions/core.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { omitResponseFields, pickResponseFields } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' -import { castStringToInt } from '@/tools/cast-helpers' - import { DesktopFileSystemCanvasPartialUpdateBody, DesktopFileSystemCanvasPartialUpdateParams, @@ -23,6 +18,9 @@ import { UsersPartialUpdateParams, UsersRetrieveParams, } from '@/generated/core/api' +import { castStringToInt } from '@/tools/cast-helpers' +import { omitResponseFields, pickResponseFields } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const DesktopFileSystemCanvasPartialUpdateSchema = DesktopFileSystemCanvasPartialUpdateParams.omit({ project_id: true }) .extend(DesktopFileSystemCanvasPartialUpdateBody.shape) diff --git a/services/mcp/src/tools/generated/customer_analytics.ts b/services/mcp/src/tools/generated/customer_analytics.ts index b9d5c494401e..f0de9e101c00 100644 --- a/services/mcp/src/tools/generated/customer_analytics.ts +++ b/services/mcp/src/tools/generated/customer_analytics.ts @@ -1,12 +1,7 @@ // AUTO-GENERATED from products/customer_analytics/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' -import { UsageMetricFiltersSchema } from '@/schema/tool-inputs' - import { AccountRelationshipDefinitionsCreateBody, AccountRelationshipDefinitionsDestroyParams, @@ -59,6 +54,9 @@ import { GroupsTypesMetricsPartialUpdateParams, GroupsTypesMetricsRetrieveParams, } from '@/generated/customer_analytics/api' +import { UsageMetricFiltersSchema } from '@/schema/tool-inputs' +import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const AccountRelationshipDefinitionsCreateSchema = AccountRelationshipDefinitionsCreateBody diff --git a/services/mcp/src/tools/generated/dashboards.ts b/services/mcp/src/tools/generated/dashboards.ts index 9a1bd022ed80..ac2f2c169e42 100644 --- a/services/mcp/src/tools/generated/dashboards.ts +++ b/services/mcp/src/tools/generated/dashboards.ts @@ -1,18 +1,7 @@ // AUTO-GENERATED from products/dashboards/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { - withPostHogUrl, - omitResponseFields, - withInformationalResponse, - type WithPostHogUrl, - type WithInformationalResponse, -} from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' -import { castStringToInt } from '@/tools/cast-helpers' - import { DashboardTemplatesListQueryParams, DashboardTemplatesRetrieveParams, @@ -46,6 +35,15 @@ import { DashboardsWidgetsBatchCreateBody, DashboardsWidgetsBatchCreateParams, } from '@/generated/dashboards/api' +import { castStringToInt } from '@/tools/cast-helpers' +import { + withPostHogUrl, + omitResponseFields, + withInformationalResponse, + type WithPostHogUrl, + type WithInformationalResponse, +} from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const DashboardCreateSchema = DashboardsCreateQueryParams.omit({ format: true }).extend(DashboardsCreateBody.shape) diff --git a/services/mcp/src/tools/generated/data_catalog.ts b/services/mcp/src/tools/generated/data_catalog.ts index 853020c1d68a..0863b51ac4c7 100644 --- a/services/mcp/src/tools/generated/data_catalog.ts +++ b/services/mcp/src/tools/generated/data_catalog.ts @@ -1,16 +1,7 @@ // AUTO-GENERATED from products/data_catalog/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' - import type { Schemas } from '@/api/generated' -import { getConfirmedActionRuntime } from '@/tools/confirmed-action-registry' -import { - executeConfirmedAction, - prepareConfirmedAction, - type PrepareConfirmedActionResult, -} from '@/tools/confirmed-action-runtime' - import { DataCatalogCertificationsCertifyCreateParams, DataCatalogCertificationsCreateBody, @@ -27,6 +18,13 @@ import { DataCatalogRelationshipProposalsRejectCreateBody, DataCatalogRelationshipProposalsRejectCreateParams, } from '@/generated/data_catalog/api' +import { getConfirmedActionRuntime } from '@/tools/confirmed-action-registry' +import { + executeConfirmedAction, + prepareConfirmedAction, + type PrepareConfirmedActionResult, +} from '@/tools/confirmed-action-runtime' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const DataCatalogCertificationCertifySchema = DataCatalogCertificationsCertifyCreateParams.omit({ project_id: true }) diff --git a/services/mcp/src/tools/generated/data_management.ts b/services/mcp/src/tools/generated/data_management.ts index 118e4fb577f4..8a808dcfc66e 100644 --- a/services/mcp/src/tools/generated/data_management.ts +++ b/services/mcp/src/tools/generated/data_management.ts @@ -1,12 +1,10 @@ // AUTO-GENERATED from services/mcp/definitions/data_management.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' - import { IngestionWarningsV2ListQueryParams } from '@/generated/data_management/api' +import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const IngestionWarningsListSchema = IngestionWarningsV2ListQueryParams diff --git a/services/mcp/src/tools/generated/data_warehouse.ts b/services/mcp/src/tools/generated/data_warehouse.ts index 8e9252661dbd..3e2392023479 100644 --- a/services/mcp/src/tools/generated/data_warehouse.ts +++ b/services/mcp/src/tools/generated/data_warehouse.ts @@ -1,11 +1,7 @@ // AUTO-GENERATED from products/data_warehouse/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' - import { InsightVariablesCreateBody, InsightVariablesDestroyParams, @@ -32,6 +28,8 @@ import { WarehouseSavedQueriesRunHistoryRetrieveParams, WarehouseTablesRefreshSchemaCreateParams, } from '@/generated/data_warehouse/api' +import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const SavedQueryColumnAnnotationsCreateSchema = SavedQueryColumnAnnotationsCreateBody.extend({ column_name: SavedQueryColumnAnnotationsCreateBody.shape['column_name'].describe( diff --git a/services/mcp/src/tools/generated/docs.ts b/services/mcp/src/tools/generated/docs.ts index 22bd38d828c8..5c196ff3806f 100644 --- a/services/mcp/src/tools/generated/docs.ts +++ b/services/mcp/src/tools/generated/docs.ts @@ -1,11 +1,9 @@ // AUTO-GENERATED from services/mcp/definitions/docs.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' - import type { Schemas } from '@/api/generated' - import { DocsSearchBody } from '@/generated/docs/api' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const DocsSearchSchema = DocsSearchBody diff --git a/services/mcp/src/tools/generated/early_access_features.ts b/services/mcp/src/tools/generated/early_access_features.ts index 04a436833083..8a6ed4eff7db 100644 --- a/services/mcp/src/tools/generated/early_access_features.ts +++ b/services/mcp/src/tools/generated/early_access_features.ts @@ -1,11 +1,7 @@ // AUTO-GENERATED from products/early_access_features/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' - import { EarlyAccessFeatureCreateBody, EarlyAccessFeatureDestroyParams, @@ -14,6 +10,8 @@ import { EarlyAccessFeaturePartialUpdateParams, EarlyAccessFeatureRetrieveParams, } from '@/generated/early_access_features/api' +import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const EarlyAccessFeatureCreateSchema = EarlyAccessFeatureCreateBody.omit({ _create_in_folder: true }) diff --git a/services/mcp/src/tools/generated/email_templates.ts b/services/mcp/src/tools/generated/email_templates.ts index b6dbc72ca767..7ab4573a7d25 100644 --- a/services/mcp/src/tools/generated/email_templates.ts +++ b/services/mcp/src/tools/generated/email_templates.ts @@ -1,13 +1,7 @@ // AUTO-GENERATED from products/workflows/mcp/email_templates.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, omitResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' -import { withUiApp } from '@/resources/ui-apps' -import { EmailTemplateDesignPatchSchema } from '@/schema/tool-inputs' - import { MessagingTemplatesCreateBody, MessagingTemplatesListQueryParams, @@ -15,6 +9,10 @@ import { MessagingTemplatesPartialUpdateParams, MessagingTemplatesRetrieveParams, } from '@/generated/email_templates/api' +import { withUiApp } from '@/resources/ui-apps' +import { EmailTemplateDesignPatchSchema } from '@/schema/tool-inputs' +import { withPostHogUrl, omitResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const WorkflowsCreateEmailTemplateSchema = MessagingTemplatesCreateBody diff --git a/services/mcp/src/tools/generated/endpoints.ts b/services/mcp/src/tools/generated/endpoints.ts index 471c0162bf0b..46e2dad828a4 100644 --- a/services/mcp/src/tools/generated/endpoints.ts +++ b/services/mcp/src/tools/generated/endpoints.ts @@ -1,11 +1,7 @@ // AUTO-GENERATED from products/endpoints/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' - import { EndpointsCreateBody, EndpointsDestroyParams, @@ -28,6 +24,8 @@ import { EndpointsVersionsListParams, EndpointsVersionsListQueryParams, } from '@/generated/endpoints/api' +import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const EndpointCreateSchema = EndpointsCreateBody.omit({ is_active: true, diff --git a/services/mcp/src/tools/generated/engineering_analytics.ts b/services/mcp/src/tools/generated/engineering_analytics.ts index e1143485edc2..2297d23d9694 100644 --- a/services/mcp/src/tools/generated/engineering_analytics.ts +++ b/services/mcp/src/tools/generated/engineering_analytics.ts @@ -1,11 +1,7 @@ // AUTO-GENERATED from products/engineering_analytics/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' - import { EngineeringAnalyticsBrokenTestsQueryParams, EngineeringAnalyticsCiFailureLogsQueryParams, @@ -19,6 +15,8 @@ import { EngineeringAnalyticsWorkflowJobsQueryParams, EngineeringAnalyticsWorkflowRunnerCostsQueryParams, } from '@/generated/engineering_analytics/api' +import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const EngineeringAnalyticsBrokenTestsSchema = EngineeringAnalyticsBrokenTestsQueryParams diff --git a/services/mcp/src/tools/generated/error_tracking.ts b/services/mcp/src/tools/generated/error_tracking.ts index 73d96c218cc8..6366810730d5 100644 --- a/services/mcp/src/tools/generated/error_tracking.ts +++ b/services/mcp/src/tools/generated/error_tracking.ts @@ -1,12 +1,7 @@ // AUTO-GENERATED from products/error_tracking/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, pickResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' -import { withUiApp } from '@/resources/ui-apps' - import { ErrorTrackingAssignmentRulesCreateBody, ErrorTrackingAssignmentRulesListQueryParams, @@ -37,6 +32,9 @@ import { ErrorTrackingSymbolSetsListQueryParams, ErrorTrackingSymbolSetsRetrieveParams, } from '@/generated/error_tracking/api' +import { withUiApp } from '@/resources/ui-apps' +import { withPostHogUrl, pickResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const ErrorTrackingAssignmentRulesCreateSchema = ErrorTrackingAssignmentRulesCreateBody diff --git a/services/mcp/src/tools/generated/error_tracking_alerts.ts b/services/mcp/src/tools/generated/error_tracking_alerts.ts index 87ed90f2eefa..11f204ebd4af 100644 --- a/services/mcp/src/tools/generated/error_tracking_alerts.ts +++ b/services/mcp/src/tools/generated/error_tracking_alerts.ts @@ -1,11 +1,7 @@ // AUTO-GENERATED from products/error_tracking/mcp/error_tracking_alerts.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, pickResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' - import { HogFunctionsCreateBody, HogFunctionsDestroyParams, @@ -13,6 +9,8 @@ import { HogFunctionsPartialUpdateBody, HogFunctionsPartialUpdateParams, } from '@/generated/error_tracking_alerts/api' +import { withPostHogUrl, pickResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const ErrorTrackingAlertsCreateSchema = HogFunctionsCreateBody.extend({ type: HogFunctionsCreateBody.shape['type'].describe( diff --git a/services/mcp/src/tools/generated/experiments.ts b/services/mcp/src/tools/generated/experiments.ts index 98ca8a887f3c..c495cde3a9fe 100644 --- a/services/mcp/src/tools/generated/experiments.ts +++ b/services/mcp/src/tools/generated/experiments.ts @@ -1,14 +1,7 @@ // AUTO-GENERATED from products/experiments/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, pickResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' -import { withUiApp } from '@/resources/ui-apps' -import { SavedMetricsAttachSchema } from '@/schema/tool-inputs' -import { castStringToInt } from '@/tools/cast-helpers' - import { ExperimentHoldoutsCreateBody, ExperimentHoldoutsDestroyParams, @@ -49,6 +42,11 @@ import { ExperimentsUnarchiveCreateParams, ExperimentsUnfreezeExposureCreateParams, } from '@/generated/experiments/api' +import { withUiApp } from '@/resources/ui-apps' +import { SavedMetricsAttachSchema } from '@/schema/tool-inputs' +import { castStringToInt } from '@/tools/cast-helpers' +import { withPostHogUrl, pickResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const ExperimentArchiveSchema = ExperimentsArchiveCreateParams.omit({ project_id: true }) .extend(ExperimentsArchiveCreateBody.shape) diff --git a/services/mcp/src/tools/generated/feature_flags.ts b/services/mcp/src/tools/generated/feature_flags.ts index 06b897b61210..836f4ec1345f 100644 --- a/services/mcp/src/tools/generated/feature_flags.ts +++ b/services/mcp/src/tools/generated/feature_flags.ts @@ -1,14 +1,7 @@ // AUTO-GENERATED from products/feature_flags/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, pickResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' -import { withUiApp } from '@/resources/ui-apps' -import { validateDistinctIdPersonIdExclusive } from '@/schema/tool-inputs' -import { castStringToInt } from '@/tools/cast-helpers' - import { FeatureFlagsActivityRetrieveParams, FeatureFlagsActivityRetrieveQueryParams, @@ -36,6 +29,11 @@ import { ScheduledChangesPartialUpdateParams, ScheduledChangesRetrieveParams, } from '@/generated/feature_flags/api' +import { withUiApp } from '@/resources/ui-apps' +import { validateDistinctIdPersonIdExclusive } from '@/schema/tool-inputs' +import { castStringToInt } from '@/tools/cast-helpers' +import { withPostHogUrl, pickResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const CreateFeatureFlagSchema = FeatureFlagsCreateBody.omit({ archived: true }).extend({ is_remote_configuration: FeatureFlagsCreateBody.shape['is_remote_configuration'].describe( diff --git a/services/mcp/src/tools/generated/field_notes.ts b/services/mcp/src/tools/generated/field_notes.ts index 05c6d1af55ce..72d430b802af 100644 --- a/services/mcp/src/tools/generated/field_notes.ts +++ b/services/mcp/src/tools/generated/field_notes.ts @@ -1,17 +1,15 @@ // AUTO-GENERATED from products/field_notes/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, pickResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' - import { FieldNotesListQueryParams, FieldNotesPartialUpdateBody, FieldNotesPartialUpdateParams, FieldNotesRetrieveParams, } from '@/generated/field_notes/api' +import { withPostHogUrl, pickResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const FieldNotesGetSchema = FieldNotesRetrieveParams.omit({ project_id: true }) diff --git a/services/mcp/src/tools/generated/health_issues.ts b/services/mcp/src/tools/generated/health_issues.ts index 925c98795caa..ffed524d74ec 100644 --- a/services/mcp/src/tools/generated/health_issues.ts +++ b/services/mcp/src/tools/generated/health_issues.ts @@ -1,12 +1,10 @@ // AUTO-GENERATED from services/mcp/definitions/health_issues.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' - import { HealthIssuesListQueryParams, HealthIssuesRetrieveParams } from '@/generated/health_issues/api' +import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const HealthIssuesGetSchema = HealthIssuesRetrieveParams.omit({ project_id: true }) diff --git a/services/mcp/src/tools/generated/integrations.ts b/services/mcp/src/tools/generated/integrations.ts index 0df344b5cd0b..e666e955df9d 100644 --- a/services/mcp/src/tools/generated/integrations.ts +++ b/services/mcp/src/tools/generated/integrations.ts @@ -1,11 +1,7 @@ // AUTO-GENERATED from products/integrations/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, pickResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' - import { IntegrationsChannelsRetrieveParams, IntegrationsChannelsRetrieveQueryParams, @@ -17,6 +13,8 @@ import { IntegrationsListQueryParams, IntegrationsRetrieveParams, } from '@/generated/integrations/api' +import { withPostHogUrl, pickResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const IntegrationDeleteSchema = IntegrationsDestroyParams.omit({ project_id: true }) diff --git a/services/mcp/src/tools/generated/logs.ts b/services/mcp/src/tools/generated/logs.ts index ecf4486bee02..540bcf677dd2 100644 --- a/services/mcp/src/tools/generated/logs.ts +++ b/services/mcp/src/tools/generated/logs.ts @@ -1,11 +1,7 @@ // AUTO-GENERATED from products/logs/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, pickResponseFields, omitResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' - import { LogsAlertsCreateBody, LogsAlertsDestinationsCreateBody, @@ -31,6 +27,8 @@ import { LogsSparklineCreateBody, LogsValuesRetrieveQueryParams, } from '@/generated/logs/api' +import { withPostHogUrl, pickResponseFields, omitResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const LogsAlertsCreateSchema = LogsAlertsCreateBody diff --git a/services/mcp/src/tools/generated/managed_migrations.ts b/services/mcp/src/tools/generated/managed_migrations.ts index 0fa3575e84dd..2444f8505b3d 100644 --- a/services/mcp/src/tools/generated/managed_migrations.ts +++ b/services/mcp/src/tools/generated/managed_migrations.ts @@ -1,15 +1,13 @@ // AUTO-GENERATED from products/managed_migrations/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' - import { ManagedMigrationsSupportListQueryParams, ManagedMigrationsSupportRetrieveParams, } from '@/generated/managed_migrations/api' +import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const ManagedMigrationsSupportGetSchema = ManagedMigrationsSupportRetrieveParams diff --git a/services/mcp/src/tools/generated/marketing_analytics.ts b/services/mcp/src/tools/generated/marketing_analytics.ts index b137502b8b19..61233f931d6a 100644 --- a/services/mcp/src/tools/generated/marketing_analytics.ts +++ b/services/mcp/src/tools/generated/marketing_analytics.ts @@ -1,10 +1,7 @@ // AUTO-GENERATED from products/marketing_analytics/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' - import type { Schemas } from '@/api/generated' - import { MarketingAnalyticsDataSourcesRetrieveQueryParams, MarketingAnalyticsDiagnoseRetrieveQueryParams, @@ -13,6 +10,7 @@ import { MarketingAnalyticsSuggestUtmMappingsRetrieveQueryParams, MarketingAnalyticsUtmAuditRetrieveQueryParams, } from '@/generated/marketing_analytics/api' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const MarketingAnalyticsConversionGoalsSchema = z.object({}) diff --git a/services/mcp/src/tools/generated/mcp_analytics.ts b/services/mcp/src/tools/generated/mcp_analytics.ts index 44e36cb876b2..5134c92609f0 100644 --- a/services/mcp/src/tools/generated/mcp_analytics.ts +++ b/services/mcp/src/tools/generated/mcp_analytics.ts @@ -1,12 +1,7 @@ // AUTO-GENERATED from products/mcp_analytics/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' -import { createQueryWrapper } from '@/tools/query-wrapper-factory' - import { McpAnalyticsFeedbackCreateBody, McpAnalyticsMissingCapabilitiesCreateBody, @@ -16,6 +11,9 @@ import { McpAnalyticsSessionsToolCallsParams, McpAnalyticsSessionsToolCallsQueryParams, } from '@/generated/mcp_analytics/api' +import { createQueryWrapper } from '@/tools/query-wrapper-factory' +import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const McpAnalyticsIntentClustersRecomputeSchema = z.object({}) diff --git a/services/mcp/src/tools/generated/mcp_store.ts b/services/mcp/src/tools/generated/mcp_store.ts index 8332fddacb4b..3615b7095d66 100644 --- a/services/mcp/src/tools/generated/mcp_store.ts +++ b/services/mcp/src/tools/generated/mcp_store.ts @@ -1,15 +1,13 @@ // AUTO-GENERATED from products/mcp_store/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' - import { McpServerInstallationsListQueryParams, McpServerInstallationsToolsRetrieveParams, } from '@/generated/mcp_store/api' +import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const McpConnectionToolsListSchema = McpServerInstallationsToolsRetrieveParams.omit({ project_id: true }) diff --git a/services/mcp/src/tools/generated/metrics.ts b/services/mcp/src/tools/generated/metrics.ts index be22d85411e4..72403997d411 100644 --- a/services/mcp/src/tools/generated/metrics.ts +++ b/services/mcp/src/tools/generated/metrics.ts @@ -1,16 +1,14 @@ // AUTO-GENERATED from products/metrics/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { pickResponseFields } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' - import { MetricsCharacterizeCreateBody, MetricsQueryCreateBody, MetricsValuesRetrieveQueryParams, } from '@/generated/metrics/api' +import { pickResponseFields } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const CharacterizeMetricAnomalySchema = MetricsCharacterizeCreateBody diff --git a/services/mcp/src/tools/generated/notebooks.ts b/services/mcp/src/tools/generated/notebooks.ts index 1db29051ee43..7ed7d8a45eac 100644 --- a/services/mcp/src/tools/generated/notebooks.ts +++ b/services/mcp/src/tools/generated/notebooks.ts @@ -1,11 +1,7 @@ // AUTO-GENERATED from products/notebooks/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' - import { NotebooksCreateBody, NotebooksDestroyParams, @@ -14,6 +10,8 @@ import { NotebooksPartialUpdateParams, NotebooksRetrieveParams, } from '@/generated/notebooks/api' +import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const NotebooksCreateSchema = NotebooksCreateBody diff --git a/services/mcp/src/tools/generated/persons.ts b/services/mcp/src/tools/generated/persons.ts index ccae7e69f729..6c5b4be8d3e2 100644 --- a/services/mcp/src/tools/generated/persons.ts +++ b/services/mcp/src/tools/generated/persons.ts @@ -1,12 +1,7 @@ // AUTO-GENERATED from products/persons/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, pickResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' -import { castStringToInt } from '@/tools/cast-helpers' - import { PersonsBulkDeleteCreateBody, PersonsCohortsRetrieveQueryParams, @@ -18,6 +13,9 @@ import { PersonsUpdatePropertyCreateParams, PersonsValuesRetrieveQueryParams, } from '@/generated/persons/api' +import { castStringToInt } from '@/tools/cast-helpers' +import { withPostHogUrl, pickResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const PersonsBulkDeleteSchema = PersonsBulkDeleteCreateBody diff --git a/services/mcp/src/tools/generated/platform_features.ts b/services/mcp/src/tools/generated/platform_features.ts index a30fbf17e0d9..2fa82bcae245 100644 --- a/services/mcp/src/tools/generated/platform_features.ts +++ b/services/mcp/src/tools/generated/platform_features.ts @@ -1,23 +1,7 @@ // AUTO-GENERATED from products/platform_features/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { - withPostHogUrl, - pickResponseFields, - withInformationalResponse, - type WithPostHogUrl, - type WithInformationalResponse, -} from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' -import { getConfirmedActionRuntime } from '@/tools/confirmed-action-registry' -import { - executeConfirmedAction, - prepareConfirmedAction, - type PrepareConfirmedActionResult, -} from '@/tools/confirmed-action-runtime' - import { AdvancedActivityLogsListQueryParams, ApprovalPoliciesListQueryParams, @@ -45,6 +29,20 @@ import { UserHomeSettingsPartialUpdateParams, UserHomeSettingsRetrieveParams, } from '@/generated/platform_features/api' +import { getConfirmedActionRuntime } from '@/tools/confirmed-action-registry' +import { + executeConfirmedAction, + prepareConfirmedAction, + type PrepareConfirmedActionResult, +} from '@/tools/confirmed-action-runtime' +import { + withPostHogUrl, + pickResponseFields, + withInformationalResponse, + type WithPostHogUrl, + type WithInformationalResponse, +} from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const AdvancedActivityLogsFiltersSchema = z.object({}) diff --git a/services/mcp/src/tools/generated/product_analytics.ts b/services/mcp/src/tools/generated/product_analytics.ts index c1a6295a30e5..f7837f37c25c 100644 --- a/services/mcp/src/tools/generated/product_analytics.ts +++ b/services/mcp/src/tools/generated/product_analytics.ts @@ -1,12 +1,7 @@ // AUTO-GENERATED from products/product_analytics/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, omitResponseFields, pickResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' -import { castStringToInt, normalizeParamAliases } from '@/tools/cast-helpers' - import { ElementsStatsRetrieveQueryParams, InsightsActivityRetrieveParams, @@ -21,6 +16,9 @@ import { InsightsRetrieveQueryParams, InsightsTrendingRetrieveQueryParams, } from '@/generated/product_analytics/api' +import { castStringToInt, normalizeParamAliases } from '@/tools/cast-helpers' +import { withPostHogUrl, omitResponseFields, pickResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const AssistantInsightVizNode = z.object({ kind: z.literal('InsightVizNode').default('InsightVizNode'), diff --git a/services/mcp/src/tools/generated/proxy-records.ts b/services/mcp/src/tools/generated/proxy-records.ts index 4d699cc3196b..2df501065601 100644 --- a/services/mcp/src/tools/generated/proxy-records.ts +++ b/services/mcp/src/tools/generated/proxy-records.ts @@ -1,11 +1,7 @@ // AUTO-GENERATED from services/mcp/definitions/proxy-records.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' - import { ProxyRecordsCreateBody, ProxyRecordsDestroyParams, @@ -13,6 +9,8 @@ import { ProxyRecordsRetrieveParams, ProxyRecordsRetryCreateParams, } from '@/generated/proxy-records/api' +import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const ProxyCreateSchema = ProxyRecordsCreateBody diff --git a/services/mcp/src/tools/generated/query-wrappers.ts b/services/mcp/src/tools/generated/query-wrappers.ts index 7d58a18d1e1a..c03dbc9b39c4 100644 --- a/services/mcp/src/tools/generated/query-wrappers.ts +++ b/services/mcp/src/tools/generated/query-wrappers.ts @@ -1,8 +1,8 @@ // AUTO-GENERATED from services/mcp/definitions/query-wrappers.yaml + schema.json — do not edit import { z } from 'zod' -import type { ZodObjectAny } from '@/tools/types' import { createQueryWrapper } from '@/tools/query-wrapper-factory' +import type { ZodObjectAny } from '@/tools/types' // --- Shared Zod schemas generated from schema.json --- diff --git a/services/mcp/src/tools/generated/reminders.ts b/services/mcp/src/tools/generated/reminders.ts index 5eb5c88c946d..8c39b4a74d67 100644 --- a/services/mcp/src/tools/generated/reminders.ts +++ b/services/mcp/src/tools/generated/reminders.ts @@ -1,11 +1,7 @@ // AUTO-GENERATED from products/reminders/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' - import { RemindersCreateBody, RemindersDestroyParams, @@ -14,6 +10,8 @@ import { RemindersPartialUpdateParams, RemindersRetrieveParams, } from '@/generated/reminders/api' +import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const ReminderCreateSchema = RemindersCreateBody diff --git a/services/mcp/src/tools/generated/replay.ts b/services/mcp/src/tools/generated/replay.ts index 94224244fcb1..9ee3bf7be104 100644 --- a/services/mcp/src/tools/generated/replay.ts +++ b/services/mcp/src/tools/generated/replay.ts @@ -1,13 +1,7 @@ // AUTO-GENERATED from products/replay/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, omitResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' -import { withUiApp } from '@/resources/ui-apps' -import { createQueryWrapper } from '@/tools/query-wrapper-factory' - import { SessionRecordingPlaylistsCreateBody, SessionRecordingPlaylistsListQueryParams, @@ -20,6 +14,10 @@ import { SingleSessionSummariesListQueryParams, SingleSessionSummariesRetrieveParams, } from '@/generated/replay/api' +import { withUiApp } from '@/resources/ui-apps' +import { createQueryWrapper } from '@/tools/query-wrapper-factory' +import { withPostHogUrl, omitResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const SessionRecordingBulkDeleteSchema = SessionRecordingsBulkDeleteCreateBody diff --git a/services/mcp/src/tools/generated/replay_vision.ts b/services/mcp/src/tools/generated/replay_vision.ts index 8c83061e2682..b585362ea18e 100644 --- a/services/mcp/src/tools/generated/replay_vision.ts +++ b/services/mcp/src/tools/generated/replay_vision.ts @@ -1,11 +1,7 @@ // AUTO-GENERATED from products/replay_vision/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' - import { VisionActionsListQueryParams, VisionActionsRetrieveParams, @@ -43,6 +39,8 @@ import { VisionScannersPromptSuggestionsGenerateCreateParams, VisionScannersRetrieveParams, } from '@/generated/replay_vision/api' +import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const VisionActionsListSchema = VisionActionsListQueryParams diff --git a/services/mcp/src/tools/generated/signals.ts b/services/mcp/src/tools/generated/signals.ts index 5e8b55c6df25..3cb643d1070c 100644 --- a/services/mcp/src/tools/generated/signals.ts +++ b/services/mcp/src/tools/generated/signals.ts @@ -1,19 +1,7 @@ // AUTO-GENERATED from products/signals/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { - withPostHogUrl, - withAgentNote, - pickResponseFields, - withInformationalResponse, - type WithPostHogUrl, - type WithAgentNote, - type WithInformationalResponse, -} from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' - import { SignalsReportArtefactsCreateBody, SignalsReportArtefactsCreateParams, @@ -62,6 +50,16 @@ import { SignalsSourceConfigsUpdateBody, SignalsSourceConfigsUpdateParams, } from '@/generated/signals/api' +import { + withPostHogUrl, + withAgentNote, + pickResponseFields, + withInformationalResponse, + type WithPostHogUrl, + type WithAgentNote, + type WithInformationalResponse, +} from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const InboxReportArtefactsCreateSchema = SignalsReportArtefactsCreateParams.omit({ project_id: true }).extend( SignalsReportArtefactsCreateBody.shape diff --git a/services/mcp/src/tools/generated/skills.ts b/services/mcp/src/tools/generated/skills.ts index 67f5bf66abc1..8bdf52a0c2e3 100644 --- a/services/mcp/src/tools/generated/skills.ts +++ b/services/mcp/src/tools/generated/skills.ts @@ -1,10 +1,7 @@ // AUTO-GENERATED from products/skills/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' - import type { Schemas } from '@/api/generated' - import { LlmSkillsCreateBody, LlmSkillsListQueryParams, @@ -25,6 +22,7 @@ import { LlmSkillsNameRetrieveParams, LlmSkillsNameRetrieveQueryParams, } from '@/generated/skills/api' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const SkillArchiveSchema = LlmSkillsNameArchiveCreateParams.omit({ project_id: true }).extend({ skill_name: LlmSkillsNameArchiveCreateParams.shape['skill_name'].describe( diff --git a/services/mcp/src/tools/generated/stamphog.ts b/services/mcp/src/tools/generated/stamphog.ts index 98ba1bb7ef9f..395804f0d4a7 100644 --- a/services/mcp/src/tools/generated/stamphog.ts +++ b/services/mcp/src/tools/generated/stamphog.ts @@ -1,11 +1,7 @@ // AUTO-GENERATED from products/stamphog/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, omitResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' - import { StamphogDigestChannelsCreateBody, StamphogDigestChannelsDestroyParams, @@ -19,6 +15,8 @@ import { StamphogReviewRunsListQueryParams, StamphogReviewRunsRetrieveParams, } from '@/generated/stamphog/api' +import { withPostHogUrl, omitResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const StamphogDigestChannelsCreateSchema = StamphogDigestChannelsCreateBody diff --git a/services/mcp/src/tools/generated/subscriptions.ts b/services/mcp/src/tools/generated/subscriptions.ts index bb13d470f9a6..9d59de4c48c6 100644 --- a/services/mcp/src/tools/generated/subscriptions.ts +++ b/services/mcp/src/tools/generated/subscriptions.ts @@ -1,12 +1,7 @@ // AUTO-GENERATED from products/subscriptions/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, omitResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' -import { castStringToInt } from '@/tools/cast-helpers' - import { SubscriptionsCreateBody, SubscriptionsDeliveriesListParams, @@ -19,6 +14,9 @@ import { SubscriptionsRetrieveParams, SubscriptionsTestDeliveryCreateParams, } from '@/generated/subscriptions/api' +import { castStringToInt } from '@/tools/cast-helpers' +import { withPostHogUrl, omitResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const SubscriptionsCreateSchema = SubscriptionsCreateBody diff --git a/services/mcp/src/tools/generated/surveys.ts b/services/mcp/src/tools/generated/surveys.ts index 5a72aff0d070..7817017a5c60 100644 --- a/services/mcp/src/tools/generated/surveys.ts +++ b/services/mcp/src/tools/generated/surveys.ts @@ -1,12 +1,7 @@ // AUTO-GENERATED from products/surveys/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' -import { withUiApp } from '@/resources/ui-apps' - import { SurveysCreateBody, SurveysDestroyParams, @@ -25,6 +20,9 @@ import { SurveysSummarizeResponsesCreateParams, SurveysSummarizeResponsesCreateQueryParams, } from '@/generated/surveys/api' +import { withUiApp } from '@/resources/ui-apps' +import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const SurveyCreateSchema = SurveysCreateBody.omit({ linked_insight_id: true, diff --git a/services/mcp/src/tools/generated/tasks.ts b/services/mcp/src/tools/generated/tasks.ts index 4d75199ceb7a..f9b56ce5ca60 100644 --- a/services/mcp/src/tools/generated/tasks.ts +++ b/services/mcp/src/tools/generated/tasks.ts @@ -1,17 +1,7 @@ // AUTO-GENERATED from products/tasks/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, pickResponseFields, omitResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' -import { getConfirmedActionRuntime } from '@/tools/confirmed-action-registry' -import { - executeConfirmedAction, - prepareConfirmedAction, - type PrepareConfirmedActionResult, -} from '@/tools/confirmed-action-runtime' - import { LoopsCreateBody, LoopsDestroyParams, @@ -33,6 +23,14 @@ import { TasksRunsSessionLogsRetrieveParams, TasksRunsSessionLogsRetrieveQueryParams, } from '@/generated/tasks/api' +import { getConfirmedActionRuntime } from '@/tools/confirmed-action-registry' +import { + executeConfirmedAction, + prepareConfirmedAction, + type PrepareConfirmedActionResult, +} from '@/tools/confirmed-action-runtime' +import { withPostHogUrl, pickResponseFields, omitResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const LoopsCreateSchema = LoopsCreateBody diff --git a/services/mcp/src/tools/generated/tracing.ts b/services/mcp/src/tools/generated/tracing.ts index ca24991b3c85..139fcee72025 100644 --- a/services/mcp/src/tools/generated/tracing.ts +++ b/services/mcp/src/tools/generated/tracing.ts @@ -1,12 +1,7 @@ // AUTO-GENERATED from products/tracing/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, pickResponseFields } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' -import { withUiApp } from '@/resources/ui-apps' - import { TracingSpansAggregateCreateBody, TracingSpansAttributeBreakdownCreateBody, @@ -22,6 +17,9 @@ import { TracingSpansTreeCreateBody, TracingSpansValuesRetrieveQueryParams, } from '@/generated/tracing/api' +import { withUiApp } from '@/resources/ui-apps' +import { withPostHogUrl, pickResponseFields } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const ApmAttributeBreakdownSchema = TracingSpansAttributeBreakdownCreateBody diff --git a/services/mcp/src/tools/generated/user_interviews.ts b/services/mcp/src/tools/generated/user_interviews.ts index 57e16f78961b..d73fb545ed35 100644 --- a/services/mcp/src/tools/generated/user_interviews.ts +++ b/services/mcp/src/tools/generated/user_interviews.ts @@ -1,12 +1,7 @@ // AUTO-GENERATED from products/user_interviews/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' -import { withUiApp } from '@/resources/ui-apps' - import { UserInterviewTopicsAddIntervieweeCreateBody, UserInterviewTopicsAddIntervieweeCreateParams, @@ -38,6 +33,9 @@ import { UserInterviewsRetrieveParams, UserInterviewsSearchCreateBody, } from '@/generated/user_interviews/api' +import { withUiApp } from '@/resources/ui-apps' +import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const UserInterviewTopicsAddIntervieweeSchema = UserInterviewTopicsAddIntervieweeCreateParams.omit({ project_id: true, diff --git a/services/mcp/src/tools/generated/visual_review.ts b/services/mcp/src/tools/generated/visual_review.ts index 54e498c45411..850fb45293bf 100644 --- a/services/mcp/src/tools/generated/visual_review.ts +++ b/services/mcp/src/tools/generated/visual_review.ts @@ -1,12 +1,7 @@ // AUTO-GENERATED from products/visual_review/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' -import { withUiApp } from '@/resources/ui-apps' - import { VisualReviewReposListQueryParams, VisualReviewReposRetrieveParams, @@ -25,6 +20,9 @@ import { VisualReviewRunsToleratedHashesListParams, VisualReviewRunsToleratedHashesListQueryParams, } from '@/generated/visual_review/api' +import { withUiApp } from '@/resources/ui-apps' +import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const VisualReviewReposListSchema = VisualReviewReposListQueryParams diff --git a/services/mcp/src/tools/generated/warehouse_sources.ts b/services/mcp/src/tools/generated/warehouse_sources.ts index be8e3e0c415f..b88b7251ca24 100644 --- a/services/mcp/src/tools/generated/warehouse_sources.ts +++ b/services/mcp/src/tools/generated/warehouse_sources.ts @@ -1,12 +1,7 @@ // AUTO-GENERATED from products/warehouse_sources/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, omitResponseFields, pickResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' -import { ExternalDataSourcePayloadSchema, ExternalDataSourceTypeSchema } from '@/schema/tool-inputs' - import { ExternalDataSchemasCancelCreateParams, ExternalDataSchemasDeleteDataDestroyParams, @@ -43,6 +38,9 @@ import { ExternalDataSourcesWebhookInfoRetrieveParams, ExternalDataSourcesWizardRetrieveQueryParams, } from '@/generated/warehouse_sources/api' +import { ExternalDataSourcePayloadSchema, ExternalDataSourceTypeSchema } from '@/schema/tool-inputs' +import { withPostHogUrl, omitResponseFields, pickResponseFields, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const DataWarehouseSourceConnectLinkSchema = ExternalDataSourcesConnectLinkRetrieveQueryParams.extend({ source_type: ExternalDataSourceTypeSchema, diff --git a/services/mcp/src/tools/generated/web_analytics.ts b/services/mcp/src/tools/generated/web_analytics.ts index b3e052262da4..05907be4fae1 100644 --- a/services/mcp/src/tools/generated/web_analytics.ts +++ b/services/mcp/src/tools/generated/web_analytics.ts @@ -1,11 +1,7 @@ // AUTO-GENERATED from products/web_analytics/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' - import { HeatmapsEventsRetrieveQueryParams, HeatmapsListQueryParams, @@ -17,6 +13,8 @@ import { SavedRetrieveParams, WebAnalyticsWeeklyDigestQueryParams, } from '@/generated/web_analytics/api' +import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const HeatmapsEventsSchema = HeatmapsEventsRetrieveQueryParams diff --git a/services/mcp/src/tools/generated/workflows.ts b/services/mcp/src/tools/generated/workflows.ts index 5e1cb8cb96cc..c3a031fba4c4 100644 --- a/services/mcp/src/tools/generated/workflows.ts +++ b/services/mcp/src/tools/generated/workflows.ts @@ -1,13 +1,7 @@ // AUTO-GENERATED from products/workflows/mcp/tools.yaml + OpenAPI — do not edit import { z } from 'zod' -import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' -import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' - import type { Schemas } from '@/api/generated' -import { withUiApp } from '@/resources/ui-apps' -import { WorkflowGraphPatchSchema } from '@/schema/tool-inputs' - import { HogFlowsBatchJobsListParams, HogFlowsCreateBody, @@ -36,6 +30,10 @@ import { HogFlowsSchedulesPartialUpdateBody, HogFlowsSchedulesPartialUpdateParams, } from '@/generated/workflows/api' +import { withUiApp } from '@/resources/ui-apps' +import { WorkflowGraphPatchSchema } from '@/schema/tool-inputs' +import { withPostHogUrl, type WithPostHogUrl } from '@/tools/tool-utils' +import type { Context, ToolBase, ZodObjectAny } from '@/tools/types' const WorkflowsCreateSchema = HogFlowsCreateBody