Skip to content

Commit 12785db

Browse files
committed
fix(webapp): only charge agent message quota on a delivered send
A failed upstream send (5xx/502) or a non-2xx response burned a quota message that never reached the agent. Record only after upstream.ok.
1 parent 82035a7 commit 12785db

2 files changed

Lines changed: 17 additions & 7 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
area: webapp
3+
type: fix
4+
---
5+
6+
Messages to the dashboard agent that fail to send no longer count against your monthly message allowance. Only delivered messages are counted.

apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dashboard-agent.in.$.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ export async function action({ request, params }: ActionFunctionArgs) {
121121
parsed = undefined;
122122
}
123123

124+
// Hoisted so it is visible after the fetch: quota is charged only once the send succeeds.
125+
let countsAgainstQuota = false;
126+
124127
if (parsed) {
125128
// Actions are placed by the server only, and this proxy is the one path a browser
126129
// can reach `.in` through.
@@ -134,7 +137,7 @@ export async function action({ request, params }: ActionFunctionArgs) {
134137
}
135138

136139
// Only a real user message consumes quota; action turns were refused above.
137-
const countsAgainstQuota = agentTurnCountsAgainstQuota(parsed);
140+
countsAgainstQuota = agentTurnCountsAgainstQuota(parsed);
138141
if (countsAgainstQuota) {
139142
const quota = await resolveAgentMessageQuota(dashboardAgentDb, {
140143
organizationId: project.organizationId,
@@ -170,12 +173,6 @@ export async function action({ request, params }: ActionFunctionArgs) {
170173
...(repoSnapshot ? { repoSnapshot } : {}),
171174
};
172175
body = JSON.stringify(parsed);
173-
174-
if (countsAgainstQuota) {
175-
await recordAgentMessageSent(dashboardAgentDb, {
176-
organizationId: project.organizationId,
177-
});
178-
}
179176
}
180177
}
181178

@@ -188,6 +185,13 @@ export async function action({ request, params }: ActionFunctionArgs) {
188185
try {
189186
const upstream = await fetch(upstreamUrl, { method: "POST", headers, body });
190187
const text = await upstream.text();
188+
// Charge quota only for a delivered message: a non-2xx upstream (or a throw below)
189+
// must not burn a send that never reached the agent.
190+
if (countsAgainstQuota && upstream.ok) {
191+
await recordAgentMessageSent(dashboardAgentDb, {
192+
organizationId: project.organizationId,
193+
});
194+
}
191195
return new Response(text, {
192196
status: upstream.status,
193197
headers: { "content-type": upstream.headers.get("content-type") ?? "application/json" },

0 commit comments

Comments
 (0)