Skip to content

feat: Implement structured output for AI agent Tasks#53285

Open
ryans-posthog wants to merge 15 commits intomasterfrom
ryan/implement_task_schema
Open

feat: Implement structured output for AI agent Tasks#53285
ryans-posthog wants to merge 15 commits intomasterfrom
ryan/implement_task_schema

Conversation

@ryans-posthog
Copy link
Copy Markdown
Contributor

@ryans-posthog ryans-posthog commented Apr 3, 2026

Problem

Currently, there is no way to specify the shape of the output for a task. The tasks are currently expected to either return human language responses, or be executed interactively via PostHog Code.

Changes

This change introduces validation on the set_output endpoint and transfer of the json_schema to the code agent.

How did you test this code?

Unit testing for setting the json schema and the action of the set_output endpoint.
Manual testing:
Checkout PostHog/code#1466 on the Code repo and recompile the agent. Clear the docker image for the sandbox runners.
Create a new task via python manage.py shell with the Task.create_and_run function. Make sure to set the json_schema in the task. Verify that the Task executes and uses the set_output endpoint.

👉 Stay up-to-date with PostHog coding conventions for a smoother review.

Publish to changelog?

Docs update

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

Size Change: 0 B

Total Size: 127 MB

ℹ️ View Unchanged
Filename Size
frontend/dist/368Hedgehogs 5.26 kB
frontend/dist/abap 14.2 kB
frontend/dist/Action 23.2 kB
frontend/dist/Actions 1.02 kB
frontend/dist/AdvancedActivityLogsScene 33.9 kB
frontend/dist/AgenticAuthorize 5.25 kB
frontend/dist/apex 3.95 kB
frontend/dist/ApprovalDetail 16.2 kB
frontend/dist/array.full.es5.js 326 kB
frontend/dist/array.full.js 421 kB
frontend/dist/array.js 177 kB
frontend/dist/AsyncMigrations 13.1 kB
frontend/dist/AuthorizationStatus 716 B
frontend/dist/azcli 846 B
frontend/dist/bat 1.84 kB
frontend/dist/BatchExportScene 60.3 kB
frontend/dist/bicep 2.55 kB
frontend/dist/Billing 493 B
frontend/dist/BillingSection 20.8 kB
frontend/dist/BoxPlot 5.04 kB
frontend/dist/browserAll-0QZMN1W2 37.4 kB
frontend/dist/ButtonPrimitives 562 B
frontend/dist/CalendarHeatMap 4.79 kB
frontend/dist/cameligo 2.18 kB
frontend/dist/changeRequestsLogic 544 B
frontend/dist/CLIAuthorize 11.3 kB
frontend/dist/CLILive 3.97 kB
frontend/dist/clojure 9.64 kB
frontend/dist/coffee 3.59 kB
frontend/dist/Cohort 23.2 kB
frontend/dist/CohortCalculationHistory 6.22 kB
frontend/dist/Cohorts 9.39 kB
frontend/dist/ConfirmOrganization 4.48 kB
frontend/dist/conversations.js 63.9 kB
frontend/dist/Coupons 720 B
frontend/dist/cpp 5.3 kB
frontend/dist/Create 655 B
frontend/dist/crisp-chat-integration.js 1.88 kB
frontend/dist/csharp 4.52 kB
frontend/dist/csp 1.42 kB
frontend/dist/css 4.51 kB
frontend/dist/cssMode 4.15 kB
frontend/dist/CustomCssScene 3.55 kB
frontend/dist/CustomerAnalyticsConfigurationScene 1.99 kB
frontend/dist/CustomerAnalyticsScene 26.2 kB
frontend/dist/CustomerJourneyBuilderScene 1.69 kB
frontend/dist/CustomerJourneyTemplatesScene 7.39 kB
frontend/dist/customizations.full.js 17.9 kB
frontend/dist/CyclotronJobInputAssignee 1.32 kB
frontend/dist/CyclotronJobInputTicketTags 711 B
frontend/dist/cypher 3.38 kB
frontend/dist/dart 4.25 kB
frontend/dist/Dashboard 1.04 kB
frontend/dist/Dashboards 20 kB
frontend/dist/DataManagementScene 646 B
frontend/dist/DataPipelinesNewScene 2.28 kB
frontend/dist/DataWarehouseScene 1.19 kB
frontend/dist/DataWarehouseSourceScene 634 B
frontend/dist/Deactivated 1.13 kB
frontend/dist/dead-clicks-autocapture.js 13.1 kB
frontend/dist/DeadLetterQueue 5.38 kB
frontend/dist/DebugScene 20 kB
frontend/dist/decompressionWorker 2.85 kB
frontend/dist/decompressionWorker.js 2.85 kB
frontend/dist/DefinitionEdit 7.11 kB
frontend/dist/DefinitionView 22.7 kB
frontend/dist/DestinationsScene 2.67 kB
frontend/dist/dist 575 B
frontend/dist/dockerfile 1.87 kB
frontend/dist/EarlyAccessFeature 719 B
frontend/dist/EarlyAccessFeatures 2.84 kB
frontend/dist/ecl 5.33 kB
frontend/dist/EditorScene 896 B
frontend/dist/elixir 10.3 kB
frontend/dist/elk.bundled 1.44 MB
frontend/dist/EmailMFAVerify 2.98 kB
frontend/dist/EndpointScene 37.5 kB
frontend/dist/EndpointsScene 22 kB
frontend/dist/ErrorTrackingConfigurationScene 2.2 kB
frontend/dist/ErrorTrackingIssueFingerprintsScene 6.98 kB
frontend/dist/ErrorTrackingIssueScene 81.9 kB
frontend/dist/ErrorTrackingScene 13.2 kB
frontend/dist/EvaluationTemplates 575 B
frontend/dist/EventsScene 2.46 kB
frontend/dist/exception-autocapture.js 11.8 kB
frontend/dist/Experiment 207 kB
frontend/dist/Experiments 17.1 kB
frontend/dist/exporter 20.7 MB
frontend/dist/exporter.js 20.7 MB
frontend/dist/ExportsScene 3.86 kB
frontend/dist/FeatureFlag 127 kB
frontend/dist/FeatureFlags 572 B
frontend/dist/FeatureFlagTemplatesScene 7.03 kB
frontend/dist/FlappyHog 5.78 kB
frontend/dist/flow9 1.8 kB
frontend/dist/freemarker2 16.7 kB
frontend/dist/fsharp 2.98 kB
frontend/dist/go 2.65 kB
frontend/dist/graphql 2.26 kB
frontend/dist/Group 14.3 kB
frontend/dist/Groups 3.93 kB
frontend/dist/GroupsNew 7.34 kB
frontend/dist/handlebars 7.34 kB
frontend/dist/hcl 3.59 kB
frontend/dist/HealthCategoryDetailScene 7.23 kB
frontend/dist/HealthScene 10.3 kB
frontend/dist/HeatmapNewScene 4.16 kB
frontend/dist/HeatmapRecordingScene 3.92 kB
frontend/dist/HeatmapScene 6.04 kB
frontend/dist/HeatmapsScene 3.88 kB
frontend/dist/hls 394 kB
frontend/dist/HogFunctionScene 58.8 kB
frontend/dist/HogRepl 7.37 kB
frontend/dist/html 5.58 kB
frontend/dist/htmlMode 4.62 kB
frontend/dist/image-blob-reduce.esm 49.4 kB
frontend/dist/InboxScene 59.1 kB
frontend/dist/index 306 kB
frontend/dist/index.js 306 kB
frontend/dist/ini 1.1 kB
frontend/dist/InsightOptions 5.41 kB
frontend/dist/InsightScene 28.8 kB
frontend/dist/IntegrationsRedirect 733 B
frontend/dist/intercom-integration.js 1.93 kB
frontend/dist/InviteSignup 14.4 kB
frontend/dist/java 3.22 kB
frontend/dist/javascript 985 B
frontend/dist/jsonMode 13.9 kB
frontend/dist/julia 7.22 kB
frontend/dist/kotlin 3.4 kB
frontend/dist/lazy 150 kB
frontend/dist/LegacyPluginScene 26.6 kB
frontend/dist/LemonTextAreaMarkdown 502 B
frontend/dist/less 3.9 kB
frontend/dist/lexon 2.44 kB
frontend/dist/lib 2.22 kB
frontend/dist/Link 468 B
frontend/dist/LinkScene 24.8 kB
frontend/dist/LinksScene 4.19 kB
frontend/dist/liquid 4.53 kB
frontend/dist/LiveDebugger 19.1 kB
frontend/dist/LiveEventsTable 2.98 kB
frontend/dist/LLMAnalyticsClusterScene 15.7 kB
frontend/dist/LLMAnalyticsClustersScene 43 kB
frontend/dist/LLMAnalyticsDatasetScene 19.7 kB
frontend/dist/LLMAnalyticsDatasetsScene 3.28 kB
frontend/dist/LLMAnalyticsEvaluation 40.7 kB
frontend/dist/LLMAnalyticsEvaluationsScene 29.5 kB
frontend/dist/LLMAnalyticsPlaygroundScene 36.3 kB
frontend/dist/LLMAnalyticsScene 116 kB
frontend/dist/LLMAnalyticsSessionScene 13.4 kB
frontend/dist/LLMAnalyticsTraceScene 127 kB
frontend/dist/LLMAnalyticsUsers 526 B
frontend/dist/LLMASessionFeedbackDisplay 4.83 kB
frontend/dist/LLMPromptScene 20.6 kB
frontend/dist/LLMPromptsScene 4.21 kB
frontend/dist/Login 8.57 kB
frontend/dist/Login2FA 4.2 kB
frontend/dist/logs.js 38.5 kB
frontend/dist/LogsScene 11.3 kB
frontend/dist/lua 2.11 kB
frontend/dist/m3 2.81 kB
frontend/dist/main 819 kB
frontend/dist/ManagedMigration 14 kB
frontend/dist/markdown 3.79 kB
frontend/dist/MarketingAnalyticsScene 39.7 kB
frontend/dist/MaterializedColumns 10.2 kB
frontend/dist/Max 835 B
frontend/dist/mdx 5.39 kB
frontend/dist/MessageTemplate 16.3 kB
frontend/dist/MetricsScene 828 B
frontend/dist/mips 2.58 kB
frontend/dist/ModelsScene 13.6 kB
frontend/dist/MonacoDiffEditor 403 B
frontend/dist/monacoEditorWorker 288 kB
frontend/dist/monacoEditorWorker.js 288 kB
frontend/dist/monacoJsonWorker 419 kB
frontend/dist/monacoJsonWorker.js 419 kB
frontend/dist/monacoTsWorker 7.02 MB
frontend/dist/monacoTsWorker.js 7.02 MB
frontend/dist/MoveToPostHogCloud 4.46 kB
frontend/dist/msdax 4.91 kB
frontend/dist/mysql 11.3 kB
frontend/dist/NavTabChat 4.68 kB
frontend/dist/NewSourceWizard 724 B
frontend/dist/NewTabScene 681 B
frontend/dist/NodeDetailScene 16.3 kB
frontend/dist/NotebookCanvasScene 3.09 kB
frontend/dist/NotebookPanel 5.11 kB
frontend/dist/NotebookScene 8.11 kB
frontend/dist/NotebooksScene 7.58 kB
frontend/dist/OAuthAuthorize 573 B
frontend/dist/objective-c 2.41 kB
frontend/dist/Onboarding 683 kB
frontend/dist/OnboardingCouponRedemption 1.2 kB
frontend/dist/pascal 2.99 kB
frontend/dist/pascaligo 2 kB
frontend/dist/passkeyLogic 484 B
frontend/dist/PasswordReset 4.32 kB
frontend/dist/PasswordResetComplete 2.94 kB
frontend/dist/perl 8.25 kB
frontend/dist/PersonScene 16 kB
frontend/dist/PersonsScene 4.73 kB
frontend/dist/pgsql 13.5 kB
frontend/dist/php 8.02 kB
frontend/dist/PipelineStatusScene 6.22 kB
frontend/dist/pla 1.67 kB
frontend/dist/posthog 250 kB
frontend/dist/postiats 7.86 kB
frontend/dist/powerquery 16.9 kB
frontend/dist/powershell 3.27 kB
frontend/dist/PreflightCheck 5.53 kB
frontend/dist/product-tours.js 115 kB
frontend/dist/ProductTour 274 kB
frontend/dist/ProductTours 4.7 kB
frontend/dist/ProjectHomepage 24.9 kB
frontend/dist/protobuf 9.05 kB
frontend/dist/pug 4.82 kB
frontend/dist/python 4.76 kB
frontend/dist/qsharp 3.19 kB
frontend/dist/r 3.12 kB
frontend/dist/razor 9.35 kB
frontend/dist/recorder-v2.js 111 kB
frontend/dist/recorder.js 111 kB
frontend/dist/redis 3.55 kB
frontend/dist/redshift 11.8 kB
frontend/dist/RegionMap 29.4 kB
frontend/dist/render-query 20.4 MB
frontend/dist/render-query.js 20.4 MB
frontend/dist/ResourceTransfer 9.17 kB
frontend/dist/restructuredtext 3.9 kB
frontend/dist/RevenueAnalyticsScene 25.6 kB
frontend/dist/ruby 8.5 kB
frontend/dist/rust 4.16 kB
frontend/dist/SavedInsights 664 B
frontend/dist/sb 1.82 kB
frontend/dist/scala 7.32 kB
frontend/dist/scheme 1.76 kB
frontend/dist/scss 6.41 kB
frontend/dist/SdkDoctorScene 9.42 kB
frontend/dist/SessionAttributionExplorerScene 6.6 kB
frontend/dist/SessionGroupSummariesTable 4.62 kB
frontend/dist/SessionGroupSummaryScene 17 kB
frontend/dist/SessionProfileScene 15.8 kB
frontend/dist/SessionRecordingDetail 1.73 kB
frontend/dist/SessionRecordingFilePlaybackScene 4.46 kB
frontend/dist/SessionRecordings 742 B
frontend/dist/SessionRecordingsKiosk 8.84 kB
frontend/dist/SessionRecordingsPlaylistScene 4.14 kB
frontend/dist/SessionRecordingsSettingsScene 1.9 kB
frontend/dist/SessionsScene 3.86 kB
frontend/dist/SettingsScene 2.98 kB
frontend/dist/SharedMetric 4.83 kB
frontend/dist/SharedMetrics 549 B
frontend/dist/shell 3.07 kB
frontend/dist/SignupContainer 24.5 kB
frontend/dist/Site 1.18 kB
frontend/dist/solidity 18.6 kB
frontend/dist/sophia 2.76 kB
frontend/dist/SourcesScene 5.96 kB
frontend/dist/sourceWizardLogic 662 B
frontend/dist/sparql 2.55 kB
frontend/dist/sql 10.3 kB
frontend/dist/SqlVariableEditScene 7.24 kB
frontend/dist/st 7.4 kB
frontend/dist/StartupProgram 21.2 kB
frontend/dist/SupportSettingsScene 40.7 kB
frontend/dist/SupportTicketScene 23 kB
frontend/dist/SupportTicketsScene 733 B
frontend/dist/Survey 746 B
frontend/dist/SurveyFormBuilder 1.54 kB
frontend/dist/Surveys 18.2 kB
frontend/dist/surveys.js 89.8 kB
frontend/dist/SurveyWizard 66.8 kB
frontend/dist/swift 5.26 kB
frontend/dist/SystemStatus 16.8 kB
frontend/dist/systemverilog 7.61 kB
frontend/dist/TaskDetailScene 20.1 kB
frontend/dist/TaskTracker 13.1 kB
frontend/dist/tcl 3.57 kB
frontend/dist/TextCardMarkdownEditor 11 kB
frontend/dist/toolbar 10.1 MB
frontend/dist/toolbar.js 10.1 MB
frontend/dist/ToolbarLaunch 2.52 kB
frontend/dist/tracing-headers.js 1.74 kB
frontend/dist/TracingScene 29.3 kB
frontend/dist/TransformationsScene 1.91 kB
frontend/dist/tsMode 24 kB
frontend/dist/twig 5.97 kB
frontend/dist/TwoFactorReset 3.98 kB
frontend/dist/typescript 240 B
frontend/dist/typespec 2.82 kB
frontend/dist/Unsubscribe 1.62 kB
frontend/dist/UserInterview 4.53 kB
frontend/dist/UserInterviews 2.01 kB
frontend/dist/vb 5.79 kB
frontend/dist/VercelConnect 4.95 kB
frontend/dist/VercelLinkError 1.91 kB
frontend/dist/VerifyEmail 4.48 kB
frontend/dist/vimMode 211 kB
frontend/dist/VisualReviewRunScene 18.6 kB
frontend/dist/VisualReviewRunsScene 6.16 kB
frontend/dist/VisualReviewSettingsScene 10.6 kB
frontend/dist/web-vitals.js 6.39 kB
frontend/dist/WebAnalyticsScene 5.77 kB
frontend/dist/WebGLRenderer-DYjOwNoG 60.3 kB
frontend/dist/WebGPURenderer-B_wkl_Ja 36.3 kB
frontend/dist/WebScriptsScene 2.54 kB
frontend/dist/webworkerAll-puPV1rBA 324 B
frontend/dist/wgsl 7.34 kB
frontend/dist/Wizard 4.45 kB
frontend/dist/WorkflowScene 101 kB
frontend/dist/WorkflowsScene 46.9 kB
frontend/dist/WorldMap 4.73 kB
frontend/dist/xml 2.98 kB
frontend/dist/yaml 4.6 kB

