polygram 0.7.9 → 0.8.0-rc.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/lib/agent-loader.js +169 -0
- package/lib/approval-waiters.js +194 -0
- package/lib/attachments.js +7 -9
- package/lib/autosteer-buffer.js +80 -0
- package/lib/db.js +93 -7
- package/lib/error-classify.js +38 -9
- package/lib/process-manager-sdk.js +959 -0
- package/migrations/010-tool-use-id.sql +62 -0
- package/package.json +2 -1
- package/polygram.js +925 -43
package/lib/error-classify.js
CHANGED
|
@@ -97,7 +97,10 @@ const USER_MESSAGES = {
|
|
|
97
97
|
missingToolInput: '⚠️ Session history looks corrupted. Try /new.',
|
|
98
98
|
timeout: '⏳ I went quiet too long without finishing. Try resending or simplifying.',
|
|
99
99
|
format: '⚠️ Invalid request format. Try rephrasing or /new.',
|
|
100
|
-
|
|
100
|
+
// Used both for in-flight retry attempts AND for the post-retry-failed
|
|
101
|
+
// bubble-up message. Avoid promising "retrying once" since by the
|
|
102
|
+
// time the user reads it pm has already retried and given up.
|
|
103
|
+
transient5xx: '☁️ Server hiccup — please try again in a moment.',
|
|
101
104
|
};
|
|
102
105
|
|
|
103
106
|
// Auto-recovery actions for kinds where the session is irrecoverable
|
|
@@ -183,15 +186,16 @@ function classify(err) {
|
|
|
183
186
|
}
|
|
184
187
|
|
|
185
188
|
// SDKAssistantMessage.error is a short string code from a fixed
|
|
186
|
-
// union — match those directly, not via regex.
|
|
189
|
+
// union — match those directly, not via regex. Result subtypes
|
|
190
|
+
// are checked LATER (after pattern matching) so a more-specific
|
|
191
|
+
// pattern in the message text (e.g. 'HTTP 401' inside an
|
|
192
|
+
// error_during_execution subtype) wins over the generic subtype
|
|
193
|
+
// mapping that defaults the entire error_during_execution class
|
|
194
|
+
// to transient.
|
|
187
195
|
if (typeof err === 'string') {
|
|
188
196
|
const sdkMessageError = matchSdkMessageError(err);
|
|
189
197
|
if (sdkMessageError) return sdkMessageError;
|
|
190
198
|
}
|
|
191
|
-
if (err?.subtype && typeof err.subtype === 'string') {
|
|
192
|
-
const sdkResultSubtype = matchSdkResultSubtype(err.subtype);
|
|
193
|
-
if (sdkResultSubtype) return sdkResultSubtype;
|
|
194
|
-
}
|
|
195
199
|
|
|
196
200
|
const msg = extractMessage(err);
|
|
197
201
|
for (const [kind, re] of Object.entries(PATTERNS)) {
|
|
@@ -205,6 +209,20 @@ function classify(err) {
|
|
|
205
209
|
}
|
|
206
210
|
}
|
|
207
211
|
|
|
212
|
+
// After pattern matching: try SDK result subtypes. A bare string
|
|
213
|
+
// like 'error_during_execution' (no message context) lands here
|
|
214
|
+
// and gets the friendly transient5xx kind. Object inputs with a
|
|
215
|
+
// subtype field also land here when their message text didn't
|
|
216
|
+
// match a more specific pattern.
|
|
217
|
+
if (typeof err === 'string') {
|
|
218
|
+
const sdkResultSubtype = matchSdkResultSubtype(err);
|
|
219
|
+
if (sdkResultSubtype) return sdkResultSubtype;
|
|
220
|
+
}
|
|
221
|
+
if (err?.subtype && typeof err.subtype === 'string') {
|
|
222
|
+
const sdkResultSubtype = matchSdkResultSubtype(err.subtype);
|
|
223
|
+
if (sdkResultSubtype) return sdkResultSubtype;
|
|
224
|
+
}
|
|
225
|
+
|
|
208
226
|
// Fall-through: surface a snippet of the raw error so users at
|
|
209
227
|
// least know SOMETHING happened. Same shape as before, just
|
|
210
228
|
// routed through the classifier so callers get a uniform return.
|
|
@@ -252,8 +270,15 @@ function matchSdkMessageError(s) {
|
|
|
252
270
|
|
|
253
271
|
// SDKResultMessage.subtype values (sdk.d.ts:3121). Most are
|
|
254
272
|
// terminal-error indicators that don't have a clean pattern equivalent.
|
|
273
|
+
//
|
|
274
|
+
// `error_during_execution` is the SDK's catch-all for "something went
|
|
275
|
+
// wrong mid-turn" — could be a transient stream/network blip OR a
|
|
276
|
+
// systemic model issue. We treat it as transient (1 retry is cheap;
|
|
277
|
+
// if it's systemic the second attempt fails fast). Pre-rc.5 this was
|
|
278
|
+
// mapped to 'unknown' which fell through to the default "Hit a snag:
|
|
279
|
+
// error_during_execution" template — leaking the SDK enum to users.
|
|
255
280
|
const SDK_RESULT_SUBTYPE_MAP = {
|
|
256
|
-
error_during_execution: '
|
|
281
|
+
error_during_execution: 'transient5xx',
|
|
257
282
|
error_max_turns: 'format',
|
|
258
283
|
error_max_budget_usd: 'billing',
|
|
259
284
|
error_max_structured_output_retries: 'format',
|
|
@@ -265,8 +290,12 @@ function matchSdkResultSubtype(s) {
|
|
|
265
290
|
return {
|
|
266
291
|
kind,
|
|
267
292
|
userMessage: USER_MESSAGES[kind] ?? null,
|
|
268
|
-
|
|
269
|
-
|
|
293
|
+
// Derive transience from the kind so error_during_execution →
|
|
294
|
+
// transient5xx → isTransient=true, matching the pattern-match
|
|
295
|
+
// branch's behaviour. pm guards retry with firstAssistantSeen=
|
|
296
|
+
// false, which prevents budget waste when the turn already had
|
|
297
|
+
// billable assistant output.
|
|
298
|
+
isTransient: kind === 'transient5xx' || kind === 'rateLimit',
|
|
270
299
|
autoRecover: AUTO_RECOVER[kind] ?? null,
|
|
271
300
|
};
|
|
272
301
|
}
|