vibe64 0.1.26 → 0.1.28
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/assets/{VRadioGroup-D6WRdUau.js → VRadioGroup-BuRMvs7d.js} +1 -1
- package/dist/assets/{VTabs-BGX5dGoS.js → VTabs-CQq9CAuT.js} +1 -1
- package/dist/assets/{VTextarea-CD6H_mtJ.js → VTextarea-Duvzvmjq.js} +1 -1
- package/dist/assets/{Vibe64AsyncModuleState-Cel3OePx.js → Vibe64AsyncModuleState-DuuzlJDp.js} +1 -1
- package/dist/assets/{Vibe64AuthSettingsButton-CMMeacsl.js → Vibe64AuthSettingsButton-CKOCL-kl.js} +1 -1
- package/dist/assets/{Vibe64DashboardShell-C2UhX2ke.js → Vibe64DashboardShell-DMT8aOp1.js} +1 -1
- package/dist/assets/{Vibe64DatabaseWorkspace-C43TE5-O.js → Vibe64DatabaseWorkspace-CqH0zfFZ.js} +1 -1
- package/dist/assets/{Vibe64OutputControls-BmzH2ASf.js → Vibe64OutputControls-DDILWOYb.js} +1 -1
- package/dist/assets/{Vibe64RepositoryWorkspace-CT9tkvHh.js → Vibe64RepositoryWorkspace-D11BZHtF.js} +1 -1
- package/dist/assets/Vibe64SessionFiles-BSoB7Xrs.js +1 -0
- package/dist/assets/{Vibe64SessionFiles-CH5PCxwg.css → Vibe64SessionFiles-DVux69YS.css} +1 -1
- package/dist/assets/{Vibe64SubsystemsView-DNx-pZp8.js → Vibe64SubsystemsView-tLlxmK3M.js} +1 -1
- package/dist/assets/{Vibe64SystemWorldView-UdNJZbqX.js → Vibe64SystemWorldView-8og8TPyL.js} +1 -1
- package/dist/assets/{_sessionId_-DZTmI19N.js → _sessionId_-Dts6gv4W.js} +1 -1
- package/dist/assets/{_sessionTool_-CugJWIK4.js → _sessionTool_-bHJUlHCW.js} +1 -1
- package/dist/assets/_slug_-B3fqw8Sl.js +12 -0
- package/dist/assets/_slug_-DfHqx2_b.css +1 -0
- package/dist/assets/{dashboard-D4NXqPY1.js → dashboard-CcD6GIaB.js} +1 -1
- package/dist/assets/{definitions-CyUCoqu-.js → definitions-ChGXm26a.js} +1 -1
- package/dist/assets/{error-kYKTA8fu.js → error-CStS-Kbt.js} +1 -1
- package/dist/assets/{index-hy7AAm-B.js → index-B262pg9q.js} +1 -1
- package/dist/assets/{index-DX6Rm6jZ.js → index-B_grpOta.js} +1 -1
- package/dist/assets/{index-Cpt19GIW.js → index-BtHA_DX9.js} +1 -1
- package/dist/assets/{index-SBc6H2In.js → index-C4KnwA0g.js} +4 -4
- package/dist/assets/{index-DeRx59Iq.js → index-CC7BFJAg.js} +1 -1
- package/dist/assets/{index-6Kv-7k0S.js → index-CKFrWxnr.js} +1 -1
- package/dist/assets/{index-BDe3NnFP.js → index-CPG-_bMW.js} +1 -1
- package/dist/assets/{index-CuEZOpKL.js → index-CV9pOpbQ.js} +1 -1
- package/dist/assets/{index-D4p1hWbM.js → index-DIQxSy1c.js} +1 -1
- package/dist/assets/{index-D5vnCntG.js → index-DVaJ8fEr.js} +1 -1
- package/dist/assets/{index-BGu7hfTb.js → index-DtGqjUin.js} +1 -1
- package/dist/assets/{index-Cca4WXur.js → index-YQALXwL4.js} +1 -1
- package/dist/assets/{placement-Nw6LF6xp.js → placement-Cyt3SnRe.js} +1 -1
- package/dist/assets/{studioGateApi-B2eiydiA.js → studioGateApi-BwBnOYBp.js} +1 -1
- package/dist/assets/{useArchivedVibe64Sessions-LeGda1Y9.js → useArchivedVibe64Sessions-_FKt1-qN.js} +1 -1
- package/dist/assets/{useVibe64ConversationLog-BPyKYbvH.js → useVibe64ConversationLog-BjnpqM9K.js} +1 -1
- package/dist/assets/{useVibe64ProjectScope-n5T5l2pY.js → useVibe64ProjectScope-DcDkjbLT.js} +1 -1
- package/dist/assets/{useVibe64SessionData-BToODuTg.js → useVibe64SessionData-BHLSmuPm.js} +1 -1
- package/dist/assets/{useVibe64SessionSelection-D1wXIWTm.js → useVibe64SessionSelection-G6KQKJxb.js} +1 -1
- package/dist/assets/{vibe64RepositoryRealtime-Xo7aIksE.js → vibe64RepositoryRealtime-C2WPn5do.js} +1 -1
- package/dist/assets/{vibe64SessionInfo-Dy_4bL3a.js → vibe64SessionInfo-8kuxgD5r.js} +1 -1
- package/dist/assets/{vibe64SessionPanelModel-5UED-6V-.js → vibe64SessionPanelModel-DDaXjAJ_.js} +1 -1
- package/dist/assets/{vibe64SessionRequestConfig-B7Llggdb.js → vibe64SessionRequestConfig-uGWcyQY6.js} +1 -1
- package/dist/assets/{vibe64SessionToolDefinitions-C4maKOfp.js → vibe64SessionToolDefinitions-D5CgOIqa.js} +1 -1
- package/dist/assets/{vueRefOrGetterValue-_KqAOFjr.js → vueRefOrGetterValue-CV9c3oBd.js} +1 -1
- package/dist/index.html +1 -1
- package/node_modules/@jskit-ai/connector-google-calendar/package.json +3 -3
- package/node_modules/@jskit-ai/connector-google-calendar/patterns/calendar-cli/example/package.json +4 -4
- package/node_modules/@jskit-ai/connectors-catalog/package.json +3 -3
- package/node_modules/@jskit-ai/connectors-catalog/test/dbt-semantic-layer.test.js +3 -0
- package/node_modules/@jskit-ai/connectors-catalog/test/google-ads.test.js +3 -0
- package/node_modules/@jskit-ai/connectors-catalog/test/salesforce.test.js +3 -0
- package/node_modules/@jskit-ai/connectors-catalog/test/xero.test.js +3 -0
- package/node_modules/@jskit-ai/connectors-core/package.json +4 -4
- package/node_modules/@jskit-ai/http-web/package.json +6 -6
- package/node_modules/@jskit-ai/kernel/package.json +1 -1
- package/node_modules/@jskit-ai/kernel/server/runtime/fastifyBootstrap.js +50 -10
- package/node_modules/@jskit-ai/kernel/server/runtime/fastifyBootstrap.test.js +38 -0
- package/node_modules/@jskit-ai/kernel/shared/support/normalize.js +8 -0
- package/node_modules/@jskit-ai/kernel/shared/support/normalize.test.js +10 -0
- package/node_modules/@jskit-ai/payments-core/package.json +1 -1
- package/node_modules/@jskit-ai/realtime/package.json +3 -3
- package/node_modules/@jskit-ai/realtime/patterns/realtime-application/example/package.json +2 -2
- package/node_modules/@jskit-ai/resource-core/package.json +2 -2
- package/node_modules/@jskit-ai/resource-crud-core/package.json +3 -3
- package/node_modules/@jskit-ai/shell-web/package.json +2 -2
- package/node_modules/@jskit-ai/uploads-runtime/package.json +2 -2
- package/node_modules/@local/current-app/package.json +1 -1
- package/node_modules/@local/main/package.json +2 -2
- package/node_modules/@local/studio-health/package.json +1 -1
- package/node_modules/@local/vibe64-accounts/package.json +3 -3
- package/node_modules/@local/vibe64-core/package.json +1 -1
- package/node_modules/@local/vibe64-database-tools/package.json +3 -3
- package/node_modules/@local/vibe64-project/package.json +1 -1
- package/node_modules/@local/vibe64-runtime/src/server/codexAppServerProvider.js +34 -0
- package/node_modules/@local/vibe64-sessions/package.json +1 -1
- package/node_modules/@local/vibe64-sessions/src/server/sessionRenewal.js +4 -1
- package/node_modules/@local/vibe64-source-editor/package.json +5 -5
- package/node_modules/@local/vibe64-system-graph/package.json +3 -3
- package/node_modules/@local/vibe64-terminals/package.json +2 -2
- package/node_modules/@local/vibe64-terminals/src/server/agent/providers/codexSessionAgentProvider.js +6 -0
- package/node_modules/@local/vibe64-terminals/src/server/agent/sessionAgentManager.js +16 -0
- package/node_modules/@local/vibe64-terminals/src/server/codexTerminal.js +180 -64
- package/node_modules/@local/vibe64-terminals/src/server/registerRoutes.js +12 -0
- package/node_modules/@local/vibe64-terminals/src/server/service.js +57 -16
- package/node_modules/@local/vibe64-terminals/src/server/sessionPromptHints.js +9 -1
- package/node_modules/@local/vibe64-terminals/src/server/sessionSaveCommitMessage.js +1 -1
- package/package.json +15 -15
- package/packages/current-app/package.json +1 -1
- package/packages/main/package.json +2 -2
- package/packages/studio-health/package.json +1 -1
- package/packages/vibe64-accounts/package.json +3 -3
- package/packages/vibe64-core/package.json +1 -1
- package/packages/vibe64-database-tools/package.json +3 -3
- package/packages/vibe64-project/package.json +1 -1
- package/packages/vibe64-runtime/src/server/codexAppServerProvider.js +34 -0
- package/packages/vibe64-sessions/package.json +1 -1
- package/packages/vibe64-sessions/src/server/sessionRenewal.js +4 -1
- package/packages/vibe64-source-editor/package.json +5 -5
- package/packages/vibe64-system-graph/package.json +3 -3
- package/packages/vibe64-terminals/package.json +2 -2
- package/packages/vibe64-terminals/src/server/agent/providers/codexSessionAgentProvider.js +6 -0
- package/packages/vibe64-terminals/src/server/agent/sessionAgentManager.js +16 -0
- package/packages/vibe64-terminals/src/server/codexTerminal.js +180 -64
- package/packages/vibe64-terminals/src/server/registerRoutes.js +12 -0
- package/packages/vibe64-terminals/src/server/service.js +57 -16
- package/packages/vibe64-terminals/src/server/sessionPromptHints.js +9 -1
- package/packages/vibe64-terminals/src/server/sessionSaveCommitMessage.js +1 -1
- package/dist/assets/Vibe64SessionFiles-BS5MW7Qz.js +0 -1
- package/dist/assets/_slug_-BzRzebKA.js +0 -12
- package/dist/assets/_slug_-Q7ibe3SE.css +0 -1
|
@@ -6900,19 +6900,21 @@ function createCodexTerminalController({
|
|
|
6900
6900
|
const normalizedThreadId = normalizeText(threadId);
|
|
6901
6901
|
const notificationTurnId = codexAppServerNotificationTurnId(notification);
|
|
6902
6902
|
const goalStatus = normalizeText(notification.params?.goal?.status);
|
|
6903
|
+
const goalCleared = notification.method === "thread/goal/cleared";
|
|
6903
6904
|
const runtime = await createRuntimeForSession();
|
|
6904
6905
|
let run = await readCodexAppServerAgentRunForSession(
|
|
6905
6906
|
runtime.store,
|
|
6906
6907
|
normalizedSessionId
|
|
6907
6908
|
);
|
|
6908
6909
|
const currentThreadId = normalizeText(run?.providerThreadId);
|
|
6910
|
+
if (currentThreadId && currentThreadId !== normalizedThreadId) {
|
|
6911
|
+
return { ok: true, processed: false, reason: "goal_thread_changed" };
|
|
6912
|
+
}
|
|
6909
6913
|
if (
|
|
6910
|
-
|
|
6911
|
-
CODEX_APP_SERVER_GOAL_STATUSES.has(goalStatus) &&
|
|
6912
|
-
(!currentThreadId || currentThreadId === normalizedThreadId) &&
|
|
6914
|
+
(goalCleared || CODEX_APP_SERVER_GOAL_STATUSES.has(goalStatus)) &&
|
|
6913
6915
|
(
|
|
6914
|
-
normalizeText(run
|
|
6915
|
-
normalizeText(run
|
|
6916
|
+
normalizeText(run?.providerGoalStatus) !== goalStatus ||
|
|
6917
|
+
normalizeText(run?.providerGoalThreadId) !== normalizedThreadId
|
|
6916
6918
|
)
|
|
6917
6919
|
) {
|
|
6918
6920
|
const updatedAt = new Date().toISOString();
|
|
@@ -6924,6 +6926,12 @@ function createCodexTerminalController({
|
|
|
6924
6926
|
providerThreadId: normalizedThreadId
|
|
6925
6927
|
},
|
|
6926
6928
|
patch: {
|
|
6929
|
+
...(!run ? {
|
|
6930
|
+
provider: CODEX_AGENT_PROVIDER,
|
|
6931
|
+
providerInterface: "codex_app_server",
|
|
6932
|
+
providerThreadId: normalizedThreadId,
|
|
6933
|
+
state: VIBE64_AGENT_RUN_STATE.COMPLETED
|
|
6934
|
+
} : {}),
|
|
6927
6935
|
providerGoalStatus: goalStatus,
|
|
6928
6936
|
providerGoalThreadId: normalizedThreadId,
|
|
6929
6937
|
providerGoalUpdatedAt: updatedAt
|
|
@@ -6950,7 +6958,7 @@ function createCodexTerminalController({
|
|
|
6950
6958
|
};
|
|
6951
6959
|
}
|
|
6952
6960
|
if (
|
|
6953
|
-
CODEX_APP_SERVER_GOAL_STATUSES.has(goalStatus) &&
|
|
6961
|
+
(goalCleared || CODEX_APP_SERVER_GOAL_STATUSES.has(goalStatus)) &&
|
|
6954
6962
|
goalStatus !== "active" &&
|
|
6955
6963
|
turn.state === "finalizing" &&
|
|
6956
6964
|
turn.threadId === normalizedThreadId &&
|
|
@@ -7044,8 +7052,16 @@ function createCodexTerminalController({
|
|
|
7044
7052
|
);
|
|
7045
7053
|
});
|
|
7046
7054
|
}
|
|
7055
|
+
if (method === "thread/goal/cleared") {
|
|
7056
|
+
runCodexAppServerNotificationTask(notificationContext, async () => {
|
|
7057
|
+
await reconcileCodexAppServerGoalUpdated(normalizedSessionId, provider, normalizedThreadId, notification);
|
|
7058
|
+
await publishSessionChanged(normalizedSessionId, { reason: "codex-goal" });
|
|
7059
|
+
});
|
|
7060
|
+
return;
|
|
7061
|
+
}
|
|
7047
7062
|
if (method === "thread/goal/updated") {
|
|
7048
|
-
runCodexAppServerNotificationTask(notificationContext, () => {
|
|
7063
|
+
runCodexAppServerNotificationTask(notificationContext, async () => {
|
|
7064
|
+
await publishSessionChanged(normalizedSessionId, { reason: "codex-goal" });
|
|
7049
7065
|
return reconcileCodexAppServerGoalUpdated(
|
|
7050
7066
|
normalizedSessionId,
|
|
7051
7067
|
provider,
|
|
@@ -8990,10 +9006,10 @@ function createCodexTerminalController({
|
|
|
8990
9006
|
);
|
|
8991
9007
|
error.code = "vibe64_codex_economy_ownership_blocked";
|
|
8992
9008
|
error.statusCode = 409;
|
|
8993
|
-
error.retryable =
|
|
9009
|
+
error.retryable = details.retryable !== false;
|
|
8994
9010
|
error.details = {
|
|
8995
9011
|
...details,
|
|
8996
|
-
retryable:
|
|
9012
|
+
retryable: error.retryable
|
|
8997
9013
|
};
|
|
8998
9014
|
return error;
|
|
8999
9015
|
}
|
|
@@ -9066,33 +9082,31 @@ function createCodexTerminalController({
|
|
|
9066
9082
|
await pendingMutation.catch(() => null);
|
|
9067
9083
|
}
|
|
9068
9084
|
const existing = codexAppServerEconomyThreads.get(key);
|
|
9069
|
-
if (existing
|
|
9070
|
-
|
|
9071
|
-
|
|
9072
|
-
|
|
9073
|
-
|
|
9074
|
-
|
|
9075
|
-
|
|
9076
|
-
|
|
9077
|
-
|
|
9078
|
-
|
|
9079
|
-
|
|
9080
|
-
|
|
9081
|
-
}
|
|
9082
|
-
if (
|
|
9083
|
-
session.status !== VIBE64_SESSION_STATUS.ARCHIVED &&
|
|
9084
|
-
!sessionIsClosing(session)
|
|
9085
|
-
) {
|
|
9085
|
+
if (existing && (
|
|
9086
|
+
existing.ownershipId !== record.ownershipId ||
|
|
9087
|
+
existing.revision < record.revision
|
|
9088
|
+
)) {
|
|
9089
|
+
throw codexAppServerEconomyOwnershipError(
|
|
9090
|
+
"Persisted Codex economy ownership changed while the controller was running.",
|
|
9091
|
+
{ sessionId: record.sessionId, threadId: record.threadId }
|
|
9092
|
+
);
|
|
9093
|
+
}
|
|
9094
|
+
const cleanupRequired = record.lifecycle === CODEX_ECONOMY_THREAD_LIFECYCLES.CLEANUP_REQUIRED;
|
|
9095
|
+
if (existing && !cleanupRequired) {
|
|
9096
|
+
if (session.status !== VIBE64_SESSION_STATUS.ARCHIVED && !sessionIsClosing(session)) {
|
|
9086
9097
|
return { record: existing, retiredThreadId: "" };
|
|
9087
9098
|
}
|
|
9088
9099
|
await retireCodexAppServerEconomyThread(existing);
|
|
9089
9100
|
return { record: null, retiredThreadId: existing.threadId };
|
|
9090
9101
|
}
|
|
9091
9102
|
if (!await directoryExists(record.identity.runtime.runtimeDir)) {
|
|
9092
|
-
|
|
9103
|
+
if (existing) {
|
|
9104
|
+
await retireCodexAppServerEconomyThread(existing);
|
|
9105
|
+
} else {
|
|
9106
|
+
await ledger.remove(record);
|
|
9107
|
+
}
|
|
9093
9108
|
return { record: null, retiredThreadId: record.threadId };
|
|
9094
9109
|
}
|
|
9095
|
-
const executionRoot = terminalSessionSourceRoot(session);
|
|
9096
9110
|
const toolHome = await codexToolHomeResult();
|
|
9097
9111
|
if (toolHome.ok === false) {
|
|
9098
9112
|
throw codexAppServerEconomyOwnershipError(toolHome.error, {
|
|
@@ -9102,57 +9116,55 @@ function createCodexTerminalController({
|
|
|
9102
9116
|
}
|
|
9103
9117
|
const providerOptions = await codexAppServerEconomyRuntimeOptionsForSession(session, {
|
|
9104
9118
|
runtime,
|
|
9105
|
-
executionRoot,
|
|
9119
|
+
executionRoot: terminalSessionSourceRoot(session),
|
|
9106
9120
|
toolHomeSource: toolHome.toolHomeSource,
|
|
9107
9121
|
workdir: record.workdir
|
|
9108
9122
|
});
|
|
9109
9123
|
const providerKey = codexAppServerProviderKey(record.sessionId, providerOptions);
|
|
9110
|
-
|
|
9124
|
+
const contextChanged = !existing &&
|
|
9125
|
+
codexAppServerProviderKeyFingerprint(providerKey) !== record.identity.providerKeyFingerprint;
|
|
9126
|
+
if (cleanupRequired || contextChanged) {
|
|
9111
9127
|
const staleProvider = codexAppServerProviderFactory({
|
|
9112
9128
|
...providerOptions,
|
|
9113
9129
|
runtimeDir: record.identity.runtime.runtimeDir
|
|
9114
9130
|
});
|
|
9115
9131
|
try {
|
|
9116
|
-
if (typeof staleProvider.currentRuntimeInfo !== "function") {
|
|
9117
|
-
throw codexAppServerEconomyOwnershipError(
|
|
9118
|
-
"The Codex provider cannot verify the account for stale economy ownership.",
|
|
9119
|
-
{
|
|
9120
|
-
sessionId: record.sessionId,
|
|
9121
|
-
threadId: record.threadId
|
|
9122
|
-
}
|
|
9123
|
-
);
|
|
9124
|
-
}
|
|
9125
9132
|
const currentRuntime = await staleProvider.currentRuntimeInfo();
|
|
9126
|
-
|
|
9127
|
-
|
|
9128
|
-
|
|
9129
|
-
) {
|
|
9133
|
+
const accountChanged = record.identity.runtime.accountIdentitySignature !==
|
|
9134
|
+
normalizeText(currentRuntime.accountIdentitySignature);
|
|
9135
|
+
if (accountChanged && !cleanupRequired) {
|
|
9130
9136
|
throw codexAppServerEconomyOwnershipError(
|
|
9131
|
-
"
|
|
9132
|
-
{
|
|
9133
|
-
sessionId: record.sessionId,
|
|
9134
|
-
threadId: record.threadId
|
|
9135
|
-
}
|
|
9137
|
+
"Reconnect the original Codex account to resume or delete this helper thread.",
|
|
9138
|
+
{ retryable: false, sessionId: record.sessionId, threadId: record.threadId }
|
|
9136
9139
|
);
|
|
9137
9140
|
}
|
|
9138
|
-
|
|
9139
|
-
|
|
9140
|
-
|
|
9141
|
-
|
|
9142
|
-
|
|
9143
|
-
|
|
9144
|
-
|
|
9145
|
-
|
|
9146
|
-
|
|
9147
|
-
|
|
9148
|
-
|
|
9141
|
+
if (accountChanged || contextChanged) {
|
|
9142
|
+
// Only the local runtime owner can retire another account's ephemeral
|
|
9143
|
+
// work. Never issue a thread deletion authenticated as the new account.
|
|
9144
|
+
const stopped = await staleProvider.stopRuntime(accountChanged ? {
|
|
9145
|
+
expectedAccountIdentitySignature: record.identity.runtime.accountIdentitySignature
|
|
9146
|
+
} : {});
|
|
9147
|
+
const retired = accountChanged
|
|
9148
|
+
? stopped?.ownershipSuperseded === true || stopped?.processExitVerified === true
|
|
9149
|
+
: codexAppServerRuntimeStopWasVerified(stopped);
|
|
9150
|
+
if (!retired) {
|
|
9151
|
+
throw codexAppServerEconomyOwnershipError(
|
|
9152
|
+
"The earlier Codex runtime could not be verified as retired; its cleanup record has been preserved.",
|
|
9153
|
+
{ sessionId: record.sessionId, threadId: record.threadId }
|
|
9154
|
+
);
|
|
9155
|
+
}
|
|
9156
|
+
await ledger.remove(record);
|
|
9157
|
+
codexAppServerEconomyThreads.delete(key);
|
|
9158
|
+
return { record: null, retiredThreadId: record.threadId };
|
|
9149
9159
|
}
|
|
9150
|
-
await ledger.remove(record);
|
|
9151
|
-
return { record: null, retiredThreadId: record.threadId };
|
|
9152
9160
|
} finally {
|
|
9153
9161
|
staleProvider.close?.();
|
|
9154
9162
|
}
|
|
9155
9163
|
}
|
|
9164
|
+
if (existing) {
|
|
9165
|
+
await retireCodexAppServerEconomyThread(existing);
|
|
9166
|
+
return { record: null, retiredThreadId: existing.threadId };
|
|
9167
|
+
}
|
|
9156
9168
|
let provider = codexAppServerProviders.get(providerKey);
|
|
9157
9169
|
if (!provider) {
|
|
9158
9170
|
assertCodexAppServerControllerOpen();
|
|
@@ -9182,6 +9194,7 @@ function createCodexTerminalController({
|
|
|
9182
9194
|
throw codexAppServerEconomyOwnershipError(
|
|
9183
9195
|
"The current Codex runtime/auth identity does not match persisted economy ownership.",
|
|
9184
9196
|
{
|
|
9197
|
+
retryable: record.identity.runtime.accountIdentitySignature === normalizeText(expectedRuntime.accountIdentitySignature),
|
|
9185
9198
|
sessionId: record.sessionId,
|
|
9186
9199
|
threadId: record.threadId
|
|
9187
9200
|
}
|
|
@@ -9281,6 +9294,7 @@ function createCodexTerminalController({
|
|
|
9281
9294
|
return !normalizedSessionId || record.sessionId === normalizedSessionId;
|
|
9282
9295
|
});
|
|
9283
9296
|
const retiredThreadIds = [];
|
|
9297
|
+
const retiredBySession = new Map();
|
|
9284
9298
|
for (const record of records) {
|
|
9285
9299
|
try {
|
|
9286
9300
|
const currentSession = normalizeText(session?.sessionId || session?.id) === record.sessionId
|
|
@@ -9293,11 +9307,47 @@ function createCodexTerminalController({
|
|
|
9293
9307
|
});
|
|
9294
9308
|
if (normalizeText(restored?.retiredThreadId)) {
|
|
9295
9309
|
retiredThreadIds.push(normalizeText(restored.retiredThreadId));
|
|
9310
|
+
const retired = retiredBySession.get(record.sessionId) || [];
|
|
9311
|
+
retired.push(normalizeText(restored.retiredThreadId));
|
|
9312
|
+
retiredBySession.set(record.sessionId, retired);
|
|
9296
9313
|
}
|
|
9297
9314
|
} catch (error) {
|
|
9298
9315
|
failed.push(codexAppServerEconomyFailure(record, error));
|
|
9299
9316
|
}
|
|
9300
9317
|
}
|
|
9318
|
+
const sessionIds = new Set(records.map((record) => record.sessionId));
|
|
9319
|
+
if (normalizedSessionId) {
|
|
9320
|
+
sessionIds.add(normalizedSessionId);
|
|
9321
|
+
}
|
|
9322
|
+
for (const id of sessionIds) {
|
|
9323
|
+
const failures = failed.filter((failure) => !failure.sessionId || failure.sessionId === id);
|
|
9324
|
+
const retired = retiredBySession.get(id) || [];
|
|
9325
|
+
if (!failures.length && !retired.length) {
|
|
9326
|
+
continue;
|
|
9327
|
+
}
|
|
9328
|
+
const status = failures.length ? "failed" : "ready";
|
|
9329
|
+
const message = failures.length
|
|
9330
|
+
? `${failures.length} helper cleanup record(s) still need attention: ${failures[0].error}`
|
|
9331
|
+
: `Cleaned up ${retired.length} stale helper ownership record(s).`;
|
|
9332
|
+
await effectiveRuntime.store.writeBackgroundTaskEvent(id, "codex-economy-cleanup", {
|
|
9333
|
+
event: {
|
|
9334
|
+
kind: "cleanup-reconciled",
|
|
9335
|
+
message,
|
|
9336
|
+
status,
|
|
9337
|
+
failed: failures,
|
|
9338
|
+
retiredThreadIds: retired
|
|
9339
|
+
},
|
|
9340
|
+
patch: {
|
|
9341
|
+
label: "Low-cost assistant cleanup",
|
|
9342
|
+
message,
|
|
9343
|
+
error: failures[0]?.error || "",
|
|
9344
|
+
code: failures[0]?.code || "",
|
|
9345
|
+
details: { failed: failures },
|
|
9346
|
+
status,
|
|
9347
|
+
retryable: failures.some((failure) => failure.retryable !== false)
|
|
9348
|
+
}
|
|
9349
|
+
});
|
|
9350
|
+
}
|
|
9301
9351
|
return {
|
|
9302
9352
|
failed,
|
|
9303
9353
|
ok: failed.length === 0,
|
|
@@ -9324,6 +9374,7 @@ function createCodexTerminalController({
|
|
|
9324
9374
|
"Vibe64 could not reconcile persisted low-cost assistant thread ownership.",
|
|
9325
9375
|
{
|
|
9326
9376
|
failed: result.failed,
|
|
9377
|
+
retryable: result.failed?.some((failure) => failure.retryable !== false) !== false,
|
|
9327
9378
|
projectRuntimeRoot: normalizeText(result.projectRuntimeRoot)
|
|
9328
9379
|
}
|
|
9329
9380
|
);
|
|
@@ -9750,7 +9801,8 @@ function createCodexTerminalController({
|
|
|
9750
9801
|
? {}
|
|
9751
9802
|
: await currentConversationActorMetadata(input.vibe64User || null),
|
|
9752
9803
|
economyRestore,
|
|
9753
|
-
provider
|
|
9804
|
+
provider,
|
|
9805
|
+
providerOptions: activeProvider?.providerOptions || providerOptions
|
|
9754
9806
|
};
|
|
9755
9807
|
}
|
|
9756
9808
|
|
|
@@ -12590,7 +12642,8 @@ function createCodexTerminalController({
|
|
|
12590
12642
|
currentSession = await runtime.getSession(sessionId);
|
|
12591
12643
|
turn = codexAppServerTurnState(currentSession);
|
|
12592
12644
|
const turnId = normalizeText(turn.turnId);
|
|
12593
|
-
|
|
12645
|
+
const goalAwaitingTurn = !turn.active && turn.goalStatus === "active" && turn.goalThreadId === threadId;
|
|
12646
|
+
if (!turn.active && !goalAwaitingTurn) {
|
|
12594
12647
|
vibe64SessionDebugLog("server.codexTerminal.appServerMessage.newTurn", {
|
|
12595
12648
|
messageId,
|
|
12596
12649
|
reason: "provider_idle",
|
|
@@ -12604,7 +12657,7 @@ function createCodexTerminalController({
|
|
|
12604
12657
|
turnId
|
|
12605
12658
|
});
|
|
12606
12659
|
}
|
|
12607
|
-
if (!turnId || turn.state === "finalizing") {
|
|
12660
|
+
if (goalAwaitingTurn || !turnId || turn.state === "finalizing") {
|
|
12608
12661
|
return withCodexState({
|
|
12609
12662
|
code: CODEX_AGENT_TURN_STEER_FAILED_CODE,
|
|
12610
12663
|
delivered: false,
|
|
@@ -13099,6 +13152,69 @@ function createCodexTerminalController({
|
|
|
13099
13152
|
});
|
|
13100
13153
|
},
|
|
13101
13154
|
|
|
13155
|
+
async readGoal(sessionId, options = {}) {
|
|
13156
|
+
const context = await codexAppServerSessionContext(sessionId, options);
|
|
13157
|
+
if (context.ok === false) {
|
|
13158
|
+
return { status: "unavailable", goal: null };
|
|
13159
|
+
}
|
|
13160
|
+
const threadId = codexAppServerTurnState(context.session).threadId ||
|
|
13161
|
+
codexThreadIdForWorkdir(context.session, context.workdir);
|
|
13162
|
+
if (!threadId) {
|
|
13163
|
+
return { status: "available", goal: null };
|
|
13164
|
+
}
|
|
13165
|
+
const sessionKey = codexTerminalNamespace(sessionId);
|
|
13166
|
+
for (const [key, provider] of codexAppServerProviders) {
|
|
13167
|
+
if (codexAppServerProviderSessionKeys.get(key) === sessionKey &&
|
|
13168
|
+
!provider.isEconomyProvider() && provider.isAvailable()) {
|
|
13169
|
+
const result = await provider.readGoal(threadId);
|
|
13170
|
+
return { status: "available", goal: result.goal || null };
|
|
13171
|
+
}
|
|
13172
|
+
}
|
|
13173
|
+
return { status: "unavailable", goal: null };
|
|
13174
|
+
},
|
|
13175
|
+
|
|
13176
|
+
async updateGoal(sessionId, input = {}, options = {}) {
|
|
13177
|
+
if (!["pause", "resume"].includes(input.action)) {
|
|
13178
|
+
return { ok: false, error: "Choose pause or resume." };
|
|
13179
|
+
}
|
|
13180
|
+
const admission = beginTerminalNamespaceOperation(codexTerminalNamespace(sessionId));
|
|
13181
|
+
if (admission.ok === false) return admission;
|
|
13182
|
+
try {
|
|
13183
|
+
const context = await codexAppServerConversationContext(sessionId, {}, options);
|
|
13184
|
+
if (context.ok === false) return context;
|
|
13185
|
+
const threadId = codexAppServerTurnState(context.session).threadId ||
|
|
13186
|
+
codexThreadIdForWorkdir(context.session, context.workdir);
|
|
13187
|
+
if (!threadId || threadId !== input.threadId) {
|
|
13188
|
+
return { ok: false, error: "The Codex conversation changed. Refresh the goal before trying again." };
|
|
13189
|
+
}
|
|
13190
|
+
const { goal } = await context.provider.readGoal(threadId);
|
|
13191
|
+
if (!goal || goal.status === "complete" || goal.createdAt !== input.createdAt || goal.objective !== input.objective) {
|
|
13192
|
+
return { ok: false, error: "The Codex goal changed. Refresh it before trying again." };
|
|
13193
|
+
}
|
|
13194
|
+
if (input.action === "pause" && !["active", "paused"].includes(goal.status)) {
|
|
13195
|
+
return { ok: false, error: "This goal is already stopped. Refresh its details." };
|
|
13196
|
+
}
|
|
13197
|
+
if (input.action === "resume" && !["paused", "blocked", "usageLimited"].includes(goal.status)) {
|
|
13198
|
+
return { ok: false, error: "This goal cannot be resumed from its current status. Refresh its details." };
|
|
13199
|
+
}
|
|
13200
|
+
subscribeCodexAppServerEvents(sessionId, context.provider, threadId, context.providerOptions);
|
|
13201
|
+
const result = await context.provider.setGoalStatus(threadId, input.action === "pause" ? "paused" : "active");
|
|
13202
|
+
await reconcileCodexAppServerGoalUpdated(sessionId, context.provider, threadId, {
|
|
13203
|
+
params: { goal: result.goal }
|
|
13204
|
+
});
|
|
13205
|
+
if (input.action === "pause") {
|
|
13206
|
+
const stopped = await interruptCodexAppServerTurnWithinAdmission(sessionId, { threadId });
|
|
13207
|
+
if (stopped.ok === false) {
|
|
13208
|
+
return { ...stopped, goal: result.goal };
|
|
13209
|
+
}
|
|
13210
|
+
}
|
|
13211
|
+
await publishSessionChanged(sessionId, { reason: "codex-goal" });
|
|
13212
|
+
return { ok: true, status: "available", goal: result.goal || null };
|
|
13213
|
+
} finally {
|
|
13214
|
+
admission.release();
|
|
13215
|
+
}
|
|
13216
|
+
},
|
|
13217
|
+
|
|
13102
13218
|
async readPlanUsage(sessionId) {
|
|
13103
13219
|
const sessionKey = codexTerminalNamespace(sessionId);
|
|
13104
13220
|
for (const [key, provider] of codexAppServerProviders) {
|
|
@@ -313,6 +313,18 @@ function registerRoutes(
|
|
|
313
313
|
);
|
|
314
314
|
});
|
|
315
315
|
|
|
316
|
+
routes.serviceRoute("GET", "/sessions/:sessionId/agent-goal", {
|
|
317
|
+
summary: "Read the selected Codex conversation goal."
|
|
318
|
+
}, (request) => terminalService().readAgentGoal(
|
|
319
|
+
request.params.sessionId, withVibe64User(request, {})
|
|
320
|
+
));
|
|
321
|
+
|
|
322
|
+
routes.serviceRoute("POST", "/sessions/:sessionId/agent-goal", {
|
|
323
|
+
summary: "Pause or resume the selected Codex conversation goal."
|
|
324
|
+
}, (request) => terminalService().updateAgentGoal(
|
|
325
|
+
request.params.sessionId, withVibe64User(request, routes.requestBody(request))
|
|
326
|
+
));
|
|
327
|
+
|
|
316
328
|
routes.serviceRoute("GET", "/sessions/:sessionId/agent-plan-usage", {
|
|
317
329
|
summary: "Read the selected assistant account's remaining plan allowance."
|
|
318
330
|
}, (request) => terminalService().readAgentPlanUsage(
|
|
@@ -241,6 +241,11 @@ function timestampIso(ms = 0) {
|
|
|
241
241
|
}
|
|
242
242
|
|
|
243
243
|
function agentRunIsActive(run = {}) {
|
|
244
|
+
// Codex acknowledges Resume before its scheduler starts the next turn.
|
|
245
|
+
if (run?.providerGoalStatus === "active" && run.providerGoalThreadId &&
|
|
246
|
+
run.providerGoalThreadId === run.providerThreadId) {
|
|
247
|
+
return true;
|
|
248
|
+
}
|
|
244
249
|
if (run?.active === true) {
|
|
245
250
|
return true;
|
|
246
251
|
}
|
|
@@ -1711,22 +1716,45 @@ function createService({
|
|
|
1711
1716
|
session,
|
|
1712
1717
|
vibe64User: input.vibe64User || null
|
|
1713
1718
|
};
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
agentContext
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
threadInput,
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
turnInput,
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1719
|
+
let commitTitle;
|
|
1720
|
+
try {
|
|
1721
|
+
const providerDescription = await sessionAgent.describeProvider(agentContext);
|
|
1722
|
+
commitTitle = await generateSessionSaveCommitMessage({
|
|
1723
|
+
agentContext,
|
|
1724
|
+
changes: saveMessageInput.changes,
|
|
1725
|
+
deleteThread: (threadInput, options) => sessionAgent.deleteDetachedChatThread(
|
|
1726
|
+
normalizedSessionId,
|
|
1727
|
+
threadInput,
|
|
1728
|
+
options
|
|
1729
|
+
),
|
|
1730
|
+
runAgentTurn: (turnInput, options) => sessionAgent.streamDetachedChatTurn(
|
|
1731
|
+
normalizedSessionId,
|
|
1732
|
+
turnInput,
|
|
1733
|
+
options
|
|
1734
|
+
),
|
|
1735
|
+
expectedAccountIdentitySignature: providerDescription.accountIdentitySignature
|
|
1736
|
+
});
|
|
1737
|
+
} catch (error) {
|
|
1738
|
+
// Naming is optional. Leave failed thread ownership intact and let the
|
|
1739
|
+
// repository owner enforce the normal checkpoint and publish checks.
|
|
1740
|
+
commitTitle = {
|
|
1741
|
+
executionProfile: null,
|
|
1742
|
+
subject: `Save work ${saveMessageInput.checkpoint.checkpointTree.slice(0, 12)}`
|
|
1743
|
+
};
|
|
1744
|
+
logOperationalEvent(logger, "warn", {
|
|
1745
|
+
code: error.code || "vibe64_session_save_message_failed",
|
|
1746
|
+
component: "vibe64.session_save",
|
|
1747
|
+
event: "vibe64.session_save.message_fallback",
|
|
1748
|
+
operationId: input.operationId,
|
|
1749
|
+
sessionId: normalizedSessionId
|
|
1750
|
+
}, "Assistant naming was unavailable; Save is using a checkpoint-based version name.");
|
|
1751
|
+
await input.onProgress?.({
|
|
1752
|
+
code: error.code || "vibe64_session_save_message_failed",
|
|
1753
|
+
kind: "message",
|
|
1754
|
+
message: "Assistant naming is unavailable. Saving with a checkpoint-based version name.",
|
|
1755
|
+
stage: "message-fallback"
|
|
1756
|
+
});
|
|
1757
|
+
}
|
|
1730
1758
|
await input.onProgress?.({
|
|
1731
1759
|
executionProfile: commitTitle.executionProfile,
|
|
1732
1760
|
kind: "message",
|
|
@@ -2381,6 +2409,19 @@ function createService({
|
|
|
2381
2409
|
}
|
|
2382
2410
|
},
|
|
2383
2411
|
|
|
2412
|
+
async readAgentGoal(sessionId, options = {}) {
|
|
2413
|
+
return sessionAgent.readGoal(sessionId, await assistantSessionOptions(sessionId, options));
|
|
2414
|
+
},
|
|
2415
|
+
|
|
2416
|
+
async updateAgentGoal(sessionId, input = {}) {
|
|
2417
|
+
if (input.action === "resume") {
|
|
2418
|
+
return runMainAgentWrite(sessionId, input, (context) => (
|
|
2419
|
+
sessionAgent.updateGoal(sessionId, input, context)
|
|
2420
|
+
), { operation: "resume-agent-goal" });
|
|
2421
|
+
}
|
|
2422
|
+
return sessionAgent.updateGoal(sessionId, input, await assistantSessionOptions(sessionId, input));
|
|
2423
|
+
},
|
|
2424
|
+
|
|
2384
2425
|
async readAgentPlanUsage(sessionId, options = {}) {
|
|
2385
2426
|
return sessionAgent.readPlanUsage(sessionId, await assistantSessionOptions(sessionId, options));
|
|
2386
2427
|
},
|
|
@@ -636,7 +636,14 @@ function createSessionPromptHintsService({
|
|
|
636
636
|
executionProfile: PROMPT_HINT_EXECUTION_PROFILE_REQUEST,
|
|
637
637
|
threadId: job.threadId,
|
|
638
638
|
turnId: job.turnId
|
|
639
|
-
}, agentOptions(job.context, job.vibe64User))).
|
|
639
|
+
}, agentOptions(job.context, job.vibe64User))).then((result) => {
|
|
640
|
+
if (result?.ok !== true) {
|
|
641
|
+
const error = new Error(result?.error || "Prompt hint interruption was not confirmed.");
|
|
642
|
+
error.code = result?.code || "vibe64_prompt_hints_interrupt_unconfirmed";
|
|
643
|
+
throw error;
|
|
644
|
+
}
|
|
645
|
+
return result;
|
|
646
|
+
}).catch((error) => {
|
|
640
647
|
reportDiagnostic("vibe64_prompt_hints_interrupt_failed", error, {
|
|
641
648
|
sessionId: job.sessionId
|
|
642
649
|
});
|
|
@@ -691,6 +698,7 @@ function createSessionPromptHintsService({
|
|
|
691
698
|
} finally {
|
|
692
699
|
if (job.threadId) {
|
|
693
700
|
try {
|
|
701
|
+
await job.interruptPromise;
|
|
694
702
|
const cleanup = await deleteAgentThread(job.sessionId, {
|
|
695
703
|
executionProfile: PROMPT_HINT_EXECUTION_PROFILE_REQUEST,
|
|
696
704
|
threadId: job.threadId
|
|
@@ -155,7 +155,7 @@ async function cleanupSessionSaveCommitMessageThread({
|
|
|
155
155
|
[
|
|
156
156
|
"The temporary naming conversation could not be removed.",
|
|
157
157
|
detail,
|
|
158
|
-
"
|
|
158
|
+
"Cleanup will be retried on the next helper operation; Save can use a checkpoint-based name."
|
|
159
159
|
].filter(Boolean).join(" "),
|
|
160
160
|
text(cleanup?.code) || "vibe64_session_save_message_cleanup_failed"
|
|
161
161
|
);
|