Skip to content

Commit 528a6b9

Browse files
authored
Merge pull request #110 from esokullu/codex/fix-cloud-402-duplicate
Fix duplicate WebBrain Cloud quota errors
2 parents 0443dda + f807d86 commit 528a6b9

3 files changed

Lines changed: 59 additions & 2 deletions

File tree

src/chrome/src/agent/agent.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,12 @@ export class Agent {
576576
}
577577

578578
_isCostAllowanceError(err) {
579-
return err?.code === 'WB_COST_ALLOWANCE';
579+
// WebBrain Cloud's free-tier 402 is also an allowance terminal, but it
580+
// originates in the provider rather than _costAllowanceError(). Treat it
581+
// like the local cost cap so the agent does not retry it and then emit a
582+
// second generic error card beside the actionable Subscribe prompt.
583+
return err?.code === 'WB_COST_ALLOWANCE'
584+
|| /Subscribe for more usage:\s*https?:\/\/\S+/i.test(String(err?.message || ''));
580585
}
581586

582587
async _chatWithCostAllowance(provider, messages, options, costState) {

src/firefox/src/agent/agent.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,12 @@ export class Agent {
561561
}
562562

563563
_isCostAllowanceError(err) {
564-
return err?.code === 'WB_COST_ALLOWANCE';
564+
// WebBrain Cloud's free-tier 402 is also an allowance terminal, but it
565+
// originates in the provider rather than _costAllowanceError(). Treat it
566+
// like the local cost cap so the agent does not retry it and then emit a
567+
// second generic error card beside the actionable Subscribe prompt.
568+
return err?.code === 'WB_COST_ALLOWANCE'
569+
|| /Subscribe for more usage:\s*https?:\/\/\S+/i.test(String(err?.message || ''));
565570
}
566571

567572
async _chatWithCostAllowance(provider, messages, options, costState) {

test/run.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21956,6 +21956,53 @@ test('sidepanel routes every run-error path through request-scoped deduplication
2195621956
}
2195721957
});
2195821958

21959+
test('WebBrain Cloud subscription 402 renders as one terminal assistant prompt', async () => {
21960+
for (const [label, AgentClass] of [['chrome', AgentCh], ['firefox', AgentFx]]) {
21961+
const subscriptionMessage = 'webbrain-cloud error 402: Daily free WebBrain Cloud allowance used.\n'
21962+
+ 'Subscribe for more usage: https://webbrain.one/subscribe?client_reference_id=device-guid';
21963+
let providerCalls = 0;
21964+
const provider = {
21965+
supportsTools: true,
21966+
supportsVision: false,
21967+
promptTier: 'full',
21968+
contextWindow: 128000,
21969+
model: 'webbrain-cloud 1.0',
21970+
name: 'webbrain-cloud',
21971+
chat: async () => {
21972+
providerCalls += 1;
21973+
throw new Error(subscriptionMessage);
21974+
},
21975+
};
21976+
const agent = new AgentClass({
21977+
getActive: () => provider,
21978+
getVisionProvider: async () => null,
21979+
});
21980+
const tabId = label === 'chrome' ? 9401 : 9402;
21981+
agent.planBeforeAct = false;
21982+
agent.maxSteps = 2;
21983+
agent._manageContext = async () => {};
21984+
agent._enrichUserMessageWithCurrentPage = async (_tabId, _messages, content) => ({ role: 'user', content });
21985+
agent._maybeReinjectAdapter = async () => {};
21986+
agent._persist = () => {};
21987+
agent._startTraceRun = async () => null;
21988+
agent._endTraceRun = () => {};
21989+
21990+
const updates = [];
21991+
const final = await agent.processMessage(tabId, 'hello', (type, data) => {
21992+
updates.push({ type, data });
21993+
}, 'ask');
21994+
21995+
assert.equal(providerCalls, 1, `${label}: subscription 402 should not be retried`);
21996+
assert.equal(final, subscriptionMessage, `${label}: subscription prompt should remain the terminal assistant content`);
21997+
assert.equal(updates.filter(update => update.type === 'error').length, 0, `${label}: subscription 402 should not emit a generic error card`);
21998+
assert.equal(
21999+
updates.filter(update => update.type === 'warning' && update.data?.message === subscriptionMessage).length,
22000+
1,
22001+
`${label}: subscription 402 should emit one non-duplicating terminal warning`,
22002+
);
22003+
}
22004+
});
22005+
2195922006
test('plan review: cancellation emits plan_resolved and timeout has an explicit terminal decision', async () => {
2196022007
await withPlannerBrowserGlobals(async () => {
2196122008
for (const [label, AgentClass, sourceRel] of [

0 commit comments

Comments
 (0)