fix(plugins): set documented output limit for glm-5.3-flash (#1852)

Register the documented 65536-token default output limit and retain the existing 128000-token context window for glm-5.3-flash. Other model registrations are unchanged.

Pi's isRecoverableLength (pi-ai dist/utils/overflow.js:163), used by agent-session.js:1659, now treats a length stop below 65536 output tokens as recoverable, including context-clamped requests or a lower provider cap. Pi then compacts and retries. It allows one recovery in a row: the flag resets on a new user message or a successful assistant message that is not a length stop, so tool rounds can re-arm it within one prompt.

The recovery happens inside one runner attempt. The turn marker reflects the final agent_end, and the failed and retried messages still count in that message's usage delta, so three runner attempts need not mean three provider calls.

The 128000 context and 16384 reserve are unchanged, so threshold compaction still starts above 111616 tokens. Output clamping now starts above about 58368 estimated input tokens instead of 107520. No new local refusal.

This commit can be dropped without affecting Part A.
This commit is contained in:
jason.woltje committed 2026-11-06 16:49:31 -06:00
1 parent 1d8f1713f8
commit 03072cc08b
2 files changed
+21 -1

No files matched your search

@@ -144,3 +144,14 @@ test('row 332 R2 a session proxy context without a key or loopback URL refuses i
{ code: 'invalid-proxy-context', message: 'invalid session proxy context' }, JSON.stringify(proxy));
}
});
test('GLM 5.3 flash has documented output and existing context limits; other model ids are unchanged', t => {
const declared = {
flash: { provider:'zai', model:'glm-5.3-flash' },
other: { provider:'zai', model:'glm-fixture' },
};
const b = build(t,'flash',{baseUrl:'http://127.0.0.1:12345',key:'fx332-agent-a'},declared);
const registered = JSON.parse(b.text).providers['mosaic-proxy-glm'].models;
assert.deepEqual(registered.find(m => m.id === 'glm-5.3-flash'),{id:'glm-5.3-flash',reasoning:true,maxTokens:65536,contextWindow:128000});
assert.deepEqual(registered.find(m => m.id === 'glm-fixture'),{id:'glm-fixture',reasoning:true});
});
+10 -1
View File
@@ -67,6 +67,15 @@ export const builtins = ({ tools }) => [...tools];
export const typedName = (name) => name;
export const reliesOn = () => RELIES_ON;
export const gateTimeout = () => null;
// https://docs.z.ai/guides/overview/concept-param
// https://docs.z.ai/guides/vlm/glm-5.3-flash
// Pi may compact and retry for length stops below maxTokens (pi-ai
// overflow.js:163 and pi-coding-agent agent-session.js:1659): once in a row,
// re-armed by a new prompt or a successful reply, so tool rounds can repeat it.
const DOCUMENTED_MODEL_LIMITS = {
'glm-5.3-flash': { maxTokens: 65536, contextWindow: 128000 },
};
export function bundle({ dir, models, proxy = null } = {}) {
const sources = { piExtension: EXTENSION, ...UNSLOP };
if (!proxy) return { files: {}, digests: [], sources };
@@ -90,7 +99,7 @@ export function bundle({ dir, models, proxy = null } = {}) {
models: [],
};
if (!providers[provider].models.some(model => model.id === entry.model)) {
providers[provider].models.push({ id: entry.model, reasoning: true });
providers[provider].models.push({ id: entry.model, reasoning: true, ...(Object.hasOwn(DOCUMENTED_MODEL_LIMITS, entry.model) ? DOCUMENTED_MODEL_LIMITS[entry.model] : {}) });
}
}
const text = JSON.stringify({ providers }, null, 2) + "\n";