Content
View differences
Updated by Jonas Jabari 13 days ago
Backend for the description assistant: the HTTP contract between the editor (AI-101) and the admin-managed text transform actions (AI-96, AI-98), on top of the LLM connection (AI-3). No UI; everything stays invisible until the editor integration lands.
## What gets built
* A `GET` endpoint listing the actions available for a work package or type, filtered server-side (active, type scope, template presence, assistant setting, LLM available).
* Execution as a background job with progressive polling: `POST` creates a run and returns an id, `GET` returns the events since a cursor (text deltas, completed text, error), `POST` cancel stops it. Runs are private to their user and answer 404 to anyone else.
* Server-side prompt assembly: fixed scaffold + action prompt + optional type template as system message, the submitted content as user message only.
* A generic, transient run primitive (`ai_runs`, `ai_run_events`) with a retention setting and cleanup job, reusable by later AI features.
* LLM access through a thin gateway port, wired to `Llm::Runtime` from AI-3 in the last step.
## Why a job instead of a synchronous request
LLM calls take up to 60 s. That exceeds proxy read timeouts and Rack::Timeout, and Rack 2.2 buffers streamed responses, so neither sync nor SSE works without bypasses. Push via Action Cable stays a later additive upgrade. Full options analysis: see the earlier description of this ticket.
## Sub tickets, one PR each, stacked in this order
1. <mention class="mention" data-id="79466" data-type="work_package" data-text="#AI-133" data-display-id="AI-133">#AI-133</mention> Add the AI run primitive and its retention
2. <mention class="mention" data-id="79468" data-type="work_package" data-text="#AI-135" data-display-id="AI-135">#AI-135</mention> Execute text transforms in a background job (reordered for a better review flow)
3. <mention class="mention" data-id="79467" data-type="work_package" data-text="#AI-134" data-display-id="AI-134">#AI-134</mention> Resolve available text transform actions and expose the list endpoint (reordered for
3. <mention class="mention" data-id="79468" data-type="work_package" data-text="#AI-135" data-display-id="AI-135">#AI-135</mention> Execute text transforms in a better review flow) background job
4. <mention class="mention" data-id="79469" data-type="work_package" data-text="#AI-136" data-display-id="AI-136">#AI-136</mention> Add the run endpoints: create, poll, cancel
5. <mention class="mention" data-id="79470" data-type="work_package" data-text="#AI-137" data-display-id="AI-137">#AI-137</mention> Wire the text transform gateway to the LLM connection (blocked by AI-3 PR #24888)
## Out of scope
Editor UI and polling controller (AI-101), selection-based transforms, websocket push, usage counting and budgets, per-action model override.
## What gets built
* A `GET` endpoint listing the actions available for a work package or type, filtered server-side (active, type scope, template presence, assistant setting, LLM available).
* Execution as a background job with progressive polling: `POST` creates a run and returns an id, `GET` returns the events since a cursor (text deltas, completed text, error), `POST` cancel stops it. Runs are private to their user and answer 404 to anyone else.
* Server-side prompt assembly: fixed scaffold + action prompt + optional type template as system message, the submitted content as user message only.
* A generic, transient run primitive (`ai_runs`, `ai_run_events`) with a retention setting and cleanup job, reusable by later AI features.
* LLM access through a thin gateway port, wired to `Llm::Runtime` from AI-3 in the last step.
## Why a job instead of a synchronous request
LLM calls take up to 60 s. That exceeds proxy read timeouts and Rack::Timeout, and Rack 2.2 buffers streamed responses, so neither sync nor SSE works without bypasses. Push via Action Cable stays a later additive upgrade. Full options analysis: see the earlier description of this ticket.
## Sub tickets, one PR each, stacked in this order
1. <mention class="mention" data-id="79466" data-type="work_package" data-text="#AI-133" data-display-id="AI-133">#AI-133</mention> Add the AI run primitive and its retention
2. <mention class="mention" data-id="79468" data-type="work_package" data-text="#AI-135" data-display-id="AI-135">#AI-135</mention> Execute text transforms in a background job (reordered for a better review flow)
3. <mention class="mention" data-id="79467" data-type="work_package" data-text="#AI-134" data-display-id="AI-134">#AI-134</mention> Resolve available text transform actions and expose the list endpoint (reordered for
3. <mention class="mention" data-id="79468" data-type="work_package" data-text="#AI-135" data-display-id="AI-135">#AI-135</mention> Execute text transforms in
4. <mention class="mention" data-id="79469" data-type="work_package" data-text="#AI-136" data-display-id="AI-136">#AI-136</mention> Add the run endpoints: create, poll, cancel
5. <mention class="mention" data-id="79470" data-type="work_package" data-text="#AI-137" data-display-id="AI-137">#AI-137</mention> Wire the text transform gateway to the LLM connection (blocked by AI-3 PR #24888)
## Out of scope
Editor UI and polling controller (AI-101), selection-based transforms, websocket push, usage counting and budgets, per-action model override.