pikiloom 0.4.36 → 0.4.37
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/dist/agent/drivers/codex.js +20 -3
- package/dist/agent/index.js +2 -2
- package/dist/agent/stream.js +41 -1
- package/package.json +1 -1
|
@@ -773,6 +773,23 @@ function createCodexStreamState(opts) {
|
|
|
773
773
|
generatingImages: 0,
|
|
774
774
|
};
|
|
775
775
|
}
|
|
776
|
+
// Codex on a ChatGPT-account login rejects non-OpenAI models with a raw upstream JSON blob
|
|
777
|
+
// (e.g. {"detail":"The 'deepseek-v4-pro' model is not supported when using Codex with a
|
|
778
|
+
// ChatGPT account."}). When a third-party model is correctly bound to a Provider profile the
|
|
779
|
+
// injector routes around this; this only fires when no binding exists, so turn the opaque
|
|
780
|
+
// upstream error into an actionable instruction instead of leaking JSON to the chat bubble.
|
|
781
|
+
export function humanizeCodexError(raw) {
|
|
782
|
+
if (!raw)
|
|
783
|
+
return null;
|
|
784
|
+
const match = raw.match(/The '([^']+)' model is not supported when using Codex with a ChatGPT account/i);
|
|
785
|
+
if (match) {
|
|
786
|
+
const model = match[1];
|
|
787
|
+
return `Codex 正在使用 ChatGPT 账号登录,无法运行第三方模型「${model}」。`
|
|
788
|
+
+ `请在「智能体配置」页接入该模型的供应商(填入 Base URL 与 API Key),添加对应模型档案并绑定到 Codex,`
|
|
789
|
+
+ `或改用 Codex 原生模型(如 gpt-5.5)。`;
|
|
790
|
+
}
|
|
791
|
+
return raw;
|
|
792
|
+
}
|
|
776
793
|
function codexErrorResult(error, start, sessionId, model, thinkingEffort) {
|
|
777
794
|
return {
|
|
778
795
|
ok: false, message: error, thinking: null,
|
|
@@ -1119,7 +1136,7 @@ export async function doCodexStream(opts) {
|
|
|
1119
1136
|
if (threadResp.error) {
|
|
1120
1137
|
const errMsg = threadResp.error.message || 'thread/start failed';
|
|
1121
1138
|
agentWarn(`[codex-rpc] thread error: ${errMsg}`);
|
|
1122
|
-
return codexErrorResult(errMsg, start, opts.sessionId, opts.model, opts.thinkingEffort);
|
|
1139
|
+
return codexErrorResult(humanizeCodexError(errMsg) ?? errMsg, start, opts.sessionId, opts.model, opts.thinkingEffort);
|
|
1123
1140
|
}
|
|
1124
1141
|
const threadResult = threadResp.result;
|
|
1125
1142
|
s.sessionId = threadResult.thread?.id ?? s.sessionId;
|
|
@@ -1210,7 +1227,7 @@ export async function doCodexStream(opts) {
|
|
|
1210
1227
|
unsubscribeRequests();
|
|
1211
1228
|
const errMsg = turnResp.error.message || 'turn/start failed';
|
|
1212
1229
|
agentWarn(`[codex-rpc] turn/start error: ${errMsg}`);
|
|
1213
|
-
return codexErrorResult(errMsg, start, s.sessionId, s.model, s.thinkingEffort);
|
|
1230
|
+
return codexErrorResult(humanizeCodexError(errMsg) ?? errMsg, start, s.sessionId, s.model, s.thinkingEffort);
|
|
1214
1231
|
}
|
|
1215
1232
|
s.turnId = turnResp.result?.turn?.id ?? null;
|
|
1216
1233
|
publishTurnControl();
|
|
@@ -1226,7 +1243,7 @@ export async function doCodexStream(opts) {
|
|
|
1226
1243
|
tryEmitCodexImageBlock(s, callId);
|
|
1227
1244
|
}
|
|
1228
1245
|
const ok = s.turnStatus === 'completed' && !timedOut && !interrupted;
|
|
1229
|
-
const error = s.turnError
|
|
1246
|
+
const error = humanizeCodexError(s.turnError)
|
|
1230
1247
|
|| (interrupted ? 'Interrupted by user.' : null)
|
|
1231
1248
|
|| (timedOut ? `Timed out after ${opts.timeout}s waiting for turn completion.` : null)
|
|
1232
1249
|
|| (!ok ? `Turn ${s.turnStatus || 'unknown'}.` : null);
|
package/dist/agent/index.js
CHANGED
|
@@ -7,7 +7,7 @@ export { attachAgentImage, attachInlineImage, materializeImage, rewriteAttachmen
|
|
|
7
7
|
export { deliverArtifact, readDeliveredArtifacts, deliveredArtifactBlocks, tailDeliveredBlocks, latestDeliveredTaskId, mimeForArtifact, } from './artifacts.js';
|
|
8
8
|
export { Q, agentLog, agentWarn, agentError, dedupeStrings, numberOrNull, normalizeStreamPreviewPlan, parseTodoWriteAsPlan, normalizeActivityLine, pushRecentActivity, detectClaudeApiError, isRetryableClaudeApiError, detectClaudeModelError, claudeModelErrorMessage, firstNonEmptyLine, shortValue, normalizeErrorMessage, joinErrorMessages, appendSystemPrompt, mimeForExt, computeContext, buildStreamPreviewMeta, summarizeClaudeToolUse, summarizeClaudeToolResult, previewToolCallInput, previewToolCallResult, roundPercent, toIsoFromEpochSeconds, normalizeUsageStatus, labelFromWindowMinutes, usageWindowFromRateLimit, parseJsonTail, modelFamily, normalizeClaudeModelId, emptyUsage, readTailLines, stripInjectedPrompts, sanitizeSessionUserPreviewText, SESSION_PREVIEW_IMAGE_PLACEHOLDER_RE, CLAUDE_AT_MENTION_IMAGE_RE, extractClaudeAtMentionImagePaths, stripClaudeAtMentionImages, isPendingSessionId, emitSessionIdUpdate, sessionListDisplayTitle, } from './utils.js';
|
|
9
9
|
export { updateSessionMeta, promoteSessionId, recordFork, resolveCanonicalSessionId, getSessionPromotions, listPikiloomSessions, findPikiloomSession, getSessionStoredConfig, ensureManagedSession, findManagedThreadSession, stageSessionFiles, mergeManagedAndNativeSessions, managedRecordToSessionInfo, getSessions, getSessionTail, getSessionMessages, applyTurnWindow, applyTurnFilter, classifySession, deriveUserStatus, exportSession, importSession, deleteAgentSession, isProcessAlive, isRunningSessionStale, reconcileOrphanedRunningSessions, } from './session.js';
|
|
10
|
-
export { detectAgentBin, listAgents, resolveDefaultAgent, run, doStream, listModels, resolveAgentModels, getUsage, getAgentBoundModelId, setAgentBoundModelId, } from './stream.js';
|
|
10
|
+
export { detectAgentBin, listAgents, resolveDefaultAgent, run, doStream, recoverProfileIdForModel, listModels, resolveAgentModels, getUsage, getAgentBoundModelId, setAgentBoundModelId, } from './stream.js';
|
|
11
11
|
export { registerDriver, getDriver, getDriverCapabilities, allDrivers, allDriverIds, hasDriver, shutdownAllDrivers, } from './driver.js';
|
|
12
12
|
export { getProjectSkillPaths, initializeProjectSkills, listSkills, getGlobalSkillsRoot, collapseSkillPrompt, } from './skills.js';
|
|
13
13
|
export { readGoal, writeGoal, clearGoal, setGoal, pauseGoal, resumeGoal, completeGoal, accountTurn, bumpContinuationCount, shouldContinueAfterTurn, renderContinuationPrompt, renderBudgetLimitPrompt, sessionGoalPath, DEFAULT_MAX_CONTINUATIONS, } from './goal.js';
|
|
@@ -19,6 +19,6 @@ export { getMcpToken, saveMcpToken, deleteMcpToken, hasValidMcpToken, startAutho
|
|
|
19
19
|
export { installSkill, removeSkill, checkSkillUpdates, getGlobalSkillsDir, recordSkillInstall, getSkillLedgerEntry, forgetSkillInstall, normalizeSkillSourceKey, } from './skill-installer.js';
|
|
20
20
|
export { getRecommendedClis, getRecommendedCli, detectCli, getCachedCliStatus, invalidateCliStatus, currentPlatform, getCliCatalog, refreshCliStatus, startCliAuthSession, getAuthSession, cancelAuthSession, applyCliToken, logoutCli, startCliInstallSession, } from './cli/index.js';
|
|
21
21
|
export { doClaudeStream } from './drivers/claude.js';
|
|
22
|
-
export { doCodexStream, buildCodexTurnInput, shutdownCodexServer, getCodexUsageLive } from './drivers/codex.js';
|
|
22
|
+
export { doCodexStream, buildCodexTurnInput, shutdownCodexServer, getCodexUsageLive, humanizeCodexError } from './drivers/codex.js';
|
|
23
23
|
export { doGeminiStream } from './drivers/gemini.js';
|
|
24
24
|
export { doHermesStream } from './drivers/hermes.js';
|
package/dist/agent/stream.js
CHANGED
|
@@ -388,6 +388,35 @@ function finalizeStreamResult(result, workdir, prompt, session, workflowEnabled,
|
|
|
388
388
|
saveSessionRecord(workdir, session.record);
|
|
389
389
|
return { ...result, sessionId: session.sessionId, workspacePath: session.workspacePath };
|
|
390
390
|
}
|
|
391
|
+
function requestedModelForAgent(opts) {
|
|
392
|
+
switch (opts.agent) {
|
|
393
|
+
case 'claude': return (opts.claudeModel || opts.model || '').trim();
|
|
394
|
+
case 'codex': return (opts.codexModel || opts.model || '').trim();
|
|
395
|
+
case 'gemini': return (opts.geminiModel || opts.model || '').trim();
|
|
396
|
+
case 'hermes': return (opts.hermesModel || opts.model || '').trim();
|
|
397
|
+
}
|
|
398
|
+
return (opts.model || '').trim();
|
|
399
|
+
}
|
|
400
|
+
// When a session carries a third-party model id but its profile binding was lost
|
|
401
|
+
// (stale/deleted profileId, or a model selected without a binding), resolveAgentInjection
|
|
402
|
+
// returns null and the agent silently falls back to its native account — e.g. Codex on a
|
|
403
|
+
// ChatGPT login rejects "deepseek-v4-pro". If exactly one configured profile (for a provider
|
|
404
|
+
// kind this agent accepts) declares that model id, the intent is unambiguous: recover it.
|
|
405
|
+
export function recoverProfileIdForModel(agent, modelId) {
|
|
406
|
+
const model = modelId.trim();
|
|
407
|
+
if (!model)
|
|
408
|
+
return null;
|
|
409
|
+
const accepted = new Set(getAcceptedProviderKinds(agent));
|
|
410
|
+
if (accepted.size === 0)
|
|
411
|
+
return null;
|
|
412
|
+
const matches = listProfiles().filter(profile => {
|
|
413
|
+
if (profile.modelId !== model)
|
|
414
|
+
return false;
|
|
415
|
+
const provider = getProvider(profile.providerId);
|
|
416
|
+
return !!provider && accepted.has(provider.kind);
|
|
417
|
+
});
|
|
418
|
+
return matches.length === 1 ? matches[0].id : null;
|
|
419
|
+
}
|
|
391
420
|
export async function doStream(opts) {
|
|
392
421
|
let session;
|
|
393
422
|
let prepared;
|
|
@@ -446,7 +475,18 @@ export async function doStream(opts) {
|
|
|
446
475
|
agentWarn(`[mcp] bridge start failed: ${e.message} — proceeding without MCP`);
|
|
447
476
|
}
|
|
448
477
|
try {
|
|
449
|
-
|
|
478
|
+
let injection = await resolveAgentInjection(prepared.agent, prepared.profileId);
|
|
479
|
+
if (!injection) {
|
|
480
|
+
const requestedModel = requestedModelForAgent(prepared);
|
|
481
|
+
const recoveredProfileId = recoverProfileIdForModel(prepared.agent, requestedModel);
|
|
482
|
+
if (recoveredProfileId) {
|
|
483
|
+
injection = await resolveAgentInjection(prepared.agent, recoveredProfileId);
|
|
484
|
+
if (injection) {
|
|
485
|
+
prepared.profileId = recoveredProfileId;
|
|
486
|
+
agentLog(`[byok] recovered lost provider binding: agent=${prepared.agent} model=${requestedModel} → profile=${recoveredProfileId}`);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
}
|
|
450
490
|
if (injection) {
|
|
451
491
|
prepared.extraEnv = { ...(prepared.extraEnv || {}), ...injection.env };
|
|
452
492
|
if (injection.modelOverride) {
|
package/package.json
CHANGED