@jskit-ai/assistant-core 0.1.239 → 0.1.241
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/examples/conversation/package.json +5 -5
- package/package.json +5 -5
- package/src/client/conversation/AssistantTranscript.vue +26 -29
- package/src/client/conversation/LongTextPreviewBlocks.vue +11 -0
- package/src/client/conversation/messageDelivery.js +8 -2
- package/src/client/conversation/useAssistantAttachments.js +1 -1
- package/src/server/conversation/agentRun.js +12 -198
- package/src/server/conversation/attachments.js +6 -5
- package/src/server/conversation/boundedToolLoop.js +160 -0
- package/src/server/conversation/claudeHistory.js +20 -16
- package/src/server/conversation/claudeProcess.js +2 -2
- package/src/server/conversation/claudeTurn.js +51 -40
- package/src/server/conversation/codexAuthPreflight.js +104 -0
- package/src/server/conversation/codexClient.js +11 -16
- package/src/server/conversation/codexConfiguration.js +112 -98
- package/src/server/conversation/codexConversationStore.js +189 -0
- package/src/server/conversation/codexConversations.js +47 -44
- package/src/server/conversation/codexDetachedTurn.js +12 -11
- package/src/server/conversation/codexEvents.js +95 -99
- package/src/server/conversation/codexGoalCommands.js +1 -1
- package/src/server/conversation/codexHelperExecution.js +3 -13
- package/src/server/conversation/codexHelperThreadLedger.js +7 -13
- package/src/server/conversation/codexHelperThreadRecovery.js +2 -16
- package/src/server/conversation/codexHelperThreads.js +5 -6
- package/src/server/conversation/codexHistoryAdapter.js +32 -26
- package/src/server/conversation/codexMessageCommands.js +22 -22
- package/src/server/conversation/codexMessageDelivery.js +12 -7
- package/src/server/conversation/codexModelCatalog.js +97 -0
- package/src/server/conversation/codexNotificationObserver.js +24 -40
- package/src/server/conversation/codexNotificationQueue.js +2 -3
- package/src/server/conversation/codexOutput.js +20 -27
- package/src/server/conversation/codexProcess.js +123 -127
- package/src/server/conversation/codexProcessLeader.js +3 -3
- package/src/server/conversation/codexProvider.js +31 -614
- package/src/server/conversation/codexProviderOwner.js +2 -2
- package/src/server/conversation/codexProviderSelection.js +38 -40
- package/src/server/conversation/codexRenewalCommands.js +13 -10
- package/src/server/conversation/codexRenewalThreads.js +412 -0
- package/src/server/conversation/codexRunJournal.js +24 -42
- package/src/server/conversation/codexRuntimeLifecycle.js +19 -15
- package/src/server/conversation/codexSessionCleanup.js +11 -10
- package/src/server/conversation/codexSessionReconciliation.js +6 -6
- package/src/server/conversation/codexThreadReadiness.js +19 -33
- package/src/server/conversation/codexThreadStatus.js +3 -3
- package/src/server/conversation/codexTurn.js +124 -297
- package/src/server/conversation/codexTurnRecovery.js +49 -28
- package/src/server/conversation/codexTurnState.js +34 -13
- package/src/server/conversation/commandWrapper.js +3 -0
- package/src/server/conversation/deliveryTiming.js +14 -5
- package/src/server/conversation/index.js +1 -0
- package/src/server/conversation/localExecution.js +13 -17
- package/src/server/conversation/normalize.js +8 -3
- package/src/server/conversation/openCodeClient.js +9 -10
- package/src/server/conversation/openCodeProcess.js +9 -5
- package/src/server/conversation/openCodeRuntime.js +10 -11
- package/src/server/conversation/openCodeTurn.js +43 -29
- package/src/server/conversation/providers/claudeDriver.js +10 -16
- package/src/server/conversation/providers/codexDriver.js +27 -43
- package/src/server/conversation/providers/opencodeDriver.js +17 -42
- package/src/server/conversation/providers/scoped.js +48 -4
- package/src/server/conversation/runtime.js +50 -49
- package/src/server/conversation/runtimeStateUpgrade.js +34 -22
- package/src/server/conversation/transcript.js +10 -10
- package/src/server/hosts/codexConfiguration.js +1 -0
- package/src/server/hosts/codexProvider.js +8 -6
- package/src/server/index.js +2 -1
- package/src/server/lib/assistantToolLoop.js +1 -153
- package/src/server/lib/serviceToolCatalog.js +17 -42
- package/src/shared/assistantResource.js +4 -2
- package/src/shared/conversation/attachments.js +4 -0
- package/src/shared/conversation/longTextBlocks.js +54 -19
- package/src/shared/conversation/numberedQuestionSugar.js +17 -10
- package/src/shared/conversation/pagination.js +4 -6
- package/src/shared/conversation/patches.js +1 -4
- package/src/shared/conversation/streaming.js +3 -11
- package/src/shared/conversation/turns.js +11 -0
- package/src/shared/index.js +1 -0
- package/test/assistantBoundedToolLoop.test.js +2 -2
- package/test/assistantResource.test.js +4 -4
- package/test/assistantScroll.browser.test.js +29 -6
- package/test/assistantSettingsResource.test.js +2 -2
- package/test/claudeConversationSession.test.js +20 -3
- package/test/claudeTurn.test.js +27 -7
- package/test/codexClient.test.js +20 -0
- package/test/codexConversationSession.test.js +5 -3
- package/test/codexConversationsCheckpoint.test.js +51 -0
- package/test/codexModelCatalog.test.js +1 -1
- package/test/codexProviderHome.test.js +51 -0
- package/test/codexProviderSelection.test.js +71 -0
- package/test/codexTurn.test.js +222 -6
- package/test/conversationAgentRun.test.js +2 -1
- package/test/conversationAttachments.test.js +27 -2
- package/test/conversationDeliveryTiming.test.js +21 -0
- package/test/conversationNormalize.test.js +11 -0
- package/test/fixtures/nestedListQuestionMessage.md +37 -0
- package/test/frameworkActions.test.js +2 -2
- package/test/longTextBlocks.test.js +102 -0
- package/test/messageDelivery.test.js +7 -1
- package/test/openCodeClient.test.js +20 -0
- package/test/openCodeRuntime.test.js +1 -1
- package/test/openCodeTurn.test.js +90 -0
- package/test/opencodeConversationSession.test.js +1 -1
- package/test/serviceToolCatalog.test.js +27 -0
|
@@ -8,21 +8,24 @@ import {
|
|
|
8
8
|
} from "./codexConfiguration.js";
|
|
9
9
|
import {
|
|
10
10
|
CODEX_APP_SERVER_PROCESS_STATE, CODEX_APP_SERVER_TRANSPORT,
|
|
11
|
-
assertExistingDirectory, codexAppServerCommandBaseEnv, codexAppServerCredentialHome,
|
|
12
11
|
codexAppServerExecutionMode, codexAppServerHelperWorkspaceDir, codexAppServerIsHelper,
|
|
13
|
-
|
|
12
|
+
codexAppServerRuntimeIdentity, codexAppServerTerminalEnvHash,
|
|
14
13
|
ensureWritablePrivateDirectory, normalizeCodexAppServerTerminalEnv, tailTextFile
|
|
15
14
|
} from "./codexProcess.js";
|
|
15
|
+
import { assertCodexAuthPreflightReady } from "./codexAuthPreflight.js";
|
|
16
|
+
import { codexAppServerModelCatalogError } from "./codexModelCatalog.js";
|
|
16
17
|
import { prepareCodexHistory } from "./codexHistoryAdapter.js";
|
|
17
18
|
import { createCodexConversationAdapter } from "./providers/codex.js";
|
|
18
19
|
import { exportCodexNativeHistory } from "./codexNativeHistoryExport.js";
|
|
19
20
|
import { retireNativeConversation, readStoppedNativeDatabase } from "./nativeHistoryExport.js";
|
|
20
|
-
import {
|
|
21
|
+
import { isRecord, normalizePositiveInteger } from "@jskit-ai/kernel/shared/support/normalize";
|
|
22
|
+
import { normalizeNullableText as normalizeAgentText } from "./normalize.js";
|
|
21
23
|
import {
|
|
22
24
|
codexAppServerProviderThreadTurns,
|
|
23
25
|
codexAppServerProviderTurnItems,
|
|
24
26
|
codexAppServerProviderTurnClientIds,
|
|
25
|
-
codexAppServerThreadRawValue
|
|
27
|
+
codexAppServerThreadRawValue,
|
|
28
|
+
codexAppServerErrorText
|
|
26
29
|
} from "./codexEvents.js";
|
|
27
30
|
|
|
28
31
|
const CODEX_APP_SERVER_PROVIDER_ID = "codex_app_server";
|
|
@@ -30,8 +33,6 @@ const CODEX_APP_SERVER_EXECUTION_MODES = Object.freeze({ HELPER: "helper", INTER
|
|
|
30
33
|
const codexAppServerHelperAuthError = createCodexAccountReader().error;
|
|
31
34
|
|
|
32
35
|
const CODEX_APP_SERVER_INVALID_REQUEST_CODE = -32600;
|
|
33
|
-
const CODEX_RENEWAL_UNMATERIALIZED_THREAD_SUFFIX =
|
|
34
|
-
"is not materialized yet; includeTurns is unavailable before first user message";
|
|
35
36
|
const CODEX_APP_SERVER_MODEL_CATALOG_PAGE_LIMIT = 100;
|
|
36
37
|
const CODEX_APP_SERVER_MODEL_CATALOG_MAX_PAGES = 100;
|
|
37
38
|
const CODEX_APP_SERVER_MODEL_CATALOG_MAX_ENTRIES = 1000;
|
|
@@ -40,23 +41,16 @@ const CODEX_APP_SERVER_MODEL_CATALOG_MAX_TOTAL_BYTES = 2 * 1024 * 1024;
|
|
|
40
41
|
const CODEX_APP_SERVER_MODEL_CATALOG_MAX_CURSOR_LENGTH = 512;
|
|
41
42
|
const CODEX_APP_SERVER_THREAD_INVENTORY_PAGE_LIMIT = 100;
|
|
42
43
|
const CODEX_APP_SERVER_THREAD_INVENTORY_MAX_PAGES = 100;
|
|
43
|
-
const CODEX_APP_SERVER_THREAD_INVENTORY_MAX_COUNT = 1000;
|
|
44
|
-
const CODEX_APP_SERVER_THREAD_INVENTORY_ID_MAX_LENGTH = 512;
|
|
44
|
+
export const CODEX_APP_SERVER_THREAD_INVENTORY_MAX_COUNT = 1000;
|
|
45
|
+
export const CODEX_APP_SERVER_THREAD_INVENTORY_ID_MAX_LENGTH = 512;
|
|
45
46
|
const CODEX_APP_SERVER_THREAD_INVENTORY_MAX_ENTRY_BYTES = 64 * 1024;
|
|
46
47
|
const CODEX_APP_SERVER_THREAD_INVENTORY_MAX_TOTAL_BYTES = 2 * 1024 * 1024;
|
|
47
48
|
const CODEX_APP_SERVER_HELPER_MAX_MESSAGE_BYTES = 4 * 1024 * 1024;
|
|
48
49
|
const CODEX_APP_SERVER_SERVER_INFO_USER_AGENT_MAX_LENGTH = 512;
|
|
49
|
-
const CODEX_AUTH_PREFLIGHT_TIMEOUT_MS = 15000;
|
|
50
|
-
const CODEX_AUTH_PREFLIGHT_OUTPUT_TAIL_BYTES = 4096;
|
|
51
50
|
const CODEX_APP_SERVER_CHATGPT_REFRESH_METHOD = "account/chatgptAuthTokens/refresh";
|
|
52
51
|
const CODEX_NATIVE_STORAGE_SOURCE_KINDS = ["cli", "vscode", "exec", "appServer", "subAgent", "subAgentReview",
|
|
53
52
|
"subAgentCompact", "subAgentThreadSpawn", "subAgentOther", "unknown"];
|
|
54
53
|
|
|
55
|
-
function normalizePositiveInteger(value, fallback) {
|
|
56
|
-
const number = Number(value);
|
|
57
|
-
return Number.isSafeInteger(number) && number > 0 ? number : fallback;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
54
|
function codexAppServerRequestIsInvalid(error = null, method = "") {
|
|
61
55
|
const expectedMethod = normalizeAgentText(method);
|
|
62
56
|
const actualMethod = normalizeAgentText(error?.method);
|
|
@@ -206,7 +200,7 @@ async function inspectCodexAppServerMessageAdmission({ provider, threadId, messa
|
|
|
206
200
|
// proof and durable cleanup receipt.
|
|
207
201
|
async function deleteCodexAppServerThread({ provider, threadId } = {}) {
|
|
208
202
|
const result = await provider.deleteThread(threadId);
|
|
209
|
-
if (!
|
|
203
|
+
if (!isRecord(result)) {
|
|
210
204
|
const error = new Error("Codex app-server returned an invalid thread deletion result.");
|
|
211
205
|
error.code = "codex_helper_thread_delete_unconfirmed";
|
|
212
206
|
throw error;
|
|
@@ -354,501 +348,6 @@ async function ensureCodexAppServerThread({
|
|
|
354
348
|
};
|
|
355
349
|
}
|
|
356
350
|
|
|
357
|
-
function defineCodexRenewalThreadIds(value = [], {
|
|
358
|
-
errorCode = "codex_renewal_fresh_thread_required"
|
|
359
|
-
} = {}) {
|
|
360
|
-
if (
|
|
361
|
-
!Array.isArray(value) ||
|
|
362
|
-
value.length > CODEX_APP_SERVER_THREAD_INVENTORY_MAX_COUNT
|
|
363
|
-
) {
|
|
364
|
-
throw codexRenewalThreadError(
|
|
365
|
-
errorCode,
|
|
366
|
-
"The successor assistant thread inventory is invalid."
|
|
367
|
-
);
|
|
368
|
-
}
|
|
369
|
-
const threadIds = value.map((threadId) => normalizeAgentText(threadId));
|
|
370
|
-
if (
|
|
371
|
-
threadIds.some((threadId) => (
|
|
372
|
-
!threadId ||
|
|
373
|
-
threadId.length > CODEX_APP_SERVER_THREAD_INVENTORY_ID_MAX_LENGTH ||
|
|
374
|
-
codexAppServerTextHasControlCharacters(threadId)
|
|
375
|
-
)) ||
|
|
376
|
-
new Set(threadIds).size !== threadIds.length
|
|
377
|
-
) {
|
|
378
|
-
throw codexRenewalThreadError(
|
|
379
|
-
errorCode,
|
|
380
|
-
"The successor assistant thread inventory contains an invalid identity."
|
|
381
|
-
);
|
|
382
|
-
}
|
|
383
|
-
return Object.freeze([...threadIds].sort());
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
async function listCodexRenewalThreadIds(provider, workdir, errorCode) {
|
|
387
|
-
if (typeof provider?.listAppServerThreadsForCwd !== "function") {
|
|
388
|
-
throw codexRenewalThreadError(
|
|
389
|
-
errorCode,
|
|
390
|
-
"The assistant provider cannot inventory the successor's exact session threads."
|
|
391
|
-
);
|
|
392
|
-
}
|
|
393
|
-
const normalizedWorkdir = normalizeAgentText(workdir);
|
|
394
|
-
const inventory = await provider.listAppServerThreadsForCwd({
|
|
395
|
-
cwd: normalizedWorkdir
|
|
396
|
-
});
|
|
397
|
-
if (normalizeAgentText(inventory?.cwd) !== normalizedWorkdir) {
|
|
398
|
-
throw codexRenewalThreadError(
|
|
399
|
-
errorCode,
|
|
400
|
-
"The assistant provider returned a thread inventory for a different session source."
|
|
401
|
-
);
|
|
402
|
-
}
|
|
403
|
-
return defineCodexRenewalThreadIds(inventory?.threadIds, { errorCode });
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
function assertCodexRenewalThreadSnapshot(threadSnapshot = null, {
|
|
407
|
-
threadId = "",
|
|
408
|
-
workdir = "",
|
|
409
|
-
errorCode
|
|
410
|
-
} = {}) {
|
|
411
|
-
const expectedThreadId = normalizeAgentText(threadId);
|
|
412
|
-
const expectedWorkdir = normalizeAgentText(workdir);
|
|
413
|
-
const actualThreadId = codexAppServerThreadResponseId(threadSnapshot);
|
|
414
|
-
const actualWorkdir = normalizeAgentText(
|
|
415
|
-
threadSnapshot?.cwd ||
|
|
416
|
-
threadSnapshot?.raw?.cwd ||
|
|
417
|
-
threadSnapshot?.response?.thread?.cwd
|
|
418
|
-
);
|
|
419
|
-
if (actualThreadId !== expectedThreadId || actualWorkdir !== expectedWorkdir) {
|
|
420
|
-
throw codexRenewalThreadError(
|
|
421
|
-
errorCode,
|
|
422
|
-
"The assistant provider could not verify the exact successor thread and session source.",
|
|
423
|
-
{
|
|
424
|
-
actualThreadId,
|
|
425
|
-
actualWorkdir,
|
|
426
|
-
expectedThreadId,
|
|
427
|
-
expectedWorkdir
|
|
428
|
-
}
|
|
429
|
-
);
|
|
430
|
-
}
|
|
431
|
-
return threadSnapshot;
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
function codexRenewalThreadNeedsStatusRead(error = null, threadId = "") {
|
|
435
|
-
const normalizedThreadId = normalizeAgentText(threadId);
|
|
436
|
-
return Boolean(
|
|
437
|
-
normalizedThreadId &&
|
|
438
|
-
(
|
|
439
|
-
(
|
|
440
|
-
codexAppServerRequestIsInvalid(error, "thread/read") &&
|
|
441
|
-
normalizeAgentText(error?.message) ===
|
|
442
|
-
`thread ${normalizedThreadId} ${CODEX_RENEWAL_UNMATERIALIZED_THREAD_SUFFIX}`
|
|
443
|
-
) ||
|
|
444
|
-
(
|
|
445
|
-
Number(error?.code) === -32601 &&
|
|
446
|
-
normalizeAgentText(error?.method) === "thread/read"
|
|
447
|
-
)
|
|
448
|
-
)
|
|
449
|
-
);
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
async function readCodexRenewalSuccessorThreadSnapshot({
|
|
453
|
-
provider,
|
|
454
|
-
threadId = "",
|
|
455
|
-
workdir = "",
|
|
456
|
-
errorCode
|
|
457
|
-
} = {}) {
|
|
458
|
-
try {
|
|
459
|
-
return assertCodexRenewalThreadSnapshot(
|
|
460
|
-
await provider.readThread(threadId),
|
|
461
|
-
{ threadId, workdir, errorCode }
|
|
462
|
-
);
|
|
463
|
-
} catch (error) {
|
|
464
|
-
if (
|
|
465
|
-
!codexRenewalThreadNeedsStatusRead(error, threadId) ||
|
|
466
|
-
typeof provider?.readThreadStatus !== "function"
|
|
467
|
-
) {
|
|
468
|
-
throw error;
|
|
469
|
-
}
|
|
470
|
-
return assertCodexRenewalThreadSnapshot(
|
|
471
|
-
await provider.readThreadStatus(threadId),
|
|
472
|
-
{ threadId, workdir, errorCode }
|
|
473
|
-
);
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
function codexRenewalThreadError(code, message, details = {}, {
|
|
478
|
-
retryable = false
|
|
479
|
-
} = {}) {
|
|
480
|
-
const error = new Error(message);
|
|
481
|
-
error.code = code;
|
|
482
|
-
error.details = {
|
|
483
|
-
...details,
|
|
484
|
-
retryable
|
|
485
|
-
};
|
|
486
|
-
error.retryable = retryable;
|
|
487
|
-
return error;
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
function codexAppServerThreadResponseId(thread = null, fallback = "") {
|
|
491
|
-
return normalizeAgentText(
|
|
492
|
-
thread?.id ||
|
|
493
|
-
thread?.response?.thread?.id ||
|
|
494
|
-
fallback
|
|
495
|
-
);
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
/** Resume only the supplied retained thread; native read failures never replace it. */
|
|
499
|
-
async function resumeExactCodexAppServerThread({
|
|
500
|
-
expectedThreadId = "",
|
|
501
|
-
provider,
|
|
502
|
-
settings,
|
|
503
|
-
projectHooks = false,
|
|
504
|
-
workdir = "",
|
|
505
|
-
errorCode = "codex_renewal_thread_unreadable"
|
|
506
|
-
} = {}) {
|
|
507
|
-
const normalizedWorkdir = normalizeAgentText(workdir);
|
|
508
|
-
const normalizedExpectedThreadId = normalizeAgentText(expectedThreadId);
|
|
509
|
-
if (
|
|
510
|
-
typeof provider?.ensureRuntime !== "function" ||
|
|
511
|
-
typeof provider?.resumeThread !== "function" ||
|
|
512
|
-
typeof provider?.readThread !== "function"
|
|
513
|
-
) {
|
|
514
|
-
throw codexRenewalThreadError(
|
|
515
|
-
errorCode,
|
|
516
|
-
"The old assistant provider cannot read its exact main thread.",
|
|
517
|
-
{ expectedThreadId: normalizedExpectedThreadId }
|
|
518
|
-
);
|
|
519
|
-
}
|
|
520
|
-
const appServerRuntime = await provider.ensureRuntime();
|
|
521
|
-
const config = projectHooks
|
|
522
|
-
? await codexAppServerProjectHookTrustConfig(provider, normalizedWorkdir)
|
|
523
|
-
: null;
|
|
524
|
-
const { threadSettings } = await settings(normalizedWorkdir, config);
|
|
525
|
-
let thread = null;
|
|
526
|
-
let threadSnapshot = null;
|
|
527
|
-
try {
|
|
528
|
-
thread = await provider.resumeThread(normalizedExpectedThreadId, threadSettings);
|
|
529
|
-
const resumedThreadId = codexAppServerThreadResponseId(thread, normalizedExpectedThreadId);
|
|
530
|
-
if (resumedThreadId !== normalizedExpectedThreadId) {
|
|
531
|
-
throw codexRenewalThreadError(
|
|
532
|
-
errorCode,
|
|
533
|
-
"The old assistant provider resumed a different thread.",
|
|
534
|
-
{
|
|
535
|
-
expectedThreadId: normalizedExpectedThreadId,
|
|
536
|
-
resumedThreadId
|
|
537
|
-
}
|
|
538
|
-
);
|
|
539
|
-
}
|
|
540
|
-
threadSnapshot = await provider.readThread(normalizedExpectedThreadId);
|
|
541
|
-
} catch (error) {
|
|
542
|
-
if (
|
|
543
|
-
error?.code === errorCode ||
|
|
544
|
-
codexAppServerRequestIsInvalid(error, "thread/resume") ||
|
|
545
|
-
codexAppServerRequestIsInvalid(error, "thread/read")
|
|
546
|
-
) {
|
|
547
|
-
if (error?.code === errorCode) {
|
|
548
|
-
throw error;
|
|
549
|
-
}
|
|
550
|
-
throw codexRenewalThreadError(
|
|
551
|
-
errorCode,
|
|
552
|
-
"The old assistant thread cannot be read. Write or edit the handover manually instead.",
|
|
553
|
-
{
|
|
554
|
-
expectedThreadId: normalizedExpectedThreadId,
|
|
555
|
-
providerError: normalizeAgentText(error?.message)
|
|
556
|
-
}
|
|
557
|
-
);
|
|
558
|
-
}
|
|
559
|
-
throw error;
|
|
560
|
-
}
|
|
561
|
-
return Object.freeze({
|
|
562
|
-
appServerRuntime,
|
|
563
|
-
thread,
|
|
564
|
-
threadId: normalizedExpectedThreadId,
|
|
565
|
-
threadSnapshot,
|
|
566
|
-
threadSettings
|
|
567
|
-
});
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
/** Preserve the original baseline → create/adopt → durable identity → first-read order. */
|
|
571
|
-
async function startFreshCodexAppServerThread({
|
|
572
|
-
provider,
|
|
573
|
-
settings,
|
|
574
|
-
projectHooks = false,
|
|
575
|
-
identity,
|
|
576
|
-
resumableThreadId = "",
|
|
577
|
-
forbiddenThreadId = "",
|
|
578
|
-
operationId = "",
|
|
579
|
-
workdir = "",
|
|
580
|
-
errorCode = "codex_renewal_fresh_thread_required",
|
|
581
|
-
applicationName = "The application"
|
|
582
|
-
} = {}) {
|
|
583
|
-
const normalizedWorkdir = normalizeAgentText(workdir);
|
|
584
|
-
const normalizedForbiddenThreadId = normalizeAgentText(forbiddenThreadId);
|
|
585
|
-
const normalizedOperationId = normalizeAgentText(operationId);
|
|
586
|
-
if (resumableThreadId && resumableThreadId === normalizedForbiddenThreadId) {
|
|
587
|
-
throw codexRenewalThreadError(
|
|
588
|
-
errorCode,
|
|
589
|
-
"The renewed session cannot reuse the old session's assistant thread.",
|
|
590
|
-
{ forbiddenThreadId: normalizedForbiddenThreadId }
|
|
591
|
-
);
|
|
592
|
-
}
|
|
593
|
-
if (
|
|
594
|
-
typeof provider?.ensureRuntime !== "function" ||
|
|
595
|
-
typeof provider?.resumeThread !== "function" ||
|
|
596
|
-
typeof provider?.readThread !== "function" ||
|
|
597
|
-
typeof provider?.startThread !== "function"
|
|
598
|
-
) {
|
|
599
|
-
throw codexRenewalThreadError(
|
|
600
|
-
errorCode,
|
|
601
|
-
"The assistant provider cannot prove a genuinely fresh renewal thread."
|
|
602
|
-
);
|
|
603
|
-
}
|
|
604
|
-
const appServerRuntime = await provider.ensureRuntime();
|
|
605
|
-
const config = projectHooks
|
|
606
|
-
? await codexAppServerProjectHookTrustConfig(provider, normalizedWorkdir)
|
|
607
|
-
: null;
|
|
608
|
-
const { threadSettings, threadStartSettings } = await settings(normalizedWorkdir, config);
|
|
609
|
-
let fresh = false;
|
|
610
|
-
let thread = null;
|
|
611
|
-
let threadSnapshot = null;
|
|
612
|
-
let baselineThreadIds = Object.freeze([]);
|
|
613
|
-
if (resumableThreadId) {
|
|
614
|
-
try {
|
|
615
|
-
thread = await provider.resumeThread(resumableThreadId, threadSettings);
|
|
616
|
-
const resumedThreadId = codexAppServerThreadResponseId(thread, resumableThreadId);
|
|
617
|
-
if (resumedThreadId !== resumableThreadId) {
|
|
618
|
-
throw codexRenewalThreadError(
|
|
619
|
-
errorCode,
|
|
620
|
-
"The assistant provider resumed a different renewal thread.",
|
|
621
|
-
{
|
|
622
|
-
expectedThreadId: resumableThreadId,
|
|
623
|
-
resumedThreadId
|
|
624
|
-
}
|
|
625
|
-
);
|
|
626
|
-
}
|
|
627
|
-
threadSnapshot = await readCodexRenewalSuccessorThreadSnapshot({
|
|
628
|
-
provider,
|
|
629
|
-
threadId: resumableThreadId,
|
|
630
|
-
workdir: normalizedWorkdir,
|
|
631
|
-
errorCode
|
|
632
|
-
});
|
|
633
|
-
} catch (error) {
|
|
634
|
-
if (
|
|
635
|
-
error?.code === errorCode ||
|
|
636
|
-
codexAppServerRequestIsInvalid(error, "thread/resume") ||
|
|
637
|
-
codexAppServerRequestIsInvalid(error, "thread/read")
|
|
638
|
-
) {
|
|
639
|
-
if (error?.code === errorCode) {
|
|
640
|
-
throw error;
|
|
641
|
-
}
|
|
642
|
-
throw codexRenewalThreadError(
|
|
643
|
-
errorCode,
|
|
644
|
-
`The previously started renewal thread is no longer readable; ${applicationName} will not replace it silently.`,
|
|
645
|
-
{
|
|
646
|
-
expectedThreadId: resumableThreadId,
|
|
647
|
-
providerError: normalizeAgentText(error?.message)
|
|
648
|
-
}
|
|
649
|
-
);
|
|
650
|
-
}
|
|
651
|
-
throw error;
|
|
652
|
-
}
|
|
653
|
-
} else {
|
|
654
|
-
if (!normalizedOperationId) {
|
|
655
|
-
throw codexRenewalThreadError(
|
|
656
|
-
errorCode,
|
|
657
|
-
"Starting a fresh successor thread requires its exact renewal operation id."
|
|
658
|
-
);
|
|
659
|
-
}
|
|
660
|
-
baselineThreadIds = await identity.readBaseline();
|
|
661
|
-
if (!baselineThreadIds) {
|
|
662
|
-
baselineThreadIds = await listCodexRenewalThreadIds(
|
|
663
|
-
provider,
|
|
664
|
-
normalizedWorkdir,
|
|
665
|
-
errorCode
|
|
666
|
-
);
|
|
667
|
-
await identity.writeBaseline(baselineThreadIds);
|
|
668
|
-
}
|
|
669
|
-
const currentThreadIds = await listCodexRenewalThreadIds(
|
|
670
|
-
provider,
|
|
671
|
-
normalizedWorkdir,
|
|
672
|
-
errorCode
|
|
673
|
-
);
|
|
674
|
-
const baseline = new Set(baselineThreadIds);
|
|
675
|
-
const candidateThreadIds = currentThreadIds.filter((threadId) => !baseline.has(threadId));
|
|
676
|
-
if (candidateThreadIds.length > 1) {
|
|
677
|
-
throw codexRenewalThreadError(
|
|
678
|
-
errorCode,
|
|
679
|
-
`More than one unclaimed assistant thread appeared for this renewal; ${applicationName} will not guess which one is authoritative.`,
|
|
680
|
-
{ candidateThreadIds }
|
|
681
|
-
);
|
|
682
|
-
}
|
|
683
|
-
if (candidateThreadIds.length === 1) {
|
|
684
|
-
const [candidateThreadId] = candidateThreadIds;
|
|
685
|
-
thread = await provider.resumeThread(candidateThreadId, threadSettings);
|
|
686
|
-
const resumedThreadId = codexAppServerThreadResponseId(thread, candidateThreadId);
|
|
687
|
-
if (resumedThreadId !== candidateThreadId) {
|
|
688
|
-
throw codexRenewalThreadError(
|
|
689
|
-
errorCode,
|
|
690
|
-
"The assistant provider resumed a different recovered renewal thread.",
|
|
691
|
-
{
|
|
692
|
-
expectedThreadId: candidateThreadId,
|
|
693
|
-
resumedThreadId
|
|
694
|
-
}
|
|
695
|
-
);
|
|
696
|
-
}
|
|
697
|
-
threadSnapshot = await readCodexRenewalSuccessorThreadSnapshot({
|
|
698
|
-
provider,
|
|
699
|
-
threadId: candidateThreadId,
|
|
700
|
-
workdir: normalizedWorkdir,
|
|
701
|
-
errorCode
|
|
702
|
-
});
|
|
703
|
-
} else {
|
|
704
|
-
thread = await provider.startThread(threadStartSettings);
|
|
705
|
-
fresh = true;
|
|
706
|
-
}
|
|
707
|
-
}
|
|
708
|
-
const threadId = codexAppServerThreadResponseId(thread, resumableThreadId);
|
|
709
|
-
if (
|
|
710
|
-
!threadId ||
|
|
711
|
-
threadId === normalizedForbiddenThreadId ||
|
|
712
|
-
(fresh && baselineThreadIds.includes(threadId))
|
|
713
|
-
) {
|
|
714
|
-
throw codexRenewalThreadError(
|
|
715
|
-
errorCode,
|
|
716
|
-
threadId
|
|
717
|
-
? "The assistant provider reused the old session's thread instead of starting a fresh one."
|
|
718
|
-
: "The assistant provider did not return a fresh renewal thread id.",
|
|
719
|
-
{
|
|
720
|
-
forbiddenThreadId: normalizedForbiddenThreadId,
|
|
721
|
-
threadId
|
|
722
|
-
}
|
|
723
|
-
);
|
|
724
|
-
}
|
|
725
|
-
await identity.write({ appServerRuntime, threadId, workdir: normalizedWorkdir });
|
|
726
|
-
if (fresh) {
|
|
727
|
-
try {
|
|
728
|
-
threadSnapshot = await readCodexRenewalSuccessorThreadSnapshot({
|
|
729
|
-
provider,
|
|
730
|
-
threadId,
|
|
731
|
-
workdir: normalizedWorkdir,
|
|
732
|
-
errorCode
|
|
733
|
-
});
|
|
734
|
-
} catch (error) {
|
|
735
|
-
throw codexRenewalThreadError(
|
|
736
|
-
errorCode,
|
|
737
|
-
`The newly started renewal thread cannot be read; ${applicationName} will not replace it silently.`,
|
|
738
|
-
{
|
|
739
|
-
providerError: normalizeAgentText(error?.message),
|
|
740
|
-
threadId
|
|
741
|
-
},
|
|
742
|
-
{ retryable: true }
|
|
743
|
-
);
|
|
744
|
-
}
|
|
745
|
-
}
|
|
746
|
-
return Object.freeze({
|
|
747
|
-
appServerRuntime,
|
|
748
|
-
fresh,
|
|
749
|
-
thread,
|
|
750
|
-
threadId,
|
|
751
|
-
threadSnapshot,
|
|
752
|
-
threadStartSettings,
|
|
753
|
-
threadSettings
|
|
754
|
-
});
|
|
755
|
-
}
|
|
756
|
-
|
|
757
|
-
function codexAppServerModelCatalogError(message = "", errorPrefix = "") {
|
|
758
|
-
const error = new Error(normalizeAgentText(message) || "Codex returned an invalid model catalog.");
|
|
759
|
-
error.code = `${errorPrefix}codex_model_catalog_invalid`;
|
|
760
|
-
return error;
|
|
761
|
-
}
|
|
762
|
-
|
|
763
|
-
function codexAppServerProviderConnectionGeneration(provider = null) {
|
|
764
|
-
const generation = typeof provider?.currentConnectionGeneration === "function"
|
|
765
|
-
? provider.currentConnectionGeneration()
|
|
766
|
-
: typeof provider?.connectionGeneration === "function"
|
|
767
|
-
? provider.connectionGeneration()
|
|
768
|
-
: provider?.connectionGeneration;
|
|
769
|
-
return normalizeAgentText(generation || "");
|
|
770
|
-
}
|
|
771
|
-
|
|
772
|
-
function codexAppServerModelCatalogSnapshot(value = null, errorPrefix = "") {
|
|
773
|
-
if (!Array.isArray(value?.data)) {
|
|
774
|
-
throw codexAppServerModelCatalogError("Codex did not return a usable live model catalog.", errorPrefix);
|
|
775
|
-
}
|
|
776
|
-
return Object.freeze({
|
|
777
|
-
data: Object.freeze(value.data.map((model = {}) => Object.freeze({
|
|
778
|
-
hidden: model.hidden === true,
|
|
779
|
-
model: normalizeAgentText(model.model || ""),
|
|
780
|
-
supportedReasoningEfforts: Object.freeze((Array.isArray(model.supportedReasoningEfforts)
|
|
781
|
-
? model.supportedReasoningEfforts
|
|
782
|
-
: []).map((option = {}) => Object.freeze({
|
|
783
|
-
reasoningEffort: normalizeAgentText(option.reasoningEffort || "")
|
|
784
|
-
})))
|
|
785
|
-
})))
|
|
786
|
-
});
|
|
787
|
-
}
|
|
788
|
-
|
|
789
|
-
function createCodexAppServerModelCatalogCache({
|
|
790
|
-
cacheMs = 30_000,
|
|
791
|
-
errorPrefix = ""
|
|
792
|
-
} = {}) {
|
|
793
|
-
const codexAppServerModelCatalogs = new WeakMap();
|
|
794
|
-
return async function readCodexAppServerModelCatalog(provider, { signal = null } = {}) {
|
|
795
|
-
if (typeof provider.listModels !== "function") {
|
|
796
|
-
const error = new Error("Codex live model discovery is unavailable.");
|
|
797
|
-
error.code = `${errorPrefix}codex_model_catalog_unavailable`;
|
|
798
|
-
throw error;
|
|
799
|
-
}
|
|
800
|
-
const connectionGeneration = codexAppServerProviderConnectionGeneration(provider);
|
|
801
|
-
const now = Date.now();
|
|
802
|
-
const cached = codexAppServerModelCatalogs.get(provider);
|
|
803
|
-
if (
|
|
804
|
-
cached?.connectionGeneration === connectionGeneration &&
|
|
805
|
-
cached.value &&
|
|
806
|
-
cached.expiresAt > now
|
|
807
|
-
) {
|
|
808
|
-
return cached.value;
|
|
809
|
-
}
|
|
810
|
-
if (
|
|
811
|
-
cached?.connectionGeneration === connectionGeneration &&
|
|
812
|
-
cached.pending
|
|
813
|
-
) {
|
|
814
|
-
return cached.pending;
|
|
815
|
-
}
|
|
816
|
-
|
|
817
|
-
const pending = provider.listModels({
|
|
818
|
-
includeHidden: false,
|
|
819
|
-
limit: 100
|
|
820
|
-
}, { signal }).then((result) => {
|
|
821
|
-
if (codexAppServerProviderConnectionGeneration(provider) !== connectionGeneration) {
|
|
822
|
-
const error = new Error("Codex reconnected while resolving the helper model catalog.");
|
|
823
|
-
error.code = `${errorPrefix}codex_model_catalog_stale`;
|
|
824
|
-
throw error;
|
|
825
|
-
}
|
|
826
|
-
return codexAppServerModelCatalogSnapshot(result, errorPrefix);
|
|
827
|
-
});
|
|
828
|
-
codexAppServerModelCatalogs.set(provider, {
|
|
829
|
-
connectionGeneration,
|
|
830
|
-
expiresAt: 0,
|
|
831
|
-
pending,
|
|
832
|
-
value: null
|
|
833
|
-
});
|
|
834
|
-
try {
|
|
835
|
-
const value = await pending;
|
|
836
|
-
codexAppServerModelCatalogs.set(provider, {
|
|
837
|
-
connectionGeneration,
|
|
838
|
-
expiresAt: Date.now() + cacheMs,
|
|
839
|
-
pending: null,
|
|
840
|
-
value
|
|
841
|
-
});
|
|
842
|
-
return value;
|
|
843
|
-
} catch (error) {
|
|
844
|
-
if (codexAppServerModelCatalogs.get(provider)?.pending === pending) {
|
|
845
|
-
codexAppServerModelCatalogs.delete(provider);
|
|
846
|
-
}
|
|
847
|
-
throw error;
|
|
848
|
-
}
|
|
849
|
-
};
|
|
850
|
-
}
|
|
851
|
-
|
|
852
351
|
function codexAppServerHelperLoginParams(auth = {}, errorPrefix = "") {
|
|
853
352
|
if (auth.authMode === "chatgpt") {
|
|
854
353
|
return {
|
|
@@ -901,7 +400,7 @@ function codexAppServerHelperRequestError(error = null, reason = "", errorPrefix
|
|
|
901
400
|
}
|
|
902
401
|
|
|
903
402
|
function normalizeCodexAppServerInfo(initializeResult = null) {
|
|
904
|
-
if (!
|
|
403
|
+
if (!isRecord(initializeResult)) {
|
|
905
404
|
return null;
|
|
906
405
|
}
|
|
907
406
|
const rawUserAgent = initializeResult.userAgent;
|
|
@@ -918,77 +417,6 @@ function normalizeCodexAppServerInfo(initializeResult = null) {
|
|
|
918
417
|
});
|
|
919
418
|
}
|
|
920
419
|
|
|
921
|
-
function tailAppend(text = "", chunk = "", maxBytes = CODEX_AUTH_PREFLIGHT_OUTPUT_TAIL_BYTES) {
|
|
922
|
-
const next = `${String(text || "")}${String(chunk || "")}`;
|
|
923
|
-
return next.length > maxBytes ? next.slice(-maxBytes) : next;
|
|
924
|
-
}
|
|
925
|
-
|
|
926
|
-
function codexAuthPreflightArgs() {
|
|
927
|
-
return [
|
|
928
|
-
"-c",
|
|
929
|
-
"check_for_update_on_startup=false",
|
|
930
|
-
"debug",
|
|
931
|
-
"models"
|
|
932
|
-
];
|
|
933
|
-
}
|
|
934
|
-
|
|
935
|
-
async function runCodexAuthPreflight({
|
|
936
|
-
codexCommand = "codex",
|
|
937
|
-
env = process.env,
|
|
938
|
-
executionRoot = "",
|
|
939
|
-
runtimeDir = "",
|
|
940
|
-
terminalEnv = {},
|
|
941
|
-
timeoutMs = CODEX_AUTH_PREFLIGHT_TIMEOUT_MS,
|
|
942
|
-
toolHomeSource = "",
|
|
943
|
-
workdir = ""
|
|
944
|
-
} = {}, execution) {
|
|
945
|
-
const normalizedToolHomeSource = normalizeAgentText(toolHomeSource);
|
|
946
|
-
if (normalizedToolHomeSource) {
|
|
947
|
-
await assertExistingDirectory(normalizedToolHomeSource, "Codex credential home");
|
|
948
|
-
}
|
|
949
|
-
const normalizedRuntimeDir = normalizeAgentText(runtimeDir);
|
|
950
|
-
if (normalizedRuntimeDir) {
|
|
951
|
-
await ensureWritablePrivateDirectory(path.resolve(normalizedRuntimeDir));
|
|
952
|
-
}
|
|
953
|
-
const baseEnv = codexAppServerCommandBaseEnv({
|
|
954
|
-
env,
|
|
955
|
-
terminalEnv
|
|
956
|
-
});
|
|
957
|
-
const processCwd = codexAppServerProcessCwd({
|
|
958
|
-
executionRoot,
|
|
959
|
-
runtimeDir,
|
|
960
|
-
workdir
|
|
961
|
-
});
|
|
962
|
-
try {
|
|
963
|
-
const result = await execution.run({
|
|
964
|
-
args: codexAuthPreflightArgs(),
|
|
965
|
-
baseEnv,
|
|
966
|
-
command: codexCommand,
|
|
967
|
-
credentialHome: codexAppServerCredentialHome(normalizedToolHomeSource, baseEnv),
|
|
968
|
-
cwd: processCwd,
|
|
969
|
-
inheritProcessEnv: false,
|
|
970
|
-
mode: "capture",
|
|
971
|
-
timeout: normalizePositiveInteger(timeoutMs, CODEX_AUTH_PREFLIGHT_TIMEOUT_MS)
|
|
972
|
-
});
|
|
973
|
-
return {
|
|
974
|
-
code: result.exitCode,
|
|
975
|
-
ok: result.ok === true,
|
|
976
|
-
output: tailAppend("", result.output || [
|
|
977
|
-
result.stderr,
|
|
978
|
-
result.stdout
|
|
979
|
-
].filter(Boolean).join("\n")),
|
|
980
|
-
signal: result.signal,
|
|
981
|
-
timedOut: result.timedOut === true
|
|
982
|
-
};
|
|
983
|
-
} catch (error) {
|
|
984
|
-
return {
|
|
985
|
-
error,
|
|
986
|
-
ok: false,
|
|
987
|
-
output: normalizeAgentText(error?.message || error)
|
|
988
|
-
};
|
|
989
|
-
}
|
|
990
|
-
}
|
|
991
|
-
|
|
992
420
|
function codexAppServerEndpointForTarget(endpoint = "") {
|
|
993
421
|
const normalizedEndpoint = normalizeAgentText(endpoint);
|
|
994
422
|
if (!normalizedEndpoint) {
|
|
@@ -998,8 +426,8 @@ function codexAppServerEndpointForTarget(endpoint = "") {
|
|
|
998
426
|
}
|
|
999
427
|
|
|
1000
428
|
function codexAppServerThreadRequestParams(params = {}, threadEnv = {}) {
|
|
1001
|
-
const source =
|
|
1002
|
-
const config =
|
|
429
|
+
const source = isRecord(params) ? params : {};
|
|
430
|
+
const config = isRecord(source.config) ? source.config : {};
|
|
1003
431
|
if (Object.hasOwn(config, "shell_environment_policy")) {
|
|
1004
432
|
return source;
|
|
1005
433
|
}
|
|
@@ -1071,13 +499,13 @@ async function sendCodexAppServerPrompt({
|
|
|
1071
499
|
function codexTurnInput(input = []) {
|
|
1072
500
|
const values = Array.isArray(input) ? input : [input];
|
|
1073
501
|
return values.map((item) => {
|
|
1074
|
-
if (
|
|
502
|
+
if (isRecord(item) && item.type === "localImage" && typeof item.path === "string") {
|
|
1075
503
|
return { type: "localImage", path: item.path };
|
|
1076
504
|
}
|
|
1077
|
-
if (
|
|
505
|
+
if (isRecord(item) && item.type === "image" && typeof item.url === "string") {
|
|
1078
506
|
return { type: "image", url: item.url };
|
|
1079
507
|
}
|
|
1080
|
-
if (
|
|
508
|
+
if (isRecord(item) && item.type === "text") {
|
|
1081
509
|
return codexTextInput(item.text);
|
|
1082
510
|
}
|
|
1083
511
|
return codexTextInput(item);
|
|
@@ -1196,7 +624,7 @@ async function listBoundedCodexAppServerThreadIds({
|
|
|
1196
624
|
entryBytes = CODEX_APP_SERVER_THREAD_INVENTORY_MAX_ENTRY_BYTES + 1;
|
|
1197
625
|
}
|
|
1198
626
|
if (
|
|
1199
|
-
!
|
|
627
|
+
!isRecord(entry) ||
|
|
1200
628
|
!threadId ||
|
|
1201
629
|
threadId.length > CODEX_APP_SERVER_THREAD_INVENTORY_ID_MAX_LENGTH ||
|
|
1202
630
|
codexAppServerTextHasControlCharacters(threadId) ||
|
|
@@ -1276,24 +704,15 @@ function normalizeAgentTurn(value = {}) {
|
|
|
1276
704
|
};
|
|
1277
705
|
}
|
|
1278
706
|
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
const
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
await credentials.markInvalid( {
|
|
1289
|
-
reason
|
|
1290
|
-
});
|
|
1291
|
-
throw credentials.reconnectError({
|
|
1292
|
-
modelProviderId: "",
|
|
1293
|
-
observed
|
|
1294
|
-
});
|
|
1295
|
-
}
|
|
1296
|
-
throw new Error(observed || "Codex auth preflight failed.");
|
|
707
|
+
// The one reading of a sendTurn delivery. Its turn is already normalized; the
|
|
708
|
+
// provider's own error stays on the raw native turn.
|
|
709
|
+
function codexAppServerDeliveredTurn(delivery = {}) {
|
|
710
|
+
const turn = delivery?.turn || {};
|
|
711
|
+
return {
|
|
712
|
+
turnId: normalizeAgentText(turn.id),
|
|
713
|
+
status: normalizeAgentText(turn.status || turn.raw?.status),
|
|
714
|
+
error: codexAppServerErrorText(turn.raw?.error || turn.response?.turn?.error || turn.error)
|
|
715
|
+
};
|
|
1297
716
|
}
|
|
1298
717
|
|
|
1299
718
|
export class CodexAppServerAgentProvider {
|
|
@@ -2523,7 +1942,7 @@ export class CodexAppServerAgentProvider {
|
|
|
2523
1942
|
const includeHidden = params.includeHidden === true;
|
|
2524
1943
|
const limit = normalizePositiveInteger(
|
|
2525
1944
|
params.limit,
|
|
2526
|
-
CODEX_APP_SERVER_MODEL_CATALOG_PAGE_LIMIT
|
|
1945
|
+
{ fallback: CODEX_APP_SERVER_MODEL_CATALOG_PAGE_LIMIT }
|
|
2527
1946
|
);
|
|
2528
1947
|
const boundedLimit = Math.min(limit, CODEX_APP_SERVER_MODEL_CATALOG_PAGE_LIMIT);
|
|
2529
1948
|
let totalBytes = 0;
|
|
@@ -2562,7 +1981,7 @@ export class CodexAppServerAgentProvider {
|
|
|
2562
1981
|
throw this.modelCatalogError("Codex model catalog exceeded its entry limit.");
|
|
2563
1982
|
}
|
|
2564
1983
|
for (const entry of response.data) {
|
|
2565
|
-
if (!
|
|
1984
|
+
if (!isRecord(entry)) {
|
|
2566
1985
|
throw this.modelCatalogError("Codex model catalog contained an invalid entry.");
|
|
2567
1986
|
}
|
|
2568
1987
|
let entryBytes = 0;
|
|
@@ -2651,7 +2070,7 @@ export class CodexAppServerAgentProvider {
|
|
|
2651
2070
|
}
|
|
2652
2071
|
|
|
2653
2072
|
async writeHookTrustState(state = {}) {
|
|
2654
|
-
if (!
|
|
2073
|
+
if (!isRecord(state) || Object.keys(state).length === 0) {
|
|
2655
2074
|
return null;
|
|
2656
2075
|
}
|
|
2657
2076
|
const client = await this.activeClient();
|
|
@@ -2860,11 +2279,9 @@ export class CodexAppServerAgentProvider {
|
|
|
2860
2279
|
}
|
|
2861
2280
|
|
|
2862
2281
|
export {
|
|
2863
|
-
CODEX_APP_SERVER_INVALID_REQUEST_CODE,
|
|
2864
|
-
createCodexAppServerModelCatalogCache, codexAppServerProviderConnectionGeneration,
|
|
2282
|
+
CODEX_APP_SERVER_INVALID_REQUEST_CODE,
|
|
2865
2283
|
ensureCodexAppServerThread, codexApplicationToolConfiguration, assertCodexApplicationToolSchemaIdentity, sendCodexAppServerPrompt,
|
|
2866
|
-
|
|
2867
|
-
defineCodexRenewalThreadIds, codexRenewalThreadError,
|
|
2284
|
+
codexAppServerDeliveredTurn,
|
|
2868
2285
|
codexAppServerEndpointForTarget, codexAppServerRequestIsInvalid, codexAppServerThreadIsMissing,
|
|
2869
2286
|
codexAppServerThreadHasReadableHistory, deleteCodexAppServerThread, deleteCodexAppServerHelperThread,
|
|
2870
2287
|
inspectCodexAppServerMessageAdmission,
|