@gkorepanov/ccodex 0.4.20 → 0.4.24
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/README.md +4 -2
- package/agents/codex-wrapper.md +1 -0
- package/config/compatibility.json +5 -5
- package/dist/claude/inputMapper.d.ts +5 -0
- package/dist/claude/inputMapper.js +9 -0
- package/dist/claude/inputMapper.js.map +1 -1
- package/dist/claude/rateLimits.d.ts +2 -1
- package/dist/claude/rateLimits.js +12 -16
- package/dist/claude/rateLimits.js.map +1 -1
- package/dist/claude/service.d.ts +41 -1
- package/dist/claude/service.js +166 -69
- package/dist/claude/service.js.map +1 -1
- package/dist/claude/session/commands.d.ts +36 -0
- package/dist/claude/session/goalState.d.ts +5 -0
- package/dist/claude/session/goalState.js +22 -0
- package/dist/claude/session/goalState.js.map +1 -1
- package/dist/claude/session/providerRuntimeFactory.js +15 -7
- package/dist/claude/session/providerRuntimeFactory.js.map +1 -1
- package/dist/claude/session/repository.d.ts +3 -0
- package/dist/claude/session/repository.js +2 -0
- package/dist/claude/session/repository.js.map +1 -1
- package/dist/claude/session/runtime.d.ts +10 -0
- package/dist/claude/session/runtime.js +45 -3
- package/dist/claude/session/runtime.js.map +1 -1
- package/dist/claude/session/scopeState.js +1 -0
- package/dist/claude/session/scopeState.js.map +1 -1
- package/dist/claude/session/session.d.ts +1 -0
- package/dist/claude/session/session.js +162 -55
- package/dist/claude/session/session.js.map +1 -1
- package/dist/claude/skillCatalog.js +1 -0
- package/dist/claude/skillCatalog.js.map +1 -1
- package/dist/claude/statusCommand.js +1 -2
- package/dist/claude/statusCommand.js.map +1 -1
- package/dist/codex/generated/AuthMode.d.ts +1 -1
- package/dist/codex/generated/ClientRequest.d.ts +25 -0
- package/dist/codex/generated/InternalSessionSource.d.ts +1 -1
- package/dist/codex/generated/ResponseItem.d.ts +3 -1
- package/dist/codex/generated/ResponseItemRuntimeSchema.js +2 -2
- package/dist/codex/generated/ResponseItemRuntimeSchema.js.map +1 -1
- package/dist/codex/generated/ServerNotification.d.ts +23 -0
- package/dist/codex/generated/ServerNotificationEnvelope.d.ts +23 -0
- package/dist/codex/generated/v2/AllowDenyRequirement.d.ts +1 -0
- package/dist/codex/generated/v2/AllowDenyRequirement.js +3 -0
- package/dist/codex/generated/v2/AllowDenyRequirement.js.map +1 -0
- package/dist/codex/generated/v2/AppLinksConfig.d.ts +11 -0
- package/dist/codex/generated/v2/AppLinksConfig.js +3 -0
- package/dist/codex/generated/v2/AppLinksConfig.js.map +1 -0
- package/dist/codex/generated/v2/AppsConfig.d.ts +5 -0
- package/dist/codex/generated/v2/AsyncUserInputQuestion.d.ts +4 -0
- package/dist/codex/generated/v2/AsyncUserInputQuestion.js +3 -0
- package/dist/codex/generated/v2/AsyncUserInputQuestion.js.map +1 -0
- package/dist/codex/generated/v2/AuthRecoveryNotification.d.ts +6 -0
- package/dist/codex/generated/v2/AuthRecoveryNotification.js +3 -0
- package/dist/codex/generated/v2/AuthRecoveryNotification.js.map +1 -0
- package/dist/codex/generated/v2/BedrockSetupParams.d.ts +0 -8
- package/dist/codex/generated/v2/BrowserUseAccessApprovalLifetime.d.ts +1 -0
- package/dist/codex/generated/v2/BrowserUseAccessApprovalLifetime.js +3 -0
- package/dist/codex/generated/v2/BrowserUseAccessApprovalLifetime.js.map +1 -0
- package/dist/codex/generated/v2/BrowserUseConfig.d.ts +8 -0
- package/dist/codex/generated/v2/BrowserUseConfig.js +3 -0
- package/dist/codex/generated/v2/BrowserUseConfig.js.map +1 -0
- package/dist/codex/generated/v2/BrowserUseOriginPolicy.d.ts +11 -0
- package/dist/codex/generated/v2/BrowserUseOriginPolicy.js +3 -0
- package/dist/codex/generated/v2/BrowserUseOriginPolicy.js.map +1 -0
- package/dist/codex/generated/v2/BrowserUseOriginPolicyConfig.d.ts +7 -0
- package/dist/codex/generated/v2/BrowserUseOriginPolicyConfig.js +3 -0
- package/dist/codex/generated/v2/BrowserUseOriginPolicyConfig.js.map +1 -0
- package/dist/codex/generated/v2/BrowserUseRequirements.d.ts +7 -0
- package/dist/codex/generated/v2/CodexErrorInfo.d.ts +1 -1
- package/dist/codex/generated/v2/CollabAgentTool.d.ts +1 -1
- package/dist/codex/generated/v2/CollabAgentToolCallStatus.d.ts +1 -1
- package/dist/codex/generated/v2/CommandExecutionApprovalKind.d.ts +4 -0
- package/dist/codex/generated/v2/CommandExecutionApprovalKind.js +3 -0
- package/dist/codex/generated/v2/CommandExecutionApprovalKind.js.map +1 -0
- package/dist/codex/generated/v2/CommandExecutionRequestApprovalParams.d.ts +6 -0
- package/dist/codex/generated/v2/ComputerUseConfig.d.ts +8 -0
- package/dist/codex/generated/v2/ComputerUseConfig.js +3 -0
- package/dist/codex/generated/v2/ComputerUseConfig.js.map +1 -0
- package/dist/codex/generated/v2/ComputerUseMacosConfig.d.ts +6 -0
- package/dist/codex/generated/v2/ComputerUseMacosConfig.js +3 -0
- package/dist/codex/generated/v2/ComputerUseMacosConfig.js.map +1 -0
- package/dist/codex/generated/v2/ComputerUseMacosRequirements.d.ts +6 -0
- package/dist/codex/generated/v2/ComputerUseMacosRequirements.js +3 -0
- package/dist/codex/generated/v2/ComputerUseMacosRequirements.js.map +1 -0
- package/dist/codex/generated/v2/ComputerUseRequirements.d.ts +7 -0
- package/dist/codex/generated/v2/ComputerUseWindowsConfig.d.ts +8 -0
- package/dist/codex/generated/v2/ComputerUseWindowsConfig.js +3 -0
- package/dist/codex/generated/v2/ComputerUseWindowsConfig.js.map +1 -0
- package/dist/codex/generated/v2/ComputerUseWindowsExeConfig.d.ts +7 -0
- package/dist/codex/generated/v2/ComputerUseWindowsExeConfig.js +3 -0
- package/dist/codex/generated/v2/ComputerUseWindowsExeConfig.js.map +1 -0
- package/dist/codex/generated/v2/ComputerUseWindowsExeRequirement.d.ts +7 -0
- package/dist/codex/generated/v2/ComputerUseWindowsExeRequirement.js +3 -0
- package/dist/codex/generated/v2/ComputerUseWindowsExeRequirement.js.map +1 -0
- package/dist/codex/generated/v2/ComputerUseWindowsRequirements.d.ts +8 -0
- package/dist/codex/generated/v2/ComputerUseWindowsRequirements.js +3 -0
- package/dist/codex/generated/v2/ComputerUseWindowsRequirements.js.map +1 -0
- package/dist/codex/generated/v2/Config.d.ts +4 -0
- package/dist/codex/generated/v2/ConfigRequirements.d.ts +4 -0
- package/dist/codex/generated/v2/CyberAccessProgram.d.ts +5 -0
- package/dist/codex/generated/v2/CyberAccessProgram.js +3 -0
- package/dist/codex/generated/v2/CyberAccessProgram.js.map +1 -0
- package/dist/codex/generated/v2/GetAccountRateLimitsResponse.d.ts +10 -0
- package/dist/codex/generated/v2/GuardianApprovalReviewAction.d.ts +7 -0
- package/dist/codex/generated/v2/HookEventName.d.ts +1 -1
- package/dist/codex/generated/v2/InAppBrowserRequirements.d.ts +3 -0
- package/dist/codex/generated/v2/InAppBrowserRequirements.js +3 -0
- package/dist/codex/generated/v2/InAppBrowserRequirements.js.map +1 -0
- package/dist/codex/generated/v2/ItemGuardianApprovalReviewCompletedNotification.d.ts +2 -0
- package/dist/codex/generated/v2/ItemGuardianApprovalReviewStartedNotification.d.ts +2 -0
- package/dist/codex/generated/v2/LoginAccountParams.d.ts +6 -0
- package/dist/codex/generated/v2/ManagedHooksRequirements.d.ts +1 -0
- package/dist/codex/generated/v2/McpServerConnectionStatus.d.ts +1 -0
- package/dist/codex/generated/v2/McpServerConnectionStatus.js +3 -0
- package/dist/codex/generated/v2/McpServerConnectionStatus.js.map +1 -0
- package/dist/codex/generated/v2/McpServerElicitationRequestParams.d.ts +5 -0
- package/dist/codex/generated/v2/McpServerEventNotification.d.ts +5 -0
- package/dist/codex/generated/v2/McpServerEventNotification.js +3 -0
- package/dist/codex/generated/v2/McpServerEventNotification.js.map +1 -0
- package/dist/codex/generated/v2/McpServerEventStreamNotification.d.ts +5 -0
- package/dist/codex/generated/v2/McpServerEventStreamNotification.js +3 -0
- package/dist/codex/generated/v2/McpServerEventStreamNotification.js.map +1 -0
- package/dist/codex/generated/v2/McpServerEventStreamStartParams.d.ts +9 -0
- package/dist/codex/generated/v2/McpServerEventStreamStartParams.js +3 -0
- package/dist/codex/generated/v2/McpServerEventStreamStartParams.js.map +1 -0
- package/dist/codex/generated/v2/McpServerEventStreamStartResponse.d.ts +1 -0
- package/dist/codex/generated/v2/McpServerEventStreamStartResponse.js +3 -0
- package/dist/codex/generated/v2/McpServerEventStreamStartResponse.js.map +1 -0
- package/dist/codex/generated/v2/McpServerEventStreamStopParams.d.ts +3 -0
- package/dist/codex/generated/v2/McpServerEventStreamStopParams.js +3 -0
- package/dist/codex/generated/v2/McpServerEventStreamStopParams.js.map +1 -0
- package/dist/codex/generated/v2/McpServerEventStreamStopResponse.d.ts +1 -0
- package/dist/codex/generated/v2/McpServerEventStreamStopResponse.js +3 -0
- package/dist/codex/generated/v2/McpServerEventStreamStopResponse.js.map +1 -0
- package/dist/codex/generated/v2/McpServerStatus.d.ts +5 -0
- package/dist/codex/generated/v2/MisalignmentErrorDetails.d.ts +15 -0
- package/dist/codex/generated/v2/MisalignmentErrorDetails.js +3 -0
- package/dist/codex/generated/v2/MisalignmentErrorDetails.js.map +1 -0
- package/dist/codex/generated/v2/MisalignmentSteer.d.ts +3 -0
- package/dist/codex/generated/v2/MisalignmentSteer.js +3 -0
- package/dist/codex/generated/v2/MisalignmentSteer.js.map +1 -0
- package/dist/codex/generated/v2/PluginReconcileChangedPlugin.d.ts +19 -0
- package/dist/codex/generated/v2/PluginReconcileChangedPlugin.js +3 -0
- package/dist/codex/generated/v2/PluginReconcileChangedPlugin.js.map +1 -0
- package/dist/codex/generated/v2/PluginReconcileParams.d.ts +6 -0
- package/dist/codex/generated/v2/PluginReconcileParams.js +3 -0
- package/dist/codex/generated/v2/PluginReconcileParams.js.map +1 -0
- package/dist/codex/generated/v2/PluginReconcileResponse.d.ts +23 -0
- package/dist/codex/generated/v2/PluginReconcileResponse.js +3 -0
- package/dist/codex/generated/v2/PluginReconcileResponse.js.map +1 -0
- package/dist/codex/generated/v2/Project.d.ts +4 -0
- package/dist/codex/generated/v2/ProjectListParams.d.ts +10 -0
- package/dist/codex/generated/v2/ProjectSortKey.d.ts +1 -0
- package/dist/codex/generated/v2/ProjectSortKey.js +3 -0
- package/dist/codex/generated/v2/ProjectSortKey.js.map +1 -0
- package/dist/codex/generated/v2/RawResponseCompletedNotification.d.ts +2 -0
- package/dist/codex/generated/v2/ResponseUsageMetadata.d.ts +8 -0
- package/dist/codex/generated/v2/ResponseUsageMetadata.js +3 -0
- package/dist/codex/generated/v2/ResponseUsageMetadata.js.map +1 -0
- package/dist/codex/generated/v2/SkillMetadata.d.ts +4 -0
- package/dist/codex/generated/v2/SubAgentActivityKind.d.ts +1 -1
- package/dist/codex/generated/v2/Thread.d.ts +11 -0
- package/dist/codex/generated/v2/ThreadForkParams.d.ts +3 -1
- package/dist/codex/generated/v2/ThreadItem.d.ts +9 -0
- package/dist/codex/generated/v2/ThreadReadParams.d.ts +3 -0
- package/dist/codex/generated/v2/ThreadRealtimeBemItemPresentation.d.ts +11 -0
- package/dist/codex/generated/v2/ThreadRealtimeBemItemPresentation.js +3 -0
- package/dist/codex/generated/v2/ThreadRealtimeBemItemPresentation.js.map +1 -0
- package/dist/codex/generated/v2/ThreadRealtimeItem.d.ts +24 -0
- package/dist/codex/generated/v2/ThreadRealtimeItem.js +3 -0
- package/dist/codex/generated/v2/ThreadRealtimeItem.js.map +1 -0
- package/dist/codex/generated/v2/ThreadRealtimeItemCompletedNotification.d.ts +8 -0
- package/dist/codex/generated/v2/ThreadRealtimeItemCompletedNotification.js +3 -0
- package/dist/codex/generated/v2/ThreadRealtimeItemCompletedNotification.js.map +1 -0
- package/dist/codex/generated/v2/ThreadRealtimeItemStartedNotification.d.ts +8 -0
- package/dist/codex/generated/v2/ThreadRealtimeItemStartedNotification.js +3 -0
- package/dist/codex/generated/v2/ThreadRealtimeItemStartedNotification.js.map +1 -0
- package/dist/codex/generated/v2/ThreadRealtimeItemTranscriptDeltaNotification.d.ts +8 -0
- package/dist/codex/generated/v2/ThreadRealtimeItemTranscriptDeltaNotification.js +3 -0
- package/dist/codex/generated/v2/ThreadRealtimeItemTranscriptDeltaNotification.js.map +1 -0
- package/dist/codex/generated/v2/ThreadRealtimeSessionOutcome.d.ts +1 -0
- package/dist/codex/generated/v2/ThreadRealtimeSessionOutcome.js +3 -0
- package/dist/codex/generated/v2/ThreadRealtimeSessionOutcome.js.map +1 -0
- package/dist/codex/generated/v2/ThreadRealtimeStartTransport.d.ts +6 -0
- package/dist/codex/generated/v2/ThreadRealtimeTranscriptRole.d.ts +1 -0
- package/dist/codex/generated/v2/ThreadRealtimeTranscriptRole.js +3 -0
- package/dist/codex/generated/v2/ThreadRealtimeTranscriptRole.js.map +1 -0
- package/dist/codex/generated/v2/ThreadResumeParams.d.ts +3 -1
- package/dist/codex/generated/v2/ThreadShellCommandParams.d.ts +6 -0
- package/dist/codex/generated/v2/ThreadTimelineEntry.d.ts +31 -0
- package/dist/codex/generated/v2/ThreadTimelineEntry.js +3 -0
- package/dist/codex/generated/v2/ThreadTimelineEntry.js.map +1 -0
- package/dist/codex/generated/v2/ThreadTimelineListParams.d.ts +8 -0
- package/dist/codex/generated/v2/ThreadTimelineListParams.js +3 -0
- package/dist/codex/generated/v2/ThreadTimelineListParams.js.map +1 -0
- package/dist/codex/generated/v2/ThreadTimelineListResponse.d.ts +9 -0
- package/dist/codex/generated/v2/ThreadTimelineListResponse.js +3 -0
- package/dist/codex/generated/v2/ThreadTimelineListResponse.js.map +1 -0
- package/dist/codex/generated/v2/TurnError.d.ts +5 -0
- package/dist/codex/generated/v2/TurnSettingsUpdateParams.d.ts +34 -0
- package/dist/codex/generated/v2/TurnSettingsUpdateParams.js +3 -0
- package/dist/codex/generated/v2/TurnSettingsUpdateParams.js.map +1 -0
- package/dist/codex/generated/v2/TurnSettingsUpdateResponse.d.ts +4 -0
- package/dist/codex/generated/v2/TurnSettingsUpdateResponse.js +3 -0
- package/dist/codex/generated/v2/TurnSettingsUpdateResponse.js.map +1 -0
- package/dist/codex/generated/v2/TurnSettingsUpdateStatus.d.ts +1 -0
- package/dist/codex/generated/v2/TurnSettingsUpdateStatus.js +3 -0
- package/dist/codex/generated/v2/TurnSettingsUpdateStatus.js.map +1 -0
- package/dist/codex/generated/v2/TurnStartParams.d.ts +19 -0
- package/dist/codex/generated/v2/TurnToolOutput.d.ts +6 -0
- package/dist/codex/generated/v2/TurnToolOutput.js +3 -0
- package/dist/codex/generated/v2/TurnToolOutput.js.map +1 -0
- package/dist/codex/generated/v2/index.d.ts +46 -0
- package/dist/daemon/ownership.js +9 -1
- package/dist/daemon/ownership.js.map +1 -1
- package/dist/daemon/probe.js +1 -1
- package/dist/gateway/clientConnection.js +105 -19
- package/dist/gateway/clientConnection.js.map +1 -1
- package/dist/gateway/optimisticSideThreads.d.ts +11 -5
- package/dist/gateway/optimisticSideThreads.js +103 -47
- package/dist/gateway/optimisticSideThreads.js.map +1 -1
- package/dist/gateway/remoteRelay.js +2 -2
- package/dist/gateway/remoteRelay.js.map +1 -1
- package/dist/gateway/server.js +31 -1
- package/dist/gateway/server.js.map +1 -1
- package/dist/gateway/stockSideThreads.d.ts +3 -6
- package/dist/gateway/stockSideThreads.js +38 -43
- package/dist/gateway/stockSideThreads.js.map +1 -1
- package/dist/gateway/threadList.d.ts +9 -3
- package/dist/gateway/threadList.js +66 -15
- package/dist/gateway/threadList.js.map +1 -1
- package/dist/gateway/transientNotice.js +4 -4
- package/dist/gateway/transientNotice.js.map +1 -1
- package/dist/handoff/service.d.ts +10 -2
- package/dist/handoff/service.js +164 -106
- package/dist/handoff/service.js.map +1 -1
- package/dist/handoff/store.d.ts +21 -0
- package/dist/handoff/store.js +15 -0
- package/dist/handoff/store.js.map +1 -1
- package/dist/handoff/titleGeneration.d.ts +1 -0
- package/dist/handoff/titleGeneration.js.map +1 -1
- package/dist/management/setup.d.ts +6 -0
- package/dist/management/setup.js +11 -3
- package/dist/management/setup.js.map +1 -1
- package/dist/protocol/search.d.ts +24 -0
- package/dist/protocol/search.js +105 -0
- package/dist/protocol/search.js.map +1 -0
- package/dist/protocol/turnPagination.d.ts +16 -0
- package/dist/protocol/turnPagination.js +75 -35
- package/dist/protocol/turnPagination.js.map +1 -1
- package/dist/runtime/dependencies.js +1 -1
- package/dist/store/HybridStore.d.ts +4 -0
- package/dist/store/HybridStore.js +1 -1
- package/dist/store/HybridStore.js.map +1 -1
- package/dist/store/memoryStore.d.ts +6 -0
- package/dist/store/memoryStore.js +16 -0
- package/dist/store/memoryStore.js.map +1 -1
- package/dist/store/sqliteStore.d.ts +3 -0
- package/dist/store/sqliteStore.js +57 -0
- package/dist/store/sqliteStore.js.map +1 -1
- package/legal/THIRD_PARTY_NOTICES.md +160 -140
- package/package.json +6 -6
- package/scripts/install-claude-stack.sh +27 -4
- package/vendor/codex/continuation.md +5 -0
package/dist/claude/service.js
CHANGED
|
@@ -7,8 +7,9 @@ import { SqliteHybridStore } from "../store/sqliteStore.js";
|
|
|
7
7
|
import { LayeredHybridStore } from "../store/memoryStore.js";
|
|
8
8
|
import { createClaudeQuery } from "./queryFactory.js";
|
|
9
9
|
import { claudeEnvironment } from "./environment.js";
|
|
10
|
-
import { invalidParams } from "../protocol/errors.js";
|
|
11
|
-
import { paginateTurns,
|
|
10
|
+
import { invalidParams, invalidRequest } from "../protocol/errors.js";
|
|
11
|
+
import { historyCursors, paginateItems, paginateTurns, startedTurn } from "../protocol/turnPagination.js";
|
|
12
|
+
import { searchTurnOccurrences, threadSearchSnippet } from "../protocol/search.js";
|
|
12
13
|
import { MetricsRegistry } from "../observability/metrics.js";
|
|
13
14
|
import { SdkTranscriptBrancher, } from "./transcriptBrancher.js";
|
|
14
15
|
import { ClaudeRateLimitCoordinator, } from "./rateLimits.js";
|
|
@@ -257,6 +258,8 @@ export class ClaudeService {
|
|
|
257
258
|
nativeSessionCatalog;
|
|
258
259
|
ephemeralReleases = new Map();
|
|
259
260
|
ephemeralReleaseTimers = new Map();
|
|
261
|
+
/** Root threads whose last turn completed or failed and whose queue drains once the session is quiescent. */
|
|
262
|
+
queueDrainPending = new Set();
|
|
260
263
|
removalRetries = new Map();
|
|
261
264
|
terminalAdmins = new Map();
|
|
262
265
|
settingsUpdates = new Map();
|
|
@@ -292,7 +295,7 @@ export class ClaudeService {
|
|
|
292
295
|
const sessionRepository = new ClaudeSessionRepository(this.store);
|
|
293
296
|
this.sessionOutput = new ClaudeOutputAdapter(hub);
|
|
294
297
|
this.rateLimits = new ClaudeRateLimitCoordinator(logger);
|
|
295
|
-
this.sessions = new ClaudeSessionRegistry((threadId) => new ClaudeSession(threadId, sessionRepository, this.sessionOutput, undefined, metrics,
|
|
298
|
+
this.sessions = new ClaudeSessionRegistry((threadId) => new ClaudeSession(threadId, sessionRepository, this.sessionOutput, undefined, metrics, (update) => this.onSessionLifecycle(threadId, update), (childThreadId) => this.sessions.registerChild(childThreadId, threadId), (childThreadId) => this.sessions.unregisterChild(childThreadId), shellRunner, undefined, {
|
|
296
299
|
claudeBinary: this.config.claudeBinary,
|
|
297
300
|
logger: this.logger,
|
|
298
301
|
queryFactory: this.queryFactory,
|
|
@@ -301,7 +304,7 @@ export class ClaudeService {
|
|
|
301
304
|
invalidateModelCatalog: () => this.modelCatalog?.invalidate?.(),
|
|
302
305
|
...(this.skillsChanged ? { skillsChanged: this.skillsChanged } : {}),
|
|
303
306
|
isClosing: () => this.closing,
|
|
304
|
-
persistUserSideSessions:
|
|
307
|
+
persistUserSideSessions: true,
|
|
305
308
|
interactiveQuestions: this.config.features?.interactiveQuestions ?? true,
|
|
306
309
|
resolveChildModel: (model) => {
|
|
307
310
|
const value = normalizeClaudeModelIdentifier(model);
|
|
@@ -548,10 +551,10 @@ export class ClaudeService {
|
|
|
548
551
|
throw invalidParams(`Unknown Claude thread '${threadId}'.`);
|
|
549
552
|
if (record.thread.parentThreadId) {
|
|
550
553
|
record = this.withCatalogModel(record);
|
|
554
|
+
record = { ...record, thread: this.withNativeMetadata(record) };
|
|
551
555
|
return {
|
|
552
556
|
...threadResponse(record, !resume.excludeTurns),
|
|
553
|
-
|
|
554
|
-
itemsBackwardsCursor: record.thread.turns.some((turn) => turn.items.length) ? "hyb-item:0" : null,
|
|
557
|
+
...historyCursors(record.thread.turns),
|
|
555
558
|
initialTurnsPage: resume.initialTurnsPage
|
|
556
559
|
? this.turnsPage({
|
|
557
560
|
threadId,
|
|
@@ -575,10 +578,12 @@ export class ClaudeService {
|
|
|
575
578
|
await (await this.sessions.getOrCreate(threadId)).materializeRuntime();
|
|
576
579
|
record = await this.sessions.submit(threadId, { type: "readThread", includeTurns: true });
|
|
577
580
|
record = this.withCatalogModel(record);
|
|
581
|
+
record = { ...record, thread: this.withNativeMetadata(record) };
|
|
582
|
+
if (this.store.listQueuedSubmissions(threadId).length)
|
|
583
|
+
this.scheduleQueueDrain(threadId);
|
|
578
584
|
return {
|
|
579
585
|
...threadResponse(record, !resume.excludeTurns),
|
|
580
|
-
|
|
581
|
-
itemsBackwardsCursor: record.thread.turns.some((turn) => turn.items.length) ? "hyb-item:0" : null,
|
|
586
|
+
...historyCursors(record.thread.turns),
|
|
582
587
|
initialTurnsPage: resume.initialTurnsPage
|
|
583
588
|
? this.turnsPage({
|
|
584
589
|
threadId,
|
|
@@ -629,6 +634,10 @@ export class ClaudeService {
|
|
|
629
634
|
}
|
|
630
635
|
async prepareTurn(params, review) {
|
|
631
636
|
this.requireIndependentThread(params.threadId, "start a turn in");
|
|
637
|
+
if (params.toolOutput)
|
|
638
|
+
throw invalidParams("Claude threads do not support toolOutput.");
|
|
639
|
+
if (params.serviceTierForTurn != null)
|
|
640
|
+
this.logger.warn("claude.turn.service-tier-for-turn.ignored", { threadId: params.threadId, serviceTierForTurn: params.serviceTierForTurn });
|
|
632
641
|
const availability = await this.availabilityProbe();
|
|
633
642
|
if (availability.state !== "ready")
|
|
634
643
|
throw invalidParams(providerUnavailableMessage(availability));
|
|
@@ -655,7 +664,8 @@ export class ClaudeService {
|
|
|
655
664
|
let announcement;
|
|
656
665
|
const startAndWait = () => announcement ? announcement.then(startRuntime) : startRuntime();
|
|
657
666
|
return {
|
|
658
|
-
response: { turn: prepared.turn },
|
|
667
|
+
response: { turn: startedTurn(prepared.turn) },
|
|
668
|
+
turn: prepared.turn,
|
|
659
669
|
announce: () => announcement ??= this.sessions.submit(params.threadId, { type: "announceTurn", turnId: prepared.turn.id }),
|
|
660
670
|
start: () => {
|
|
661
671
|
void startAndWait().catch((error) => this.logger.error("claude.turn.start-failed", { threadId: params.threadId, error: String(error) }));
|
|
@@ -891,7 +901,10 @@ export class ClaudeService {
|
|
|
891
901
|
}
|
|
892
902
|
async shellCommand(params) {
|
|
893
903
|
this.requireIndependentThread(params.threadId, "run a shell command in");
|
|
894
|
-
|
|
904
|
+
const timeoutMs = params.timeoutMs ?? 3_600_000;
|
|
905
|
+
if (timeoutMs < 0)
|
|
906
|
+
throw invalidParams(`thread/shellCommand timeoutMs must be non-negative, got ${timeoutMs}`);
|
|
907
|
+
await this.sessions.submit(params.threadId, { type: "runShell", command: params.command, timeoutMs });
|
|
895
908
|
return {};
|
|
896
909
|
}
|
|
897
910
|
async prepareReview(params) {
|
|
@@ -914,6 +927,8 @@ export class ClaudeService {
|
|
|
914
927
|
let reviewThreadId = params.threadId;
|
|
915
928
|
let forkedThread;
|
|
916
929
|
if (params.delivery === "detached") {
|
|
930
|
+
if (this.requireRecord(params.threadId, false).thread.historyMode === "paginated")
|
|
931
|
+
throw invalidRequest("paginated threads do not support detached review");
|
|
917
932
|
const fork = await this.forkThread({ threadId: params.threadId, excludeTurns: false });
|
|
918
933
|
reviewThreadId = fork.thread.id;
|
|
919
934
|
forkedThread = fork.thread;
|
|
@@ -923,7 +938,7 @@ export class ClaudeService {
|
|
|
923
938
|
threadId: reviewThreadId,
|
|
924
939
|
input: [{ type: "text", text: prompt, text_elements: [] }],
|
|
925
940
|
}, { label: review, display: review });
|
|
926
|
-
const userItem = prepared.
|
|
941
|
+
const userItem = prepared.turn.items.find((item) => item.type === "userMessage");
|
|
927
942
|
return {
|
|
928
943
|
response: {
|
|
929
944
|
turn: {
|
|
@@ -982,6 +997,15 @@ export class ClaudeService {
|
|
|
982
997
|
this.nativeMetadataRead = read;
|
|
983
998
|
return read;
|
|
984
999
|
}
|
|
1000
|
+
async setGeneratedThreadName(params, userPrompt) {
|
|
1001
|
+
const record = this.requireRecord(params.threadId, false);
|
|
1002
|
+
if (record.thread.parentThreadId || this.nativeMetadata.get(record.claudeSessionId)?.customTitle)
|
|
1003
|
+
return;
|
|
1004
|
+
await this.sessions.submit(params.threadId, {
|
|
1005
|
+
type: "threadAdmin",
|
|
1006
|
+
command: { kind: "generatedName", name: params.name, userPrompt },
|
|
1007
|
+
});
|
|
1008
|
+
}
|
|
985
1009
|
async setThreadName(params) {
|
|
986
1010
|
const record = this.requireRecord(params.threadId, false);
|
|
987
1011
|
if (record.thread.parentThreadId) {
|
|
@@ -1086,7 +1110,7 @@ export class ClaudeService {
|
|
|
1086
1110
|
if (this.closing || this.ephemeralReleaseTimers.has(threadId))
|
|
1087
1111
|
return;
|
|
1088
1112
|
const record = this.store.getThreadRecord(threadId, false);
|
|
1089
|
-
if (!record?.thread.ephemeral || record.thread.parentThreadId)
|
|
1113
|
+
if (!record?.thread.ephemeral || record.thread.parentThreadId || record.thread.threadSource === "user")
|
|
1090
1114
|
return;
|
|
1091
1115
|
const timer = setTimeout(() => {
|
|
1092
1116
|
this.ephemeralReleaseTimers.delete(threadId);
|
|
@@ -1125,63 +1149,28 @@ export class ClaudeService {
|
|
|
1125
1149
|
}
|
|
1126
1150
|
listItems(params) {
|
|
1127
1151
|
this.assertThreadAvailable(params.threadId);
|
|
1128
|
-
|
|
1129
|
-
.flatMap((turn) => params.turnId && turn.id !== params.turnId
|
|
1130
|
-
? []
|
|
1131
|
-
: turn.items.map((item) => ({ turnId: turn.id, item })));
|
|
1132
|
-
const ordered = params.sortDirection === "desc" ? [...items].reverse() : items;
|
|
1133
|
-
if (params.cursor && !params.cursor.startsWith("hyb-item:"))
|
|
1134
|
-
throw invalidParams("Invalid Claude item cursor.");
|
|
1135
|
-
const offset = params.cursor?.startsWith("hyb-item:") ? Number(params.cursor.slice("hyb-item:".length)) : 0;
|
|
1136
|
-
if (!Number.isInteger(offset) || offset < 0)
|
|
1137
|
-
throw invalidParams("Invalid Claude item cursor.");
|
|
1138
|
-
const limit = Math.max(1, Math.min(params.limit ?? 50, 100));
|
|
1139
|
-
const data = ordered.slice(offset, offset + limit);
|
|
1140
|
-
return {
|
|
1141
|
-
data,
|
|
1142
|
-
nextCursor: offset + data.length < ordered.length ? `hyb-item:${offset + data.length}` : null,
|
|
1143
|
-
backwardsCursor: data.length > 0 ? `hyb-item:${Math.max(0, offset - limit)}` : null,
|
|
1144
|
-
};
|
|
1152
|
+
return paginateItems(this.store.listTurns(params.threadId), params, ["hyb-item:"]);
|
|
1145
1153
|
}
|
|
1146
1154
|
searchOccurrences(params) {
|
|
1147
1155
|
this.assertThreadAvailable(params.threadId);
|
|
1156
|
+
return searchTurnOccurrences(params.threadId, this.store.listTurns(params.threadId), params);
|
|
1157
|
+
}
|
|
1158
|
+
/** `thread/search` over durable Claude threads: one result per thread with the first matching snippet. */
|
|
1159
|
+
searchThreads(params) {
|
|
1148
1160
|
const searchTerm = params.searchTerm.trim();
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
if (params.cursor && !params.cursor.startsWith("hyb-search:"))
|
|
1152
|
-
throw invalidParams("Invalid Claude search cursor.");
|
|
1153
|
-
const offset = params.cursor ? Number(params.cursor.slice("hyb-search:".length)) : 0;
|
|
1154
|
-
if (!Number.isInteger(offset) || offset < 0)
|
|
1155
|
-
throw invalidParams("Invalid Claude search cursor.");
|
|
1156
|
-
const turns = this.store.listTurns(params.threadId);
|
|
1157
|
-
const needle = searchTerm.toLocaleLowerCase();
|
|
1158
|
-
const occurrences = turns.flatMap((turn) => turn.items.flatMap((item) => {
|
|
1159
|
-
const text = item.type === "userMessage"
|
|
1160
|
-
? item.content.flatMap((part) => part.type === "text" ? [part.text] : []).join("\n")
|
|
1161
|
-
: item.type === "agentMessage" && item.phase !== "commentary" ? item.text : undefined;
|
|
1162
|
-
if (text === undefined)
|
|
1161
|
+
return this.listThreads({ archived: params.archived ?? false }).flatMap((thread) => {
|
|
1162
|
+
if (thread.ephemeral)
|
|
1163
1163
|
return [];
|
|
1164
|
-
const
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
matches.push({
|
|
1168
|
-
turnId: turn.id,
|
|
1169
|
-
itemId: item.id,
|
|
1170
|
-
snippet: text,
|
|
1171
|
-
snippetMatchRange: { start, end: start + needle.length },
|
|
1172
|
-
turnCursor: turnCursor(turn.id, true),
|
|
1173
|
-
});
|
|
1174
|
-
}
|
|
1175
|
-
return matches;
|
|
1176
|
-
}));
|
|
1177
|
-
const limit = Math.max(1, Math.min(params.limit ?? 50, 100));
|
|
1178
|
-
const data = occurrences.slice(offset, offset + limit);
|
|
1179
|
-
return {
|
|
1180
|
-
data,
|
|
1181
|
-
nextCursor: offset + data.length < occurrences.length ? `hyb-search:${offset + data.length}` : null,
|
|
1182
|
-
};
|
|
1164
|
+
const snippet = threadSearchSnippet(this.store.listTurns(thread.id), searchTerm);
|
|
1165
|
+
return snippet === undefined ? [] : [{ thread: { ...thread, turns: [] }, snippet }];
|
|
1166
|
+
});
|
|
1183
1167
|
}
|
|
1184
|
-
async forkThread(params, visibleForkedFromId = params.threadId) {
|
|
1168
|
+
async forkThread(params, visibleForkedFromId = params.threadId, reservedSideId) {
|
|
1169
|
+
if (reservedSideId && this.store.hasThread(reservedSideId)) {
|
|
1170
|
+
const session = await this.sessions.getOrCreate(reservedSideId);
|
|
1171
|
+
await session.ensureEphemeralRuntime();
|
|
1172
|
+
return threadResponse(this.requireRecord(reservedSideId, false), false);
|
|
1173
|
+
}
|
|
1185
1174
|
if (params.path)
|
|
1186
1175
|
throw invalidParams("Claude thread forks must use threadId, not a Codex rollout path.");
|
|
1187
1176
|
this.requireIndependentThread(params.threadId, "fork");
|
|
@@ -1194,6 +1183,8 @@ export class ClaudeService {
|
|
|
1194
1183
|
: undefined;
|
|
1195
1184
|
const source = await this.sessions.submit(params.threadId, { type: "snapshotBranch" });
|
|
1196
1185
|
const sourceRecord = source.record;
|
|
1186
|
+
if (sourceRecord.thread.historyMode === "paginated" && params.ephemeral && !params.excludeTurns)
|
|
1187
|
+
throw invalidRequest("ephemeral paginated thread/fork requires `excludeTurns: true`");
|
|
1197
1188
|
const sidePromotion = Boolean((this.config.features?.sideChatPromotion ?? true)
|
|
1198
1189
|
&& sourceRecord.thread.ephemeral
|
|
1199
1190
|
&& sourceRecord.thread.threadSource === "user"
|
|
@@ -1271,12 +1262,13 @@ export class ClaudeService {
|
|
|
1271
1262
|
cwd: sourceRecord.thread.cwd,
|
|
1272
1263
|
runtimeWorkspaceRoots: storedWorkspaceRoots(sourceRecord),
|
|
1273
1264
|
});
|
|
1274
|
-
const threadId = uuidv7();
|
|
1265
|
+
const threadId = reservedSideId ?? uuidv7();
|
|
1275
1266
|
const thread = {
|
|
1276
1267
|
...sourceRecord.thread, id: threadId, ephemeral: params.ephemeral ?? false,
|
|
1277
1268
|
section: null, sectionEnteredAt: null, projectId: null,
|
|
1278
1269
|
sessionId: threadId, forkedFromId: visibleForkedFromId,
|
|
1279
|
-
cwd, modelProvider: "claude",
|
|
1270
|
+
cwd, modelProvider: "claude", model: modelPickerId, reasoningEffort,
|
|
1271
|
+
createdAt, updatedAt: createdAt, recencyAt: createdAt,
|
|
1280
1272
|
status: params.ephemeral ? { type: "idle" } : { type: "notLoaded" },
|
|
1281
1273
|
canAcceptDirectInput: true,
|
|
1282
1274
|
name: params.ephemeral
|
|
@@ -1336,6 +1328,8 @@ export class ClaudeService {
|
|
|
1336
1328
|
}
|
|
1337
1329
|
async rollbackThread(params) {
|
|
1338
1330
|
const source = await this.truncationSource(params.threadId, "roll back");
|
|
1331
|
+
if (source.record.thread.historyMode === "paginated")
|
|
1332
|
+
throw invalidRequest("paginated threads do not support thread/rollback");
|
|
1339
1333
|
if (!Number.isInteger(params.numTurns) || params.numTurns < 1)
|
|
1340
1334
|
throw invalidParams("numTurns must be at least 1.");
|
|
1341
1335
|
if (params.numTurns > source.record.thread.turns.length)
|
|
@@ -1352,8 +1346,7 @@ export class ClaudeService {
|
|
|
1352
1346
|
const retained = (await this.truncateThread(source, keepCount)).thread;
|
|
1353
1347
|
return {
|
|
1354
1348
|
thread: { ...retained, turns: [] },
|
|
1355
|
-
|
|
1356
|
-
itemsBackwardsCursor: retained.turns.some((turn) => turn.items.length) ? "hyb-item:0" : null,
|
|
1349
|
+
...historyCursors(retained.turns),
|
|
1357
1350
|
};
|
|
1358
1351
|
}
|
|
1359
1352
|
async truncationSource(threadId, verb) {
|
|
@@ -1399,6 +1392,106 @@ export class ClaudeService {
|
|
|
1399
1392
|
this.requireIndependentThread(params.threadId, "set a goal on");
|
|
1400
1393
|
return this.sessions.submit(params.threadId, { type: "goal", command: { kind: "prepareSet", params } }).then((mutation) => this.goalHandle(params.threadId, mutation));
|
|
1401
1394
|
}
|
|
1395
|
+
async addQueuedSubmission(params) {
|
|
1396
|
+
this.requireIndependentThread(params.threadId, "queue a submission in");
|
|
1397
|
+
const queuedSubmission = await this.sessions.submit(params.threadId, {
|
|
1398
|
+
type: "queue",
|
|
1399
|
+
command: { kind: "add", input: params.input, clientUserMessageId: params.clientUserMessageId },
|
|
1400
|
+
});
|
|
1401
|
+
return { response: { queuedSubmission }, after: () => this.drainQueue(params.threadId) };
|
|
1402
|
+
}
|
|
1403
|
+
/** Offset pagination over the durable per-thread queue; the cursor is the base-10 offset, as in stock. */
|
|
1404
|
+
listQueue(params) {
|
|
1405
|
+
this.requireRecord(params.threadId, false);
|
|
1406
|
+
const cursor = params.cursor ?? null;
|
|
1407
|
+
if (cursor !== null && !/^\d+$/u.test(cursor))
|
|
1408
|
+
throw invalidRequest(`invalid queue pagination cursor: ${cursor}`);
|
|
1409
|
+
const offset = cursor === null ? 0 : Number(cursor);
|
|
1410
|
+
const limit = Math.min(Math.max(params.limit ?? 25, 1), 100);
|
|
1411
|
+
const queue = this.store.listQueuedSubmissions(params.threadId);
|
|
1412
|
+
return {
|
|
1413
|
+
data: queue.slice(offset, offset + limit),
|
|
1414
|
+
nextCursor: offset + limit < queue.length ? String(offset + limit) : null,
|
|
1415
|
+
};
|
|
1416
|
+
}
|
|
1417
|
+
async updateQueuedSubmission(params) {
|
|
1418
|
+
this.requireIndependentThread(params.threadId, "update a queued submission in");
|
|
1419
|
+
const queuedSubmission = await this.sessions.submit(params.threadId, {
|
|
1420
|
+
type: "queue",
|
|
1421
|
+
command: { kind: "update", queuedSubmissionId: params.queuedSubmissionId, input: params.input },
|
|
1422
|
+
});
|
|
1423
|
+
return { queuedSubmission };
|
|
1424
|
+
}
|
|
1425
|
+
async deleteQueuedSubmission(params) {
|
|
1426
|
+
this.requireIndependentThread(params.threadId, "delete a queued submission from");
|
|
1427
|
+
const deleted = await this.sessions.submit(params.threadId, {
|
|
1428
|
+
type: "queue", command: { kind: "delete", queuedSubmissionId: params.queuedSubmissionId },
|
|
1429
|
+
});
|
|
1430
|
+
return { deleted };
|
|
1431
|
+
}
|
|
1432
|
+
async reorderQueue(params) {
|
|
1433
|
+
this.requireIndependentThread(params.threadId, "reorder the queue of");
|
|
1434
|
+
await this.sessions.submit(params.threadId, {
|
|
1435
|
+
type: "queue", command: { kind: "reorder", queuedSubmissionIds: params.queuedSubmissionIds },
|
|
1436
|
+
});
|
|
1437
|
+
return {};
|
|
1438
|
+
}
|
|
1439
|
+
async prepareQueueStart(params) {
|
|
1440
|
+
this.requireIndependentThread(params.threadId, "start a queued submission in");
|
|
1441
|
+
const entry = await this.sessions.submit(params.threadId, {
|
|
1442
|
+
type: "queue",
|
|
1443
|
+
command: {
|
|
1444
|
+
kind: "take",
|
|
1445
|
+
manual: true,
|
|
1446
|
+
...(params.queuedSubmissionId == null ? {} : { queuedSubmissionId: params.queuedSubmissionId }),
|
|
1447
|
+
},
|
|
1448
|
+
});
|
|
1449
|
+
return this.startQueuedSubmission(params.threadId, entry);
|
|
1450
|
+
}
|
|
1451
|
+
async startQueuedSubmission(threadId, entry) {
|
|
1452
|
+
try {
|
|
1453
|
+
return await this.prepareTurn({ threadId, input: entry.input, clientUserMessageId: entry.clientUserMessageId });
|
|
1454
|
+
}
|
|
1455
|
+
catch (error) {
|
|
1456
|
+
await this.sessions.submit(threadId, { type: "queue", command: { kind: "restore", entry } });
|
|
1457
|
+
throw error;
|
|
1458
|
+
}
|
|
1459
|
+
}
|
|
1460
|
+
/** Starts the head of the queue when the thread is idle and its last turn was not interrupted. */
|
|
1461
|
+
async drainQueue(threadId) {
|
|
1462
|
+
if (this.closing || this.store.listQueuedSubmissions(threadId).length === 0)
|
|
1463
|
+
return;
|
|
1464
|
+
const entry = await this.sessions.submit(threadId, {
|
|
1465
|
+
type: "queue", command: { kind: "take", manual: false },
|
|
1466
|
+
});
|
|
1467
|
+
if (!entry)
|
|
1468
|
+
return;
|
|
1469
|
+
let prepared;
|
|
1470
|
+
try {
|
|
1471
|
+
prepared = await this.startQueuedSubmission(threadId, entry);
|
|
1472
|
+
}
|
|
1473
|
+
catch (error) {
|
|
1474
|
+
this.logger[error instanceof ActiveClaudeTurnError ? "info" : "warn"]("claude.queue.drain-skipped", {
|
|
1475
|
+
threadId, queuedSubmissionId: entry.id, error: String(error),
|
|
1476
|
+
});
|
|
1477
|
+
return;
|
|
1478
|
+
}
|
|
1479
|
+
await prepared.announce();
|
|
1480
|
+
prepared.start();
|
|
1481
|
+
}
|
|
1482
|
+
scheduleQueueDrain(threadId) {
|
|
1483
|
+
queueMicrotask(() => {
|
|
1484
|
+
void this.drainQueue(threadId).catch((error) => {
|
|
1485
|
+
this.logger.warn("claude.queue.drain-failed", { threadId, error: String(error) });
|
|
1486
|
+
});
|
|
1487
|
+
});
|
|
1488
|
+
}
|
|
1489
|
+
onSessionLifecycle(threadId, update) {
|
|
1490
|
+
if (update.completed && update.completed.turn.status !== "interrupted")
|
|
1491
|
+
this.queueDrainPending.add(threadId);
|
|
1492
|
+
if (update.quiescent && this.queueDrainPending.delete(threadId))
|
|
1493
|
+
this.scheduleQueueDrain(threadId);
|
|
1494
|
+
}
|
|
1402
1495
|
async getGoal(threadId) {
|
|
1403
1496
|
if (this.requireRecord(threadId, false).thread.parentThreadId)
|
|
1404
1497
|
return { goal: null };
|
|
@@ -1708,6 +1801,10 @@ export class ClaudeService {
|
|
|
1708
1801
|
return record;
|
|
1709
1802
|
}
|
|
1710
1803
|
withNativeMetadata(record) {
|
|
1804
|
+
if (record.thread.ephemeral && record.thread.threadSource === "user"
|
|
1805
|
+
&& !record.thread.parentThreadId && record.thread.status.type === "notLoaded") {
|
|
1806
|
+
record = { ...record, thread: { ...record.thread, status: { type: "idle" } } };
|
|
1807
|
+
}
|
|
1711
1808
|
const native = this.nativeMetadata.get(record.claudeSessionId);
|
|
1712
1809
|
if (!native)
|
|
1713
1810
|
return {
|
|
@@ -1807,8 +1904,8 @@ export class ClaudeService {
|
|
|
1807
1904
|
section: null,
|
|
1808
1905
|
sectionEnteredAt: null,
|
|
1809
1906
|
projectId: null,
|
|
1810
|
-
historyMode: params.historyMode ?? "legacy",
|
|
1811
|
-
modelProvider: "claude",
|
|
1907
|
+
historyMode: params.historyMode ?? (params.ephemeral ? "legacy" : "paginated"),
|
|
1908
|
+
modelProvider: "claude", model: modelPickerId, reasoningEffort,
|
|
1812
1909
|
createdAt,
|
|
1813
1910
|
updatedAt: createdAt,
|
|
1814
1911
|
recencyAt: createdAt,
|