@@ -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+
2195922006test('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