compressed-size-action

@ryans-posthog ryans-posthog marked this pull request as ready for review April 7, 2026 01:26
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 7, 2026

Prompt To Fix All With AI
This is a comment left during a code review.
Path: products/tasks/backend/models.py
Line: 861

Comment:
**Wrong field: `state` vs `status`**

`instance.state` is a `JSONField` that stores run execution data (e.g., `{"mode": "background"}`), not the run's completion status. Comparing it to `TaskRun.Status.COMPLETED` (a string like `"completed"`) will always evaluate to `False`, so `track_structured_result` is never invoked from this signal — the analytics event is silently dropped every time.

The correct field is `instance.status`:

```suggestion
    if not created and instance.status == TaskRun.Status.COMPLETED and instance.output and instance.task.json_schema:
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: products/tasks/backend/models.py
Line: 534-546

Comment:
**Redundant nested try/except with duplicate log key**

`track_structured_result` already wraps `capture_event` in its own `try/except` that catches all exceptions and logs them under `"task_run.track_structured_result_failed"`. The outer `try/except` in `track_task_run_completion` uses the exact same log key. Because the inner handler swallows everything, the outer one can only ever fire for errors in the condition check (e.g., `instance.task.json_schema` raising), which is a different concern that would be clearer with its own log message. Consider consolidating to a single layer of error handling.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "Merge branch 'master' into ryan/implemen..." | Re-trigger Greptile

ryans-posthog and others added 3 commits April 6, 2026 19:30
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

@ryans-posthog ryans-posthog left a comment

Choose a reason for hiding this comment

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

Fixes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant