Repository navigation
v1.3.0
Promoted to production from candidate 1.3.0-rc.1 without rebuilding.
- Released commit:
243cfae93d45bbb454895f7841c5ed31e292fc3a(tree3a47f4b109e4ed84a2f5415d83ae372d0f37b2a9) - Candidate commit:
fded2750f1277083b3b566ffae33ec79648803deonrelease/1.3.0 - Image:
ghcr.io/kntro-soft/reqsai-api@sha256:b1411b7cf07c01a7abfc2b79565a67d3bd193aaf09efeec4c41e994b5ea69d5c - Production: https://reqsai.tech
Changes
Added
- Accepting a suggestion decides the story's review status in the same transaction.
POST /api/projects/{projectId}/suggestions/{id}/acceptandPOST /api/sessions/{sessionId}/suggestions/{id}/accepttake an optionalapproveflag (defaultfalse, so older clients keep working).approve: truecreates (NEW_STORY) or updates (UPDATE_STORY,EDGE_CASE) the story and leaves itAPPROVED; it needsSTORY_APPROVEon top ofSESSION_DECIDE, otherwise 403 and nothing changes. Without it the story is saved as a draft. - Status rules: a new story starts
DRAFTorAPPROVED. A target story that wasAPPROVEDorREJECTEDgoes back toDRAFTwhen saved as a draft (its content changed and needs a new review) and becomesAPPROVEDwhen approved. A target alreadyEXPORTEDorMERGEDkeeps its status either way.CLARIFYING_QUESTIONignores the flag. - The accepted suggestion (REST responses, the project suggestion list, the session suggestion list, the assistant chat history) and the realtime
SUGGESTION_ACCEPTEDmessage carryresolvedStoryStatus, so the decision row can say whether the story ended approved or as a draft. No migration: the status is read from the story.
Added (Token metering — feature/130-token-metering)
-
Usage ledger. Every successful AI call is one idempotent row of the tenant table
ai_usage_events(feature, project, model, input / output / cached input tokens, the quota tokens it added, audio seconds), written off the request thread so a metering problem never fails the AI call. Features: live suggestions, chat, final stories, code index, code deep search, document classification, embeddings and transcription. Tenant migrationV20261012100000__ai_usage_events.sql.TokenUsageRecorderPortgainsrecord(TokenUsage);record(long)still works. -
Embeddings and speech-to-text are metered. Embeddings report the tokens the provider counted (an estimate of one per four characters when it returns none) and count at a tenth in the quota. Streaming and uploaded audio are metered in seconds (
audio_seconds) and never count as tokens. -
Atomic quota counter.
token_quota_usedis raised with oneUPDATE ... SET token_quota_used = token_quota_used + nin the transaction of the ledger insert, so parallel calls no longer lose increments; the period rollover is kept. A cached input token counts at half (the provider bills it at half), seedocs/BILLING.md. Common migrationV20261012100100__subscription_quota_warning.sql. -
The monthly allowance is enforced. The chat, "Analizar ahora", live suggestions, code indexing and document classification check it first. At the cap an explicit AI request fails with
AI_QUOTA_EXCEEDED(HTTP 402, withplan,limit,usedandresetsAt); live suggestions pause quietly and the session gets oneAI_QUOTA_PAUSEDmessage; code indexing keeps the structural description of the modules; an uploaded document is stored unclassified. Reading, editing and exporting never stop. The check fails open. -
Warnings at 80, 90 and 100 %.
GET /api/subscriptions/organization/{id}/usagereturnswarningLevel, and aTOKEN_QUOTA_WARNINGmessage goes to/topic/organizations/{id}/usageonce per level per period. -
Usage read model. The usage response adds the period's tokens by feature and by project, the transcription seconds and a
meetingEstimate(minutes left at the organization's own measured tokens per meeting minute, or a documented default of 10,000). -
reqsai.ai.generation.live-model(GENERATION_LIVE_MODEL) sets a cheaper model for live passes only; unset keeps the provider's default. -
Deep search of the pure source code (
codebase:DeepCodeSearchPort). It fetches the repository archive at the indexed commit through the indexer's access (installation token, or anonymous for a public repository) into a temporary file kept 10 minutes (ArchiveCache: at most 4 files and 400 MB, always deleted), removes secrets, and ranks windows of code with a BM25-like lexical search (CodeSearcher) that matches Spanish requests with English identifiers by word root. It returns at most 10 snippets and 12000 characters with file, lines and a GitHub link. Nothing is persisted. Seedocs/CODE_COPILOT.md. -
Verify a suggestion in the code.
POST /api/projects/{projectId}/suggestions/{suggestionId}/verify-code(SESSION_DECIDEandINTEGRATION_READ; 202, or 409 when no repository is ready) searches the code and has the model read the passages once (at most one model call and 25 seconds). The suggestion gets a verdict (ALREADY_EXISTS,CONFLICTS_WITH_CODE,NOT_FOUND,UNSURE), a note, references with file and lines,verifiedAt, or averifyErrorto retry. The card is updated live bySUGGESTION_CODE_UPDATED(session topic, and/topic/projects/{projectId}/suggestions). MigrationsV20261012110000andV20261012110100. -
CodeReferenceand its response gain optionalfile,lineStart,lineEndandquote;urlpoints at…/blob/<commitSha>/<file>#L<a>-L<b>. Older references still read as module references.codein a suggestion gainsverdict,verifyState,verifiedAtandverifyError. -
Assistant chat searches the code when the model says the question is about the code and the index does not answer it: the reply says it searched the source code and cites file and lines (
codeSearched,codeReferencesin the message). Latency of other messages is unchanged; it falls back to the model's own reply when the search cannot run. -
Create a project with Jira and GitHub (#132).
POST /api/organizations/{orgId}/projectsaccepts optionalsources:{jira?: {connectionId?, projectKey, issueTypeName, importStories}, github?: [{repository, branch?, installationId?}]}. The project is created and answers at once; the sources are set up in the background.- What can be checked at once is checked before the project exists, with a 4xx: the Jira connection exists, each repository is readable (shared by an installation, or public), the per-project repository limit, no repeated repository.
workspaceannounces the request with the public eventProjectSetupRequestedIntegrationEventonworkspace::api(after commit, in the background, bound to the tenant).gatewaysaves the Jira target and starts the import;codebaseconnects and indexes the repositories. Both use the same handlers as the REST endpoints, on behalf of the creator.workspacedepends on neither: they implementProjectSetupParticipantand report throughProjectSetupReporter.- A source that fails never fails or undoes the project: the failure is recorded in the new tenant table
project_setup_steps(migrationV20261012120000) and logged. GET /api/projects/{projectId}/setup(INTEGRATION_READ) returns the steps (JIRA_LINK,JIRA_IMPORT,GITHUB_REPOS) with state and counts, merged from the repositories' indexing, the Jira target and import job and the recorded state, plus the stack detected in the indexed repositories. The same object is pushed on/topic/projects/{projectId}/setup.POST …/setup/steps/{step}/skipand…/retry(INTEGRATION_WRITE) leave a step out or run a failed one again.GET /api/organizations/{orgId}/code/github/repositorieslists what the organization's GitHub installations share, so a project that does not exist yet can pick repositories.
-
New
overviewmodule: read-only dashboards of a project and of an organization (#129).GET /api/projects/{projectId}/overview: stories by status and priority, story points,
coverage (acceptance criteria, origin quote, linked code), sessions and stories per week over the
last 12 weeks, how often the copilot's proposals were accepted or dismissed, glossary, constraints,
documents and assigned members, and the connected code. Each section follows the permission that
guards the same data (STORY_READ,SESSION_READ,GLOSSARY_READ,CONSTRAINT_READ,
DOCUMENT_READ,MEMBER_READ,INTEGRATION_READ) and isnullwithout it;403when the caller
holds none,404for an unknown project.GET /api/organizations/{organizationId}/overview(any member): the same figures across the
projects the caller may see, the busiest projects and, for owners and admins only, the headcount.
Answers403for an organization other than the one the token is bound to.- Everything is counted in SQL (
COUNT/GROUP BY/FILTER); no entity is loaded. Each context owns its
figures behind a new named interface:discovery::insights,workspace::insightsand
CodebaseModuleApi.footprint. No migration.
Changed
- Final stories (processing a session or an uploaded recording) now get the same context as live suggestions: backlog candidates, glossary, constraints and the related modules of the connected code. Without context, or if the lookup fails, they are generated from the transcript alone as before.
- The release pull request and the back-merge pull request are opened by the GitHub App
reqsai-release-bot(a short-lived token minted per job fromRELEASE_APP_IDandRELEASE_APP_PRIVATE_KEY), so their CI runs: opened withGITHUB_TOKENthey started nopull_requestworkflow. The back-merge turns on auto-merge (merge commit) when the repository allows it; without the App configuration the job fails instead of falling back toGITHUB_TOKEN. produccion.ymlandrollback.ymldispatchreqsai-infra'sdeploy-mvp.ymlwith areqsai-release-bottoken limited toreqsai-infra(Actions: write) and watch the run with the workflow token, instead of the personal tokenINFRA_DEPLOY_TOKEN, which is no longer used.- The live extraction prompt puts its fixed rules and schema first and the project context, backlog and transcript last, so the provider's automatic prompt cache serves the rules from the second pass on (also across the chat). On the 24.7 s reference recording the quota the meeting counts went from 13,819 to 11,090 with a cold cache and 7,649 with a warm one; one chat requirement from 7,938 to 5,480. The glossary and constraints sent on each pass are capped and a client document summary is cut at 1,000 characters.
Fixed
- Release notes longer than GitHub's 125000-character limit are cut at a line break with a link to the full CHANGELOG, instead of failing the tag after the deploy (1.2.0 of reqsai-api).